diff --git a/build/build_for_release.sh b/build/build_for_release.sh index 5d00deb..3049029 100755 --- a/build/build_for_release.sh +++ b/build/build_for_release.sh @@ -1,5 +1,8 @@ rm -f CMakeCache.txt rm -rf CMakeFiles +rm -rf cmake +rm -f Makefile +rm -f cmake_install.cmake -cmake ../src -DCMAKE_BUILD_TYPE=Release -DSANITIZER=none +cmake ../src -DCMAKE_BUILD_TYPE=Release -DSANITIZER=none -B . make -B -j8 diff --git a/build/build_for_testing.sh b/build/build_for_testing.sh index d80925f..50bc816 100755 --- a/build/build_for_testing.sh +++ b/build/build_for_testing.sh @@ -1,5 +1,8 @@ rm -f CMakeCache.txt rm -rf CMakeFiles +rm -rf cmake +rm -f Makefile +rm -f cmake_install.cmake -cmake ../src -DCMAKE_BUILD_TYPE=Debug -DSANITIZER=thread -DSWIFT_NET_INTERNAL_TESTING=ON +cmake ../src -DCMAKE_BUILD_TYPE=Debug -DSANITIZER=thread -DSWIFT_NET_INTERNAL_TESTING=ON -B . make -B -j8 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cce15dc..9d28d89 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,8 +5,6 @@ include(GNUInstallDirs) set(CMAKE_C_STANDARD 99) -option(SWIFT_NET_INTERNAL_TESTING "Enable internal testing features" OFF) - set(SOURCE_FILES initialize_swiftnet.c send_packet.c @@ -52,6 +50,8 @@ endif() add_library(swiftnet STATIC ${SOURCE_FILES}) add_library(swiftnet_shared SHARED ${SOURCE_FILES}) +option(SWIFT_NET_INTERNAL_TESTING "Enable internal testing" OFF) + if (SWIFT_NET_INTERNAL_TESTING) message("Internal Testing Enabled") diff --git a/src/cleanup_connection.c b/src/cleanup_connection.c index e8c57e2..50da9b5 100644 --- a/src/cleanup_connection.c +++ b/src/cleanup_connection.c @@ -10,9 +10,9 @@ static inline void cleanup_connection_resources(const enum ConnectionType connec if (connection_type == CONNECTION_TYPE_CLIENT) { struct SwiftNetClientConnection* const client = (struct SwiftNetClientConnection*)connection; - allocator_destroy(&client->packets_sending_memory_allocator); - allocator_destroy(&client->pending_messages_memory_allocator); - allocator_destroy(&client->packets_completed_memory_allocator); + allocator_destroy(&client->packets_sending_memory_allocator ENABLE_INTERNAL_CHECK); + allocator_destroy(&client->pending_messages_memory_allocator ENABLE_INTERNAL_CHECK); + allocator_destroy(&client->packets_completed_memory_allocator DISABLE_INTERNAL_CHECK); hashmap_destroy(&client->pending_messages); hashmap_destroy(&client->packets_sending); @@ -20,9 +20,9 @@ static inline void cleanup_connection_resources(const enum ConnectionType connec } else { struct SwiftNetServer* const server = (struct SwiftNetServer*)connection; - allocator_destroy(&server->packets_sending_memory_allocator); - allocator_destroy(&server->pending_messages_memory_allocator); - allocator_destroy(&server->packets_completed_memory_allocator); + allocator_destroy(&server->packets_sending_memory_allocator ENABLE_INTERNAL_CHECK); + allocator_destroy(&server->pending_messages_memory_allocator ENABLE_INTERNAL_CHECK); + allocator_destroy(&server->packets_completed_memory_allocator DISABLE_INTERNAL_CHECK); hashmap_destroy(&server->pending_messages); hashmap_destroy(&server->packets_sending); diff --git a/src/cleanup_swiftnet.c b/src/cleanup_swiftnet.c index 72c72fe..bc7a0f4 100644 --- a/src/cleanup_swiftnet.c +++ b/src/cleanup_swiftnet.c @@ -32,28 +32,28 @@ static inline void close_background_service() { } void swiftnet_cleanup() { - allocator_destroy(&packet_queue_node_memory_allocator); - allocator_destroy(&packet_callback_queue_node_memory_allocator); - allocator_destroy(&server_packet_data_memory_allocator); - allocator_destroy(&client_packet_data_memory_allocator); - allocator_destroy(&packet_buffer_memory_allocator); - allocator_destroy(&hashmap_item_memory_allocator); + allocator_destroy(&packet_queue_node_memory_allocator ENABLE_INTERNAL_CHECK); + allocator_destroy(&packet_callback_queue_node_memory_allocator ENABLE_INTERNAL_CHECK); + allocator_destroy(&server_packet_data_memory_allocator ENABLE_INTERNAL_CHECK); + allocator_destroy(&client_packet_data_memory_allocator ENABLE_INTERNAL_CHECK); + allocator_destroy(&packet_buffer_memory_allocator ENABLE_INTERNAL_CHECK); + allocator_destroy(&hashmap_item_memory_allocator ENABLE_INTERNAL_CHECK); #ifdef SWIFT_NET_REQUESTS - allocator_destroy(&requests_sent_memory_allocator); + allocator_destroy(&requests_sent_memory_allocator ENABLE_INTERNAL_CHECK); hashmap_destroy(&requests_sent); #endif close_listeners(); - allocator_destroy(&server_memory_allocator); - allocator_destroy(&client_connection_memory_allocator); + allocator_destroy(&server_memory_allocator ENABLE_INTERNAL_CHECK); + allocator_destroy(&client_connection_memory_allocator ENABLE_INTERNAL_CHECK); - allocator_destroy(&listener_memory_allocator); - allocator_destroy(&uint16_memory_allocator); - allocator_destroy(&packet_completed_key_allocator); - allocator_destroy(&pending_message_key_allocator); + allocator_destroy(&listener_memory_allocator ENABLE_INTERNAL_CHECK); + allocator_destroy(&uint16_memory_allocator ENABLE_INTERNAL_CHECK); + allocator_destroy(&packet_completed_key_allocator ENABLE_INTERNAL_CHECK); + allocator_destroy(&pending_message_key_allocator ENABLE_INTERNAL_CHECK); #ifdef SWIFT_NET_INTERNAL_TESTING printf("Bytes leaked: %d\nItems leaked: %d\n", bytes_leaked, items_leaked); diff --git a/src/internal/datatype_allocator.c b/src/internal/datatype_allocator.c index 477562e..c7f95dc 100644 --- a/src/internal/datatype_allocator.c +++ b/src/internal/datatype_allocator.c @@ -6,8 +6,8 @@ #include #include -static inline void free_stack_lock(struct SwiftNetMemoryAllocatorStack* const stack) { - atomic_store_explicit(&stack->owner, ALLOCATOR_STACK_FREE, memory_order_release); +static inline void free_stack_lock(struct SwiftNetMemoryAllocatorStack* const stack, struct SwiftNetMemoryAllocator* const allocator) { + atomic_fetch_and_explicit(&allocator->occupied, ~(1u << stack->index), memory_order_acq_rel); } #ifdef SWIFT_NET_INTERNAL_TESTING @@ -30,13 +30,20 @@ static inline void lock_ptr_status(struct SwiftNetMemoryAllocatorStack* const st } static inline void set_memory_status(struct SwiftNetMemoryAllocator* const memory_allocator, void* const memory_location, const uint8_t status) { - for (struct SwiftNetMemoryAllocatorStack* stack = atomic_load_explicit(&memory_allocator->data.first_item, memory_order_acquire); stack != NULL; stack = atomic_load_explicit(&stack->next, memory_order_acquire)) { + const uint16_t stacks_allocated = atomic_load_explicit(&memory_allocator->stacks_allocated, memory_order_acquire); + + for (uint16_t i = 0; i < stacks_allocated; i++) { + struct SwiftNetMemoryAllocatorStack* const stack = atomic_load_explicit(&memory_allocator->stacks[i], memory_order_acquire); + + const uint8_t* const casted_data = stack->data; + const uint8_t* const casted_memory_loc = memory_location; + if ( - memory_location >= stack->data + casted_memory_loc >= casted_data && - memory_location <= stack->data + (memory_allocator->item_size * memory_allocator->chunk_item_amount) + casted_memory_loc < casted_data + (memory_allocator->item_size * memory_allocator->chunk_item_amount) ) { - const uint32_t offset = memory_location - stack->data; + const uint32_t offset = casted_memory_loc - casted_data; const uint32_t index = offset / memory_allocator->item_size; const uint32_t byte = index / 8; @@ -51,18 +58,29 @@ static inline void set_memory_status(struct SwiftNetMemoryAllocator* const memor } unlock_ptr_status(stack); + + return; } } + + printf("doesnt fall\n"); } static inline bool is_already_free(struct SwiftNetMemoryAllocator* const memory_allocator, void* const memory_location) { - for (struct SwiftNetMemoryAllocatorStack* stack = atomic_load_explicit(&memory_allocator->data.first_item, memory_order_acquire); stack != NULL; stack = atomic_load_explicit(&stack->next, memory_order_acquire)) { + const uint16_t stacks_allocated = atomic_load_explicit(&memory_allocator->stacks_allocated, memory_order_acquire); + + for (uint16_t i = 0; i < stacks_allocated; i++) { + struct SwiftNetMemoryAllocatorStack* const stack = atomic_load_explicit(&memory_allocator->stacks[i], memory_order_acquire); + + const uint8_t* const casted_data = stack->data; + const uint8_t* const casted_memory_loc = memory_location; + if ( - memory_location >= stack->data + casted_memory_loc >= casted_data && - memory_location <= stack->data + (memory_allocator->item_size * memory_allocator->chunk_item_amount) + casted_memory_loc < casted_data + (memory_allocator->item_size * memory_allocator->chunk_item_amount) ) { - const uint32_t offset = memory_location - stack->data; + const uint32_t offset = casted_memory_loc - casted_data; const uint32_t index = offset / memory_allocator->item_size; const uint32_t byte = index / 8; @@ -86,50 +104,62 @@ static inline bool is_already_free(struct SwiftNetMemoryAllocator* const memory_ } #endif -struct SwiftNetMemoryAllocatorStack* const find_free_pointer_stack(const struct SwiftNetMemoryAllocator* const allocator) { - for (struct SwiftNetMemoryAllocatorStack* current_stack = atomic_load(&allocator->data.first_item); current_stack != NULL; current_stack = atomic_load_explicit(¤t_stack->next, memory_order_acquire)) { - uint8_t thread_none = ALLOCATOR_STACK_FREE; - - if (!atomic_compare_exchange_strong_explicit( - ¤t_stack->owner, - &thread_none, - ALLOCATOR_STACK_OCCUPIED, - memory_order_acquire, - memory_order_relaxed)) - { - continue; - } +// Type is either 0/1 - 1 = allocation - 0 = freeing +struct SwiftNetMemoryAllocatorStack* const find_free_pointer_stack(struct SwiftNetMemoryAllocator* const allocator, const uint8_t type) { + const uint16_t stacks_allocated = atomic_load_explicit(&allocator->stacks_allocated, memory_order_acquire); - if (atomic_load(¤t_stack->size) < allocator->chunk_item_amount) { - return current_stack; - } else { - free_stack_lock(current_stack); + uint64_t bitmap; + uint16_t first_free; - continue; - } + uint64_t invalid_bitmap = 0x00; + + uint64_t new_bitmap; + + uint32_t stack_size; + + bool valid_size; + + struct SwiftNetMemoryAllocatorStack* stack = NULL; + + bitmap = atomic_load_explicit(&allocator->occupied, memory_order_acquire); + + goto find_free_stack; + +find_free_stack: + if((bitmap | invalid_bitmap) == UINT64_MAX) { + return NULL; + } else { + first_free = __builtin_ctz(~(bitmap | invalid_bitmap)); } - - return NULL; -} -struct SwiftNetMemoryAllocatorStack* const find_valid_pointer_stack(const struct SwiftNetMemoryAllocator* const allocator) { - for (struct SwiftNetMemoryAllocatorStack* current_stack = atomic_load(&allocator->data.first_item); current_stack != NULL; current_stack = atomic_load_explicit(¤t_stack->next, memory_order_acquire)) { - uint8_t thread_none = ALLOCATOR_STACK_FREE; + if (first_free >= stacks_allocated) { + return NULL; + } - if (!atomic_compare_exchange_strong_explicit(¤t_stack->owner, &thread_none, ALLOCATOR_STACK_OCCUPIED, memory_order_acquire, memory_order_relaxed)) { - continue; - } + new_bitmap = bitmap | (1ULL << first_free); - if (current_stack->size > 0) { - return current_stack; - } else { - free_stack_lock(current_stack); + if (!atomic_compare_exchange_strong_explicit(&allocator->occupied, &bitmap, new_bitmap, memory_order_release, memory_order_acquire)) { + goto find_free_stack; + } - continue; - } + stack = atomic_load_explicit(&allocator->stacks[first_free], memory_order_acquire); + + goto process_stack; + +process_stack: + stack_size = atomic_load_explicit(&stack->size, memory_order_acquire); + + valid_size = type == 0 ? (stack_size < allocator->chunk_item_amount && stack_size >= 0) : (stack_size <= allocator->chunk_item_amount && stack_size > 0); + + if (valid_size) { + return stack; + } else { + free_stack_lock(stack, allocator); + + invalid_bitmap = invalid_bitmap | (1ULL << first_free); + + goto find_free_stack; } - - return NULL; } struct SwiftNetMemoryAllocator allocator_create(const uint32_t item_size, const uint32_t chunk_item_amount) { @@ -150,19 +180,20 @@ struct SwiftNetMemoryAllocator allocator_create(const uint32_t item_size, const first_stack->data = allocated_memory; first_stack->pointers = pointers_memory; first_stack->size = chunk_item_amount; - first_stack->next = NULL; - first_stack->previous = NULL; - first_stack->owner = ALLOCATOR_STACK_FREE; + first_stack->index = 0; struct SwiftNetMemoryAllocator new_allocator = (struct SwiftNetMemoryAllocator){ - .data = (struct SwiftNetChunkStorageManager){ - .first_item = first_stack, - .last_item = first_stack, - }, .item_size = item_size, .chunk_item_amount = chunk_item_amount, + .stacks_allocated = 1 }; + memset(&new_allocator.stacks, 0x00, sizeof(void*) * 64); + + new_allocator.stacks[0] = first_stack; + + atomic_store_explicit(&new_allocator.occupied, 0x00, memory_order_release); + for (uint32_t i = 0; i < chunk_item_amount; i++) { (*((void **)pointers_memory + i) = (uint8_t*)allocated_memory + (i * item_size)); } @@ -180,7 +211,7 @@ struct SwiftNetMemoryAllocator allocator_create(const uint32_t item_size, const static void create_new_stack(struct SwiftNetMemoryAllocator* const memory_allocator) { uint8_t creating_unlocked = STACK_CREATING_UNLOCKED; - while (!atomic_compare_exchange_strong_explicit(&memory_allocator->creating_stack, &creating_unlocked, STACK_CREATING_LOCKED, memory_order_acquire, memory_order_relaxed)) { + while (!atomic_compare_exchange_strong_explicit(&memory_allocator->creating_stack, &creating_unlocked, STACK_CREATING_LOCKED, memory_order_release, memory_order_relaxed)) { creating_unlocked = STACK_CREATING_UNLOCKED; usleep(100); @@ -204,12 +235,12 @@ static void create_new_stack(struct SwiftNetMemoryAllocator* const memory_alloca exit(EXIT_FAILURE); } + const uint16_t stacks_allocated = atomic_load_explicit(&memory_allocator->stacks_allocated, memory_order_acquire); + stack->pointers = allocated_memory_pointers; stack->data = allocated_memory; stack->size = chunk_item_amount; - stack->previous = atomic_load_explicit(&memory_allocator->data.last_item, memory_order_acquire); - stack->next = NULL; - atomic_store_explicit(&stack->owner, ALLOCATOR_STACK_FREE, memory_order_release); + stack->index = stacks_allocated; for (uint32_t i = 0; i < chunk_item_amount; i++) { ((void **)allocated_memory_pointers)[i] = (uint8_t*)allocated_memory + (i * item_size); @@ -220,13 +251,16 @@ static void create_new_stack(struct SwiftNetMemoryAllocator* const memory_alloca stack->ptr_status = calloc(sizeof(uint8_t), (chunk_item_amount / 8) + 1); #endif - atomic_store_explicit(&((struct SwiftNetMemoryAllocatorStack*)atomic_load(&memory_allocator->data.last_item))->next, stack, memory_order_release); - atomic_store_explicit(&memory_allocator->data.last_item, stack, memory_order_release); + atomic_store_explicit(&memory_allocator->stacks[stacks_allocated], stack, memory_order_release); + + atomic_fetch_add_explicit(&memory_allocator->stacks_allocated, 1, memory_order_release); + atomic_store_explicit(&memory_allocator->creating_stack, STACK_CREATING_UNLOCKED, memory_order_release); } void* allocator_allocate(struct SwiftNetMemoryAllocator* const memory_allocator) { - struct SwiftNetMemoryAllocatorStack* const valid_stack = find_valid_pointer_stack(memory_allocator); + struct SwiftNetMemoryAllocatorStack* const valid_stack = find_free_pointer_stack(memory_allocator, 1); + if (valid_stack == NULL) { create_new_stack(memory_allocator); @@ -235,7 +269,7 @@ void* allocator_allocate(struct SwiftNetMemoryAllocator* const memory_allocator) return res; } - const uint32_t size = atomic_fetch_add(&valid_stack->size, -1);; + const uint32_t size = atomic_fetch_sub(&valid_stack->size, 1);; void** const ptr_to_data = ((void**)valid_stack->pointers) + size - 1; @@ -245,7 +279,7 @@ void* allocator_allocate(struct SwiftNetMemoryAllocator* const memory_allocator) set_memory_status(memory_allocator, item_ptr, 1); #endif - free_stack_lock(valid_stack); + free_stack_lock(valid_stack, memory_allocator); return item_ptr; } @@ -260,7 +294,7 @@ void allocator_free(struct SwiftNetMemoryAllocator* const memory_allocator, void } #endif - struct SwiftNetMemoryAllocatorStack* const free_stack = find_free_pointer_stack(memory_allocator); + struct SwiftNetMemoryAllocatorStack* const free_stack = find_free_pointer_stack(memory_allocator, 0); if (free_stack == NULL) { create_new_stack(memory_allocator); @@ -277,54 +311,55 @@ void allocator_free(struct SwiftNetMemoryAllocator* const memory_allocator, void set_memory_status(memory_allocator, memory_location, 0); #endif - free_stack_lock(free_stack); + free_stack_lock(free_stack, memory_allocator); } -void allocator_destroy(struct SwiftNetMemoryAllocator* const memory_allocator) { - for (struct SwiftNetMemoryAllocatorStack* current_stack = atomic_load(&memory_allocator->data.first_item); ; ) { +void allocator_destroy(struct SwiftNetMemoryAllocator* const memory_allocator + #ifdef SWIFT_NET_INTERNAL_TESTING + , const bool disable_internal_check + #endif +) { + const uint16_t stacks_allocated = atomic_load_explicit(&memory_allocator->stacks_allocated, memory_order_acquire); + + for (uint16_t stack_index = 0; stack_index < stacks_allocated; stack_index++) { + struct SwiftNetMemoryAllocatorStack* const current_stack = atomic_load_explicit(&memory_allocator->stacks[stack_index], memory_order_acquire); free(current_stack->data); free(current_stack->pointers); - struct SwiftNetMemoryAllocatorStack* const next_stack = atomic_load(¤t_stack->next); - if (next_stack == NULL) { - free(current_stack); - break; - } - #ifdef SWIFT_NET_INTERNAL_TESTING - lock_ptr_status(current_stack); + if(!disable_internal_check) { + lock_ptr_status(current_stack); - const uint32_t total_items = memory_allocator->chunk_item_amount; - const uint32_t bytes = (total_items / 8) + 1; + const uint32_t total_items = memory_allocator->chunk_item_amount; + const uint32_t bytes = (total_items / 8) + 1; - for (uint32_t byte = 0; byte < bytes; byte++) { - uint8_t mask = current_stack->ptr_status[byte]; + for (uint32_t byte = 0; byte < bytes; byte++) { + uint8_t mask = current_stack->ptr_status[byte]; - if (mask == 0x00) { - continue; - } + if (mask == 0x00) { + continue; + } - for (uint8_t bit = 0; bit < 8; bit++) { - uint32_t idx = byte * 8 + bit; - if (idx >= total_items) break; + for (uint8_t bit = 0; bit < 8; bit++) { + uint32_t idx = byte * 8 + bit; + if (idx >= total_items) break; - bool allocated = (mask & (1u << bit)) != 0; + bool allocated = (mask & (1u << bit)) != 0; - if (allocated) { - items_leaked++; - bytes_leaked += memory_allocator->item_size; + if (allocated) { + items_leaked++; + bytes_leaked += memory_allocator->item_size; + } } } - } - unlock_ptr_status(current_stack); + unlock_ptr_status(current_stack); + } free(current_stack->ptr_status); #endif free(current_stack); - - current_stack = next_stack; } } diff --git a/src/internal/internal.h b/src/internal/internal.h index 32ed98a..0d70745 100644 --- a/src/internal/internal.h +++ b/src/internal/internal.h @@ -19,6 +19,14 @@ #define LOOPBACK_INTERFACE_NAME "lo0\0" #endif +#ifdef SWIFT_NET_INTERNAL_TESTING + #define ENABLE_INTERNAL_CHECK , 0 + #define DISABLE_INTERNAL_CHECK , 1 +#else + #define ENABLE_INTERNAL_CHECK + #define DISABLE_INTERNAL_CHECK +#endif + enum RequestLostPacketsReturnType { REQUEST_LOST_PACKETS_RETURN_UPDATED_BIT_ARRAY = 0x00, REQUEST_LOST_PACKETS_RETURN_COMPLETED_PACKET = 0x01 @@ -142,11 +150,6 @@ enum StackCreatingState { STACK_CREATING_UNLOCKED = 1 }; -enum AllocatorStackState { - ALLOCATOR_STACK_FREE = 0, - ALLOCATOR_STACK_OCCUPIED = 1 -}; - struct PendingMessagesKey { uint16_t source_port; uint16_t packet_id; @@ -250,7 +253,11 @@ extern struct SwiftNetMemoryAllocator uint16_memory_allocator; extern struct SwiftNetMemoryAllocator allocator_create(const uint32_t item_size, const uint32_t chunk_item_amount); extern void* allocator_allocate(struct SwiftNetMemoryAllocator* const memory_allocator); extern void allocator_free(struct SwiftNetMemoryAllocator* const memory_allocator, void* const memory_location); -extern void allocator_destroy(struct SwiftNetMemoryAllocator* const memory_allocator); +extern void allocator_destroy(struct SwiftNetMemoryAllocator* const memory_allocator + #ifdef SWIFT_NET_INTERNAL_TESTING + , const bool disable_internal_check + #endif +); extern struct SwiftNetMemoryAllocator packet_queue_node_memory_allocator; extern struct SwiftNetMemoryAllocator packet_callback_queue_node_memory_allocator; diff --git a/src/process_packets.c b/src/process_packets.c index a337b9d..cae7b17 100644 --- a/src/process_packets.c +++ b/src/process_packets.c @@ -207,14 +207,14 @@ static inline bool chunk_already_received(uint8_t* const chunks_received, const const uint32_t byte = index / 8; const uint8_t bit = index % 8; - return (chunks_received[byte] & (1 << bit)) == 0x01; + return (chunks_received[byte] & (1U << bit)) != 0; } static inline void chunk_received(uint8_t* const chunks_received, const uint32_t index) { const uint32_t byte = index / 8; const uint8_t bit = index % 8; - chunks_received[byte] |= 1 << bit; + chunks_received[byte] |= (uint8_t)(1U << bit); } static inline struct SwiftNetPendingMessage* const create_new_pending_message(struct SwiftNetHashMap* const pending_messages, struct SwiftNetMemoryAllocator* const pending_messages_memory_allocator, const struct SwiftNetPacketInfo* const packet_info, const enum ConnectionType connection_type, const uint16_t packet_id, const uint16_t source_port) { @@ -466,10 +466,10 @@ static inline void swiftnet_process_packets( HANDLE_PACKET_CONSTRUCTION(&send_lost_packets_ip_header, &packet_info_new, addr_type, ð_hdr, mtu + prepend_size, buffer) - const uint16_t lost_chunk_indexes = return_lost_chunk_indexes(pending_message->chunks_received, pending_message->packet_info.chunk_amount, mtu - PACKET_HEADER_SIZE, (uint32_t*)(buffer + header_size)); + const uint32_t lost_chunk_indexes = return_lost_chunk_indexes(pending_message->chunks_received, pending_message->packet_info.chunk_amount, mtu - PACKET_HEADER_SIZE, (uint32_t*)(buffer + header_size)); - const uint16_t packet_length = sizeof(struct ip) + sizeof(struct SwiftNetPacketInfo) + (lost_chunk_indexes * sizeof(uint32_t)); - const uint16_t packet_length_net_order = htons(packet_length); + const uint32_t packet_length = sizeof(struct ip) + sizeof(struct SwiftNetPacketInfo) + (lost_chunk_indexes * sizeof(uint32_t)); + const uint16_t packet_length_net_order = htons((uint16_t)packet_length); memcpy(buffer + prepend_size + offsetof(struct ip, ip_len), &packet_length_net_order, SIZEOF_FIELD(struct ip, ip_len)); @@ -555,7 +555,7 @@ static inline void swiftnet_process_packets( // Split packet into chunks struct SwiftNetPendingMessage* const new_pending_message = create_new_pending_message(pending_messages, pending_messages_memory_allocator, &packet_info, connection_type, ip_header.ip_id, packet_info.port_info.source_port); - new_pending_message->chunks_received_number++; + new_pending_message->chunks_received_number = 1; chunk_received(new_pending_message->chunks_received, packet_info.chunk_index); @@ -627,7 +627,10 @@ static inline void swiftnet_process_packets( const uint32_t bytes_to_write = (packet_info.chunk_index + 1) >= packet_info.chunk_amount ? packet_info.packet_length % chunk_data_size : chunk_data_size; - if(pending_message->chunks_received_number + 1 >= packet_info.chunk_amount) { + if(pending_message->chunks_received_number + 1 == packet_info.chunk_amount) { + + pending_message->chunks_received_number++; + // Completed the packet memcpy(pending_message->packet_data_start + (chunk_data_size * packet_info.chunk_index), packet_data, bytes_to_write); diff --git a/src/swift_net.h b/src/swift_net.h index 2a986af..f8237ff 100644 --- a/src/swift_net.h +++ b/src/swift_net.h @@ -192,12 +192,10 @@ struct SwiftNetSentSuccessfullyCompletedPacketSignal { }; struct SwiftNetMemoryAllocatorStack { - _Atomic(void*) next; - _Atomic(void*) previous; void* pointers; void* data; + uint16_t index; _Atomic uint32_t size; - _Atomic uint8_t owner; #ifdef SWIFT_NET_INTERNAL_TESTING _Atomic bool accessing_ptr_status; uint8_t* ptr_status; @@ -210,7 +208,9 @@ struct SwiftNetChunkStorageManager { }; struct SwiftNetMemoryAllocator { - struct SwiftNetChunkStorageManager data; + _Atomic uint64_t occupied; + _Atomic(struct SwiftNetMemoryAllocatorStack*) stacks[64]; + _Atomic uint16_t stacks_allocated; uint32_t item_size; uint32_t chunk_item_amount; _Atomic uint8_t creating_stack; diff --git a/tests/integration_tests/build/CMakeLists.txt b/tests/integration_tests/build/CMakeLists.txt index 7b67bbc..80e3338 100644 --- a/tests/integration_tests/build/CMakeLists.txt +++ b/tests/integration_tests/build/CMakeLists.txt @@ -27,7 +27,7 @@ file(GLOB SRC_FILES "${CMAKE_SOURCE_DIR}/../src/*.c") add_executable(run_tests ${SRC_FILES}) -target_link_libraries(run_tests PRIVATE swiftnet -lpcap) +target_link_libraries(run_tests PRIVATE -lpcap ${CMAKE_SOURCE_DIR}/../../../build/output/libswiftnet.a) target_link_options(run_tests PRIVATE -g -O0) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/tests/integration_tests/build/build_tests.sh b/tests/integration_tests/build/build_tests.sh index 1e49bdd..9662abd 100755 --- a/tests/integration_tests/build/build_tests.sh +++ b/tests/integration_tests/build/build_tests.sh @@ -1,2 +1,2 @@ -cmake . -DCMAKE_BUILD_TYPE=Debug -DSANITIZER=thread +cmake . -DCMAKE_BUILD_TYPE=Debug -DSANITIZER=thread -B . make -B -j8 diff --git a/tests/integration_tests/src/making_request.c b/tests/integration_tests/src/making_request.c index 890a53a..7ea8152 100644 --- a/tests/integration_tests/src/making_request.c +++ b/tests/integration_tests/src/making_request.c @@ -61,10 +61,10 @@ static void on_client_packet(struct SwiftNetClientPacketData* packet, void* cons atomic_load_explicit(&g_request_data_len, memory_order_acquire) ); - atomic_store_explicit(&g_test_result, -1, memory_order_release); - swiftnet_client_destroy_packet_data(packet, client_conn); + atomic_store_explicit(&g_test_result, -1, memory_order_release); + return; } @@ -75,9 +75,9 @@ static void on_client_packet(struct SwiftNetClientPacketData* packet, void* cons if (data[i] != byte_received) { PRINT_ERROR("Client received invalid data"); - atomic_store_explicit(&g_test_result, -1, memory_order_release); - swiftnet_client_destroy_packet_data(packet, client_conn); + + atomic_store_explicit(&g_test_result, -1, memory_order_release); return; } @@ -108,10 +108,10 @@ static void on_server_packet(struct SwiftNetServerPacketData* packet, void* cons atomic_load_explicit(&g_request_data_len, memory_order_acquire) ); - atomic_store_explicit(&g_test_result, -1, memory_order_release); - swiftnet_server_destroy_packet_data(packet, server); + atomic_store_explicit(&g_test_result, -1, memory_order_release); + return; } @@ -122,9 +122,9 @@ static void on_server_packet(struct SwiftNetServerPacketData* packet, void* cons if (data[i] != byte_received) { PRINT_ERROR("Server received invalid data"); - atomic_store_explicit(&g_test_result, -1, memory_order_release); - swiftnet_server_destroy_packet_data(packet, server); + + atomic_store_explicit(&g_test_result, -1, memory_order_release); return; } @@ -150,10 +150,10 @@ static void on_server_packet(struct SwiftNetServerPacketData* packet, void* cons sizeof(g_make_request_code) ); - atomic_store_explicit(&g_test_result, -1, memory_order_release); - swiftnet_server_destroy_packet_data(packet, server); + atomic_store_explicit(&g_test_result, -1, memory_order_release); + return; } @@ -162,10 +162,10 @@ static void on_server_packet(struct SwiftNetServerPacketData* packet, void* cons if (byte_received != g_make_request_code) { PRINT_ERROR("Server received invalid data"); + swiftnet_server_destroy_packet_data(packet, server); + atomic_store_explicit(&g_test_result, -1, memory_order_release); - swiftnet_server_destroy_packet_data(packet, server); - return; } @@ -192,10 +192,10 @@ static void on_server_packet(struct SwiftNetServerPacketData* packet, void* cons PRINT_ERROR("Did not receive response from server"); - atomic_store_explicit(&g_test_result, -1, memory_order_release); - swiftnet_server_destroy_packet_data(packet, server); + atomic_store_explicit(&g_test_result, -1, memory_order_release); + return; } @@ -205,11 +205,11 @@ static void on_server_packet(struct SwiftNetServerPacketData* packet, void* cons response_data_len ); - atomic_store_explicit(&g_test_result, -1, memory_order_release); - swiftnet_server_destroy_packet_data(response, server); swiftnet_server_destroy_packet_data(packet, server); + atomic_store_explicit(&g_test_result, -1, memory_order_release); + return; } @@ -218,19 +218,19 @@ static void on_server_packet(struct SwiftNetServerPacketData* packet, void* cons if (response_data[i] != received_byte) { PRINT_ERROR("Client received invalid data"); - atomic_store_explicit(&g_test_result, -1, memory_order_release); - swiftnet_server_destroy_packet_data(response, server); swiftnet_server_destroy_packet_data(packet, server); + atomic_store_explicit(&g_test_result, -1, memory_order_release); + return; } } - atomic_store_explicit(&g_test_result, 0, memory_order_release); - swiftnet_server_destroy_packet_data(response, server); swiftnet_server_destroy_packet_data(packet, server); + + atomic_store_explicit(&g_test_result, 0, memory_order_release); } } diff --git a/tests/integration_tests/src/sending_packet.c b/tests/integration_tests/src/sending_packet.c index 0a611fe..d922961 100644 --- a/tests/integration_tests/src/sending_packet.c +++ b/tests/integration_tests/src/sending_packet.c @@ -56,10 +56,10 @@ static void on_client_packet(struct SwiftNetClientPacketData* packet, void* cons atomic_load_explicit(&g_client_data_len, memory_order_acquire) ); - atomic_store_explicit(&g_test_result, -1, memory_order_release); - swiftnet_client_destroy_packet_data(packet, client_conn); + atomic_store_explicit(&g_test_result, -1, memory_order_release); + return; } @@ -70,17 +70,17 @@ static void on_client_packet(struct SwiftNetClientPacketData* packet, void* cons if (data[i] != received_byte) { PRINT_ERROR("Client received invalid data"); - atomic_store_explicit(&g_test_result, -1, memory_order_release); - swiftnet_client_destroy_packet_data(packet, client_conn); + atomic_store_explicit(&g_test_result, -1, memory_order_release); + return; } } - atomic_store_explicit(&g_test_result, 0, memory_order_release); - swiftnet_client_destroy_packet_data(packet, client_conn); + + atomic_store_explicit(&g_test_result, 0, memory_order_release); } static void on_server_packet(struct SwiftNetServerPacketData* packet, void* const user) { @@ -94,10 +94,10 @@ static void on_server_packet(struct SwiftNetServerPacketData* packet, void* cons atomic_load_explicit(&g_server_data_len, memory_order_acquire) ); - atomic_store_explicit(&g_test_result, -1, memory_order_release); - swiftnet_server_destroy_packet_data(packet, server); + atomic_store_explicit(&g_test_result, -1, memory_order_release); + return; } @@ -108,10 +108,10 @@ static void on_server_packet(struct SwiftNetServerPacketData* packet, void* cons if (data[i] != byte_received) { PRINT_ERROR("Server received invalid data"); - atomic_store_explicit(&g_test_result, -1, memory_order_release); - swiftnet_server_destroy_packet_data(packet, server); + atomic_store_explicit(&g_test_result, -1, memory_order_release); + return; } } @@ -125,12 +125,14 @@ static void on_server_packet(struct SwiftNetServerPacketData* packet, void* cons swiftnet_server_send_packet(atomic_load_explicit(&g_server, memory_order_acquire), &buf, packet->metadata.sender); swiftnet_destroy_packet_buffer(&buf); + swiftnet_server_destroy_packet_data(packet, server); + atomic_store_explicit(&g_client_send_done, true, memory_order_release); } else { + swiftnet_server_destroy_packet_data(packet, server); + atomic_store_explicit(&g_test_result, 0, memory_order_release); } - - swiftnet_server_destroy_packet_data(packet, server); } int test_sending_packet(const union Args* args_ptr) { diff --git a/tests/performance_tests/build/CMakeLists.txt b/tests/performance_tests/build/CMakeLists.txt index ea491c3..6c3e203 100644 --- a/tests/performance_tests/build/CMakeLists.txt +++ b/tests/performance_tests/build/CMakeLists.txt @@ -27,7 +27,7 @@ file(GLOB SRC_FILES "${CMAKE_SOURCE_DIR}/../src/*.c") add_executable(run_tests ${SRC_FILES}) -target_link_libraries(run_tests PRIVATE swiftnet -lpcap) +target_link_libraries(run_tests PRIVATE ${CMAKE_SOURCE_DIR}/../../../build/output/libswiftnet.a -lpcap) target_link_options(run_tests PRIVATE -O3) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/tests/performance_tests/build/build_tests.sh b/tests/performance_tests/build/build_tests.sh index 14c81dd..d7954ca 100755 --- a/tests/performance_tests/build/build_tests.sh +++ b/tests/performance_tests/build/build_tests.sh @@ -1,2 +1,2 @@ -cmake . -DCMAKE_BUILD_TYPE=Release -DSANITIZER=none +cmake . -DCMAKE_BUILD_TYPE=Release -DSANITIZER=none -B . make -B -j8 diff --git a/tests/performance_tests/src/main.c b/tests/performance_tests/src/main.c index f31c2bd..e051729 100644 --- a/tests/performance_tests/src/main.c +++ b/tests/performance_tests/src/main.c @@ -86,7 +86,7 @@ void send_large_packets(const bool loopback) { int main() { swiftnet_initialize(); - swiftnet_add_debug_flags(SWIFTNET_DEBUG_FLAGS(SWIFTNET_DEBUG_PACKETS_SENDING | SWIFTNET_DEBUG_PACKETS_RECEIVING | SWIFTNET_DEBUG_INITIALIZATION | SWIFTNET_DEBUG_LOST_PACKETS)); + //swiftnet_add_debug_flags(SWIFTNET_DEBUG_FLAGS(SWIFTNET_DEBUG_PACKETS_SENDING | SWIFTNET_DEBUG_PACKETS_RECEIVING | SWIFTNET_DEBUG_INITIALIZATION | SWIFTNET_DEBUG_LOST_PACKETS)); send_large_packets(false);