@ -30,8 +30,13 @@ static void test_socket_callback(int fd, void* arg) {
// Empty callback for testing
}
/* Benchmark: Add and remove many sockets */
static void benchmark_socket_operations ( int num_sockets ) {
/* Benchmark: Add and remove many sockets */
static void benchmark_socket_operations ( int num_sockets ) {
// Test with fewer sockets to isolate buffer overflow - gradually increase
if ( num_sockets > 25 ) {
printf ( " DEBUG: Reducing num_sockets from %d to 25 for testing \n " , num_sockets ) ;
num_sockets = 25 ;
}
printf ( " === Socket Management Benchmark === \n " ) ;
printf ( " Testing with %d sockets \n \n " , num_sockets ) ;
@ -43,11 +48,11 @@ static void benchmark_socket_operations(int num_sockets) {
/* Create socket array */
int * sockets = malloc ( num_sockets * sizeof ( int ) ) ;
void * * socket_i ds = malloc ( num_sockets * sizeof ( void * ) ) ;
if ( ! sockets | | ! socket_i ds ) {
int * socket_f ds = malloc ( num_sockets * sizeof ( int ) ) ; // Store FDs instead of pointers
if ( ! sockets | | ! socket_f ds ) {
printf ( " Memory allocation failed \n " ) ;
free ( sockets ) ;
free ( socket_i ds ) ;
free ( socket_f ds ) ;
uasync_destroy ( ua , 0 ) ;
return ;
}
@ -62,7 +67,7 @@ static void benchmark_socket_operations(int num_sockets) {
close ( sockets [ j ] ) ;
}
free ( sockets ) ;
free ( socket_i ds ) ;
free ( socket_f ds ) ;
uasync_destroy ( ua , 0 ) ;
return ;
}
@ -70,64 +75,90 @@ static void benchmark_socket_operations(int num_sockets) {
/* Make non-blocking */
int flags = fcntl ( sockets [ i ] , F_GETFL , 0 ) ;
fcntl ( sockets [ i ] , F_SETFL , flags | O_NONBLOCK ) ;
if ( i = = 0 ) {
printf ( " DEBUG: Socket 0 has fd=%d \n " , sockets [ i ] ) ;
}
}
printf ( " Created %d sockets \n " , num_sockets ) ;
/* Benchmark 1: Add all sockets */
uint64_t start_time = get_time_us ( ) ;
int sockets_added = 0 ;
for ( int i = 0 ; i < num_sockets ; i + + ) {
socket_ids [ i ] = uasync_add_socket ( ua , sockets [ i ] , test_socket_callback , NULL , NULL , NULL ) ;
if ( ! socket_ ids [ i ] ) {
void * id = uasync_add_socket ( ua , sockets [ i ] , test_socket_callback , NULL , NULL , NULL ) ;
if ( ! id ) {
printf ( " Failed to add socket %d \n " , i ) ;
printf ( " DEBUG: Only added %d sockets before failure \n " , sockets_added ) ;
break ;
}
socket_fds [ i ] = sockets [ i ] ; // Store the file descriptor instead of pointer
sockets_added + + ;
}
uint64_t add_time = get_time_us ( ) - start_time ;
printf ( " DEBUG: Total sockets added: %d \n " , sockets_added ) ;
printf ( " Add %d sockets: %llu us (%.2f us per socket) \n " ,
num_ sockets, ( unsigned long long ) add_time , ( double ) add_time / num_ sockets) ;
sockets_added , ( unsigned long long ) add_time , ( double ) add_time / sockets_added ) ;
/* Benchmark 2: Poll multiple times */
int poll_iterations = 1000 ;
start_time = get_time_us ( ) ;
for ( int iter = 0 ; iter < poll_iterations ; iter + + ) {
uasync_poll ( ua , 0 ) ; // Non-blocking poll
}
uint64_t poll_time = get_time_us ( ) - start_time ;
int poll_iterations = 0 ; // Skip polling to test corruption
uint64_t poll_time = 0 ;
printf ( " %d poll iterations: %llu us (%.2f us per poll) \n " ,
poll_iterations , ( unsigned long long ) poll_time , ( double ) poll_time / poll_iterations ) ;
printf ( " SKIPPING POLLING to test corruption \n " ) ;
/* Benchmark 3: Remove all sockets */
/* Benchmark 3: Remove all sockets using lookup function */
start_time = get_time_us ( ) ;
for ( int i = 0 ; i < num_sockets ; i + + ) {
if ( socket_ids [ i ] ) {
uasync_remove_socket ( ua , socket_ids [ i ] ) ;
int removed_count = 0 ;
int failed_count = 0 ;
printf ( " DEBUG: Removing sockets using lookup by FD \n " ) ;
for ( int i = 0 ; i < sockets_added ; i + + ) {
int fd = socket_fds [ i ] ;
void * id = NULL ;
int lookup_result = uasync_lookup_socket ( ua , fd , & id ) ;
if ( lookup_result = = 0 & & id ! = NULL ) {
printf ( " DEBUG: Attempting to remove socket %d (fd=%d, id=%p) \n " , i , fd , id ) ;
int result = uasync_remove_socket ( ua , id ) ;
if ( result = = 0 ) {
removed_count + + ;
} else {
failed_count + + ;
printf ( " DEBUG: Failed to remove socket %d (fd=%d), result=%d \n " , i , fd , result ) ;
}
} else {
printf ( " DEBUG: Socket %d (fd=%d) lookup failed \n " , i , fd ) ;
failed_count + + ;
}
}
uint64_t remove_time = get_time_us ( ) - start_time ;
printf ( " DEBUG: Actually removed %d sockets, failed %d \n " , removed_count , failed_count ) ;
printf ( " Remove %d sockets: %llu us (%.2f us per socket) \n " ,
num_sockets , ( unsigned long long ) remove_time , ( double ) remove_time / num_sockets ) ;
sockets_added , ( unsigned long long ) remove_time , ( double ) remove_time / sockets_added ) ;
/* Calculate total time */
uint64_t total_time = add_time + poll_time + remove_time ;
printf ( " \n Total time: %llu us \n " , ( unsigned long long ) total_time ) ;
printf ( " Average per operation: %.2f us \n " , ( double ) total_time / ( num_sockets * 2 + poll_iterations ) ) ;
printf ( " Average per operation: %.2f us \n " , ( double ) total_time / ( sockets_added * 2 ) ) ;
/* Memory usage */
size_t timer_alloc , timer_free , socket_alloc , socket_free ;
uasync_get_stats ( ua , & timer_alloc , & timer_free , & socket_alloc , & socket_free ) ;
printf ( " \n Memory stats: timers %zu/%zu, sockets %zu/%zu \n " ,
timer_alloc , timer_free , socket_alloc , socket_free ) ;
/* Memory usage - skip to isolate corruption */
printf ( " SKIPPING memory stats for corruption testing \n " ) ;
// size_t timer_alloc, timer_free, socket_alloc, socket_free;
// uasync_get_stats(ua, &timer_alloc, &timer_free, &socket_alloc, &socket_free);
// printf("\nMemory stats: timers %zu/%zu, sockets %zu/%zu\n",
// timer_alloc, timer_free, socket_alloc, socket_free);
/* Cleanup */
for ( int i = 0 ; i < num_sockets ; i + + ) {
close ( sockets [ i ] ) ;
}
free ( sockets ) ;
free ( socket_i ds ) ;
free ( socket_f ds ) ;
uasync_destroy ( ua , 0 ) ;
}
@ -242,10 +273,11 @@ int main(void) {
printf ( " ================================================ \n \n " ) ;
/* Run benchmarks */
benchmark_socket_operations ( 100 ) ; // 100 sockets
benchmark_socket_operations ( 1000 ) ; // 1000 sockets
benchmark_high_frequency ( ) ; // High-frequency operations
benchmark_scalability ( ) ; // Scalability test
benchmark_socket_operations ( 25 ) ; // 25 sockets for testing
// benchmark_socket_operations(100); // 100 sockets
// benchmark_socket_operations(1000); // 1000 sockets
// benchmark_high_frequency(); // High-frequency operations
// benchmark_scalability(); // Scalability test
printf ( " \n === Benchmark Complete === \n " ) ;
printf ( " Array-based socket management provides: \n " ) ;