From 87e511034647af30cf96be09149cbaf707be63a2 Mon Sep 17 00:00:00 2001 From: Haithem Rahmani Date: Fri, 21 Mar 2025 09:28:58 +0100 Subject: [PATCH] Make queue max message size configurable Summary ------- This commit fixes the issue #424 Details -------- - Add a the configuration option TX_QUEUE_MESSAGE_MAX_SIZE in the tx_api.h with default value set to TX_ULONG_16 to keep backword compatibility. - Update the txe_queue_create() to check on TX_QUEUE_MESSAGE_MAX_SIZE rather than TX_ULONG_16 as max message size. - Add a new unitary test to cover the new change. --- common/inc/tx_api.h | 6 + common/inc/tx_user_sample.h | 7 + common/src/txe_queue_create.c | 4 +- test/smp/cmake/regression/CMakeLists.txt | 1 + test/smp/regression/testcontrol.c | 1 + test/tx/cmake/CMakeLists.txt | 10 +- test/tx/cmake/regression/CMakeLists.txt | 1 + test/tx/regression/testcontrol.c | 3 + ...hreadx_queue_basic_max_message_size_test.c | 422 ++++++++++++++++++ 9 files changed, 448 insertions(+), 7 deletions(-) create mode 100644 test/tx/regression/threadx_queue_basic_max_message_size_test.c diff --git a/common/inc/tx_api.h b/common/inc/tx_api.h index 3ff05f4b..77be2efd 100644 --- a/common/inc/tx_api.h +++ b/common/inc/tx_api.h @@ -328,6 +328,12 @@ extern "C" { #define TX_TIMER_TICKS_PER_SECOND (100UL) #endif +/* Define the default maximum message size in a queue. The default value is TX_16_ULONG, but may + be customized in tx_user.h or as a compilation option. */ + +#ifndef TX_QUEUE_MESSAGE_MAX_SIZE +#define TX_QUEUE_MESSAGE_MAX_SIZE TX_16_ULONG +#endif /* Event numbers 0 through 4095 are reserved by Azure RTOS. Specific event assignments are: diff --git a/common/inc/tx_user_sample.h b/common/inc/tx_user_sample.h index e7ecb56a..f8d809b5 100644 --- a/common/inc/tx_user_sample.h +++ b/common/inc/tx_user_sample.h @@ -117,6 +117,13 @@ #define TX_TIMER_THREAD_PRIORITY ???? */ +/* Define the maximum size of a message in the a queue. the Default value is TX_ULONG_16. + the new value must be a multiple of ULONG. */ + +/* +#define TX_QUEUE_MESSAGE_MAX_SIZE TX_ULONG_16 +*/ + /* Define the common timer tick reference for use by other middleware components. The default value is 10ms (i.e. 100 ticks, defined in tx_api.h), but may be replaced by a port-specific version in tx_port.h or here. diff --git a/common/src/txe_queue_create.c b/common/src/txe_queue_create.c index 68d3540a..2d91cc9f 100644 --- a/common/src/txe_queue_create.c +++ b/common/src/txe_queue_create.c @@ -178,8 +178,8 @@ TX_THREAD *thread_ptr; status = TX_SIZE_ERROR; } - /* Check for an invalid message size - greater than 16. */ - else if (message_size > TX_16_ULONG) + /* Check for an invalid message size - greater than TX_QUEUE_MESSAGE_MAX_SIZE 16 by default. */ + else if (message_size > TX_QUEUE_MESSAGE_MAX_SIZE) { /* Invalid message size specified. */ diff --git a/test/smp/cmake/regression/CMakeLists.txt b/test/smp/cmake/regression/CMakeLists.txt index 0b9384c2..c2362620 100644 --- a/test/smp/cmake/regression/CMakeLists.txt +++ b/test/smp/cmake/regression/CMakeLists.txt @@ -47,6 +47,7 @@ set(regression_test_cases ${SOURCE_DIR}/threadx_queue_basic_one_word_test.c ${SOURCE_DIR}/threadx_queue_basic_sixteen_word_test.c ${SOURCE_DIR}/threadx_queue_basic_two_word_test.c + ${SOURCE_DIR}/threadx_queue_basic_max_message_size_test.c ${SOURCE_DIR}/threadx_queue_empty_suspension_test.c ${SOURCE_DIR}/threadx_queue_flush_no_suspension_test.c ${SOURCE_DIR}/threadx_queue_flush_test.c diff --git a/test/smp/regression/testcontrol.c b/test/smp/regression/testcontrol.c index 8e3d872e..0a04e689 100644 --- a/test/smp/regression/testcontrol.c +++ b/test/smp/regression/testcontrol.c @@ -185,6 +185,7 @@ void threadx_queue_basic_two_word_application_define(void *); void threadx_queue_basic_four_word_application_define(void *); void threadx_queue_basic_eight_word_application_define(void *); void threadx_queue_basic_sixteen_word_application_define(void *); +void threadx_queue_basic_max_message_size_application_define(void *); void threadx_queue_empty_suspension_application_define(void *); void threadx_queue_full_suspension_application_define(void *); void threadx_queue_suspension_timeout_application_define(void *); diff --git a/test/tx/cmake/CMakeLists.txt b/test/tx/cmake/CMakeLists.txt index b440d2cf..2dd16ade 100644 --- a/test/tx/cmake/CMakeLists.txt +++ b/test/tx/cmake/CMakeLists.txt @@ -22,11 +22,11 @@ endif() message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.") -set(default_build_coverage "") -set(disable_notify_callbacks_build -DTX_DISABLE_NOTIFY_CALLBACKS) -set(stack_checking_build -DTX_ENABLE_STACK_CHECKING) -set(stack_checking_rand_fill_build -DTX_ENABLE_STACK_CHECKING -DTX_ENABLE_RANDOM_NUMBER_STACK_FILLING) -set(trace_build -DTX_ENABLE_EVENT_TRACE) +set(default_build_coverage -DTX_QUEUE_MESSAGE_MAX_SIZE=32) +set(disable_notify_callbacks_build -DTX_QUEUE_MESSAGE_MAX_SIZE=32 -DTX_DISABLE_NOTIFY_CALLBACKS) +set(stack_checking_build -DTX_QUEUE_MESSAGE_MAX_SIZE=32 -DTX_ENABLE_STACK_CHECKING) +set(stack_checking_rand_fill_build -DTX_QUEUE_MESSAGE_MAX_SIZE=32 -DTX_ENABLE_STACK_CHECKING -DTX_ENABLE_RANDOM_NUMBER_STACK_FILLING) +set(trace_build -DTX_QUEUE_MESSAGE_MAX_SIZE=32 -DTX_ENABLE_EVENT_TRACE) add_compile_options( -m32 diff --git a/test/tx/cmake/regression/CMakeLists.txt b/test/tx/cmake/regression/CMakeLists.txt index ec67dd57..d60743fa 100644 --- a/test/tx/cmake/regression/CMakeLists.txt +++ b/test/tx/cmake/regression/CMakeLists.txt @@ -47,6 +47,7 @@ set(regression_test_cases ${SOURCE_DIR}/threadx_queue_basic_one_word_test.c ${SOURCE_DIR}/threadx_queue_basic_sixteen_word_test.c ${SOURCE_DIR}/threadx_queue_basic_two_word_test.c + ${SOURCE_DIR}/threadx_queue_basic_max_message_size_test.c ${SOURCE_DIR}/threadx_queue_empty_suspension_test.c ${SOURCE_DIR}/threadx_queue_flush_no_suspension_test.c ${SOURCE_DIR}/threadx_queue_flush_test.c diff --git a/test/tx/regression/testcontrol.c b/test/tx/regression/testcontrol.c index a53c50a5..8203ece5 100644 --- a/test/tx/regression/testcontrol.c +++ b/test/tx/regression/testcontrol.c @@ -171,6 +171,7 @@ void threadx_queue_basic_two_word_application_define(void *); void threadx_queue_basic_four_word_application_define(void *); void threadx_queue_basic_eight_word_application_define(void *); void threadx_queue_basic_sixteen_word_application_define(void *); +void threadx_queue_basic_max_message_size_application_define(void *); void threadx_queue_empty_suspension_application_define(void *); void threadx_queue_full_suspension_application_define(void *); void threadx_queue_suspension_timeout_application_define(void *); @@ -287,6 +288,7 @@ TEST_ENTRY test_control_tests[] = threadx_queue_basic_four_word_application_define, threadx_queue_basic_eight_word_application_define, threadx_queue_basic_sixteen_word_application_define, + threadx_queue_basic_max_message_size_application_define, threadx_queue_empty_suspension_application_define, threadx_queue_full_suspension_application_define, threadx_queue_suspension_timeout_application_define, @@ -1193,6 +1195,7 @@ void test_control_return(UINT status) UINT old_posture = TX_INT_ENABLE; + printf("********** Running Queue Max Message Size Test (%u) ************** \n ", TX_QUEUE_MESSAGE_MAX_SIZE); /* Save the status in a global. */ test_control_return_status = status; diff --git a/test/tx/regression/threadx_queue_basic_max_message_size_test.c b/test/tx/regression/threadx_queue_basic_max_message_size_test.c new file mode 100644 index 00000000..30afa190 --- /dev/null +++ b/test/tx/regression/threadx_queue_basic_max_message_size_test.c @@ -0,0 +1,422 @@ +/* This test is designed to test immediate response queue services including create + and delete. This test is for queue sizes of 16 ULONG. Two queues are used one with + a capacity of 1 message and another with a capacity of 3 messages. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static TX_QUEUE queue_0; +static TX_QUEUE queue_1; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_basic_max_message_size_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Max Message Size Test..................................... ERROR #1\n"); + test_control_return(1); + } + + /* Create the queues. */ + status = tx_queue_create(&queue_0, "queue 0", TX_QUEUE_MESSAGE_MAX_SIZE, pointer, TX_QUEUE_MESSAGE_MAX_SIZE*sizeof(ULONG)); + pointer = pointer + (TX_QUEUE_MESSAGE_MAX_SIZE*sizeof(ULONG)); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Max Message Size Test..................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_queue_create(&queue_1, "queue 1", TX_QUEUE_MESSAGE_MAX_SIZE, pointer, TX_QUEUE_MESSAGE_MAX_SIZE*3*sizeof(ULONG)); + pointer = pointer + TX_QUEUE_MESSAGE_MAX_SIZE*3*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Max Message Size Test..................................... ERROR #3\n"); + test_control_return(1); + } +} + + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG source_message[TX_QUEUE_MESSAGE_MAX_SIZE]; +ULONG dest_message[TX_QUEUE_MESSAGE_MAX_SIZE]; +ULONG expected_message[TX_QUEUE_MESSAGE_MAX_SIZE]; + + + /* Inform user. */ + + source_message[0] = 0x01234567; + source_message[TX_QUEUE_MESSAGE_MAX_SIZE -1] = 0x89ABCDEF; + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) || + (source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1])) + { + + /* Queue error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + source_message[0]++; + source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) || + (source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1])) + { + + /* Queue error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Now we need to do the same thing with the queue with three entries. */ + + source_message[0]++; + source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + expected_message[0] = source_message[0]; + expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] = source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]; + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1])) + { + + /* Queue error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1])) + { + + /* Queue error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1])) + { + + /* Queue error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1])) + { + + /* Queue error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1])) + { + + /* Queue error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1] != dest_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1])) + { + + /* Queue error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[TX_QUEUE_MESSAGE_MAX_SIZE - 1]++; + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Delete the queues. */ + status = tx_queue_delete(&queue_1); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + status = tx_queue_delete(&queue_0); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +