summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/.gitignore2
-rw-r--r--test/smp/cmake/CMakeLists.txt76
-rwxr-xr-xtest/smp/cmake/coverage.sh9
-rw-r--r--test/smp/cmake/regression/CMakeLists.txt133
-rwxr-xr-xtest/smp/cmake/regression/generate_test_file.sh10
l---------test/smp/cmake/run.sh1
-rw-r--r--test/smp/cmake/samples/CMakeLists.txt15
-rw-r--r--test/smp/cmake/samples/fake.c22
-rw-r--r--test/smp/cmake/threadx_smp/CMakeLists.txt60
-rw-r--r--test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt220
-rw-r--r--test/smp/cmake/threadx_smp/ports_smp/linux/gnu/CMakeLists.txt32
-rw-r--r--test/smp/regression/testcontrol.c1609
-rw-r--r--test/smp/regression/threadx_block_memory_basic_test.c568
-rw-r--r--test/smp/regression/threadx_block_memory_error_detection_test.c387
-rw-r--r--test/smp/regression/threadx_block_memory_information_test.c713
-rw-r--r--test/smp/regression/threadx_block_memory_prioritize_test.c500
-rw-r--r--test/smp/regression/threadx_block_memory_suspension_test.c311
-rw-r--r--test/smp/regression/threadx_block_memory_suspension_timeout_test.c212
-rw-r--r--test/smp/regression/threadx_block_memory_thread_terminate_test.c185
-rw-r--r--test/smp/regression/threadx_byte_memory_basic_test.c1064
-rw-r--r--test/smp/regression/threadx_byte_memory_information_test.c784
-rw-r--r--test/smp/regression/threadx_byte_memory_prioritize_test.c498
-rw-r--r--test/smp/regression/threadx_byte_memory_suspension_test.c391
-rw-r--r--test/smp/regression/threadx_byte_memory_suspension_timeout_test.c196
-rw-r--r--test/smp/regression/threadx_byte_memory_thread_contention_test.c255
-rw-r--r--test/smp/regression/threadx_byte_memory_thread_terminate_test.c177
-rw-r--r--test/smp/regression/threadx_event_flag_basic_test.c743
-rw-r--r--test/smp/regression/threadx_event_flag_information_test.c562
-rw-r--r--test/smp/regression/threadx_event_flag_isr_set_clear_test.c358
-rw-r--r--test/smp/regression/threadx_event_flag_isr_wait_abort_test.c330
-rw-r--r--test/smp/regression/threadx_event_flag_single_thread_terminate_test.c331
-rw-r--r--test/smp/regression/threadx_event_flag_suspension_consume_test.c281
-rw-r--r--test/smp/regression/threadx_event_flag_suspension_different_bits_consume_test.c224
-rw-r--r--test/smp/regression/threadx_event_flag_suspension_different_bits_test.c230
-rw-r--r--test/smp/regression/threadx_event_flag_suspension_test.c349
-rw-r--r--test/smp/regression/threadx_event_flag_suspension_timeout_test.c266
-rw-r--r--test/smp/regression/threadx_event_flag_thread_terminate_test.c234
-rw-r--r--test/smp/regression/threadx_initialize_kernel_setup_test.c83
-rw-r--r--test/smp/regression/threadx_interrupt_control_test.c94
-rw-r--r--test/smp/regression/threadx_mutex_basic_test.c767
-rw-r--r--test/smp/regression/threadx_mutex_delete_test.c194
-rw-r--r--test/smp/regression/threadx_mutex_information_test.c592
-rw-r--r--test/smp/regression/threadx_mutex_nested_priority_inheritance_test.c701
-rw-r--r--test/smp/regression/threadx_mutex_no_preemption_test.c173
-rw-r--r--test/smp/regression/threadx_mutex_preemption_test.c161
-rw-r--r--test/smp/regression/threadx_mutex_priority_inheritance_test.c607
-rw-r--r--test/smp/regression/threadx_mutex_proritize_test.c525
-rw-r--r--test/smp/regression/threadx_mutex_suspension_timeout_test.c474
-rw-r--r--test/smp/regression/threadx_mutex_thread_terminate_test.c198
-rw-r--r--test/smp/regression/threadx_queue_basic_eight_word_test.c423
-rw-r--r--test/smp/regression/threadx_queue_basic_four_word_test.c423
-rw-r--r--test/smp/regression/threadx_queue_basic_one_word_test.c867
-rw-r--r--test/smp/regression/threadx_queue_basic_sixteen_word_test.c423
-rw-r--r--test/smp/regression/threadx_queue_basic_two_word_test.c463
-rw-r--r--test/smp/regression/threadx_queue_empty_suspension_test.c271
-rw-r--r--test/smp/regression/threadx_queue_flush_no_suspension_test.c216
-rw-r--r--test/smp/regression/threadx_queue_flush_test.c249
-rw-r--r--test/smp/regression/threadx_queue_front_send_test.c686
-rw-r--r--test/smp/regression/threadx_queue_full_suspension_test.c368
-rw-r--r--test/smp/regression/threadx_queue_information_test.c664
-rw-r--r--test/smp/regression/threadx_queue_prioritize.c534
-rw-r--r--test/smp/regression/threadx_queue_suspension_timeout_test.c254
-rw-r--r--test/smp/regression/threadx_queue_thread_terminate_test.c183
-rw-r--r--test/smp/regression/threadx_semaphore_basic_test.c545
-rw-r--r--test/smp/regression/threadx_semaphore_ceiling_put_test.c334
-rw-r--r--test/smp/regression/threadx_semaphore_delete_test.c213
-rw-r--r--test/smp/regression/threadx_semaphore_information_test.c418
-rw-r--r--test/smp/regression/threadx_semaphore_non_preemption_test.c271
-rw-r--r--test/smp/regression/threadx_semaphore_preemption_test.c179
-rw-r--r--test/smp/regression/threadx_semaphore_prioritize.c525
-rw-r--r--test/smp/regression/threadx_semaphore_thread_terminate_test.c224
-rw-r--r--test/smp/regression/threadx_semaphore_timeout_test.c165
-rw-r--r--test/smp/regression/threadx_smp_multiple_threads_one_core_test.c348
-rw-r--r--test/smp/regression/threadx_smp_non_trivial_scheduling_test.c350
-rw-r--r--test/smp/regression/threadx_smp_one_thread_dynamic_exclusion_test.c145
-rw-r--r--test/smp/regression/threadx_smp_preemption_threshold_test.c534
-rw-r--r--test/smp/regression/threadx_smp_random_resume_suspend_exclusion_pt_test.c2490
-rw-r--r--test/smp/regression/threadx_smp_random_resume_suspend_exclusion_test.c2373
-rw-r--r--test/smp/regression/threadx_smp_random_resume_suspend_test.c2329
-rw-r--r--test/smp/regression/threadx_smp_rebalance_exclusion_test.c204
-rw-r--r--test/smp/regression/threadx_smp_relinquish_test.c365
-rw-r--r--test/smp/regression/threadx_smp_resume_suspend_accending_order_test.c1428
-rw-r--r--test/smp/regression/threadx_smp_resume_suspend_decending_order_test.c1427
-rw-r--r--test/smp/regression/threadx_smp_time_slice_test.c361
-rw-r--r--test/smp/regression/threadx_smp_two_threads_one_core_test.c268
-rw-r--r--test/smp/regression/threadx_thread_basic_execution_test.c863
-rw-r--r--test/smp/regression/threadx_thread_basic_time_slice_test.c117
-rw-r--r--test/smp/regression/threadx_thread_completed_test.c258
-rw-r--r--test/smp/regression/threadx_thread_create_preemption_threshold_test.c140
-rw-r--r--test/smp/regression/threadx_thread_delayed_suspension_test.c390
-rw-r--r--test/smp/regression/threadx_thread_information_test.c474
-rw-r--r--test/smp/regression/threadx_thread_multi_level_preemption_threshold_test.c982
-rw-r--r--test/smp/regression/threadx_thread_multiple_non_current_test.c222
-rw-r--r--test/smp/regression/threadx_thread_multiple_sleep_test.c184
-rw-r--r--test/smp/regression/threadx_thread_multiple_suspension_test.c432
-rw-r--r--test/smp/regression/threadx_thread_multiple_time_slice_test.c269
-rw-r--r--test/smp/regression/threadx_thread_preemptable_suspension_test.c416
-rw-r--r--test/smp/regression/threadx_thread_preemption_change_test.c379
-rw-r--r--test/smp/regression/threadx_thread_priority_change.c544
-rw-r--r--test/smp/regression/threadx_thread_relinquish_test.c459
-rw-r--r--test/smp/regression/threadx_thread_reset_test.c248
-rw-r--r--test/smp/regression/threadx_thread_simple_sleep_non_clear_test.c90
-rw-r--r--test/smp/regression/threadx_thread_simple_sleep_test.c85
-rw-r--r--test/smp/regression/threadx_thread_simple_suspend_test.c116
-rw-r--r--test/smp/regression/threadx_thread_sleep_for_100ticks_test.c435
-rw-r--r--test/smp/regression/threadx_thread_sleep_terminate_test.c187
-rw-r--r--test/smp/regression/threadx_thread_stack_checking_test.c224
-rw-r--r--test/smp/regression/threadx_thread_terminate_delete_test.c341
-rw-r--r--test/smp/regression/threadx_thread_time_slice_change_test.c149
-rw-r--r--test/smp/regression/threadx_thread_wait_abort_and_isr_test.c272
-rw-r--r--test/smp/regression/threadx_thread_wait_abort_test.c138
-rw-r--r--test/smp/regression/threadx_time_get_set_test.c109
-rw-r--r--test/smp/regression/threadx_timer_activate_deactivate_test.c268
-rw-r--r--test/smp/regression/threadx_timer_deactivate_accuracy_test.c286
-rw-r--r--test/smp/regression/threadx_timer_information_test.c538
-rw-r--r--test/smp/regression/threadx_timer_large_timer_accuracy_test.c286
-rw-r--r--test/smp/regression/threadx_timer_multiple_accuracy_test.c186
-rw-r--r--test/smp/regression/threadx_timer_multiple_test.c349
-rw-r--r--test/smp/regression/threadx_timer_simple_test.c830
-rw-r--r--test/smp/regression/threadx_trace_basic_test.c824
-rw-r--r--test/tx/cmake/CMakeLists.txt73
-rwxr-xr-xtest/tx/cmake/coverage.sh8
-rw-r--r--test/tx/cmake/regression/CMakeLists.txt121
-rwxr-xr-xtest/tx/cmake/regression/generate_test_file.sh10
l---------test/tx/cmake/run.sh1
-rw-r--r--test/tx/cmake/samples/CMakeLists.txt15
-rw-r--r--test/tx/cmake/samples/fake.c20
-rw-r--r--test/tx/regression/testcontrol.c1411
-rw-r--r--test/tx/regression/threadx_block_memory_basic_test.c568
-rw-r--r--test/tx/regression/threadx_block_memory_error_detection_test.c387
-rw-r--r--test/tx/regression/threadx_block_memory_information_test.c713
-rw-r--r--test/tx/regression/threadx_block_memory_prioritize_test.c500
-rw-r--r--test/tx/regression/threadx_block_memory_suspension_test.c311
-rw-r--r--test/tx/regression/threadx_block_memory_suspension_timeout_test.c212
-rw-r--r--test/tx/regression/threadx_block_memory_thread_terminate_test.c185
-rw-r--r--test/tx/regression/threadx_byte_memory_basic_test.c1064
-rw-r--r--test/tx/regression/threadx_byte_memory_information_test.c784
-rw-r--r--test/tx/regression/threadx_byte_memory_prioritize_test.c498
-rw-r--r--test/tx/regression/threadx_byte_memory_suspension_test.c391
-rw-r--r--test/tx/regression/threadx_byte_memory_suspension_timeout_test.c196
-rw-r--r--test/tx/regression/threadx_byte_memory_thread_contention_test.c255
-rw-r--r--test/tx/regression/threadx_byte_memory_thread_terminate_test.c177
-rw-r--r--test/tx/regression/threadx_event_flag_basic_test.c743
-rw-r--r--test/tx/regression/threadx_event_flag_information_test.c562
-rw-r--r--test/tx/regression/threadx_event_flag_isr_set_clear_test.c359
-rw-r--r--test/tx/regression/threadx_event_flag_isr_wait_abort_test.c331
-rw-r--r--test/tx/regression/threadx_event_flag_single_thread_terminate_test.c331
-rw-r--r--test/tx/regression/threadx_event_flag_suspension_consume_test.c281
-rw-r--r--test/tx/regression/threadx_event_flag_suspension_different_bits_consume_test.c224
-rw-r--r--test/tx/regression/threadx_event_flag_suspension_different_bits_test.c230
-rw-r--r--test/tx/regression/threadx_event_flag_suspension_test.c349
-rw-r--r--test/tx/regression/threadx_event_flag_suspension_timeout_test.c266
-rw-r--r--test/tx/regression/threadx_event_flag_thread_terminate_test.c234
-rw-r--r--test/tx/regression/threadx_initialize_kernel_setup_test.c81
-rw-r--r--test/tx/regression/threadx_interrupt_control_test.c94
-rw-r--r--test/tx/regression/threadx_mutex_basic_test.c767
-rw-r--r--test/tx/regression/threadx_mutex_delete_test.c194
-rw-r--r--test/tx/regression/threadx_mutex_information_test.c592
-rw-r--r--test/tx/regression/threadx_mutex_nested_priority_inheritance_test.c701
-rw-r--r--test/tx/regression/threadx_mutex_no_preemption_test.c173
-rw-r--r--test/tx/regression/threadx_mutex_preemption_test.c161
-rw-r--r--test/tx/regression/threadx_mutex_priority_inheritance_test.c573
-rw-r--r--test/tx/regression/threadx_mutex_proritize_test.c525
-rw-r--r--test/tx/regression/threadx_mutex_suspension_timeout_test.c319
-rw-r--r--test/tx/regression/threadx_mutex_thread_terminate_test.c198
-rw-r--r--test/tx/regression/threadx_queue_basic_eight_word_test.c423
-rw-r--r--test/tx/regression/threadx_queue_basic_four_word_test.c423
-rw-r--r--test/tx/regression/threadx_queue_basic_one_word_test.c867
-rw-r--r--test/tx/regression/threadx_queue_basic_sixteen_word_test.c423
-rw-r--r--test/tx/regression/threadx_queue_basic_two_word_test.c463
-rw-r--r--test/tx/regression/threadx_queue_empty_suspension_test.c271
-rw-r--r--test/tx/regression/threadx_queue_flush_no_suspension_test.c216
-rw-r--r--test/tx/regression/threadx_queue_flush_test.c249
-rw-r--r--test/tx/regression/threadx_queue_front_send_test.c686
-rw-r--r--test/tx/regression/threadx_queue_full_suspension_test.c368
-rw-r--r--test/tx/regression/threadx_queue_information_test.c664
-rw-r--r--test/tx/regression/threadx_queue_prioritize.c534
-rw-r--r--test/tx/regression/threadx_queue_suspension_timeout_test.c254
-rw-r--r--test/tx/regression/threadx_queue_thread_terminate_test.c183
-rw-r--r--test/tx/regression/threadx_semaphore_basic_test.c545
-rw-r--r--test/tx/regression/threadx_semaphore_ceiling_put_test.c334
-rw-r--r--test/tx/regression/threadx_semaphore_delete_test.c213
-rw-r--r--test/tx/regression/threadx_semaphore_information_test.c418
-rw-r--r--test/tx/regression/threadx_semaphore_non_preemption_test.c271
-rw-r--r--test/tx/regression/threadx_semaphore_preemption_test.c179
-rw-r--r--test/tx/regression/threadx_semaphore_prioritize.c525
-rw-r--r--test/tx/regression/threadx_semaphore_thread_terminate_test.c224
-rw-r--r--test/tx/regression/threadx_semaphore_timeout_test.c167
-rw-r--r--test/tx/regression/threadx_thread_basic_execution_test.c979
-rw-r--r--test/tx/regression/threadx_thread_basic_time_slice_test.c73
-rw-r--r--test/tx/regression/threadx_thread_completed_test.c258
-rw-r--r--test/tx/regression/threadx_thread_create_preemption_threshold_test.c140
-rw-r--r--test/tx/regression/threadx_thread_delayed_suspension_test.c390
-rw-r--r--test/tx/regression/threadx_thread_information_test.c474
-rw-r--r--test/tx/regression/threadx_thread_multi_level_preemption_threshold_test.c982
-rw-r--r--test/tx/regression/threadx_thread_multiple_non_current_test.c222
-rw-r--r--test/tx/regression/threadx_thread_multiple_sleep_test.c184
-rw-r--r--test/tx/regression/threadx_thread_multiple_suspension_test.c432
-rw-r--r--test/tx/regression/threadx_thread_multiple_time_slice_test.c269
-rw-r--r--test/tx/regression/threadx_thread_preemptable_suspension_test.c416
-rw-r--r--test/tx/regression/threadx_thread_preemption_change_test.c363
-rw-r--r--test/tx/regression/threadx_thread_priority_change.c378
-rw-r--r--test/tx/regression/threadx_thread_relinquish_test.c193
-rw-r--r--test/tx/regression/threadx_thread_reset_test.c248
-rw-r--r--test/tx/regression/threadx_thread_simple_sleep_non_clear_test.c92
-rw-r--r--test/tx/regression/threadx_thread_simple_sleep_test.c87
-rw-r--r--test/tx/regression/threadx_thread_simple_suspend_test.c116
-rw-r--r--test/tx/regression/threadx_thread_sleep_for_100ticks_test.c435
-rw-r--r--test/tx/regression/threadx_thread_sleep_terminate_test.c187
-rw-r--r--test/tx/regression/threadx_thread_stack_checking_test.c224
-rw-r--r--test/tx/regression/threadx_thread_terminate_delete_test.c341
-rw-r--r--test/tx/regression/threadx_thread_time_slice_change_test.c149
-rw-r--r--test/tx/regression/threadx_thread_wait_abort_and_isr_test.c271
-rw-r--r--test/tx/regression/threadx_thread_wait_abort_test.c138
-rw-r--r--test/tx/regression/threadx_time_get_set_test.c107
-rw-r--r--test/tx/regression/threadx_timer_activate_deactivate_test.c268
-rw-r--r--test/tx/regression/threadx_timer_deactivate_accuracy_test.c286
-rw-r--r--test/tx/regression/threadx_timer_information_test.c538
-rw-r--r--test/tx/regression/threadx_timer_large_timer_accuracy_test.c286
-rw-r--r--test/tx/regression/threadx_timer_multiple_accuracy_test.c186
-rw-r--r--test/tx/regression/threadx_timer_multiple_test.c349
-rw-r--r--test/tx/regression/threadx_timer_simple_test.c664
-rw-r--r--test/tx/regression/threadx_trace_basic_test.c779
223 files changed, 87109 insertions, 0 deletions
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 00000000..c751f6fb
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1,2 @@
+tx_initialize_low_level.c
+coverage_report/ \ No newline at end of file
diff --git a/test/smp/cmake/CMakeLists.txt b/test/smp/cmake/CMakeLists.txt
new file mode 100644
index 00000000..f50c7861
--- /dev/null
+++ b/test/smp/cmake/CMakeLists.txt
@@ -0,0 +1,76 @@
+cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
+cmake_policy(SET CMP0054 NEW)
+cmake_policy(SET CMP0057 NEW)
+
+project(threadx_smp_test LANGUAGES C)
+
+# Set build configurations
+set(BUILD_CONFIGURATIONS default_build_coverage
+ disable_notify_callbacks_build stack_checking_build
+ trace_build)
+set(CMAKE_CONFIGURATION_TYPES
+ ${BUILD_CONFIGURATIONS}
+ CACHE STRING "list of supported configuration types" FORCE)
+set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
+ ${CMAKE_CONFIGURATION_TYPES})
+list(GET CMAKE_CONFIGURATION_TYPES 0 BUILD_TYPE)
+if((NOT CMAKE_BUILD_TYPE) OR (NOT ("${CMAKE_BUILD_TYPE}" IN_LIST
+ CMAKE_CONFIGURATION_TYPES)))
+ set(CMAKE_BUILD_TYPE
+ "${BUILD_TYPE}"
+ CACHE STRING "Build Type of the project" FORCE)
+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(trace_build -DTX_ENABLE_EVENT_TRACE)
+
+add_compile_options(
+ -m32
+ -std=c99
+ -ggdb
+ -g3
+ -gdwarf-2
+ -fdiagnostics-color
+ # -Werror
+ -DTX_THREAD_SMP_ONLY_CORE_0_DEFAULT
+ -DTX_SMP_NOT_POSSIBLE
+ -DTX_REGRESSION_TEST
+ -DTEST_STACK_SIZE_PRINTF=4096
+ ${${CMAKE_BUILD_TYPE}})
+add_link_options(-m32)
+
+enable_testing()
+
+add_subdirectory(threadx_smp)
+add_subdirectory(regression)
+add_subdirectory(samples)
+
+# Coverage
+if(CMAKE_BUILD_TYPE MATCHES ".*_coverage")
+ target_compile_options(threadx_smp PRIVATE -fprofile-arcs -ftest-coverage)
+ target_link_options(threadx_smp PRIVATE -fprofile-arcs -ftest-coverage)
+endif()
+
+target_compile_options(
+ threadx_smp
+ PRIVATE # -Werror
+ -Wall
+ -Wextra
+ -pedantic
+ -fmessage-length=0
+ -fsigned-char
+ -ffunction-sections
+ -fdata-sections
+ -Wunused
+ -Wuninitialized
+ -Wmissing-declarations
+ -Wconversion
+ -Wpointer-arith
+ # -Wshadow
+ -Wlogical-op
+ -Waggregate-return
+ -Wfloat-equal)
diff --git a/test/smp/cmake/coverage.sh b/test/smp/cmake/coverage.sh
new file mode 100755
index 00000000..51b2e8ca
--- /dev/null
+++ b/test/smp/cmake/coverage.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+
+cd $(dirname $0)
+threadx_smp=$(realpath ../../../common_smp/src)
+mkdir -p coverage_report/$1
+gcovr --object-directory=build/$1/threadx_smp/CMakeFiles/threadx_smp.dir/$threadx_smp -r build/$1 -f ../../../common_smp/src --xml-pretty --output coverage_report/$1.xml
+gcovr --object-directory=build/$1/threadx_smp/CMakeFiles/threadx_smp.dir/$threadx_smp -r build/$1 -f ../../../common_smp/src --html --html-details --output coverage_report/$1/index.html
diff --git a/test/smp/cmake/regression/CMakeLists.txt b/test/smp/cmake/regression/CMakeLists.txt
new file mode 100644
index 00000000..ad002d18
--- /dev/null
+++ b/test/smp/cmake/regression/CMakeLists.txt
@@ -0,0 +1,133 @@
+cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
+cmake_policy(SET CMP0057 NEW)
+
+project(regression_test LANGUAGES C)
+
+set(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../regression)
+
+set(regression_test_cases
+ ${SOURCE_DIR}/threadx_block_memory_basic_test.c
+ ${SOURCE_DIR}/threadx_block_memory_error_detection_test.c
+ ${SOURCE_DIR}/threadx_block_memory_information_test.c
+ ${SOURCE_DIR}/threadx_block_memory_prioritize_test.c
+ ${SOURCE_DIR}/threadx_block_memory_suspension_test.c
+ ${SOURCE_DIR}/threadx_block_memory_suspension_timeout_test.c
+ ${SOURCE_DIR}/threadx_block_memory_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_basic_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_information_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_prioritize_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_suspension_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_suspension_timeout_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_thread_contention_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_event_flag_basic_test.c
+ ${SOURCE_DIR}/threadx_event_flag_information_test.c
+ ${SOURCE_DIR}/threadx_event_flag_isr_set_clear_test.c
+ ${SOURCE_DIR}/threadx_event_flag_isr_wait_abort_test.c
+ ${SOURCE_DIR}/threadx_event_flag_single_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_event_flag_suspension_consume_test.c
+ ${SOURCE_DIR}/threadx_event_flag_suspension_different_bits_consume_test.c
+ ${SOURCE_DIR}/threadx_event_flag_suspension_different_bits_test.c
+ ${SOURCE_DIR}/threadx_event_flag_suspension_test.c
+ ${SOURCE_DIR}/threadx_event_flag_suspension_timeout_test.c
+ ${SOURCE_DIR}/threadx_event_flag_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_interrupt_control_test.c
+ ${SOURCE_DIR}/threadx_mutex_basic_test.c
+ ${SOURCE_DIR}/threadx_mutex_delete_test.c
+ ${SOURCE_DIR}/threadx_mutex_information_test.c
+ ${SOURCE_DIR}/threadx_mutex_nested_priority_inheritance_test.c
+ ${SOURCE_DIR}/threadx_mutex_no_preemption_test.c
+ ${SOURCE_DIR}/threadx_mutex_preemption_test.c
+ ${SOURCE_DIR}/threadx_mutex_priority_inheritance_test.c
+ ${SOURCE_DIR}/threadx_mutex_proritize_test.c
+ ${SOURCE_DIR}/threadx_mutex_suspension_timeout_test.c
+ ${SOURCE_DIR}/threadx_mutex_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_queue_basic_eight_word_test.c
+ ${SOURCE_DIR}/threadx_queue_basic_four_word_test.c
+ ${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_empty_suspension_test.c
+ ${SOURCE_DIR}/threadx_queue_flush_no_suspension_test.c
+ ${SOURCE_DIR}/threadx_queue_flush_test.c
+ ${SOURCE_DIR}/threadx_queue_front_send_test.c
+ ${SOURCE_DIR}/threadx_queue_full_suspension_test.c
+ ${SOURCE_DIR}/threadx_queue_information_test.c
+ ${SOURCE_DIR}/threadx_queue_prioritize.c
+ ${SOURCE_DIR}/threadx_queue_suspension_timeout_test.c
+ ${SOURCE_DIR}/threadx_queue_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_semaphore_basic_test.c
+ ${SOURCE_DIR}/threadx_semaphore_ceiling_put_test.c
+ ${SOURCE_DIR}/threadx_semaphore_delete_test.c
+ ${SOURCE_DIR}/threadx_semaphore_information_test.c
+ ${SOURCE_DIR}/threadx_semaphore_non_preemption_test.c
+ ${SOURCE_DIR}/threadx_semaphore_preemption_test.c
+ ${SOURCE_DIR}/threadx_semaphore_prioritize.c
+ ${SOURCE_DIR}/threadx_semaphore_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_semaphore_timeout_test.c
+ ${SOURCE_DIR}/threadx_smp_multiple_threads_one_core_test.c
+ ${SOURCE_DIR}/threadx_smp_non_trivial_scheduling_test.c
+ ${SOURCE_DIR}/threadx_smp_one_thread_dynamic_exclusion_test.c
+ ${SOURCE_DIR}/threadx_smp_preemption_threshold_test.c
+ ${SOURCE_DIR}/threadx_smp_random_resume_suspend_exclusion_pt_test.c
+ ${SOURCE_DIR}/threadx_smp_random_resume_suspend_exclusion_test.c
+ ${SOURCE_DIR}/threadx_smp_random_resume_suspend_test.c
+ ${SOURCE_DIR}/threadx_smp_rebalance_exclusion_test.c
+ ${SOURCE_DIR}/threadx_smp_relinquish_test.c
+ ${SOURCE_DIR}/threadx_smp_resume_suspend_accending_order_test.c
+ ${SOURCE_DIR}/threadx_smp_resume_suspend_decending_order_test.c
+ ${SOURCE_DIR}/threadx_smp_time_slice_test.c
+ ${SOURCE_DIR}/threadx_smp_two_threads_one_core_test.c
+ ${SOURCE_DIR}/threadx_thread_basic_execution_test.c
+ ${SOURCE_DIR}/threadx_thread_basic_time_slice_test.c
+ ${SOURCE_DIR}/threadx_thread_completed_test.c
+ ${SOURCE_DIR}/threadx_thread_create_preemption_threshold_test.c
+ ${SOURCE_DIR}/threadx_thread_delayed_suspension_test.c
+ ${SOURCE_DIR}/threadx_thread_information_test.c
+ ${SOURCE_DIR}/threadx_thread_multi_level_preemption_threshold_test.c
+ ${SOURCE_DIR}/threadx_thread_multiple_non_current_test.c
+ ${SOURCE_DIR}/threadx_thread_multiple_sleep_test.c
+ ${SOURCE_DIR}/threadx_thread_multiple_suspension_test.c
+ ${SOURCE_DIR}/threadx_thread_multiple_time_slice_test.c
+ ${SOURCE_DIR}/threadx_thread_preemptable_suspension_test.c
+ ${SOURCE_DIR}/threadx_thread_preemption_change_test.c
+ ${SOURCE_DIR}/threadx_thread_priority_change.c
+ ${SOURCE_DIR}/threadx_thread_relinquish_test.c
+ ${SOURCE_DIR}/threadx_thread_reset_test.c
+ ${SOURCE_DIR}/threadx_thread_simple_sleep_non_clear_test.c
+ ${SOURCE_DIR}/threadx_thread_simple_sleep_test.c
+ ${SOURCE_DIR}/threadx_thread_simple_suspend_test.c
+ ${SOURCE_DIR}/threadx_thread_sleep_for_100ticks_test.c
+ ${SOURCE_DIR}/threadx_thread_sleep_terminate_test.c
+ ${SOURCE_DIR}/threadx_thread_stack_checking_test.c
+ ${SOURCE_DIR}/threadx_thread_terminate_delete_test.c
+ ${SOURCE_DIR}/threadx_thread_time_slice_change_test.c
+ ${SOURCE_DIR}/threadx_thread_wait_abort_and_isr_test.c
+ ${SOURCE_DIR}/threadx_thread_wait_abort_test.c
+ ${SOURCE_DIR}/threadx_time_get_set_test.c
+ ${SOURCE_DIR}/threadx_timer_activate_deactivate_test.c
+ ${SOURCE_DIR}/threadx_timer_deactivate_accuracy_test.c
+ ${SOURCE_DIR}/threadx_timer_information_test.c
+ ${SOURCE_DIR}/threadx_timer_large_timer_accuracy_test.c
+ ${SOURCE_DIR}/threadx_timer_multiple_accuracy_test.c
+ ${SOURCE_DIR}/threadx_timer_multiple_test.c
+ ${SOURCE_DIR}/threadx_timer_simple_test.c
+ ${SOURCE_DIR}/threadx_trace_basic_test.c
+ ${SOURCE_DIR}/threadx_initialize_kernel_setup_test.c)
+
+add_custom_command(
+ OUTPUT ${SOURCE_DIR}/tx_initialize_low_level.c
+ COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/generate_test_file.sh
+ COMMENT "Generating tx_initialize_low_level.c for test")
+
+add_library(test_utility ${SOURCE_DIR}/tx_initialize_low_level.c
+ ${SOURCE_DIR}/testcontrol.c)
+target_link_libraries(test_utility PUBLIC azrtos::threadx_smp)
+target_compile_definitions(test_utility PUBLIC CTEST BATCH_TEST)
+
+foreach(test_case ${regression_test_cases})
+ get_filename_component(test_name ${test_case} NAME_WE)
+ add_executable(${test_name} ${test_case})
+ target_link_libraries(${test_name} PRIVATE test_utility)
+ add_test(${CMAKE_BUILD_TYPE}::${test_name} ${test_name})
+endforeach()
diff --git a/test/smp/cmake/regression/generate_test_file.sh b/test/smp/cmake/regression/generate_test_file.sh
new file mode 100755
index 00000000..0172469a
--- /dev/null
+++ b/test/smp/cmake/regression/generate_test_file.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+dst=$(dirname $0)/../../regression/tx_initialize_low_level.c
+src=$(dirname $0)/../../../../ports_smp/linux/gnu/src/tx_initialize_low_level.c
+
+line=`sed -n '/_tx_linux_timer_interrupt/=' $src | tail -n 1`
+sed "${line}iVOID test_interrupt_dispatch(VOID);" $src > tmp1
+line=`sed -n '/_tx_timer_interrupt/=' $src | tail -n 1`
+sed "${line}itest_interrupt_dispatch();" tmp1 > $dst
+rm tmp1 \ No newline at end of file
diff --git a/test/smp/cmake/run.sh b/test/smp/cmake/run.sh
new file mode 120000
index 00000000..429ff2bd
--- /dev/null
+++ b/test/smp/cmake/run.sh
@@ -0,0 +1 @@
+../../../scripts/cmake_bootstrap.sh \ No newline at end of file
diff --git a/test/smp/cmake/samples/CMakeLists.txt b/test/smp/cmake/samples/CMakeLists.txt
new file mode 100644
index 00000000..4925246c
--- /dev/null
+++ b/test/smp/cmake/samples/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
+cmake_policy(SET CMP0057 NEW)
+
+project(samples LANGUAGES C)
+
+set(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../../ports_smp/linux/gnu/example_build)
+
+set(sample_files
+ ${SOURCE_DIR}/sample_threadx.c)
+
+foreach(sample_file ${sample_files})
+ get_filename_component(sample_file_name ${sample_file} NAME_WE)
+ add_executable(${sample_file_name} ${sample_file} ${CMAKE_CURRENT_LIST_DIR}/fake.c)
+ target_link_libraries(${sample_file_name} PRIVATE azrtos::threadx_smp)
+endforeach()
diff --git a/test/smp/cmake/samples/fake.c b/test/smp/cmake/samples/fake.c
new file mode 100644
index 00000000..8159fef4
--- /dev/null
+++ b/test/smp/cmake/samples/fake.c
@@ -0,0 +1,22 @@
+#include "tx_api.h"
+
+typedef unsigned int TEST_FLAG;
+TEST_FLAG threadx_byte_allocate_loop_test;
+TEST_FLAG threadx_byte_release_loop_test;
+TEST_FLAG threadx_mutex_suspension_put_test;
+TEST_FLAG threadx_mutex_suspension_priority_test;
+#ifndef TX_TIMER_PROCESS_IN_ISR
+TEST_FLAG threadx_delete_timer_thread;
+#endif
+
+void abort_and_resume_byte_allocating_thread(void){}
+void abort_all_threads_suspended_on_mutex(void){}
+void suspend_lowest_priority(void){}
+#ifndef TX_TIMER_PROCESS_IN_ISR
+void delete_timer_thread(void){}
+#endif
+TEST_FLAG test_stack_analyze_flag;
+TEST_FLAG test_initialize_flag;
+TEST_FLAG test_forced_mutex_timeout;
+UINT mutex_priority_change_extension_selection;
+UINT priority_change_extension_selection; \ No newline at end of file
diff --git a/test/smp/cmake/threadx_smp/CMakeLists.txt b/test/smp/cmake/threadx_smp/CMakeLists.txt
new file mode 100644
index 00000000..f12de984
--- /dev/null
+++ b/test/smp/cmake/threadx_smp/CMakeLists.txt
@@ -0,0 +1,60 @@
+cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
+
+# Set up the project
+project(threadx_smp
+ VERSION 6.0.0
+ LANGUAGES C ASM
+)
+
+if(NOT DEFINED THREADX_ARCH)
+ message(FATAL_ERROR "Error: THREADX_ARCH not defined")
+endif()
+if(NOT DEFINED THREADX_TOOLCHAIN)
+ message(FATAL_ERROR "Error: THREADX_TOOLCHAIN not defined")
+endif()
+
+set(PROJECT_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../..)
+
+# Define our target library and an alias for consumers
+add_library(${PROJECT_NAME})
+add_library("azrtos::${PROJECT_NAME}" ALIAS ${PROJECT_NAME})
+
+# A place for generated/copied include files (no need to change)
+set(CUSTOM_INC_DIR ${CMAKE_CURRENT_BINARY_DIR}/custom_inc)
+
+# Pick up the port specific variables and apply them
+add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/ports_smp/${THREADX_ARCH}/${THREADX_TOOLCHAIN})
+
+# Pick up the common stuff
+add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/common_smp)
+
+
+
+
+# If the user provided an override, copy it to the custom directory
+if (NOT TX_USER_FILE)
+ message(STATUS "Using default tx_user.h file")
+ set(TX_USER_FILE ${PROJECT_DIR}/common_smp/inc/tx_user_sample.h)
+else()
+ message(STATUS "Using custom tx_user.h file from ${TX_USER_FILE}")
+endif()
+configure_file(${TX_USER_FILE} ${CUSTOM_INC_DIR}/tx_user.h COPYONLY)
+target_include_directories(${PROJECT_NAME}
+ PUBLIC
+ ${CUSTOM_INC_DIR}
+)
+target_compile_definitions(${PROJECT_NAME} PUBLIC "TX_INCLUDE_USER_DEFINE_FILE" )
+
+# Enable a build target that produces a ZIP file of all sources
+set(CPACK_SOURCE_GENERATOR "ZIP")
+set(CPACK_SOURCE_IGNORE_FILES
+ \\.git/
+ \\.github/
+ _build/
+ \\.git
+ \\.gitattributes
+ \\.gitignore
+ ".*~$"
+)
+set(CPACK_VERBATIM_VARIABLES YES)
+include(CPack) \ No newline at end of file
diff --git a/test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt b/test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt
new file mode 100644
index 00000000..f7e35fde
--- /dev/null
+++ b/test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt
@@ -0,0 +1,220 @@
+set(CURRENT_DIR ${PROJECT_DIR}/common_smp)
+
+function(target_sources_if_not_overridden filename)
+ list(FIND TX_SRC_OVERRIDES ${filename} OVERRIDE_FOUND)
+ if( OVERRIDE_FOUND EQUAL -1 )
+ # message(STATUS "** Using original ${filename} from common/src **")
+ target_sources(${PROJECT_NAME} PRIVATE ${CURRENT_DIR}/src/${filename})
+ endif()
+endfunction()
+
+# These files can be overridden by setting them in the variable list named TX_SRC_OVERRIDES
+target_sources_if_not_overridden("tx_thread_delete.c")
+target_sources_if_not_overridden("tx_thread_reset.c")
+
+target_sources(${PROJECT_NAME}
+ PRIVATE
+ # {{BEGIN_TARGET_SOURCES}}
+ ${CURRENT_DIR}/src/tx_block_allocate.c
+ ${CURRENT_DIR}/src/tx_block_allocate.c
+ ${CURRENT_DIR}/src/tx_block_pool_cleanup.c
+ ${CURRENT_DIR}/src/tx_block_pool_create.c
+ ${CURRENT_DIR}/src/tx_block_pool_delete.c
+ ${CURRENT_DIR}/src/tx_block_pool_info_get.c
+ ${CURRENT_DIR}/src/tx_block_pool_initialize.c
+ ${CURRENT_DIR}/src/tx_block_pool_performance_info_get.c
+ ${CURRENT_DIR}/src/tx_block_pool_performance_system_info_get.c
+ ${CURRENT_DIR}/src/tx_block_pool_prioritize.c
+ ${CURRENT_DIR}/src/tx_block_release.c
+ ${CURRENT_DIR}/src/tx_byte_allocate.c
+ ${CURRENT_DIR}/src/tx_byte_pool_cleanup.c
+ ${CURRENT_DIR}/src/tx_byte_pool_create.c
+ ${CURRENT_DIR}/src/tx_byte_pool_delete.c
+ ${CURRENT_DIR}/src/tx_byte_pool_info_get.c
+ ${CURRENT_DIR}/src/tx_byte_pool_initialize.c
+ ${CURRENT_DIR}/src/tx_byte_pool_performance_info_get.c
+ ${CURRENT_DIR}/src/tx_byte_pool_performance_system_info_get.c
+ ${CURRENT_DIR}/src/tx_byte_pool_prioritize.c
+ ${CURRENT_DIR}/src/tx_byte_pool_search.c
+ ${CURRENT_DIR}/src/tx_byte_release.c
+ ${CURRENT_DIR}/src/txe_block_allocate.c
+ ${CURRENT_DIR}/src/txe_block_pool_create.c
+ ${CURRENT_DIR}/src/txe_block_pool_delete.c
+ ${CURRENT_DIR}/src/txe_block_pool_info_get.c
+ ${CURRENT_DIR}/src/txe_block_pool_prioritize.c
+ ${CURRENT_DIR}/src/txe_block_release.c
+ ${CURRENT_DIR}/src/txe_byte_allocate.c
+ ${CURRENT_DIR}/src/txe_byte_pool_create.c
+ ${CURRENT_DIR}/src/txe_byte_pool_delete.c
+ ${CURRENT_DIR}/src/txe_byte_pool_info_get.c
+ ${CURRENT_DIR}/src/txe_byte_pool_prioritize.c
+ ${CURRENT_DIR}/src/txe_byte_release.c
+ ${CURRENT_DIR}/src/txe_event_flags_create.c
+ ${CURRENT_DIR}/src/txe_event_flags_delete.c
+ ${CURRENT_DIR}/src/txe_event_flags_get.c
+ ${CURRENT_DIR}/src/txe_event_flags_info_get.c
+ ${CURRENT_DIR}/src/txe_event_flags_set.c
+ ${CURRENT_DIR}/src/txe_event_flags_set_notify.c
+ ${CURRENT_DIR}/src/txe_mutex_create.c
+ ${CURRENT_DIR}/src/txe_mutex_delete.c
+ ${CURRENT_DIR}/src/txe_mutex_get.c
+ ${CURRENT_DIR}/src/txe_mutex_info_get.c
+ ${CURRENT_DIR}/src/txe_mutex_prioritize.c
+ ${CURRENT_DIR}/src/txe_mutex_put.c
+ ${CURRENT_DIR}/src/txe_queue_create.c
+ ${CURRENT_DIR}/src/txe_queue_delete.c
+ ${CURRENT_DIR}/src/txe_queue_flush.c
+ ${CURRENT_DIR}/src/txe_queue_front_send.c
+ ${CURRENT_DIR}/src/txe_queue_info_get.c
+ ${CURRENT_DIR}/src/txe_queue_prioritize.c
+ ${CURRENT_DIR}/src/txe_queue_receive.c
+ ${CURRENT_DIR}/src/txe_queue_send.c
+ ${CURRENT_DIR}/src/txe_queue_send_notify.c
+ ${CURRENT_DIR}/src/txe_semaphore_ceiling_put.c
+ ${CURRENT_DIR}/src/txe_semaphore_create.c
+ ${CURRENT_DIR}/src/txe_semaphore_delete.c
+ ${CURRENT_DIR}/src/txe_semaphore_get.c
+ ${CURRENT_DIR}/src/txe_semaphore_info_get.c
+ ${CURRENT_DIR}/src/txe_semaphore_prioritize.c
+ ${CURRENT_DIR}/src/txe_semaphore_put.c
+ ${CURRENT_DIR}/src/txe_semaphore_put_notify.c
+ ${CURRENT_DIR}/src/txe_thread_create.c
+ ${CURRENT_DIR}/src/txe_thread_delete.c
+ ${CURRENT_DIR}/src/txe_thread_entry_exit_notify.c
+ ${CURRENT_DIR}/src/txe_thread_info_get.c
+ ${CURRENT_DIR}/src/txe_thread_preemption_change.c
+ ${CURRENT_DIR}/src/txe_thread_priority_change.c
+ ${CURRENT_DIR}/src/txe_thread_relinquish.c
+ ${CURRENT_DIR}/src/txe_thread_reset.c
+ ${CURRENT_DIR}/src/txe_thread_resume.c
+ ${CURRENT_DIR}/src/txe_thread_suspend.c
+ ${CURRENT_DIR}/src/txe_thread_terminate.c
+ ${CURRENT_DIR}/src/txe_thread_time_slice_change.c
+ ${CURRENT_DIR}/src/txe_thread_wait_abort.c
+ ${CURRENT_DIR}/src/txe_timer_activate.c
+ ${CURRENT_DIR}/src/txe_timer_change.c
+ ${CURRENT_DIR}/src/txe_timer_create.c
+ ${CURRENT_DIR}/src/txe_timer_deactivate.c
+ ${CURRENT_DIR}/src/txe_timer_delete.c
+ ${CURRENT_DIR}/src/txe_timer_info_get.c
+ ${CURRENT_DIR}/src/tx_event_flags_cleanup.c
+ ${CURRENT_DIR}/src/tx_event_flags_create.c
+ ${CURRENT_DIR}/src/tx_event_flags_delete.c
+ ${CURRENT_DIR}/src/tx_event_flags_get.c
+ ${CURRENT_DIR}/src/tx_event_flags_info_get.c
+ ${CURRENT_DIR}/src/tx_event_flags_initialize.c
+ ${CURRENT_DIR}/src/tx_event_flags_performance_info_get.c
+ ${CURRENT_DIR}/src/tx_event_flags_performance_system_info_get.c
+ ${CURRENT_DIR}/src/tx_event_flags_set.c
+ ${CURRENT_DIR}/src/tx_event_flags_set_notify.c
+ ${CURRENT_DIR}/src/tx_initialize_high_level.c
+ ${CURRENT_DIR}/src/tx_initialize_kernel_enter.c
+ ${CURRENT_DIR}/src/tx_initialize_kernel_setup.c
+ ${CURRENT_DIR}/src/tx_misra.c
+ ${CURRENT_DIR}/src/tx_mutex_cleanup.c
+ ${CURRENT_DIR}/src/tx_mutex_create.c
+ ${CURRENT_DIR}/src/tx_mutex_delete.c
+ ${CURRENT_DIR}/src/tx_mutex_get.c
+ ${CURRENT_DIR}/src/tx_mutex_info_get.c
+ ${CURRENT_DIR}/src/tx_mutex_initialize.c
+ ${CURRENT_DIR}/src/tx_mutex_performance_info_get.c
+ ${CURRENT_DIR}/src/tx_mutex_performance_system_info_get.c
+ ${CURRENT_DIR}/src/tx_mutex_prioritize.c
+ ${CURRENT_DIR}/src/tx_mutex_priority_change.c
+ ${CURRENT_DIR}/src/tx_mutex_put.c
+ ${CURRENT_DIR}/src/tx_queue_cleanup.c
+ ${CURRENT_DIR}/src/tx_queue_create.c
+ ${CURRENT_DIR}/src/tx_queue_delete.c
+ ${CURRENT_DIR}/src/tx_queue_flush.c
+ ${CURRENT_DIR}/src/tx_queue_front_send.c
+ ${CURRENT_DIR}/src/tx_queue_info_get.c
+ ${CURRENT_DIR}/src/tx_queue_initialize.c
+ ${CURRENT_DIR}/src/tx_queue_performance_info_get.c
+ ${CURRENT_DIR}/src/tx_queue_performance_system_info_get.c
+ ${CURRENT_DIR}/src/tx_queue_prioritize.c
+ ${CURRENT_DIR}/src/tx_queue_receive.c
+ ${CURRENT_DIR}/src/tx_queue_send.c
+ ${CURRENT_DIR}/src/tx_queue_send_notify.c
+ ${CURRENT_DIR}/src/tx_semaphore_ceiling_put.c
+ ${CURRENT_DIR}/src/tx_semaphore_cleanup.c
+ ${CURRENT_DIR}/src/tx_semaphore_create.c
+ ${CURRENT_DIR}/src/tx_semaphore_delete.c
+ ${CURRENT_DIR}/src/tx_semaphore_get.c
+ ${CURRENT_DIR}/src/tx_semaphore_info_get.c
+ ${CURRENT_DIR}/src/tx_semaphore_initialize.c
+ ${CURRENT_DIR}/src/tx_semaphore_performance_info_get.c
+ ${CURRENT_DIR}/src/tx_semaphore_performance_system_info_get.c
+ ${CURRENT_DIR}/src/tx_semaphore_prioritize.c
+ ${CURRENT_DIR}/src/tx_semaphore_put.c
+ ${CURRENT_DIR}/src/tx_semaphore_put_notify.c
+ ${CURRENT_DIR}/src/tx_thread_create.c
+ ${CURRENT_DIR}/src/tx_thread_entry_exit_notify.c
+ ${CURRENT_DIR}/src/tx_thread_identify.c
+ ${CURRENT_DIR}/src/tx_thread_info_get.c
+ ${CURRENT_DIR}/src/tx_thread_initialize.c
+ ${CURRENT_DIR}/src/tx_thread_performance_info_get.c
+ ${CURRENT_DIR}/src/tx_thread_performance_system_info_get.c
+ ${CURRENT_DIR}/src/tx_thread_preemption_change.c
+ ${CURRENT_DIR}/src/tx_thread_priority_change.c
+ ${CURRENT_DIR}/src/tx_thread_relinquish.c
+ ${CURRENT_DIR}/src/tx_thread_resume.c
+ ${CURRENT_DIR}/src/tx_thread_shell_entry.c
+ ${CURRENT_DIR}/src/tx_thread_sleep.c
+ ${CURRENT_DIR}/src/tx_thread_smp_utilities.c
+ ${CURRENT_DIR}/src/tx_thread_stack_analyze.c
+ ${CURRENT_DIR}/src/tx_thread_stack_error_handler.c
+ ${CURRENT_DIR}/src/tx_thread_stack_error_notify.c
+ ${CURRENT_DIR}/src/tx_thread_suspend.c
+ ${CURRENT_DIR}/src/tx_thread_system_preempt_check.c
+ ${CURRENT_DIR}/src/tx_thread_system_resume.c
+ ${CURRENT_DIR}/src/tx_thread_system_suspend.c
+ ${CURRENT_DIR}/src/tx_thread_terminate.c
+ ${CURRENT_DIR}/src/tx_thread_timeout.c
+ ${CURRENT_DIR}/src/tx_thread_time_slice.c
+ ${CURRENT_DIR}/src/tx_thread_time_slice_change.c
+ ${CURRENT_DIR}/src/tx_thread_wait_abort.c
+ ${CURRENT_DIR}/src/tx_time_get.c
+ ${CURRENT_DIR}/src/tx_timer_activate.c
+ ${CURRENT_DIR}/src/tx_timer_change.c
+ ${CURRENT_DIR}/src/tx_timer_create.c
+ ${CURRENT_DIR}/src/tx_timer_deactivate.c
+ ${CURRENT_DIR}/src/tx_timer_delete.c
+ ${CURRENT_DIR}/src/tx_timer_expiration_process.c
+ ${CURRENT_DIR}/src/tx_timer_info_get.c
+ ${CURRENT_DIR}/src/tx_timer_initialize.c
+ ${CURRENT_DIR}/src/tx_timer_performance_info_get.c
+ ${CURRENT_DIR}/src/tx_timer_performance_system_info_get.c
+ ${CURRENT_DIR}/src/tx_timer_system_activate.c
+ ${CURRENT_DIR}/src/tx_timer_system_deactivate.c
+ ${CURRENT_DIR}/src/tx_timer_thread_entry.c
+ ${CURRENT_DIR}/src/tx_time_set.c
+ ${CURRENT_DIR}/src/tx_trace_buffer_full_notify.c
+ ${CURRENT_DIR}/src/tx_trace_disable.c
+ ${CURRENT_DIR}/src/tx_trace_enable.c
+ ${CURRENT_DIR}/src/tx_trace_event_filter.c
+ ${CURRENT_DIR}/src/tx_trace_event_unfilter.c
+ ${CURRENT_DIR}/src/tx_trace_initialize.c
+ ${CURRENT_DIR}/src/tx_trace_interrupt_control.c
+ ${CURRENT_DIR}/src/tx_trace_isr_enter_insert.c
+ ${CURRENT_DIR}/src/tx_trace_isr_exit_insert.c
+ ${CURRENT_DIR}/src/tx_trace_object_register.c
+ ${CURRENT_DIR}/src/tx_trace_object_unregister.c
+ ${CURRENT_DIR}/src/tx_trace_user_event_insert.c
+ ${CURRENT_DIR}/src/tx_thread_smp_core_exclude.c
+ ${CURRENT_DIR}/src/tx_thread_smp_core_exclude_get.c
+ ${CURRENT_DIR}/src/tx_thread_smp_current_state_set.c
+ ${CURRENT_DIR}/src/tx_thread_smp_debug_entry_insert.c
+ ${CURRENT_DIR}/src/tx_thread_smp_high_level_initialize.c
+ ${CURRENT_DIR}/src/tx_thread_smp_rebalance_execute_list.c
+ ${CURRENT_DIR}/src/tx_timer_smp_core_exclude.c
+ ${CURRENT_DIR}/src/tx_timer_smp_core_exclude_get.c
+
+ # {{END_TARGET_SOURCES}}
+)
+
+# Add the Common/inc directory to the project include list
+target_include_directories(${PROJECT_NAME}
+ PUBLIC
+ ${CURRENT_DIR}/inc
+)
+
diff --git a/test/smp/cmake/threadx_smp/ports_smp/linux/gnu/CMakeLists.txt b/test/smp/cmake/threadx_smp/ports_smp/linux/gnu/CMakeLists.txt
new file mode 100644
index 00000000..9c51522c
--- /dev/null
+++ b/test/smp/cmake/threadx_smp/ports_smp/linux/gnu/CMakeLists.txt
@@ -0,0 +1,32 @@
+
+set(CURRENT_DIR ${PROJECT_DIR}/ports_smp/linux/gnu)
+target_sources(${PROJECT_NAME}
+ PRIVATE
+ # {{BEGIN_TARGET_SOURCES}}
+ ${CURRENT_DIR}/src/tx_initialize_low_level.c
+ ${CURRENT_DIR}/src/tx_thread_context_restore.c
+ ${CURRENT_DIR}/src/tx_thread_context_save.c
+ ${CURRENT_DIR}/src/tx_thread_interrupt_control.c
+ ${CURRENT_DIR}/src/tx_thread_schedule.c
+ ${CURRENT_DIR}/src/tx_thread_smp_core_get.c
+ ${CURRENT_DIR}/src/tx_thread_smp_core_preempt.c
+ ${CURRENT_DIR}/src/tx_thread_smp_current_state_get.c
+ ${CURRENT_DIR}/src/tx_thread_smp_current_thread_get.c
+ ${CURRENT_DIR}/src/tx_thread_smp_initialize_wait.c
+ ${CURRENT_DIR}/src/tx_thread_smp_low_level_initialize.c
+ ${CURRENT_DIR}/src/tx_thread_smp_protect.c
+ ${CURRENT_DIR}/src/tx_thread_smp_time_get.c
+ ${CURRENT_DIR}/src/tx_thread_smp_unprotect.c
+ ${CURRENT_DIR}/src/tx_thread_stack_build.c
+ ${CURRENT_DIR}/src/tx_thread_system_return.c
+ ${CURRENT_DIR}/src/tx_timer_interrupt.c
+
+ # {{END_TARGET_SOURCES}}
+)
+
+target_include_directories(${PROJECT_NAME}
+ PUBLIC
+ ${CURRENT_DIR}/inc
+)
+
+target_compile_definitions(${PROJECT_NAME} PUBLIC "-D_GNU_SOURCE -DTX_LINUX_DEBUG_ENABLE") \ No newline at end of file
diff --git a/test/smp/regression/testcontrol.c b/test/smp/regression/testcontrol.c
new file mode 100644
index 00000000..1813d42f
--- /dev/null
+++ b/test/smp/regression/testcontrol.c
@@ -0,0 +1,1609 @@
+/* This is the test control routine of the ThreadX kernel. All tests are dispatched from this routine. */
+
+#define TX_THREAD_SMP_SOURCE_CODE
+
+#include "tx_api.h"
+#include <stdio.h>
+#include "tx_initialize.h"
+#include "tx_timer.h"
+#include "tx_thread.h"
+#include "tx_semaphore.h"
+#include "tx_queue.h"
+#include "tx_mutex.h"
+#include "tx_block_pool.h"
+#include "tx_byte_pool.h"
+#include "tx_event_flags.h"
+
+
+#define TEST_STACK_SIZE 6144
+
+
+/* Define the test control ThreadX objects... */
+
+TX_THREAD test_control_thread;
+TX_THREAD test_thread;
+TX_THREAD test_thread1;
+TX_THREAD test_thread2;
+TX_THREAD test_thread3;
+ULONG test_thread3_stack[256];
+TX_QUEUE test_queue;
+ULONG test_thread2_stack[256];
+TX_TIMER test_timer;
+TX_MUTEX init_mutex;
+TX_MUTEX init_mutex_inherit;
+TX_MUTEX cleanup_mutex;
+TX_EVENT_FLAGS_GROUP cleanup_event_flags;
+TX_BLOCK_POOL cleanup_block_pool;
+TX_BYTE_POOL cleanup_byte_pool;
+TX_QUEUE cleanup_queue;
+TX_SEMAPHORE cleanup_semaphore;
+TX_SEMAPHORE init_semaphore;
+ULONG init_queue_area[20];
+TX_QUEUE init_queue;
+TX_BYTE_POOL init_byte_pool;
+ULONG init_byte_pool_area[50];
+TX_BLOCK_POOL init_block_pool;
+ULONG init_block_pool_area[50];
+TX_EVENT_FLAGS_GROUP init_event_flags;
+TX_TIMER init_timer;
+TX_THREAD init_test_thread;
+TX_THREAD second_test_thread;
+#ifndef TX_TIMER_PROCESS_IN_ISR
+TEST_FLAG threadx_delete_timer_thread;
+#endif
+TX_TIMER_INTERNAL **_timer_list_start_backup;
+TEST_FLAG test_stack_analyze_flag;
+TEST_FLAG test_initialize_flag;
+TX_BLOCK_POOL fake_block_pool;
+TX_BYTE_POOL fake_byte_pool;
+TX_EVENT_FLAGS_GROUP fake_event_flags;
+TX_MUTEX fake_mutex;
+TX_QUEUE fake_queue;
+TX_SEMAPHORE fake_semaphore;
+TX_THREAD test_thread4;
+TX_THREAD test_thread5;
+TX_THREAD test_thread6;
+TX_THREAD test_thread7;
+TX_THREAD test_thread8;
+TX_THREAD test_thread9;
+TX_THREAD test_thread10;
+TX_THREAD test_thread11;
+TX_THREAD test_thread12;
+TX_THREAD test_thread13;
+TX_THREAD test_thread14;
+ULONG test_thread4_stack[256];
+ULONG test_thread5_stack[256];
+ULONG test_thread6_stack[256];
+ULONG test_thread7_stack[256];
+ULONG test_thread8_stack[256];
+ULONG test_thread9_stack[256];
+ULONG test_thread10_stack[256];
+ULONG test_thread11_stack[256];
+ULONG test_thread12_stack[256];
+ULONG test_thread13_stack[256];
+ULONG test_thread14_stack[256];
+
+
+/* Define the test control global variables. */
+
+ULONG test_control_return_status;
+ULONG test_control_successful_tests;
+ULONG test_control_failed_tests;
+ULONG test_control_system_errors;
+
+UINT test_mutex_from_init;
+UINT test_semaphore_from_init;
+UINT test_queue_from_init;
+UINT test_event_flags_from_init;
+UINT test_byte_pool_create_init;
+UINT test_block_pool_create_init;
+UINT test_timer_create_init;
+
+
+/* Remember the start of free memory. */
+
+UCHAR *test_free_memory_ptr;
+
+
+/* Define the function pointer for ISR dispatch. */
+
+VOID (*test_isr_dispatch)(void);
+
+
+UCHAR test_control_memory[0x60000];
+UCHAR tests_memory[0x60000];
+
+UINT mutex_priority_change_extension_selection;
+UINT priority_change_extension_selection;
+TEST_FLAG test_forced_mutex_timeout;
+TEST_FLAG threadx_byte_allocate_loop_test;
+TEST_FLAG threadx_byte_release_loop_test;
+TEST_FLAG threadx_mutex_suspension_put_test;
+TEST_FLAG threadx_mutex_suspension_priority_test;
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+extern volatile ULONG _tx_thread_system_state[TX_THREAD_SMP_MAX_CORES];
+
+
+/* Define test entry pointer type. */
+
+typedef struct TEST_ENTRY_STRUCT
+{
+
+VOID (*test_entry)(void *);
+} TEST_ENTRY;
+
+
+/* Define the prototypes for the test entry points. */
+
+void threadx_block_memory_basic_application_define(void *);
+void threadx_block_memory_error_detection_application_define(void *);
+void threadx_block_memory_suspension_application_define(void *);
+void threadx_block_memory_suspension_timeout_application_define(void *);
+void threadx_block_memory_thread_terminate_application_define(void *);
+void threadx_block_memory_prioritize_application_define(void *);
+void threadx_block_memory_information_application_define(void *);
+
+void threadx_byte_memory_basic_application_define(void *);
+void threadx_byte_memory_thread_contention_application_define(void *);
+void threadx_byte_memory_suspension_application_define(void *);
+void threadx_byte_memory_suspension_timeout_application_define(void *);
+void threadx_byte_memory_thread_terminate_application_define(void *);
+void threadx_byte_memory_prioritize_application_define(void *);
+void threadx_byte_memory_information_application_define(void *);
+
+void threadx_event_flag_basic_application_define(void *);
+void threadx_event_flag_suspension_application_define(void *);
+void threadx_event_flag_suspension_consume_application_define(void *);
+void threadx_event_flag_suspension_different_bits_application_define(void *);
+void threadx_event_flag_suspension_different_bits_consume_application_define(void *);
+void threadx_event_flag_suspension_timeout_application_define(void *);
+void threadx_event_flag_thread_terminate_application_define(void *);
+void threadx_event_flag_single_thread_terminate_application_define(void *);
+void threadx_event_flag_isr_set_clear_application_define(void *);
+void threadx_event_flag_isr_wait_abort_application_define(void *);
+void threadx_event_flag_information_application_define(void *);
+
+void threadx_interrupt_control_application_define(void *);
+
+void threadx_mutex_basic_application_define(void *);
+void threadx_mutex_delete_application_define(void *);
+void threadx_mutex_preemption_application_define(void *);
+void threadx_mutext_no_preemption_application_define(void *);
+void threadx_mutex_suspension_timeout_application_define(void *);
+void threadx_mutex_thread_terminate_application_define(void *);
+void threadx_mutex_priority_inheritance_application_define(void *);
+void threadx_mutex_nested_priority_inheritance_application_define(void *);
+void threadx_mutex_prioritize_application_define(void *);
+void threadx_mutex_information_application_define(void *);
+
+void threadx_queue_basic_application_define(void *);
+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_empty_suspension_application_define(void *);
+void threadx_queue_full_suspension_application_define(void *);
+void threadx_queue_suspension_timeout_application_define(void *);
+void threadx_queue_thread_terminate_application_define(void *);
+void threadx_queue_flush_application_define(void *);
+void threadx_queue_flush_no_suspension_application_define(void *);
+void threadx_queue_front_send_application_define(void *);
+void threadx_queue_prioritize_application_define(void *);
+void threadx_queue_information_application_define(void *);
+
+void threadx_semaphore_basic_application_define(void *);
+void threadx_semaphore_delete_application_define(void *);
+void threadx_semaphore_preemption_application_define(void *);
+void threadx_semaphore_non_preemption_application_define(void *);
+void threadx_semaphore_timeout_application_define(void *);
+void threadx_semaphore_thread_terminate_application_define(void *);
+void threadx_semaphore_prioritize_application_define(void *);
+void threadx_semaphore_ceiling_put_application_define(void *);
+void threadx_semaphore_information_application_define(void *);
+
+void threadx_thread_basic_execution_application_define(void *);
+void threadx_thread_completed_application_define(void *);
+void threadx_thread_relinquish_application_define(void *);
+void threadx_thread_simple_supsend_application_define(void *);
+void threadx_thread_multiple_suspension_application_define(void *);
+void threadx_thread_multiple_non_current_suspension_application_define(void *);
+void threadx_thread_multi_level_preemption_threshold_application_define(void *);
+void threadx_thread_preemptable_suspension_application_define(void *);
+void threadx_thread_basic_time_slice_application_define(void *);
+void threadx_thread_multiple_time_slice_application_define(void *);
+void threadx_thread_simple_sleep_application_define(void *);
+void threadx_thread_simple_sleep_non_clear_application_define(void *);
+void threadx_thread_sleep_for_100ticks_application_define(void *);
+void threadx_thread_multiple_sleep_application_define(void *);
+void threadx_thread_terminate_delete_application_define(void *);
+void threadx_thread_preemption_change_application_define(void *);
+void threadx_thread_priority_change_application_define(void *);
+void threadx_thread_time_slice_change_application_define(void *);
+void threadx_thread_sleep_terminate_application_define(void *);
+void threadx_thread_delayed_suspension_application_define(void *);
+void threadx_thread_wait_abort_application_define(void *);
+void threadx_thread_wait_abort_and_isr_application_define(void *);
+void threadx_thread_create_preemption_threshold_application_define(void *);
+void threadx_thread_information_application_define(void *);
+void threadx_thread_reset_application_define(void *);
+void threadx_thread_stack_checking_application_define(void *);
+
+void threadx_time_get_set_application_define(void *);
+
+void threadx_timer_simple_application_define(void *);
+void threadx_timer_activate_deactivate_application_define(void *);
+void threadx_timer_deactivate_accuracy_application_define(void *);
+void threadx_timer_large_timer_accuracy_application_define(void *);
+void threadx_timer_multiple_application_define(void *);
+void threadx_timer_multiple_accuracy_application_define(void *);
+void threadx_timer_information_application_define(void *);
+
+void threadx_trace_basic_application_define(void *);
+
+void threadx_smp_rebalance_exclustion_test(void *first_unused_memory);
+void threadx_smp_two_threads_one_core_test(void *first_unused_memory);
+void threadx_smp_multiple_threads_one_core_test(void *first_unused_memory);
+void threadx_smp_one_thread_dynamic_exclusion_test(void *first_unused_memory);
+void threadx_smp_non_trivial_scheduling_test(void *first_unused_memory);
+void threadx_smp_resume_suspend_accending_order_test(void *first_unused_memory);
+void threadx_smp_resume_suspend_decending_order_test(void *first_unused_memory);
+void threadx_smp_preemption_threshold_test(void *first_unused_memory);
+void threadx_smp_relinquish_test(void *first_unused_memory);
+void threadx_smp_time_slice_test(void *first_unused_memory);
+void threadx_smp_random_resume_suspend_test(void *first_unused_memory);
+void threadx_smp_random_resume_suspend_exclusion_test(void *first_unused_memory);
+void threadx_smp_random_resume_suspend_exclusion_pt_test(void *first_unused_memory);
+void test_application_define(void *first_unused_memory);
+
+
+/* Define the array of test entry points. */
+
+TEST_ENTRY test_control_tests[] =
+{
+#if CTEST
+ test_application_define,
+#else
+
+ threadx_smp_rebalance_exclustion_test,
+ threadx_smp_two_threads_one_core_test,
+ threadx_smp_multiple_threads_one_core_test,
+ threadx_smp_one_thread_dynamic_exclusion_test,
+ threadx_smp_non_trivial_scheduling_test,
+ threadx_smp_resume_suspend_accending_order_test,
+ threadx_smp_resume_suspend_decending_order_test,
+ threadx_smp_preemption_threshold_test,
+ threadx_smp_relinquish_test,
+ threadx_smp_time_slice_test,
+ threadx_smp_random_resume_suspend_test,
+ threadx_smp_random_resume_suspend_exclusion_test,
+ threadx_smp_random_resume_suspend_exclusion_pt_test,
+
+ threadx_block_memory_basic_application_define,
+ threadx_block_memory_error_detection_application_define,
+ threadx_block_memory_prioritize_application_define,
+ threadx_block_memory_suspension_application_define,
+ threadx_block_memory_suspension_timeout_application_define,
+ threadx_block_memory_thread_terminate_application_define,
+ threadx_block_memory_information_application_define,
+
+ threadx_byte_memory_basic_application_define,
+ threadx_byte_memory_suspension_application_define,
+ threadx_byte_memory_suspension_timeout_application_define,
+ threadx_byte_memory_thread_terminate_application_define,
+ threadx_byte_memory_prioritize_application_define,
+ threadx_byte_memory_thread_contention_application_define,
+ threadx_byte_memory_information_application_define,
+
+ threadx_event_flag_basic_application_define,
+ threadx_event_flag_suspension_application_define,
+ threadx_event_flag_suspension_consume_application_define,
+ threadx_event_flag_suspension_different_bits_application_define,
+ threadx_event_flag_suspension_different_bits_consume_application_define,
+ threadx_event_flag_suspension_timeout_application_define,
+ threadx_event_flag_thread_terminate_application_define,
+ threadx_event_flag_single_thread_terminate_application_define,
+ threadx_event_flag_isr_set_clear_application_define,
+ threadx_event_flag_isr_wait_abort_application_define,
+ threadx_event_flag_information_application_define,
+
+ threadx_interrupt_control_application_define,
+
+ threadx_mutex_basic_application_define,
+ threadx_mutex_delete_application_define,
+ threadx_mutex_preemption_application_define,
+ threadx_mutext_no_preemption_application_define,
+ threadx_mutex_suspension_timeout_application_define,
+ threadx_mutex_thread_terminate_application_define,
+ threadx_mutex_priority_inheritance_application_define,
+ threadx_mutex_prioritize_application_define,
+ threadx_mutex_nested_priority_inheritance_application_define,
+ threadx_mutex_information_application_define,
+
+ threadx_queue_basic_application_define,
+ threadx_queue_basic_two_word_application_define,
+ threadx_queue_basic_four_word_application_define,
+ threadx_queue_basic_eight_word_application_define,
+ threadx_queue_basic_sixteen_word_application_define,
+ threadx_queue_empty_suspension_application_define,
+ threadx_queue_full_suspension_application_define,
+ threadx_queue_suspension_timeout_application_define,
+ threadx_queue_thread_terminate_application_define,
+ threadx_queue_flush_application_define,
+ threadx_queue_flush_no_suspension_application_define,
+ threadx_queue_front_send_application_define,
+ threadx_queue_prioritize_application_define,
+ threadx_queue_information_application_define,
+
+ threadx_semaphore_basic_application_define,
+ threadx_semaphore_delete_application_define,
+ threadx_semaphore_preemption_application_define,
+ threadx_semaphore_non_preemption_application_define,
+ threadx_semaphore_timeout_application_define,
+ threadx_semaphore_thread_terminate_application_define,
+ threadx_semaphore_prioritize_application_define,
+ threadx_semaphore_ceiling_put_application_define,
+ threadx_semaphore_information_application_define,
+
+ threadx_thread_basic_execution_application_define,
+ threadx_thread_completed_application_define,
+ threadx_thread_relinquish_application_define,
+ threadx_thread_simple_supsend_application_define,
+ threadx_thread_multiple_suspension_application_define,
+ threadx_thread_multiple_non_current_suspension_application_define,
+ threadx_thread_multi_level_preemption_threshold_application_define,
+ threadx_thread_preemptable_suspension_application_define,
+ threadx_thread_basic_time_slice_application_define,
+ threadx_thread_multiple_time_slice_application_define,
+ threadx_thread_simple_sleep_application_define,
+ threadx_thread_simple_sleep_non_clear_application_define,
+ threadx_thread_sleep_for_100ticks_application_define,
+ threadx_thread_multiple_sleep_application_define,
+ threadx_thread_terminate_delete_application_define,
+
+ threadx_thread_priority_change_application_define,
+
+ threadx_thread_time_slice_change_application_define,
+ threadx_thread_sleep_terminate_application_define,
+ threadx_thread_delayed_suspension_application_define,
+ threadx_thread_wait_abort_application_define,
+ threadx_thread_wait_abort_and_isr_application_define,
+ threadx_thread_create_preemption_threshold_application_define,
+ threadx_thread_preemption_change_application_define,
+ threadx_thread_information_application_define,
+ threadx_thread_reset_application_define,
+ threadx_thread_stack_checking_application_define,
+
+ threadx_time_get_set_application_define,
+
+ threadx_timer_simple_application_define,
+ threadx_timer_activate_deactivate_application_define,
+ threadx_timer_deactivate_accuracy_application_define,
+ threadx_timer_large_timer_accuracy_application_define,
+ threadx_timer_multiple_application_define,
+ threadx_timer_multiple_accuracy_application_define,
+ threadx_timer_information_application_define,
+
+ threadx_trace_basic_application_define,
+#endif
+
+ TX_NULL,
+};
+
+/* Define thread prototypes. */
+
+void test_control_thread_entry(ULONG thread_input);
+void test_thread_entry(ULONG thread_input);
+void test_thread_entry1(ULONG thread_input);
+void test_control_return(UINT status);
+void test_control_cleanup(void);
+void test_exit_notify(TX_THREAD *thread_ptr, UINT type);
+
+
+/* Define necessary exernal references. */
+
+#ifdef __ghs
+extern TX_MUTEX __ghLockMutex;
+#endif
+
+extern TX_TIMER *_tx_timer_created_ptr;
+extern ULONG _tx_timer_created_count;
+#ifndef TX_TIMER_PROCESS_IN_ISR
+extern TX_THREAD _tx_timer_thread;
+#endif
+extern TX_THREAD *_tx_thread_created_ptr;
+extern ULONG _tx_thread_created_count;
+extern TX_SEMAPHORE *_tx_semaphore_created_ptr;
+extern ULONG _tx_semaphore_created_count;
+extern TX_QUEUE *_tx_queue_created_ptr;
+extern ULONG _tx_queue_created_count;
+extern TX_MUTEX *_tx_mutex_created_ptr;
+extern ULONG _tx_mutex_created_count;
+extern TX_EVENT_FLAGS_GROUP *_tx_event_flags_created_ptr;
+extern ULONG _tx_event_flags_created_count;
+extern TX_BYTE_POOL *_tx_byte_pool_created_ptr;
+extern ULONG _tx_byte_pool_created_count;
+extern TX_BLOCK_POOL *_tx_block_pool_created_ptr;
+extern ULONG _tx_block_pool_created_count;
+
+#ifdef EXTERNAL_EXIT
+void external_exit(UINT code);
+#endif
+
+
+/* Define the interrupt processing dispatcher. The individual tests will set this up when they desire
+ asynchrouns processing for testing purposes. */
+
+void test_interrupt_dispatch(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Test calling tx_thread_relinquish from ISR to see if the error checking throws it out. */
+ tx_thread_relinquish();
+#endif
+
+ /* Check for something to run... */
+ if (test_isr_dispatch)
+ {
+
+ (test_isr_dispatch)();
+ }
+}
+
+
+/* Define init timer entry. */
+
+static void init_timer_entry(ULONG timer_input)
+{
+
+}
+
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+
+/* Define the deletion of the system timer thread. */
+
+void delete_timer_thread(void)
+{
+
+ _tx_thread_terminate(&_tx_timer_thread);
+ _tx_thread_delete(&_tx_timer_thread);
+}
+
+#endif
+
+
+/* Define main entry point. */
+#ifndef EXTERNAL_MAIN
+void main()
+{
+
+#ifndef TX_MISRA_ENABLE
+#ifndef TX_MANUAL_TEST
+
+ /* Test the pre-initialize path through _tx_initialize_kernel_enter. */
+ _tx_thread_system_state[0] = TX_INITIALIZE_ALMOST_DONE;
+ test_initialize_flag = 1;
+
+ /* Call the internal kernel enter function to exercise two paths. */
+ _tx_initialize_kernel_enter();
+ _tx_thread_system_state[0] = 0;
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+ threadx_delete_timer_thread = 1;
+#endif
+#endif
+#endif
+
+ /* Enter the ThreadX kernel. */
+ tx_kernel_enter();
+}
+#endif
+
+
+/* Define what the initial system looks like. */
+
+void tx_application_define(void *first_unused_memory)
+{
+
+UCHAR *pointer;
+VOID (*temp_mutex_release)(TX_THREAD *thread_ptr);
+TX_THREAD *temp_thread;
+UINT old_preemption;
+ULONG old_time_slice;
+UINT status;
+ULONG flags;
+ULONG temp;
+UINT i, j;
+
+
+ /* Initialize the test error/success counters. */
+ test_control_successful_tests = 0;
+ test_control_failed_tests = 0;
+ test_control_system_errors = 0;
+
+ /* Create two equal priority threads. */
+ status = tx_thread_create(&test_thread4, "test thread 4", test_thread_entry1, 4,
+ test_thread4_stack, sizeof(test_thread4_stack), 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ status += tx_thread_create(&test_thread5, "test thread 5", test_thread_entry1, 5,
+ test_thread5_stack, sizeof(test_thread5_stack), 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ status += tx_thread_create(&test_thread6, "test thread 6", test_thread_entry1, 6,
+ test_thread6_stack, sizeof(test_thread6_stack), 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ status += tx_thread_create(&test_thread7, "test thread 7", test_thread_entry1, 7,
+ test_thread7_stack, sizeof(test_thread7_stack), 17, 17, TX_NO_TIME_SLICE, TX_DONT_START);
+ status += tx_thread_create(&test_thread8, "test thread 8", test_thread_entry1, 8,
+ test_thread8_stack, sizeof(test_thread8_stack), 18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
+ status += tx_thread_create(&test_thread9, "test thread 9", test_thread_entry1, 9,
+ test_thread9_stack, sizeof(test_thread9_stack), 19, 19, TX_NO_TIME_SLICE, TX_DONT_START);
+ status += tx_thread_create(&test_thread10, "test thread 10", test_thread_entry1, 10,
+ test_thread10_stack, sizeof(test_thread10_stack), 20, 20, TX_NO_TIME_SLICE, TX_DONT_START);
+ status += tx_thread_create(&test_thread11, "test thread 11", test_thread_entry1, 11,
+ test_thread11_stack, sizeof(test_thread11_stack), 20, 20, TX_NO_TIME_SLICE, TX_DONT_START);
+ status += tx_thread_create(&test_thread12, "test thread 12", test_thread_entry1, 12,
+ test_thread12_stack, sizeof(test_thread12_stack), 20, 20, TX_NO_TIME_SLICE, TX_DONT_START);
+ status += tx_thread_create(&test_thread13, "test thread 13", test_thread_entry1, 13,
+ test_thread13_stack, sizeof(test_thread13_stack), 20, 20, TX_NO_TIME_SLICE, TX_DONT_START);
+ status += tx_thread_create(&test_thread14, "test thread 14", test_thread_entry1, 14,
+ test_thread14_stack, sizeof(test_thread14_stack), 20, 20, TX_NO_TIME_SLICE, TX_DONT_START);
+ status += tx_thread_smp_core_exclude(&test_thread4, 0xD);
+ status += tx_thread_smp_core_exclude(&test_thread5, 0xD);
+ status += tx_thread_resume(&test_thread4);
+ status += tx_thread_suspend(&test_thread4);
+ status += tx_thread_resume(&test_thread4);
+ status += tx_thread_resume(&test_thread5);
+ status += tx_thread_suspend(&test_thread4);
+ status += tx_thread_suspend(&test_thread5);
+
+ /* Test the fringe cases in tx_thread_system_resume to make sure the behave properly. */
+ status += tx_thread_smp_core_exclude(&test_thread14, 0);
+ status += tx_thread_smp_core_exclude(&test_thread13, 0);
+ status += tx_thread_smp_core_exclude(&test_thread12, 0);
+ status += tx_thread_smp_core_exclude(&test_thread11, 0);
+ status += tx_thread_smp_core_exclude(&test_thread10, 0);
+ status += tx_thread_smp_core_exclude(&test_thread9, 0xC);
+ status += tx_thread_smp_core_exclude(&test_thread8, 0x3);
+ status += tx_thread_smp_core_exclude(&test_thread7, 0xE);
+ status += tx_thread_smp_core_exclude(&test_thread6, 0xD);
+ status += tx_thread_smp_core_exclude(&test_thread5, 0xB);
+ status += tx_thread_smp_core_exclude(&test_thread4, 0x7);
+ test_thread13.tx_thread_timer.tx_timer_internal_active_next = &test_thread13.tx_thread_timer;
+ test_thread13.tx_thread_timer.tx_timer_internal_list_head = (TX_TIMER_INTERNAL **) &test_thread13.tx_thread_timer;
+ status += tx_thread_resume(&test_thread14);
+ status += tx_thread_resume(&test_thread13);
+ status += tx_thread_resume(&test_thread12);
+ status += tx_thread_resume(&test_thread11);
+ status += tx_thread_resume(&test_thread10);
+ status += tx_thread_resume(&test_thread9);
+ status += tx_thread_resume(&test_thread8);
+ status += tx_thread_resume(&test_thread7);
+ status += tx_thread_resume(&test_thread6);
+ status += tx_thread_resume(&test_thread5);
+ status += tx_thread_resume(&test_thread4);
+ status += tx_thread_suspend(&test_thread14);
+ status += tx_thread_suspend(&test_thread13);
+ status += tx_thread_suspend(&test_thread12);
+ status += tx_thread_suspend(&test_thread11);
+ status += tx_thread_suspend(&test_thread10);
+ status += tx_thread_suspend(&test_thread9);
+ status += tx_thread_suspend(&test_thread8);
+ status += _tx_thread_preemption_change(&test_thread8, 17, &old_preemption);
+ status += tx_thread_resume(&test_thread8);
+ status += tx_thread_suspend(&test_thread8);
+ status += tx_thread_suspend(&test_thread7);
+ status += tx_thread_suspend(&test_thread6);
+ status += tx_thread_suspend(&test_thread5);
+ status += tx_thread_suspend(&test_thread4);
+
+ /* Setup a pointer to the first unused memory. */
+ pointer = (UCHAR *) &test_control_memory[0]; //first_unused_memory;
+
+ /* Create the test control thread. */
+ tx_thread_create(&test_control_thread, "test control thread", test_control_thread_entry, 0,
+ pointer, TEST_STACK_SIZE,
+ 17, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE;
+
+ /* Create the test thread. */
+ tx_thread_create(&test_thread, "test thread", test_thread_entry, 0,
+ pointer, TEST_STACK_SIZE,
+ 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE;
+
+ /* Create the second test thread. */
+ tx_thread_create(&test_thread1, "test thread 1", test_thread_entry1, 0,
+ pointer, TEST_STACK_SIZE,
+ 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE;
+
+ /* Suspend the test thread temporarily. */
+ tx_thread_suspend(&test_thread);
+
+ /* Resume the test thread again to exercise the resume code fully. */
+ tx_thread_resume(&test_thread);
+
+ /* Timer change just to exercise the code... an error from initialization! */
+ test_timer.tx_timer_id = TX_TIMER_ID;
+ tx_timer_change(&test_timer, 1, 1);
+
+ /* Test mutex created and used in initialization. */
+ test_mutex_from_init = tx_mutex_create(&init_mutex, "init mutex", TX_INHERIT);
+ test_mutex_from_init += tx_mutex_get(&init_mutex, TX_NO_WAIT);
+ test_mutex_from_init += tx_mutex_get(&init_mutex, TX_NO_WAIT);
+ test_mutex_from_init += tx_mutex_put(&init_mutex);
+ test_mutex_from_init += tx_mutex_put(&init_mutex);
+ test_mutex_from_init = tx_mutex_create(&init_mutex_inherit, "init mutex", TX_INHERIT);
+ test_mutex_from_init += tx_mutex_get(&init_mutex_inherit, TX_NO_WAIT);
+ test_mutex_from_init += tx_mutex_get(&init_mutex_inherit, TX_NO_WAIT);
+ test_mutex_from_init += tx_mutex_put(&init_mutex_inherit);
+ test_mutex_from_init += tx_mutex_put(&init_mutex_inherit);
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Test timer create from initialization. */
+ test_block_pool_create_init = tx_block_pool_create(&init_block_pool, "init block pool", 10, init_block_pool_area, sizeof(init_block_pool_area));
+
+ /* Test byte pool create from initialization. */
+ test_byte_pool_create_init = tx_byte_pool_create(&init_byte_pool, "init byte pool", init_byte_pool_area, sizeof(init_byte_pool_area));
+ test_byte_pool_create_init += tx_byte_allocate(&init_byte_pool, (VOID **) &pointer, 20, TX_NO_WAIT);
+ test_byte_pool_create_init += tx_byte_release(pointer);
+
+ /* Test event flag create from initialization. */
+ test_event_flags_from_init = tx_event_flags_create(&init_event_flags, "init events");
+
+ /* Test queue create from initialization. */
+ test_queue_from_init = tx_queue_create(&init_queue, "init queue", TX_1_ULONG, init_queue_area, sizeof(init_queue_area));
+
+ /* Test semaphore create from initialization. */
+ test_semaphore_from_init = tx_semaphore_create(&init_semaphore, "init semaphore", 0);
+
+ /* Test timer creat from initialization. */
+ test_timer_create_init = tx_timer_create(&init_timer, "init timer", init_timer_entry, 0x5678,
+ 100, 200, TX_AUTO_ACTIVATE);
+
+ /* Test calling tx_thread_relinquish to see if the error checking throws it out. */
+ tx_thread_relinquish();
+#endif
+
+ /* Remember the free memory pointer. */
+ test_free_memory_ptr = &tests_memory[0]; //pointer;
+
+ /* Clear the ISR dispatch. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Ensure that _tx_thread_time_slice can handle NULL thread, note that current thread pointer is NULL at this point. */
+ _tx_thread_time_slice();
+
+ /* Test to make sure _tx_thread_time_slice can handle a none-ready thread. */
+ init_test_thread.tx_thread_state = TX_IO_DRIVER;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_TRUE;
+ _tx_thread_current_ptr[0] = &init_test_thread;
+ _tx_thread_time_slice();
+
+ /* Test to make sure _tx_thread_time_slice can handle preemption-threshold set. */
+ init_test_thread.tx_thread_state = TX_READY;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_priority = 10;
+ init_test_thread.tx_thread_preempt_threshold = 9;
+ init_test_thread.tx_thread_ready_next = &init_test_thread;
+ init_test_thread.tx_thread_ready_previous = &init_test_thread;
+ _tx_thread_time_slice();
+ _tx_thread_current_ptr[0] = TX_NULL;
+
+ /* Test to make sure _tx_thread_shell_entry can handle a NULL mutex release function pointer. */
+ temp_mutex_release = _tx_thread_mutex_release;
+ temp_thread = _tx_thread_execute_ptr[0];
+ _tx_thread_mutex_release = TX_NULL;
+ init_test_thread.tx_thread_state = TX_READY;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_FALSE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+ _tx_thread_current_ptr[0] = &init_test_thread;
+ _tx_thread_execute_ptr[0] = &init_test_thread;
+ _tx_thread_entry_exit_notify(&init_test_thread, test_exit_notify);
+ _tx_thread_shell_entry();
+ _tx_thread_current_ptr[0] = TX_NULL;
+ _tx_thread_execute_ptr[0] = temp_thread;
+ _tx_thread_mutex_release = temp_mutex_release; /* Recover Mutex release pointer. */
+
+ /* Test _tx_thread_system_suspend when not current, preemption is needed but disabled. */
+ temp_thread = _tx_thread_execute_ptr[0];
+ init_test_thread.tx_thread_state = TX_READY;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_FALSE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+ _tx_thread_execute_ptr[0] = &init_test_thread;
+#ifndef TX_NOT_INTERRUPTABLE
+ _tx_thread_preempt_disable++;
+#endif
+ _tx_thread_system_suspend(&init_test_thread);
+ _tx_thread_execute_ptr[0] = temp_thread;
+
+ /* Test _tx_thread_system_resume when not current, suspending and in a COMPLETED state. */
+ temp_thread = _tx_thread_execute_ptr[0];
+ init_test_thread.tx_thread_state = TX_COMPLETED;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_TRUE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+#ifndef TX_NOT_INTERRUPTABLE
+ _tx_thread_preempt_disable++;
+#endif
+ _tx_thread_execute_ptr[0] = &init_test_thread;
+ _tx_thread_system_resume(&init_test_thread);
+ _tx_thread_execute_ptr[0] = temp_thread;
+
+
+ /* Test _tx_thread_system_resume when not current, not suspending and already in a TX_READY state. */
+ temp_thread = _tx_thread_execute_ptr[0];
+ init_test_thread.tx_thread_state = TX_READY;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_FALSE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+#ifndef TX_NOT_INTERRUPTABLE
+ _tx_thread_preempt_disable++;
+#endif
+ _tx_thread_execute_ptr[0] = &init_test_thread;
+ _tx_thread_system_resume(&init_test_thread);
+ _tx_thread_execute_ptr[0] = temp_thread;
+
+ /* Test _tx_thread_system_resume when not current, suspending and in a TERMINATED state. */
+ temp_thread = _tx_thread_execute_ptr[0];
+ init_test_thread.tx_thread_state = TX_TERMINATED;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_TRUE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+#ifndef TX_NOT_INTERRUPTABLE
+ _tx_thread_preempt_disable++;
+#endif
+ _tx_thread_execute_ptr[0] = &init_test_thread;
+ _tx_thread_system_resume(&init_test_thread);
+ _tx_thread_execute_ptr[0] = temp_thread;
+
+ /* Test tx_thread_resume to test the saved_thread_ptr being NULL. */
+ temp_thread = _tx_thread_execute_ptr[0];
+ _tx_thread_execute_ptr[0] = TX_NULL;
+ tx_thread_resume(&test_thread1);
+ tx_thread_suspend(&test_thread1);
+ _tx_thread_execute_ptr[0] = temp_thread;
+
+ /* Test preemption change when the new priority is the same as the threshold. */
+ init_test_thread.tx_thread_state = TX_SUSPENDED;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_FALSE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_user_priority = 10;
+ init_test_thread.tx_thread_user_preempt_threshold = 10;
+ init_test_thread.tx_thread_priority = 10;
+ init_test_thread.tx_thread_preempt_threshold = 10;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+ _tx_thread_preemption_change(&init_test_thread, 10, &old_preemption);
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Test semaphore cleanup with an invalid semaphore ID. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_semaphore;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup);
+ cleanup_semaphore.tx_semaphore_id = 0;
+ cleanup_semaphore.tx_semaphore_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_semaphore_cleanup(&init_test_thread, 0);
+
+ /* Test semaphore cleanup with an invalid suspension sequence. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_semaphore;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup);
+ cleanup_semaphore.tx_semaphore_id = 0;
+ cleanup_semaphore.tx_semaphore_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_semaphore_cleanup(&init_test_thread, 1);
+
+ /* Test semaphore cleanup with a NULL semaphore pointer. */
+ init_test_thread.tx_thread_suspend_control_block = TX_NULL;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup);
+ cleanup_semaphore.tx_semaphore_id = TX_SEMAPHORE_ID;
+ cleanup_semaphore.tx_semaphore_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_semaphore_cleanup(&init_test_thread, 0);
+
+ /* Test semaphore cleanup with an valid semaphore ID but a suspension count of 0. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_semaphore;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup);
+ cleanup_semaphore.tx_semaphore_id = TX_SEMAPHORE_ID;
+ cleanup_semaphore.tx_semaphore_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_semaphore_cleanup(&init_test_thread, 0);
+
+ /* Test queue cleanup with a NULL cleanup pointer. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ cleanup_queue.tx_queue_id = 0;
+ cleanup_queue.tx_queue_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_queue_cleanup(&init_test_thread, 0);
+
+ /* Test queue cleanup with a NULL queue pointer. */
+ init_test_thread.tx_thread_suspend_control_block = TX_NULL;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup);
+ cleanup_queue.tx_queue_id = 0;
+ cleanup_queue.tx_queue_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_queue_cleanup(&init_test_thread, 0);
+
+ /* Test queue cleanup with an invalid queue ID. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup);
+ cleanup_queue.tx_queue_id = 0;
+ cleanup_queue.tx_queue_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_queue_cleanup(&init_test_thread, 0);
+
+ /* Test queue cleanup with an invalid suspension sequence. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup);
+ cleanup_queue.tx_queue_id = 0;
+ cleanup_queue.tx_queue_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_queue_cleanup(&init_test_thread, 1);
+
+ /* Test queue cleanup with an valid queue ID but a suspension count of 0. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup);
+ cleanup_queue.tx_queue_id = TX_QUEUE_ID;
+ cleanup_queue.tx_queue_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_queue_cleanup(&init_test_thread, 0);
+
+ /* Test mutex cleanup with a NULL cleanup pointer. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ cleanup_mutex.tx_mutex_id = 0;
+ cleanup_mutex.tx_mutex_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_mutex_cleanup(&init_test_thread, 0);
+
+ /* Test mutex cleanup with a NULL mutex pointer. */
+ init_test_thread.tx_thread_suspend_control_block = TX_NULL;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup);
+ cleanup_mutex.tx_mutex_id = 0;
+ cleanup_mutex.tx_mutex_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_mutex_cleanup(&init_test_thread, 0);
+
+ /* Test mutex cleanup with an invalid mutex ID. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup);
+ cleanup_mutex.tx_mutex_id = 0;
+ cleanup_mutex.tx_mutex_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_mutex_cleanup(&init_test_thread, 0);
+
+ /* Test mutex cleanup with an invalid suspension sequence. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup);
+ cleanup_mutex.tx_mutex_id = 0;
+ cleanup_mutex.tx_mutex_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_mutex_cleanup(&init_test_thread, 1);
+
+ /* Test mutex cleanup with an valid mutex ID but a suspension count of 0. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup);
+ cleanup_mutex.tx_mutex_id = TX_MUTEX_ID;
+ cleanup_mutex.tx_mutex_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_mutex_cleanup(&init_test_thread, 0);
+
+ /* Test event flag cleanup with a NULL cleanup pointer. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ cleanup_event_flags.tx_event_flags_group_id = 0;
+ cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_event_flags_cleanup(&init_test_thread, 0);
+
+ /* Test event flag cleanup with a NULL event flag pointer. */
+ init_test_thread.tx_thread_suspend_control_block = TX_NULL;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
+ cleanup_event_flags.tx_event_flags_group_id = 0;
+ cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_event_flags_cleanup(&init_test_thread, 0);
+
+ /* Test event flag cleanup with an invalid ID. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
+ cleanup_event_flags.tx_event_flags_group_id = 0;
+ cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_event_flags_cleanup(&init_test_thread, 0);
+
+ /* Test event flag cleanup with an invalid suspension sequence. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
+ cleanup_event_flags.tx_event_flags_group_id = 0;
+ cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_event_flags_cleanup(&init_test_thread, 1);
+
+ /* Test event flag cleanup with an valid ID but a suspension count of 0. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
+ cleanup_event_flags.tx_event_flags_group_id = TX_EVENT_FLAGS_ID;
+ cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_event_flags_cleanup(&init_test_thread, 0);
+
+ /* Test block pool cleanup with a NULL cleanup pointer. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ cleanup_block_pool.tx_block_pool_id = 0;
+ cleanup_block_pool.tx_block_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_block_pool_cleanup(&init_test_thread, 0);
+
+ /* Test block pool cleanup with a NULL block pool pointer. */
+ init_test_thread.tx_thread_suspend_control_block = TX_NULL;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
+ cleanup_block_pool.tx_block_pool_id = 0;
+ cleanup_block_pool.tx_block_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_block_pool_cleanup(&init_test_thread, 0);
+
+ /* Test block pool cleanup with an invalid ID. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
+ cleanup_block_pool.tx_block_pool_id = 0;
+ cleanup_block_pool.tx_block_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_block_pool_cleanup(&init_test_thread, 0);
+
+ /* Test block pool cleanup with an invalid suspension sequence. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
+ cleanup_block_pool.tx_block_pool_id = 0;
+ cleanup_block_pool.tx_block_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_block_pool_cleanup(&init_test_thread, 1);
+
+ /* Test block pool cleanup with an valid ID but a suspension count of 0. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
+ cleanup_block_pool.tx_block_pool_id = TX_BLOCK_POOL_ID;
+ cleanup_block_pool.tx_block_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_block_pool_cleanup(&init_test_thread, 0);
+
+ /* Test byte pool cleanup with a NULL cleanup pointer. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ cleanup_byte_pool.tx_byte_pool_id = 0;
+ cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_byte_pool_cleanup(&init_test_thread, 0);
+
+ /* Test byte pool cleanup with a NULL byte pool pointer. */
+ init_test_thread.tx_thread_suspend_control_block = TX_NULL;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
+ cleanup_byte_pool.tx_byte_pool_id = 0;
+ cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_byte_pool_cleanup(&init_test_thread, 0);
+
+ /* Test byte pool cleanup with an invalid ID. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
+ cleanup_byte_pool.tx_byte_pool_id = 0;
+ cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_byte_pool_cleanup(&init_test_thread, 0);
+
+ /* Test byte pool cleanup with an invalid suspension sequence. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
+ cleanup_byte_pool.tx_byte_pool_id = 0;
+ cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_byte_pool_cleanup(&init_test_thread, 1);
+
+ /* Test byte pool cleanup with an valid ID but a suspension count of 0. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
+ cleanup_byte_pool.tx_byte_pool_id = TX_BYTE_POOL_ID;
+ cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_byte_pool_cleanup(&init_test_thread, 0);
+#endif
+
+#ifndef TX_ENABLE_EVENT_TRACE
+
+ /* Call ISR trace events when trace is not enabled. */
+
+ /* Call trace ISR enter event insert. */
+ tx_trace_isr_enter_insert(1);
+
+ /* Call trace ISR exit event insert. */
+ tx_trace_isr_exit_insert(1);
+
+ /* Call trace ISR enter event insert. */
+ tx_trace_isr_enter_insert(0);
+
+ /* Call trace ISR exit event insert. */
+ tx_trace_isr_exit_insert(0);
+
+#endif
+
+ /* Test the list start path in timer info get and timer deactivate. */
+ test_timer.tx_timer_id = 0;
+ _tx_timer_create(&test_timer, "init timer", init_timer_entry, 0x5678, 100, 200, TX_AUTO_ACTIVATE);
+ _timer_list_start_backup = _tx_timer_list_start;
+ _tx_timer_list_start = _tx_timer_list_end;
+ _tx_timer_info_get(&test_timer, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ _tx_timer_deactivate(&test_timer);
+ _tx_timer_list_start = _timer_list_start_backup;
+ _tx_timer_deactivate(&test_timer);
+ _tx_timer_delete(&test_timer);
+
+ /* Test the stack analyze function with a dummy thread. */
+
+ /* Clear the test stack analyze flag. */
+ test_stack_analyze_flag = 0;
+
+ /* Make a fake thread with a fake stack. */
+ test_thread2.tx_thread_id = TX_THREAD_ID;
+ for (i = 0; i < (sizeof(test_thread2_stack)/sizeof(ULONG)); i++)
+ {
+ /* Set the fake thread stack to the fill pattern. */
+ test_thread2_stack[i] = TX_STACK_FILL;
+ }
+
+ /* Setup index to last point. */
+ i = (sizeof(test_thread2_stack)/sizeof(ULONG)) - 1;
+
+ /* Setup the stack start and end pointers. */
+ test_thread2.tx_thread_stack_start = &(test_thread2_stack[0]);
+ test_thread2.tx_thread_stack_end = &(test_thread2_stack[i]);
+ test_thread2.tx_thread_stack_size = sizeof(test_thread2_stack);
+ test_thread2.tx_thread_stack_highest_ptr = test_thread2.tx_thread_stack_end;
+ test_thread2.tx_thread_stack_ptr = test_thread2.tx_thread_stack_start;
+
+ /* Fill 20 words of stack. */
+ for (j = 0; j < 20; j++)
+ {
+ /* Fill the stack with 0s. */
+ test_thread2_stack[i--] = 0;
+ }
+
+ /* Call the analyze stack function. */
+ _tx_thread_stack_analyze(&test_thread2);
+
+ /* Call it again for no change coverage. */
+ _tx_thread_stack_analyze(&test_thread2);
+
+ /* Fill 99 words of stack. */
+ for (j = 0; j < 99; j++)
+ {
+ /* Fill the stack with 1s. */
+ test_thread2_stack[i--] = 1;
+ }
+
+ /* Call the analyze stack function. */
+ _tx_thread_stack_analyze(&test_thread2);
+
+ /* Call it again for no change coverage. */
+ _tx_thread_stack_analyze(&test_thread2);
+
+#ifndef TX_MANUAL_TEST
+
+ /* Now set the flag to 1 to cause the thread ID to be cleared. */
+ test_stack_analyze_flag = 1;
+
+ /* Call stack analyze with an ID that is cleared in the middle. */
+ _tx_thread_stack_analyze(&test_thread2);
+
+ /* Restore the ID. */
+ test_thread2.tx_thread_id = TX_THREAD_ID;
+
+ /* Now set the flag to 2 to cause the stack ptr to be equal to the start of the stack. */
+ test_stack_analyze_flag = 2;
+
+ /* Call stack analyze with an ID that is cleared in the middle. */
+ _tx_thread_stack_analyze(&test_thread2);
+ test_thread2.tx_thread_stack_highest_ptr = test_thread2.tx_thread_stack_end;
+
+ /* Now set the flag to 3 to cause the stack pointer to not have the fill pattern. */
+ test_stack_analyze_flag = 3;
+
+ /* Call stack analyze with an ID that is cleared in the middle. */
+ _tx_thread_stack_analyze(&test_thread2);
+#endif
+
+ /* Test error condition on _tx_queue_flush. */
+ test_queue.tx_queue_enqueued = 1;
+ test_queue.tx_queue_suspended_count = 1;
+ test_queue.tx_queue_suspension_list = TX_NULL;
+
+ /* Call _tx_queue_flush to test the thread NULL check. */
+ _tx_queue_flush(&test_queue);
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Make sure the suspension cancelled path is exercised in tx_thread_system_resume... This normally happens,
+ however, sometimes on less real-time platforms the timing is not guaranteed. */
+
+ /* Increment the preempt disable flag. */
+ _tx_thread_preempt_disable++;
+
+ /* Build a thread control block with fake info. */
+ test_thread3.tx_thread_suspending = TX_TRUE;
+ test_thread3.tx_thread_state = TX_SUSPENDED;
+ test_thread3.tx_thread_delayed_suspend = TX_FALSE;
+ test_thread3.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ test_thread3.tx_thread_stack_start = (VOID *) &test_thread2_stack[0];
+ test_thread3.tx_thread_stack_end = (VOID *) &test_thread2_stack[255];
+ test_thread3.tx_thread_stack_ptr = (VOID *) &test_thread2_stack[255];
+
+ /* Call the system resume function directly to insure the suspension cancel works properly. */
+ _tx_thread_system_resume(&test_thread3);
+#endif
+
+ /* Test preempt-disable safeguard. */
+
+ /* Increment the preempt disable flag. */
+ _tx_thread_preempt_disable++;
+
+ /* Test block pool suspenson safeguard. */
+ fake_block_pool.tx_block_pool_available = 0;
+ status = _tx_block_allocate(&fake_block_pool, (VOID **) &pointer, TX_WAIT_FOREVER);
+ if (status != TX_NO_MEMORY)
+ test_control_system_errors++;
+
+ /* Test byte pool suspension safeguard. */
+ fake_byte_pool.tx_byte_pool_fragments = 2;
+ fake_byte_pool.tx_byte_pool_available = 0;
+ status = _tx_byte_allocate(&fake_byte_pool, (VOID **) &pointer, 1000, TX_WAIT_FOREVER);
+ if (status != TX_NO_MEMORY)
+ test_control_system_errors++;
+
+ /* Test event flags suspension safeguard. */
+ fake_event_flags.tx_event_flags_group_current = 0;
+ status = _tx_event_flags_get(&fake_event_flags, 1, TX_AND, &flags, TX_WAIT_FOREVER);
+ if (status != TX_NO_EVENTS)
+ test_control_system_errors++;
+
+ /* Test mutex suspension safeguard. */
+ fake_mutex.tx_mutex_ownership_count = 1;
+ fake_mutex.tx_mutex_inherit = 0;
+ fake_mutex.tx_mutex_owner = &init_test_thread;
+ status = _tx_mutex_get(&fake_mutex, TX_WAIT_FOREVER);
+ if (status != TX_NOT_AVAILABLE)
+ test_control_system_errors++;
+
+ /* Test queue front send suspension safeguard. */
+ fake_queue.tx_queue_available_storage = 0;
+ status = _tx_queue_front_send(&fake_queue, (VOID *) pointer, TX_WAIT_FOREVER);
+ if (status != TX_QUEUE_FULL)
+ test_control_system_errors++;
+
+ /* Test queue receive suspension safeguard. */
+ fake_queue.tx_queue_enqueued = 0;
+ status = _tx_queue_receive(&fake_queue, (VOID **) &pointer, TX_WAIT_FOREVER);
+ if (status != TX_QUEUE_EMPTY)
+ test_control_system_errors++;
+
+ /* Test queue send suspension safeguard. */
+ fake_queue.tx_queue_available_storage = 0;
+ status = _tx_queue_send(&fake_queue, (VOID *) pointer, TX_WAIT_FOREVER);
+ if (status != TX_QUEUE_FULL)
+ test_control_system_errors++;
+
+ /* Test semaphore suspension safeguard. */
+ fake_semaphore.tx_semaphore_count = 0;
+ status = _tx_semaphore_get(&fake_semaphore, TX_WAIT_FOREVER);
+ if (status != TX_NO_INSTANCE)
+ test_control_system_errors++;
+
+ /* Test thread sleep suspension safeguard. */
+ _tx_thread_current_ptr[0] = &init_test_thread;
+ temp = _tx_thread_system_state[0];
+ _tx_thread_system_state[0] = 0;
+ status = _tx_thread_sleep(10);
+ if (status != TX_CALLER_ERROR)
+ test_control_system_errors++;
+
+ /* Test thread suspend suspension safeguard. */
+ init_test_thread.tx_thread_state = TX_READY;
+ status = _tx_thread_suspend(&init_test_thread);
+ if (status != TX_SUSPEND_ERROR)
+ test_control_system_errors++;
+ _tx_thread_system_state[0] = temp;
+ _tx_thread_current_ptr[0] = TX_NULL;
+
+
+ /* Pickup the current core exclusion. */
+ tx_thread_smp_core_exclude_get(&test_thread, &temp);
+
+ /* Move the test thread form core 0. */
+ tx_thread_smp_core_exclude(&test_thread, 0x1);
+
+ /* Restore the core exclusion for the test thread. */
+ tx_thread_smp_core_exclude(&test_thread, temp);
+
+ /* Test some code paths in the tx_thread_smp_utilities file. */
+ temp_thread = _tx_thread_current_ptr[3];
+ _tx_thread_current_ptr[3] = &init_test_thread;
+ _tx_thread_smp_core_interrupt(&test_thread, 0, 3);
+ _tx_thread_current_ptr[3] = temp_thread;
+ temp_thread = _tx_thread_execute_ptr[0];
+ _tx_thread_execute_ptr[0] = TX_NULL;
+ _tx_thread_smp_lowest_priority_get();
+ _tx_thread_execute_ptr[0] = temp_thread;
+ _tx_thread_smp_schedule_list[0] = TX_NULL;
+ _tx_thread_smp_remap_solution_find(&init_test_thread, 1, 1, 1);
+
+ /* Test a corner case in time-slice change. */
+ init_test_thread.tx_thread_smp_core_mapped = TX_THREAD_SMP_MAX_CORES;
+ _tx_thread_time_slice_change(&init_test_thread, 3, &old_time_slice);
+
+ /* Test time-slice paths. */
+ _tx_timer_time_slice[0] = 0;
+ _tx_timer_time_slice[1] = 1;
+ _tx_timer_time_slice[2] = 0;
+ _tx_timer_time_slice[3] = 0;
+ _tx_thread_time_slice();
+
+ _tx_timer_time_slice[0] = 0;
+ _tx_timer_time_slice[1] = 0;
+ _tx_timer_time_slice[2] = 1;
+ _tx_timer_time_slice[3] = 0;
+ _tx_thread_time_slice();
+
+ _tx_timer_time_slice[0] = 0;
+ _tx_timer_time_slice[1] = 0;
+ _tx_timer_time_slice[2] = 0;
+ _tx_timer_time_slice[3] = 1;
+ _tx_thread_time_slice();
+
+ _tx_timer_time_slice[0] = 1;
+ _tx_timer_time_slice[1] = 0;
+ _tx_timer_time_slice[2] = 0;
+ _tx_timer_time_slice[3] = 0;
+ temp_thread -> tx_thread_state = TX_COMPLETED;
+ _tx_thread_current_ptr[0] = temp_thread;
+ _tx_thread_time_slice();
+ temp_thread -> tx_thread_state = TX_READY;
+ _tx_thread_current_ptr[0] = TX_NULL;
+
+ _tx_timer_time_slice[0] = 1;
+ _tx_timer_time_slice[1] = 0;
+ _tx_timer_time_slice[2] = 0;
+ _tx_timer_time_slice[3] = 0;
+ temp_thread -> tx_thread_time_slice = 0;
+ _tx_thread_current_ptr[0] = temp_thread;
+ _tx_thread_time_slice();
+ _tx_thread_current_ptr[0] = TX_NULL;
+
+ /* Decrement the preempt disable flag. */
+ _tx_thread_preempt_disable--;
+}
+
+
+
+/* Define the test control thread. This thread is responsible for dispatching all of the
+ tests in the ThreadX test suite. */
+
+void test_control_thread_entry(ULONG thread_input)
+{
+
+UINT i;
+
+ /* Raise the priority of the control thread to 0. */
+ tx_thread_priority_change(&test_control_thread, 0, &i);
+#ifdef CTEST
+ test_control_cleanup();
+#endif
+
+ /* Print out banner. */
+ printf("********************** ThreadX Validation/Regression Test Suite *********************************\n\n");
+
+ /* Print version id. */
+ printf("Version: %s\n\n", _tx_version_id);
+
+ /* Print out the tests... */
+ printf("Running validation/regression test:\n\n");
+
+ /* Loop to process all tests... */
+ i = 0;
+ while (test_control_tests[i].test_entry != TX_NULL)
+ {
+
+ /* Clear the ISR dispatch. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Dispatch the test. */
+ (test_control_tests[i++].test_entry)(test_free_memory_ptr);
+
+ /* Clear the ISR dispatch. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Suspend control test to allow test to run. */
+ tx_thread_suspend(&test_control_thread);
+
+ /* Test finished, cleanup in preparation for the next test. */
+ test_control_cleanup();
+ }
+
+ /* Finished with all tests, print results and return! */
+ printf("**** Testing Complete ****\n");
+ printf("**** Test Summary: Tests Passed: %lu Tests Failed: %lu System Errors: %lu\n", test_control_successful_tests, test_control_failed_tests, test_control_system_errors);
+#ifndef EXTERNAL_EXIT
+ exit(test_control_failed_tests + test_control_system_errors);
+#else
+ external_exit(test_control_failed_tests + test_control_system_errors);
+#endif
+}
+
+
+void test_control_return(UINT status)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+UINT old_posture = TX_INT_ENABLE;
+
+ fflush(stdout);
+
+ /* Save the status in a global. */
+ test_control_return_status = status;
+
+ /* Ensure interrupts are enabled. */
+ old_posture = tx_interrupt_control(TX_INT_ENABLE);
+
+ /* Determine if it was successful or not. */
+ if (status)
+ test_control_failed_tests++;
+ else
+ test_control_successful_tests++;
+
+ /* Now check for system errors. */
+
+ /* Get protection for examination of preempt disable and system state variables. */
+ TX_DISABLE
+
+ /* Is preempt disable flag set? */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* System error - preempt disable should never be set inside of a thread! */
+ printf(" ***** SYSTEM ERROR ***** _tx_thread_preempt_disable is non-zero!\n");
+ test_control_system_errors++;
+ }
+
+ /* Is system state set? */
+ if (_tx_thread_system_state[0])
+ {
+
+ /* System error - system state should never be set inside of a thread! */
+ printf(" ***** SYSTEM ERROR ***** _tx_thread_system_state is non-zero!\n");
+ test_control_system_errors++;
+ }
+
+ /* Release protection. */
+ TX_RESTORE
+
+ /* Are interrupts disabled? */
+ if (old_posture == TX_INT_DISABLE)
+ {
+
+ /* System error - interrupts should alwasy be enabled in our test threads! */
+ printf(" ***** SYSTEM ERROR ***** test returned with interrupts disabled!\n");
+ test_control_system_errors++;
+ }
+
+ /* Resume the control thread to fully exit the test. */
+ tx_thread_resume(&test_control_thread);
+}
+
+
+void test_control_cleanup(void)
+{
+
+TX_MUTEX *mutex_ptr;
+TX_THREAD *thread_ptr;
+
+
+ /* Delete all queues. */
+ while(_tx_queue_created_ptr)
+ {
+
+ /* Delete queue. */
+ tx_queue_delete(_tx_queue_created_ptr);
+ }
+
+ /* Delete all semaphores. */
+ while(_tx_semaphore_created_ptr)
+ {
+
+ /* Delete semaphore. */
+ tx_semaphore_delete(_tx_semaphore_created_ptr);
+ }
+
+ /* Delete all event flag groups. */
+ while(_tx_event_flags_created_ptr)
+ {
+
+ /* Delete event flag group. */
+ tx_event_flags_delete(_tx_event_flags_created_ptr);
+ }
+
+ /* Delete all byte pools. */
+ while(_tx_byte_pool_created_ptr)
+ {
+
+ /* Delete byte pool. */
+ tx_byte_pool_delete(_tx_byte_pool_created_ptr);
+ }
+
+ /* Delete all block pools. */
+ while(_tx_block_pool_created_ptr)
+ {
+
+ /* Delete block pool. */
+ tx_block_pool_delete(_tx_block_pool_created_ptr);
+ }
+
+ /* Delete all timers. */
+ while(_tx_timer_created_ptr)
+ {
+
+ /* Deactivate timer. */
+ tx_timer_deactivate(_tx_timer_created_ptr);
+
+ /* Delete timer. */
+ tx_timer_delete(_tx_timer_created_ptr);
+ }
+
+ /* Delete all mutexes (except for system mutex). */
+ while(_tx_mutex_created_ptr)
+ {
+
+ /* Setup working mutex pointer. */
+ mutex_ptr = _tx_mutex_created_ptr;
+
+#ifdef __ghs
+
+ /* Determine if the mutex is the GHS system mutex. If so, don't delete! */
+ if (mutex_ptr == &__ghLockMutex)
+ {
+
+ /* Move to next mutex. */
+ mutex_ptr = mutex_ptr -> tx_mutex_created_next;
+ }
+
+ /* Determine if there are no more mutexes to delete. */
+ if (_tx_mutex_created_count == 1)
+ break;
+#endif
+
+ /* Delete mutex. */
+ tx_mutex_delete(mutex_ptr);
+ }
+
+ /* Delete all threads, except for timer thread, and test control thread. */
+ while (_tx_thread_created_ptr)
+ {
+
+ /* Setup working pointer. */
+ thread_ptr = _tx_thread_created_ptr;
+
+
+#ifdef TX_TIMER_PROCESS_IN_ISR
+
+ /* Determine if there are more threads to delete. */
+ if (_tx_thread_created_count == 1)
+ break;
+
+ /* Determine if this thread is the test control thread. */
+ if (thread_ptr == &test_control_thread)
+ {
+
+ /* Move to the next thread pointer. */
+ thread_ptr = thread_ptr -> tx_thread_created_next;
+ }
+#else
+
+ /* Determine if there are more threads to delete. */
+ if (_tx_thread_created_count == 2)
+ break;
+
+ /* Move to the thread not protected. */
+ while ((thread_ptr == &_tx_timer_thread) || (thread_ptr == &test_control_thread))
+ {
+
+ /* Yes, move to the next thread. */
+ thread_ptr = thread_ptr -> tx_thread_created_next;
+ }
+#endif
+
+ /* First terminate the thread to ensure it is ready for deletion. */
+ tx_thread_terminate(thread_ptr);
+
+ /* Delete the thread. */
+ tx_thread_delete(thread_ptr);
+ }
+
+ /* At this point, only the test control thread and the system timer thread and/or mutex should still be
+ in the system. */
+}
+
+void test_thread_entry(ULONG thread_input)
+{
+
+ /* Resume the next test thread. */
+ tx_thread_resume(&test_thread1);
+
+ /* Suspend this thread but with preemption disabled, so we will actually return. */
+ _tx_thread_preempt_disable++;
+ tx_thread_suspend(&test_thread);
+
+ /* Now perform a fake thread resume to cause preemption and exercise the path in _tx_thread_system_resume that returns to the scheduler. */
+ init_test_thread.tx_thread_state = TX_TERMINATED;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_TRUE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+ _tx_thread_system_resume(&init_test_thread);
+#ifdef TX_NOT_INTERRUPTABLE
+ _tx_thread_preempt_disable--;
+#endif
+}
+
+
+void test_thread_entry1(ULONG thread_input)
+{
+
+ /* Do nothing, just return! */
+}
+
+
+void test_exit_notify(TX_THREAD *thread_ptr, UINT type)
+{
+
+ /* Clear the suspending flag to short-circuit the suspension. */
+ thread_ptr -> tx_thread_suspending = TX_FALSE;
+}
+
+__attribute__((weak)) void abort_all_threads_suspended_on_mutex(void)
+{
+}
+
+__attribute__((weak)) void suspend_lowest_priority(void)
+{
+}
+
+__attribute__((weak)) void abort_and_resume_byte_allocating_thread(void)
+{
+}
diff --git a/test/smp/regression/threadx_block_memory_basic_test.c b/test/smp/regression/threadx_block_memory_basic_test.c
new file mode 100644
index 00000000..5f2afa01
--- /dev/null
+++ b/test/smp/regression/threadx_block_memory_basic_test.c
@@ -0,0 +1,568 @@
+/* This test is designed to test simple memory block pool creation, deletion, and
+ allocates and releases. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+typedef struct BLOCK_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_BLOCK_POOL pool;
+ ULONG first_middle;
+ ULONG second_middle;
+ ULONG pool_area[2048/sizeof(ULONG)];
+ ULONG next_to_last;
+ ULONG last;
+
+} BLOCK_MEMORY_TEST;
+
+static BLOCK_MEMORY_TEST block_memory;
+
+
+/* Define external reference for status of block pool create from initialization. */
+
+extern UINT test_block_pool_create_init;
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+
+
+static TX_BLOCK_POOL pool_0;
+static TX_BLOCK_POOL pool_1;
+static TX_BLOCK_POOL pool_2;
+static TX_BLOCK_POOL pool_3;
+
+static TX_TIMER timer_0;
+
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Prototype direct call to block pool core service. */
+
+UINT _tx_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size,
+ VOID *pool_start, ULONG pool_size);
+
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Determine if calling block pool create from initialization was successful. */
+ if (test_block_pool_create_init != TX_SUCCESS)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a block pool from a timer. */
+ pointer = (CHAR *) 0x30000;
+ status = tx_block_pool_create(&pool_3, "pool 3", 100, pointer, 320);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a block pool. */
+ status = tx_block_pool_delete(&pool_0);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ timer_executed = 1;
+
+ /* Attempt to allocate a block with suspension from a timer. */
+ status = tx_block_allocate(&pool_0, (void **) &pointer, 10);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+CHAR *pointer;
+UINT status;
+
+
+ /* Attempt to Allocate block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a block pool from an ISR. */
+ status = tx_block_pool_create(&pool_3, "pool 3", 100, (void *) 0x100000, 320);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a pool from an ISR. */
+ status = tx_block_pool_delete(&pool_0);
+
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_block_memory_basic_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Basic Functionality Test....................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Basic Functionality Test....................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create block pools 0 and 1. */
+ status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
+ pointer = pointer + 320;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Basic Functionality Test....................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_block_pool_create(&pool_1, "pool 1", 100, pointer, 320);
+ pointer = pointer + 320;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Basic Functionality Test....................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Check the no-blocks path. */
+ status = _tx_block_pool_create(&pool_2, "pool 2", 100, pointer, 50);
+ pointer = pointer + 320;
+
+ /* Check status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ printf("Running Block Memory Basic Functionality Test....................... ERROR #5\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+CHAR *pointer_2;
+CHAR *pointer_3;
+CHAR *pointer_4;
+INT i;
+unsigned long fake_block[20];
+
+
+ /* Inform user. */
+ printf("Running Block Memory Basic Functionality Test....................... ");
+
+ /* Perform block memory test. */
+ block_memory.first = 0x11223344;
+ block_memory.second = 0x55667788;
+ block_memory.first_middle = 0x21314151;
+ block_memory.second_middle= 0x61718191;
+ block_memory.next_to_last = 0x99aabbcc;
+ block_memory.last = 0xddeeff00;
+
+ /* Create the block pool. */
+ status = tx_block_pool_create(&block_memory.pool, "pool memory", 16, &block_memory.pool_area[0], (2048*sizeof(ULONG))/sizeof(ULONG));
+ tx_block_pool_delete(&block_memory.pool);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (block_memory.first != 0x11223344) ||
+ (block_memory.second != 0x55667788) ||
+ (block_memory.first_middle != 0x21314151) ||
+ (block_memory.second_middle != 0x61718191) ||
+ (block_memory.next_to_last != 0x99aabbcc) ||
+ (block_memory.last != 0xddeeff00))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Try to release a non-block. */
+ fake_block[0] = 0;
+ fake_block[1] = 0;
+ status = tx_block_release(&fake_block[2]);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Try to release a block that points to a non-pool. */
+ fake_block[0] = 0;
+ fake_block[1] = (unsigned long) &fake_block[0];
+ status = tx_block_release(&fake_block[2]);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Allocate first block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Allocate second block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+
+ /* Allocate third block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Attempt to allocate fourth block from the pool. This should fail because
+ there should be no more blocks in the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Block memory error. */
+ printf("ERROR ##12\n");
+ test_control_return(1);
+ }
+
+ /* Set the memory of all of the allocated blocks. */
+ for (i =0; i < 100; i++)
+ {
+ pointer_1[i] = (CHAR) 0xFF;
+ pointer_2[i] = (CHAR) 0xFF;
+ pointer_3[i] = (CHAR) 0xFF;
+ }
+
+ /* Now release each of the blocks. */
+ status = tx_block_release(pointer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Release the second block. */
+ status = tx_block_release(pointer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Release the third block. */
+ status = tx_block_release(pointer_3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Allocate each block again to make sure everything still
+ works. The block addresses should come out in reverse
+ order, because a released block is placed at the head of
+ the list. */
+
+ /* Allocate first block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Allocate second block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+
+ /* Allocate third block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Attempt to allocate fourth block from the pool. This should fail because
+ there should be no more blocks in the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Now resume the background thread. */
+ tx_thread_resume(&thread_1);
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete both block pools. */
+ status = tx_block_pool_delete(&pool_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ status = tx_block_pool_delete(&pool_1);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (error))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+ }
+}
diff --git a/test/smp/regression/threadx_block_memory_error_detection_test.c b/test/smp/regression/threadx_block_memory_error_detection_test.c
new file mode 100644
index 00000000..de28012f
--- /dev/null
+++ b/test/smp/regression/threadx_block_memory_error_detection_test.c
@@ -0,0 +1,387 @@
+/* This test is designed to test error detection for simple memory block operations. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+
+static TX_BLOCK_POOL pool_0;
+static TX_BLOCK_POOL pool_1;
+static TX_BLOCK_POOL pool_2;
+static CHAR *pointer;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+UINT _txe_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size,
+ VOID *pool_start, ULONG pool_size, UINT pool_control_block_size);
+
+
+/* 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_block_memory_error_detection_application_define(void *first_unused_memory)
+#endif
+{
+
+INT status;
+
+ /* 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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Create block pool 0. */
+ status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
+ pointer = pointer + 320;
+
+#ifndef TX_DISABLE_ERROR_CHECKING /* skip this test and pretend it passed */
+
+ /* Create block pool again to get pool_ptr error. */
+ status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
+ if (status != TX_POOL_ERROR)
+ return;
+
+ /* Create block pool with NULL pointer. */
+ status = tx_block_pool_create(TX_NULL, "pool 0", 100, pointer, 320);
+ if (status != TX_POOL_ERROR)
+ {
+
+ printf("Running Block Memory Error Detection Test........................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create block pool pointer if NULL start. */
+ status = tx_block_pool_create(&pool_1, "pool 0", 100, NULL, 320);
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("Running Block Memory Error Detection Test........................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create block pool pointer with invalid size. */
+ status = tx_block_pool_create(&pool_1, "pool 0", 100, pointer, 100);
+ if (status != TX_SIZE_ERROR)
+ {
+
+ printf("Running Block Memory Error Detection Test........................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Attempt of allocate block with NULL dest. */
+ status = tx_block_allocate(&pool_0, (VOID **) TX_NULL, TX_NO_WAIT);
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("Running Block Memory Error Detection Test........................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Delete null pointer. */
+ status = tx_block_pool_delete(TX_NULL);
+ if (status != TX_POOL_ERROR)
+ {
+
+ printf("Running Block Memory Error Detection Test........................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+#endif /* TX_DISABLE_ERROR_CHECKING */
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+UINT status;
+CHAR *pointer_1;
+CHAR *pointer_2;
+CHAR *pointer_3;
+CHAR *pointer_4;
+INT i;
+#endif
+
+ /* Inform user. */
+ printf("Running Block Memory Error Detection Test........................... ");
+
+#ifndef TX_DISABLE_ERROR_CHECKING /* skip this test and pretend it passed */
+
+ status = tx_block_pool_create(&pool_1, "pool 1", 100, pointer, 320);
+ pointer = pointer + 320;
+
+ /* Attempt to create a pool with an invalid size. */
+ status = _txe_block_pool_create(&pool_2, "pool 2", 100, pointer, 320, 777777);
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Error! */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Allocate with a NULL destination pointer. */
+ status = tx_block_allocate(&pool_0, (VOID **) TX_NULL, TX_NO_WAIT);
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Error! */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Allocate with a NULL pool pointer. */
+ status = tx_block_allocate(TX_NULL, (VOID **) TX_NULL, TX_NO_WAIT);
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Error! */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Allocate with bad pool pointer. */
+ pool_2.tx_block_pool_id = 0;
+ status = tx_block_allocate(&pool_2, (VOID **) TX_NULL, TX_NO_WAIT);
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Error! */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Release bad pool ptr. */
+ status = tx_block_release(TX_NULL);
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Error! */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Allocate first block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Allocate second block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+
+ /* Allocate third block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Attempt to allocate fourth block from the pool. This should fail because
+ there should be no more blocks in the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Error! */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Set the memory of all of the allocated blocks. */
+ for (i =0; i < 100; i++)
+ {
+ pointer_1[i] = (CHAR) 0xFF;
+ pointer_2[i] = (CHAR) 0xFF;
+ pointer_3[i] = (CHAR) 0xFF;
+ }
+
+ /* Now release each of the blocks. */
+ status = tx_block_release(pointer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Release the second block. */
+ status = tx_block_release(pointer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Release the third block. */
+ status = tx_block_release(pointer_3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Allocate each block again to make sure everything still
+ works. The block addresses should come out in reverse
+ order, because a released block is placed at the head of
+ the list. */
+
+ /* Allocate first block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Allocate second block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+
+ /* Allocate third block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Attempt to allocate fourth block from the pool. This should fail because
+ there should be no more blocks in the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Error! */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Delete both block pools. */
+ status = tx_block_pool_delete(&pool_0);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ status = tx_block_pool_delete(&pool_1);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete again. */
+ status = tx_block_pool_delete(&pool_1);
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Error! */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ thread_0_counter++;
+
+#endif /* TX_DISABLE_ERROR_CHECKING */
+
+ /* All is good! */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
diff --git a/test/smp/regression/threadx_block_memory_information_test.c b/test/smp/regression/threadx_block_memory_information_test.c
new file mode 100644
index 00000000..d6416bc2
--- /dev/null
+++ b/test/smp/regression/threadx_block_memory_information_test.c
@@ -0,0 +1,713 @@
+/* This test is designed to test block memory information services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_block_pool.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static TX_BLOCK_POOL block_pool_0;
+static TX_BLOCK_POOL block_pool_2;
+#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
+static TX_BLOCK_POOL block_pool_1;
+#endif
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+/* Direct core function to bypass the error checking shell. */
+UINT _tx_block_pool_info_get(TX_BLOCK_POOL *pool_ptr, CHAR **name, ULONG *available_blocks,
+ ULONG *total_blocks, TX_THREAD **first_suspended,
+ ULONG *suspended_count, TX_BLOCK_POOL **next_pool);
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_block_memory_information_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create the block_pool with one block. */
+ status = tx_block_pool_create(&block_pool_0, "block_pool 0", 30, pointer, 40);
+ pointer = pointer + 40;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #8\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+CHAR *name;
+ULONG available;
+ULONG total_blocks;
+TX_THREAD *first_suspended;
+ULONG suspended_count;
+TX_BLOCK_POOL *next_pool;
+ULONG allocates;
+ULONG releases;
+ULONG suspensions;
+ULONG timeouts;
+
+
+ /* Inform user. */
+ printf("Running Block Memory Information Test............................... ");
+
+ /* Allocate the one block. */
+ tx_block_allocate(&block_pool_0, &pointer, TX_NO_WAIT);
+
+ /* Nothing to do here, but check prioritization with no suspended threads. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check for an error condition. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Get both threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 and 2 are suspended on the block_pool. */
+ if ((thread_1.tx_thread_state != TX_BLOCK_MEMORY) || (thread_2.tx_thread_state != TX_BLOCK_MEMORY) ||
+ (block_pool_0.tx_block_pool_suspension_list != &thread_1))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_2))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check status and make sure thread 3 is at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_3))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Now determine if thread 4 is at the front of the list... It should be! */
+ if (block_pool_0.tx_block_pool_suspension_list != &thread_4)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Test the NULL pointer on the info get call. */
+ status = tx_block_pool_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for the proper error code. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Test the non-thread pointer on the info get call. */
+ block_pool_2.tx_block_pool_id = 0;
+ status = tx_block_pool_info_get(&block_pool_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for the proper error code. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Now use the information services in order to test them. */
+ status = tx_block_pool_info_get(&block_pool_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_block_pool_info_get(&block_pool_0, &name, &available, &total_blocks, &first_suspended, &suspended_count, &next_pool);
+
+ /* Check for an error condition. */
+ if ((status) || (available != block_pool_0.tx_block_pool_available) || (total_blocks != block_pool_0.tx_block_pool_total) ||
+ (first_suspended != &thread_4) || (suspended_count != block_pool_0.tx_block_pool_suspended_count) || (next_pool != &block_pool_0))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
+
+ /* Call the core block pool info get function with a NULL pointer. */
+ status = _tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for the proper error code. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Call the core block pool info get function with a non-initialized pool. */
+ status = _tx_block_pool_performance_info_get(&block_pool_1, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for the proper error code. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Now get the pool performance information. */
+ status = tx_block_pool_performance_info_get(&block_pool_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_block_pool_performance_info_get(&block_pool_0, &allocates, &releases, &suspensions, &timeouts);
+
+ /* Check for an error condition. */
+ if ((status) || (allocates != block_pool_0.tx_block_pool_performance_allocate_count) ||
+ (releases != block_pool_0.tx_block_pool_performance_release_count) ||
+ (suspensions != block_pool_0.tx_block_pool_performance_suspension_count) ||
+ (timeouts != block_pool_0.tx_block_pool_performance_timeout_count))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system pool performance information. */
+ status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_block_pool_performance_system_info_get(&allocates, &releases, &suspensions, &timeouts);
+
+ /* Check for an error condition. */
+ if ((status) || (allocates != _tx_block_pool_performance_allocate_count) || (releases != _tx_block_pool_performance_release_count) ||
+ (suspensions != _tx_block_pool_performance_suspension_count) || (timeouts != _tx_block_pool_performance_timeout_count))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+#else
+
+ /* Call the block pool performance info get function. */
+ status = tx_block_pool_performance_info_get(&block_pool_0, &allocates, &releases, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Call the block pool performance info get function. */
+ status = tx_block_pool_performance_info_get(TX_NULL, &allocates, &releases, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Call the block pool performance info get function. */
+ status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, &releases, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Call the block pool performance info get function. */
+ status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Call the block pool performance info get function. */
+ status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Call the block pool performance info get function. */
+ status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system pool performance information. */
+ status = tx_block_pool_performance_system_info_get(&allocates, &releases, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system pool performance information. */
+ status = tx_block_pool_performance_system_info_get(TX_NULL, &releases, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system pool performance information. */
+ status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system pool performance information. */
+ status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system pool performance information. */
+ status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+#endif
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+VOID *pointer;
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+ }
+}
+
diff --git a/test/smp/regression/threadx_block_memory_prioritize_test.c b/test/smp/regression/threadx_block_memory_prioritize_test.c
new file mode 100644
index 00000000..274daa01
--- /dev/null
+++ b/test/smp/regression/threadx_block_memory_prioritize_test.c
@@ -0,0 +1,500 @@
+/* This test is designed to test block memory pool prioritize. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static TX_BLOCK_POOL block_pool_0;
+static TX_BLOCK_POOL block_pool_1;
+
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Determine if thread 3 is at the front of the suspension list. */
+ if (block_pool_0.tx_block_pool_suspension_list == &thread_3)
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+ }
+ else
+ {
+
+ /* Abort the wait of thread 5. */
+ tx_thread_wait_abort(&thread_5);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_block_memory_prioritize_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create the block_pool with one block. */
+ status = tx_block_pool_create(&block_pool_0, "block_pool 0", 30, pointer, 40);
+ pointer = pointer + 40;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #8\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Inform user. */
+ printf("Running Block Memory Prioritize Test................................ ");
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to prioritize with a NULL pointer. */
+ status = tx_block_pool_prioritize(TX_NULL);
+
+ /* Check for an error condition. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to prioritize with a bad pool pointer. */
+ block_pool_1.tx_block_pool_id = 0;
+ status = tx_block_pool_prioritize(&block_pool_1);
+
+ /* Check for an error condition. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Allocate the one block. */
+ tx_block_allocate(&block_pool_0, &pointer, TX_NO_WAIT);
+
+ /* Nothing to do here, but check prioritization with no suspended threads. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check for an error condition. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Get both threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 and 2 are suspended on the block_pool. */
+ if ((thread_1.tx_thread_state != TX_BLOCK_MEMORY) || (thread_2.tx_thread_state != TX_BLOCK_MEMORY) ||
+ (block_pool_0.tx_block_pool_suspension_list != &thread_1))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check status and make sure thread 2 is at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_2))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Call block pool prioritize again to test the don't-do-anything path in tx_block_pool_prioritize. */
+ status += tx_block_pool_prioritize(&block_pool_0);
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check status and make sure thread 3 is at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_3))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Now determine if thread 4 is at the front of the list... It should be! */
+ if (block_pool_0.tx_block_pool_suspension_list != &thread_4)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+VOID *pointer;
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+ }
+}
diff --git a/test/smp/regression/threadx_block_memory_suspension_test.c b/test/smp/regression/threadx_block_memory_suspension_test.c
new file mode 100644
index 00000000..6f2d635c
--- /dev/null
+++ b/test/smp/regression/threadx_block_memory_suspension_test.c
@@ -0,0 +1,311 @@
+/* This test is designed to test suspension on memory block pools. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_BLOCK_POOL pool_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_block_memory_suspension_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Test................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Test................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Test................................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create block pool. */
+ status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
+ pointer = pointer + 320;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Test................................ ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+CHAR *pointer_2;
+CHAR *pointer_3;
+
+
+ /* Inform user. */
+ printf("Running Block Memory Suspension Test................................ ");
+
+ /* Increment the run counter. */
+ thread_0_counter++;
+
+ /* Allocate all blocks from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+
+ /* Get the last block. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Let the other thread suspend on the pool. */
+ tx_thread_relinquish();
+
+ /* Now release the block to lift the suspension on the other thread. */
+ status = tx_block_release(pointer_3);
+
+ /* Check status and run counter. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Let the other thread run again. */
+ tx_thread_relinquish();
+
+ /* Check the run counter of the other thread. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* At this point the other thread has run and there is one block free. */
+
+ /* Get the last block again. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Resume the second thread. */
+ tx_thread_resume(&thread_2);
+
+ /* Let both threads suspend on the block pool via relinquish. */
+ tx_thread_relinquish();
+
+ /* Now release the block. */
+ status = tx_block_release(pointer_3);
+
+ /* Check status and run counter. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Let thread 1 release the block. */
+ tx_thread_relinquish();
+
+ /* Let thread 2 get the block and release the block. */
+ tx_thread_relinquish();
+
+ /* Check status and run counter. */
+ if ((thread_1_counter != 3) || (thread_2_counter != 1))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+ else
+ {
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+
+
+ /* Attempt to get a block from the pool. */
+ while(1)
+ {
+
+ /* Allocate a block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_WAIT_FOREVER);
+
+ /* Determine if the allocate was successful. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Release the block. */
+ tx_block_release(pointer_1);
+
+ /* Switch back to other thread. */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+
+
+ /* Attempt to get a block from the pool. */
+ while(1)
+ {
+
+ /* Allocate a block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_WAIT_FOREVER);
+
+ /* Determine if the allocate was successful. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Release the block. */
+ tx_block_release(pointer_1);
+
+ /* Switch back to other thread. */
+ tx_thread_relinquish();
+ }
+}
+
+
diff --git a/test/smp/regression/threadx_block_memory_suspension_timeout_test.c b/test/smp/regression/threadx_block_memory_suspension_timeout_test.c
new file mode 100644
index 00000000..f290f01a
--- /dev/null
+++ b/test/smp/regression/threadx_block_memory_suspension_timeout_test.c
@@ -0,0 +1,212 @@
+/* This test is designed to test timeouts on suspension on memory block pools. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_BLOCK_POOL pool_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_block_memory_suspension_timeout_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Timeout Test........................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Timeout Test........................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Timeout Test........................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create block pool. */
+ status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
+ pointer = pointer + 320;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Timeout Test........................ ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+CHAR *pointer_2;
+CHAR *pointer_3;
+
+
+ /* Inform user. */
+ printf("Running Block Memory Suspension Timeout Test........................ ");
+
+ /* Allocate all blocks from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+ status += tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+ status += tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Sleep for 64 ticks to allow the other thread 6 timeouts on the block
+ pool. */
+ tx_thread_sleep(64);
+
+ /* Incrment the run counter. */
+ thread_0_counter++;
+
+ /* Check the counter of the other thread. */
+ if ((thread_1_counter != 6) || (thread_2_counter != 3))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+
+
+ /* Attempt to get a block from the pool. */
+ while(1)
+ {
+
+ /* Allocate a block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, 10);
+
+ /* Determine if the allocate was successful. */
+ if (status != TX_NO_MEMORY)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+
+
+ /* Delay so we get some single suspension timeouts as well. */
+ tx_thread_sleep(32);
+
+ /* Attempt to get a block from the pool. */
+ while(1)
+ {
+
+ /* Allocate a block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, 10);
+
+ /* Determine if the allocate was successful. */
+ if (status != TX_NO_MEMORY)
+ return;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
diff --git a/test/smp/regression/threadx_block_memory_thread_terminate_test.c b/test/smp/regression/threadx_block_memory_thread_terminate_test.c
new file mode 100644
index 00000000..c9221af9
--- /dev/null
+++ b/test/smp/regression/threadx_block_memory_thread_terminate_test.c
@@ -0,0 +1,185 @@
+/* This test is designed to test thread termination on a thread suspended on a block
+ memory pool. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+
+static TX_BLOCK_POOL pool_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_block_memory_thread_terminate_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Thread Terminate Test.......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Thread Terminate Test.......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create block pool. */
+ status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
+ pointer = pointer + 320;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Thread Terminate Test.......................... ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+CHAR *pointer_2;
+CHAR *pointer_3;
+
+
+ /* Inform user. */
+ printf("Running Block Memory Thread Terminate Test.......................... ");
+
+ /* Allocate all blocks from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+ status += tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+ status += tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Increment the run counter. */
+ thread_0_counter++;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+
+ /* Let other thread suspend on block pool. */
+ tx_thread_relinquish();
+
+ /* Terminate the other thread. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_TERMINATED) ||
+ (thread_1_counter != 0))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Release all the blocks. */
+ status = tx_block_release(pointer_1);
+ status += tx_block_release(pointer_2);
+ status += tx_block_release(pointer_3);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_TERMINATED) ||
+ (thread_1_counter != 0))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+
+
+ /* Attempt to get a block from the pool. */
+ while(1)
+ {
+
+ /* Allocate a block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, 10);
+
+ /* Determine if the allocate was successful. */
+ if (status != TX_NO_MEMORY)
+ return;
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
diff --git a/test/smp/regression/threadx_byte_memory_basic_test.c b/test/smp/regression/threadx_byte_memory_basic_test.c
new file mode 100644
index 00000000..9fffc840
--- /dev/null
+++ b/test/smp/regression/threadx_byte_memory_basic_test.c
@@ -0,0 +1,1064 @@
+/* This test is designed to test simple memory byte pool creation, deletion, and
+ allocates and releases. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+typedef struct BYTE_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_BYTE_POOL pool;
+ ULONG first_middle;
+ ULONG second_middle;
+ ULONG pool_area[2048/sizeof(ULONG)];
+ ULONG next_to_last;
+ ULONG last;
+
+} BYTE_MEMORY_TEST;
+
+static BYTE_MEMORY_TEST byte_memory;
+
+
+/* Define external reference to byte pool creation status. */
+
+extern UINT test_byte_pool_create_init;
+
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+UINT _txe_byte_pool_create(TX_BYTE_POOL *pool_ptr, CHAR *name_ptr, VOID *pool_start,
+ ULONG pool_size, UINT pool_control_block_size);
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+
+static TX_BYTE_POOL pool_0;
+static TX_BYTE_POOL pool_1;
+static TX_BYTE_POOL pool_2;
+static TX_BYTE_POOL pool_3;
+
+static TX_BYTE_POOL pool_4;
+static UCHAR *search_ptr_1;
+static UCHAR *block_0;
+static UCHAR *block_1;
+static UCHAR *block_2;
+static UCHAR *block_3;
+static UCHAR *block_4;
+static CHAR *pool_4_memory;
+static TX_TIMER timer_0;
+
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+UINT _tx_byte_release(VOID *memory_ptr);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Determine if calling byte pool create from initialization was successful. */
+ if (test_byte_pool_create_init != TX_SUCCESS)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a byte pool from a timer. */
+ pointer = (CHAR *) 0x30000;
+ status = tx_byte_pool_create(&pool_2, "pool 2", pointer, 108);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a byte pool with an invalid size. */
+ status = _txe_byte_pool_create(&pool_3, "pool 3", pointer,
+ 108, (sizeof(TX_BYTE_POOL)+1));
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Try to delete a byte pool from a timer. */
+ status = tx_byte_pool_delete(&pool_0);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to release byte memory from timer. */
+ pointer = (CHAR *) 0x30000;
+ status = tx_byte_release(pointer);
+
+ /* Check for error status! */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+CHAR *pointer;
+UINT status;
+
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 24, 100);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+
+ /* Attempt to create a byte pool from an ISR. */
+ status = tx_byte_pool_create(&pool_2, "pool 0", (void *) 0x100000, 108);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to deleate a pool from an ISR. */
+ status = tx_byte_pool_delete(&pool_0);
+
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to release byte memory from ISR. */
+ pointer = (CHAR *) 0x30000;
+ status = tx_byte_release(pointer);
+
+ /* Check for error status! */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_byte_memory_basic_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Basic Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create byte pools 0 and 1. */
+ status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
+ pointer = pointer + 108;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Basic Test...................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_byte_pool_create(&pool_1, "pool 1", pointer, 200);
+ pointer = pointer + 200;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Basic Test...................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Test for search pointer issue on wrapped seach with prior block to search pointer merged. */
+ status = tx_byte_pool_create(&pool_4, "pool 4", pointer, 300);
+ pool_4_memory = pointer;
+ pointer = pointer + 300;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Basic Test...................................... ERROR #3a\n");
+ test_control_return(1);
+ }
+
+ /* Allocate first block. */
+ status += tx_byte_allocate(&pool_4, (VOID **) &block_0, 80, TX_NO_WAIT);
+
+ /* Save next search pointer. */
+ search_ptr_1 = pool_4.tx_byte_pool_search;
+
+ /* Clear the allocatged memory. */
+ TX_MEMSET(block_0, 0, 80);
+
+ /* Allocate another block. */
+ status += tx_byte_allocate(&pool_4, (VOID **) &block_1, 80, TX_NO_WAIT);
+
+ /* Clear the allocated block. */
+ TX_MEMSET(block_1, 0, 80);
+
+ /* Allocate the third and final block. */
+ status += tx_byte_allocate(&pool_4, (VOID **) &block_2, 80, TX_NO_WAIT);
+
+ /* Clear the allocated block. */
+ TX_MEMSET(block_2, 0, 80);
+
+ /* Release the first block. */
+ status += tx_byte_release(block_0);
+
+ /* Release the second block. */
+ status += tx_byte_release(block_1);
+
+ /* Manually move the search pointer to create the case where the search wraps and a merge happens on the search pointer
+ necessitating its update. */
+ pool_4.tx_byte_pool_search = search_ptr_1; /* Point to the middle block. */
+
+ /* Allocate a larger block that will wrap the search and require moving as well as an update of the search pointer. */
+ status += tx_byte_allocate(&pool_4, (VOID **) &block_3, 120, TX_NO_WAIT);
+
+ /* Clear the newly allocated block. */
+ TX_MEMSET(block_3, 0, 120);
+
+ /* At this point, verify the search pointer was properly updated in the previous allocation. */
+ status += tx_byte_allocate(&pool_4, (VOID **) &block_4, 40, TX_NO_WAIT); /* Should fail since search pointer is now invalid! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Basic Test...................................... ERROR #3b\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+CHAR *pointer_2;
+CHAR *pointer_3;
+CHAR *pointer_4;
+INT i;
+ULONG array[20];
+UCHAR *save_search;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Basic Test...................................... ");
+
+ /* Perform byte memory test. */
+ byte_memory.first = 0x11223344;
+ byte_memory.second = 0x55667788;
+ byte_memory.first_middle = 0x21314151;
+ byte_memory.second_middle= 0x61718191;
+ byte_memory.next_to_last = 0x99aabbcc;
+ byte_memory.last = 0xddeeff00;
+
+ /* Create the byte pool. */
+ status = tx_byte_pool_create(&byte_memory.pool, "pool memory", &byte_memory.pool_area[0], (2048*sizeof(ULONG))/sizeof(ULONG));
+ tx_byte_pool_delete(&byte_memory.pool);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (byte_memory.first != 0x11223344) ||
+ (byte_memory.second != 0x55667788) ||
+ (byte_memory.first_middle != 0x21314151) ||
+ (byte_memory.second_middle != 0x61718191) ||
+ (byte_memory.next_to_last != 0x99aabbcc) ||
+ (byte_memory.last != 0xddeeff00))
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Increment the run counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Try to create a NULL pool. */
+ pointer_1 = (CHAR *) 0x30000;
+ status = tx_byte_pool_create(TX_NULL, "pool 0", pointer_1, 108);
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Try to create the same pool. */
+ status = tx_byte_pool_create(&pool_0, "pool 0", pointer_1, 108);
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Try to create a pool with a NULL start address. */
+ status = tx_byte_pool_create(&pool_2, "pool 2", TX_NULL, 108);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Try to create a pool with a a bad size. */
+ status = tx_byte_pool_create(&pool_2, "pool 2", pointer_1, 1);
+
+ /* Check status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Try to delete a byte pool with a NULL pointer. */
+ status = tx_byte_pool_delete(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Try to delete a byte pool that hasn't been created. */
+ pool_2.tx_byte_pool_id = 0;
+ status = tx_byte_pool_delete(&pool_2);
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Test NULL pool pointer. */
+ status = tx_byte_allocate(TX_NULL, (VOID **) &pointer_1, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Test non-created pool pointer. */
+ pool_2.tx_byte_pool_id = 0;
+ status = tx_byte_allocate(&pool_2, (VOID **) &pointer_1, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Test NULL memory pointer. */
+ status = tx_byte_allocate(&pool_0, (VOID **) TX_NULL, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Test extreme size. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 240000, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Test size of 0. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Test NULL pointer release. */
+ status = tx_byte_release(TX_NULL);
+
+ /* Check for error status! */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_2, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to allocate fourth area from the pool. This should fail because
+ there should be not enough bytes in the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_4, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Set the memory of all of the allocated memory. */
+ for (i =0; i < 24; i++)
+ {
+ pointer_1[i] = (CHAR) 0xFF;
+ pointer_2[i] = (CHAR) 0xFF;
+ pointer_3[i] = (CHAR) 0xFF;
+ }
+
+ /* Test the byte release with a bad block pointer. */
+ status = _tx_byte_release(TX_NULL);
+
+ /* Check for error status! */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Test another bad block release... no pool pointer! */
+ array[0] = 0;
+ array[1] = 0;
+ array[2] = 0;
+ status = _tx_byte_release(&array[2]);
+
+ /* Check for error status! */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Test another bad block release.... pool pointer is not a valid pool! */
+ array[0] = 0;
+ array[1] = (ULONG) &array[3];
+ array[2] = 0;
+ array[3] = 0;
+ status = _tx_byte_release(&array[2]);
+
+ /* Check for error status! */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Now release each of the blocks. */
+ status = tx_byte_release(pointer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Now release the same block again. */
+ status = tx_byte_release(pointer_1);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Release the second memory area. */
+ status = tx_byte_release(pointer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Release the third memory area. */
+ status = tx_byte_release(pointer_3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Allocate each block again to make sure everything still
+ works. */
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Allocate second memory area from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_2, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Allocate third memory area from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to allocate fourth memory area from the pool. This should fail because
+ there should be not enough bytes in the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_4, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Now release each of the blocks. */
+ status = tx_byte_release(pointer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Release the second memory area. */
+ status = tx_byte_release(pointer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Release the third memory area. */
+ status = tx_byte_release(pointer_3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Now allocate a block that should cause all of the blocks to merge
+ together. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 88, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to allocate fourth memory area from the pool. This should fail because
+ there should be not enough bytes in the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_4, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+ /* Release the block. */
+ status = tx_byte_release(pointer_3);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+ /* Now ensure the search pointer update in the byte search algorithm is updated. */
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ /* Allocate second memory area from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_2, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+
+ /* Allocate third memory area from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #39\n");
+ test_control_return(1);
+ }
+
+ /* Release the middle block. */
+ status = tx_byte_release(pointer_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #40\n");
+ test_control_return(1);
+ }
+
+ /* Move the search pointer to the third block to exercise that code in the byte search algorithm. */
+ pool_0.tx_byte_pool_search = (UCHAR *) pointer_3-8;
+
+ /* Now allocate the block again. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_2, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #41\n");
+ test_control_return(1);
+ }
+
+ /* Now release the blocks are test the merge with the update of the search pointer. */
+ status = tx_byte_release(pointer_3);
+ status += tx_byte_release(pointer_2);
+ status += tx_byte_release(pointer_1);
+
+ /* Move the search pointer to the third block to exercise that code in the byte search algorithm. */
+ pool_0.tx_byte_pool_search = (UCHAR *) pointer_3-8;
+
+ /* Allocate a large block to force the search pointer update. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 88, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #42\n");
+ test_control_return(1);
+ }
+
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #43\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete both byte pools. */
+ status = tx_byte_pool_delete(&pool_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #44\n");
+ test_control_return(1);
+ }
+
+ status = tx_byte_pool_delete(&pool_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #45\n");
+ test_control_return(1);
+ }
+
+ /* Delete pool 4. */
+ status = tx_byte_pool_delete(&pool_4);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #46\n");
+ test_control_return(1);
+ }
+
+ /* Create pool 4. */
+ status = tx_byte_pool_create(&pool_4, "pool 4", pool_4_memory, 300);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #47\n");
+ test_control_return(1);
+ }
+
+ /* Allocate three blocks... */
+ status = tx_byte_allocate(&pool_4, (VOID **) &pointer_1, 84, TX_NO_WAIT);
+ status += tx_byte_allocate(&pool_4, (VOID **) &pointer_2, 84, TX_NO_WAIT);
+ status += tx_byte_allocate(&pool_4, (VOID **) &pointer_3, 84, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #48\n");
+ test_control_return(1);
+ }
+
+ /* At this point, there should be three allocated blocks and the reserved block at the end. */
+
+ /* Now release all the blocks in reverse order. This should leave the search pointer at the last block. */
+ status = tx_byte_release(pointer_3);
+ save_search = pool_4.tx_byte_pool_search;
+ status += tx_byte_release(pointer_2);
+ status += tx_byte_release(pointer_1);
+
+ /* Move the search pointer back to the last block. */
+ pool_4.tx_byte_pool_search = save_search;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #49\n");
+ test_control_return(1);
+ }
+
+ /* Now attempt to allocate a block that requires a merge, which should exercise the branch in byte search that does not
+ result in a search pointer change. */
+ status = tx_byte_allocate(&pool_4, (VOID **) &pointer_1, 168, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #50\n");
+ test_control_return(1);
+ }
+
+ /* Release the last block. */
+ status = tx_byte_release(pointer_1);
+
+ /* Allocate all the blocks. */
+ status = tx_byte_allocate(&pool_4, (VOID **) &pointer_1, 84, TX_NO_WAIT);
+ status += tx_byte_allocate(&pool_4, (VOID **) &pointer_2, 84, TX_NO_WAIT);
+ status += tx_byte_allocate(&pool_4, (VOID **) &pointer_3, 84, TX_NO_WAIT);
+
+ /* Release all of the blocks in order. */
+ status += tx_byte_release(pointer_1);
+ status += tx_byte_release(pointer_2);
+ status += tx_byte_release(pointer_3);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #50\n");
+ test_control_return(1);
+ }
+
+ /* Now setup a special test to exercise the examine blocks equal to 0 path in the byte pool search. */
+ pool_4.tx_byte_pool_search = save_search;
+ pool_4.tx_byte_pool_fragments = (UINT) (-1);
+
+ /* Call byte allocate to execise the examine blocks equal to 0 path on non-merge block condition. */
+ status = tx_byte_allocate(&pool_4, (VOID **) &pointer_1, 168, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #51\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
diff --git a/test/smp/regression/threadx_byte_memory_information_test.c b/test/smp/regression/threadx_byte_memory_information_test.c
new file mode 100644
index 00000000..2d1c20bc
--- /dev/null
+++ b/test/smp/regression/threadx_byte_memory_information_test.c
@@ -0,0 +1,784 @@
+/* This test is designed to test byte memory information. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_byte_pool.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static TX_BYTE_POOL byte_pool_0;
+#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
+static TX_BYTE_POOL byte_pool_1;
+#endif
+static TX_BYTE_POOL byte_pool_2;
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+UINT _tx_byte_pool_performance_info_get(TX_BYTE_POOL *pool_ptr, ULONG *allocates, ULONG *releases,
+ ULONG *fragments_searched, ULONG *merges, ULONG *splits, ULONG *suspensions, ULONG *timeouts);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_byte_memory_information_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create the byte_pool with one byte. */
+ status = tx_byte_pool_create(&byte_pool_0, "byte_pool 0", pointer, 100);
+ pointer = pointer + 100;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #8\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+CHAR *name;
+ULONG available;
+ULONG fragments;
+TX_THREAD *first_suspended;
+ULONG suspended_count;
+TX_BYTE_POOL *next_pool;
+ULONG allocates;
+ULONG releases;
+ULONG fragments_searched;
+ULONG merges;
+ULONG splits;
+ULONG suspensions;
+ULONG timeouts;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Information Test................................ ");
+
+ /* Allocate the one byte. */
+ tx_byte_allocate(&byte_pool_0, &pointer, 80, TX_NO_WAIT);
+
+ /* Nothing to do here, but check prioritization with no suspended threads. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 and 2 are suspended on the byte_pool. */
+ if ((thread_1.tx_thread_state != TX_BYTE_MEMORY) || (thread_2.tx_thread_state != TX_BYTE_MEMORY) ||
+ (byte_pool_0.tx_byte_pool_suspension_list != &thread_1))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the byte pool suspension list. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 2 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_2))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the byte pool suspension list. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 3 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_3))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the byte pool suspension list. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Check status and make sure thread 3 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_4))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Call byte pool info with a NULL pointer. */
+ status = tx_byte_pool_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Call byte pool info with an non-created pool pointer. */
+ byte_pool_2.tx_byte_pool_id = 0;
+ status = tx_byte_pool_info_get(&byte_pool_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Get the byte pool information. */
+ status = tx_byte_pool_info_get(&byte_pool_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_byte_pool_info_get(&byte_pool_0, &name, &available, &fragments, &first_suspended, &suspended_count, &next_pool);
+
+ /* Check the status. */
+ if ((status != TX_SUCCESS) || (available != byte_pool_0.tx_byte_pool_available) || (fragments != byte_pool_0.tx_byte_pool_fragments) ||
+ (first_suspended != &thread_4) || (suspended_count != byte_pool_0.tx_byte_pool_suspended_count) || (next_pool != &byte_pool_0))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+
+#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(&byte_pool_1, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(&byte_pool_0, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if ((status != TX_SUCCESS) || (allocates != byte_pool_0.tx_byte_pool_performance_allocate_count) || (releases != byte_pool_0.tx_byte_pool_performance_release_count) ||
+ (fragments_searched != byte_pool_0.tx_byte_pool_performance_search_count) || (merges != byte_pool_0.tx_byte_pool_performance_merge_count) ||
+ (splits != byte_pool_0.tx_byte_pool_performance_split_count) || (suspensions != byte_pool_0.tx_byte_pool_performance_suspension_count) ||
+ (timeouts != byte_pool_0.tx_byte_pool_performance_timeout_count))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(&allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if ((status != TX_SUCCESS) || (allocates != _tx_byte_pool_performance_allocate_count) || (releases != _tx_byte_pool_performance_release_count) ||
+ (fragments_searched != _tx_byte_pool_performance_search_count) || (merges != _tx_byte_pool_performance_merge_count) ||
+ (splits != _tx_byte_pool_performance_split_count) || (suspensions != _tx_byte_pool_performance_suspension_count) ||
+ (timeouts != _tx_byte_pool_performance_timeout_count))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+#else
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(&byte_pool_0, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(&allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+#endif
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+VOID *pointer;
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+ }
+}
diff --git a/test/smp/regression/threadx_byte_memory_prioritize_test.c b/test/smp/regression/threadx_byte_memory_prioritize_test.c
new file mode 100644
index 00000000..f06d5cd3
--- /dev/null
+++ b/test/smp/regression/threadx_byte_memory_prioritize_test.c
@@ -0,0 +1,498 @@
+/* This test is designed to test byte memory prioritize. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static TX_BYTE_POOL byte_pool_0;
+static TX_BYTE_POOL byte_pool_1;
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Determine if thread 3 is at the front of the suspension list. */
+ if (byte_pool_0.tx_byte_pool_suspension_list == &thread_3)
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+ }
+ else
+ {
+
+ /* Abort the wait of thread 5. */
+ tx_thread_wait_abort(&thread_5);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_byte_memory_prioritize_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create the byte_pool with one byte. */
+ status = tx_byte_pool_create(&byte_pool_0, "byte_pool 0", pointer, 100);
+ pointer = pointer + 100;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #8\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Prioritize Test................................. ");
+
+ /* Allocate the one byte. */
+ tx_byte_allocate(&byte_pool_0, &pointer, 80, TX_NO_WAIT);
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Call byte pool prioritize with a NULL pointer. */
+ status = tx_byte_pool_prioritize(TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Call byte pool info with an non-created pool pointer. */
+ byte_pool_1.tx_byte_pool_id = 0;
+ status = tx_byte_pool_prioritize(&byte_pool_1);
+
+ /* Check for error. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Nothing to do here, but check prioritization with no suspended threads. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 and 2 are suspended on the byte_pool. */
+ if ((thread_1.tx_thread_state != TX_BYTE_MEMORY) || (thread_2.tx_thread_state != TX_BYTE_MEMORY) ||
+ (byte_pool_0.tx_byte_pool_suspension_list != &thread_1))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the byte pool suspension list. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 2 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_2))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Call byte pool prioritize again to test the don't-do-anything path in tx_byte_pool_prioritize. */
+ status += tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the byte pool suspension list. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 3 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_3))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the byte pool suspension list. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Check status and make sure thread 3 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_4))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+VOID *pointer;
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+ }
+}
+
diff --git a/test/smp/regression/threadx_byte_memory_suspension_test.c b/test/smp/regression/threadx_byte_memory_suspension_test.c
new file mode 100644
index 00000000..069410c5
--- /dev/null
+++ b/test/smp/regression/threadx_byte_memory_suspension_test.c
@@ -0,0 +1,391 @@
+/* This test is designed to test suspension on a memory byte pool. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+
+static TX_BYTE_POOL pool_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+
+
+
+#ifndef TX_MANUAL_TEST
+
+/* Define test flags for automated test. */
+
+extern TEST_FLAG threadx_byte_allocate_loop_test;
+extern TEST_FLAG threadx_byte_release_loop_test;
+
+#endif
+
+
+void abort_and_resume_byte_allocating_thread(void)
+{
+
+UCHAR *search_ptr;
+
+ /* Adjust the search pointer to avoid the search pointer change for this test. */
+ search_ptr = pool_0.tx_byte_pool_search;
+ while (search_ptr >= pool_0.tx_byte_pool_search)
+
+ {
+ search_ptr = *((UCHAR **) ((VOID *) search_ptr));
+ }
+ pool_0.tx_byte_pool_search = search_ptr;
+
+ tx_thread_wait_abort(&thread_3);
+ tx_thread_resume(&thread_3);
+}
+
+
+/* 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_byte_memory_suspension_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create byte pool 0. */
+ status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
+ pointer = pointer + 108;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Test................................. ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Suspension Test................................. ");
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Allocate memory from the pool. Only one block of this size will fit. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Let other thread suspend on byte pool. */
+ tx_thread_relinquish();
+
+ /* Now release the blocks. */
+ status = tx_byte_release(pointer);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) && (thread_1_counter == 0))
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Let other thread run again. */
+ tx_thread_relinquish();
+
+ /* Check to make sure thread 1 has now run. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Now allocate the memory again. Only one block of this size will fit. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Resume the second thread. */
+ tx_thread_resume(&thread_2);
+
+ /* Now relinquish to let both thread 1 and 2 suspend. */
+ tx_thread_relinquish();
+
+ /* At this point both threads should be suspended on the byte pool. */
+
+ /* Release the memory again. */
+ status = tx_byte_release(pointer);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Now relinquish to get the other threads to run once. */
+ tx_thread_relinquish();
+ tx_thread_relinquish();
+
+ /* At this point both threads 1 and 2 are suspended on the byte pool again. */
+ if ((thread_1_counter != 3) && (thread_2_counter != 1))
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Now allocate the memory again. Only one block of this size will fit. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #10a\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 3 to get it suspended on the the pool. */
+ tx_thread_resume(&thread_3);
+
+#ifdef TX_MANUAL_TEST
+
+ /* Set BP hear. Now release the memory and step into the code. After byte search issue IRQ2 mannually, which will
+ make thread 3 abort the first request and make another request of a different size. This is the path we are trying
+ to generate in the test. */
+ status = tx_byte_release(pointer);
+#else
+
+ /* Set the flag that will make thread 3 abort the first request and make another request of a different size. This tests the memory size change path
+ in the byte release loop logic. */
+ threadx_byte_release_loop_test = 1;
+ status = tx_byte_release(pointer);
+
+#endif
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #10b\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+ while(1)
+ {
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Now release each of the blocks. */
+ status = tx_byte_release(pointer);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Let thread 0 run again. */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+ while(1)
+ {
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Now release each of the blocks. */
+ status = tx_byte_release(pointer);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Let thread 0 run again. */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+ while (1)
+ {
+
+ /* Allocate memory from the pool. */
+ tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
+
+#ifdef TX_MANUAL_TEST
+
+ /* Set BP here and manually clear the owner after one failed byte search just to test the loop
+ construct in tx_byte_allocate.c. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 90, TX_WAIT_FOREVER);
+#else
+
+ /* Set the flag that clears the pool owner after one failed byte search to test the loop
+ construct processing in tx_byte_allocate.c. */
+ threadx_byte_allocate_loop_test = 1;
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 90, TX_WAIT_FOREVER);
+#endif
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+
+ /* Now release the block. */
+ status = tx_byte_release(pointer);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* suspend this thread. */
+ tx_thread_suspend(&thread_3);
+ }
+}
diff --git a/test/smp/regression/threadx_byte_memory_suspension_timeout_test.c b/test/smp/regression/threadx_byte_memory_suspension_timeout_test.c
new file mode 100644
index 00000000..ed122dab
--- /dev/null
+++ b/test/smp/regression/threadx_byte_memory_suspension_timeout_test.c
@@ -0,0 +1,196 @@
+/* This test is designed to test suspension timeout on a memory byte pool. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_BYTE_POOL pool_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_byte_memory_suspension_timeout_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Timeout Test......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Timeout Test......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Timeout Test......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create byte pool 0. */
+ status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
+ pointer = pointer + 108;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Timeout Test......................... ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Suspension Timeout Test......................... ");
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Allocate memory from the pool. Only one block of this size will fit. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0))
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Sleep to allow the other thread to suspend and timeout on the memory
+ pool once. */
+ tx_thread_sleep(64);
+
+ /* Check the counter of the other thread. */
+ if ((thread_1_counter != 6) || (thread_2_counter != 3))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+ while(1)
+ {
+
+ /* Allocate memory from the pool - with timeout. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, 10);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Delay so we get some single suspension timeouts as well. */
+ tx_thread_sleep(32);
+
+ while(1)
+ {
+
+ /* Allocate memory from the pool - with timeout. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, 10);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ return;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
diff --git a/test/smp/regression/threadx_byte_memory_thread_contention_test.c b/test/smp/regression/threadx_byte_memory_thread_contention_test.c
new file mode 100644
index 00000000..55f7f4f3
--- /dev/null
+++ b/test/smp/regression/threadx_byte_memory_thread_contention_test.c
@@ -0,0 +1,255 @@
+/* This test is designed to test contention of two threads on a single
+ memory byte pool. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static unsigned long initial_pool_size;
+
+
+static TX_BYTE_POOL pool_0;
+
+
+static int test_done;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_byte_memory_thread_contention_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,
+ 17, 17, 1, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Contention Test.......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 1, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Contention Test.......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 1, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Contention Test.......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create byte pool 0. */
+ status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
+ pointer = pointer + 108;
+
+ /* Save off the intial pool size. */
+ initial_pool_size = pool_0.tx_byte_pool_available;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Contention Test.......................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Set the test done flag to false. */
+ test_done = TX_FALSE;
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Thread Contention Test.......................... ");
+
+ /* Set time to 0. */
+ tx_time_set(0);
+
+ while(1)
+ {
+
+ /* Allocate memory from the pool. This size will cause merge activity
+ because the search pointer will sit in this large block about half
+ the time. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Fill the memory. */
+ TX_MEMSET(pointer, (CHAR) 0xEF, 60);
+
+ /* Now release the block. */
+ status = tx_byte_release(pointer);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Check the time. */
+ if (tx_time_get() > 1280)
+ break;
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+ }
+
+ /* Set the done flag. */
+ test_done = TX_TRUE;
+
+ /* Sleep to let the other threads finish up! */
+ tx_thread_sleep(2);
+
+ /* Determine if we all all the original memory and that thread 1
+ is in the proper place. */
+ if (pool_0.tx_byte_pool_available != initial_pool_size)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ while(test_done == TX_FALSE)
+ {
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 30, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Fill the memory. */
+ TX_MEMSET(pointer, (CHAR) 0xEF, 30);
+
+ /* Now release the block. */
+ status = tx_byte_release(pointer);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ while(test_done == TX_FALSE)
+ {
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 12, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Fill the memory. */
+ TX_MEMSET(pointer, (CHAR) 0xEF, 12);
+
+ /* Now release the block. */
+ status = tx_byte_release(pointer);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
diff --git a/test/smp/regression/threadx_byte_memory_thread_terminate_test.c b/test/smp/regression/threadx_byte_memory_thread_terminate_test.c
new file mode 100644
index 00000000..29fec0c0
--- /dev/null
+++ b/test/smp/regression/threadx_byte_memory_thread_terminate_test.c
@@ -0,0 +1,177 @@
+/* This test is designed to test termination on thread suspended on memory byte pool. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+
+static TX_BYTE_POOL pool_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_byte_memory_thread_terminate_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Terminate Test........................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Terminate Test........................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create byte pools 0 and 1. */
+ status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
+ pointer = pointer + 108;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Terminate Test........................... ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Thread Terminate Test........................... ");
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Allocate memory from the pool. Only one block of this size will fit. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Let other thread suspend on byte pool. */
+ tx_thread_relinquish();
+
+ /* Terminate the other thread. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Release block back. */
+ status = tx_byte_release(pointer);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Allocate memory from the pool. Only one block of this size will fit. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0))
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+ while(1)
+ {
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
+
+ /* Should never get here! */
+ if (status != TX_NO_MEMORY)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
diff --git a/test/smp/regression/threadx_event_flag_basic_test.c b/test/smp/regression/threadx_event_flag_basic_test.c
new file mode 100644
index 00000000..9c19f9bd
--- /dev/null
+++ b/test/smp/regression/threadx_event_flag_basic_test.c
@@ -0,0 +1,743 @@
+/* This test is designed to test simple event flag group creation, deletion, gets and
+ sets. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+typedef struct EVENT_FLAG_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_EVENT_FLAGS_GROUP event_flags;
+ ULONG next_to_last;
+ ULONG last;
+
+} EVENT_FLAG_MEMORY_TEST;
+
+static EVENT_FLAG_MEMORY_TEST event_flag_memory;
+
+
+/* Define external reference to the event flag create call from initialization. */
+
+extern UINT test_event_flags_from_init;
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_TIMER timer_0;
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+static TX_EVENT_FLAGS_GROUP group_0;
+static TX_EVENT_FLAGS_GROUP group_1;
+static TX_EVENT_FLAGS_GROUP group_2;
+static TX_EVENT_FLAGS_GROUP group_3;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+UINT _txe_event_flags_create(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name_ptr, UINT event_control_block_size);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+ULONG actual_events;
+
+
+ /* Determine if calling event flag create from initialization was successful. */
+ if (test_event_flags_from_init != TX_SUCCESS)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create an event flag group from a timer. */
+ status = tx_event_flags_create(&group_2, "group 2");
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Try to delete an event flags group from a timer. */
+ status = tx_event_flags_delete(&group_0);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Get events with suspendsion from a timer. */
+ status = tx_event_flags_get(&group_0, 0x80008000, 14, &actual_events, 100);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+ULONG actual_events;
+
+
+ /* Attempt to create an event flag group from an ISR. */
+ status = tx_event_flags_create(&group_2, "group 2");
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete an event flags group from an ISR. */
+ status = tx_event_flags_delete(&group_0);
+
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Get events with suspendsion from an ISR. */
+ status = tx_event_flags_get(&group_0, 0x80008000, 14, &actual_events, 100);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+
+ isr_executed = 1;
+#endif
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_basic_application_define(void *first_unused_memory)
+#endif
+{
+
+INT 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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0 and 1. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_event_flags_create(&group_1, "group 1");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Un-register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, TX_NULL);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #5a\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #6a\n");
+ test_control_return(1);
+ }
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Basic Test....................................... ");
+
+ /* Perform event flag memory test. */
+ event_flag_memory.first = 0x11223344;
+ event_flag_memory.second = 0x55667788;
+ event_flag_memory.next_to_last = 0x99aabbcc;
+ event_flag_memory.last = 0xddeeff00;
+
+ /* Create the event flag group. */
+ status = tx_event_flags_create(&event_flag_memory.event_flags, "group memory");
+ tx_event_flags_delete(&event_flag_memory.event_flags);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (event_flag_memory.first != 0x11223344) ||
+ (event_flag_memory.second != 0x55667788) ||
+ (event_flag_memory.next_to_last != 0x99aabbcc) ||
+ (event_flag_memory.last != 0xddeeff00))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Event flags should be created now. */
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Try to create with a NULL pointer. */
+ status = tx_event_flags_create(TX_NULL, "group 0");
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Try to create with a bad size. */
+ status = _txe_event_flags_create(&group_3, "group 3", (sizeof(TX_EVENT_FLAGS_GROUP)+1));
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Try to create an already created group. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Delete with a NULL pointer. */
+ status = tx_event_flags_delete(TX_NULL);
+
+ /* Check the status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Delete with a non-created pointer. */
+ group_2.tx_event_flags_group_id = 0;
+ status = tx_event_flags_delete(&group_2);
+
+ /* Check the status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Get events with a null group pointer. */
+ status = tx_event_flags_get(TX_NULL, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Get events with a non-created group pointer. */
+ group_2.tx_event_flags_group_id = 0;
+ status = tx_event_flags_get(&group_2, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Get events with a null flags retun pointer. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, TX_NULL, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Get events with a bad option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, 14, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_OPTION_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Set evetns with a NULL group pointer. */
+ status = tx_event_flags_set(TX_NULL, 0x80008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Set events with a non-created group pointer. */
+ group_2.tx_event_flags_group_id = 0;
+ status = tx_event_flags_set(&group_2, 0x80008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Set events with a bad option. */
+ status = tx_event_flags_set(&group_0, 0x80008000, 14);
+
+ /* Check status. */
+ if (status != TX_OPTION_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to register the event set notify function with a NULL group pointer. */
+ status = tx_event_flags_set_notify(TX_NULL, event_set_notify);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to register the event set notify function with a non-created group pointer. */
+ group_2.tx_event_flags_group_id = 0;
+ status = tx_event_flags_set_notify(&group_2, event_set_notify);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Attempt to get events from an empty event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. OR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. AND CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Set the necessary events. */
+ status = tx_event_flags_set(&group_0, 0x80008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Just for fun, clear bit 15. */
+ status = tx_event_flags_set(&group_0, 0x80000000, TX_AND);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Set bit 15 again. */
+ status = tx_event_flags_set(&group_0, 0x00008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Now attemp to retrieve events... */
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. OR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. AND CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Put event flags back in the group. */
+
+ /* Set the necessary events. */
+ status = tx_event_flags_set(&group_0, 0x80008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x00008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Now resume thread 1. */
+ tx_thread_resume(&thread_1);
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete both event flag groups. */
+ status = tx_event_flags_delete(&group_0);
+
+ /* Check the status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ status = tx_event_flags_delete(&group_1);
+
+ /* Check the status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+ }
+}
+
diff --git a/test/smp/regression/threadx_event_flag_information_test.c b/test/smp/regression/threadx_event_flag_information_test.c
new file mode 100644
index 00000000..1f03fdf3
--- /dev/null
+++ b/test/smp/regression/threadx_event_flag_information_test.c
@@ -0,0 +1,562 @@
+/* This test is designed to test the event flag group information gathering services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_event_flags.h"
+
+
+static TX_THREAD thread_0;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+static TX_EVENT_FLAGS_GROUP group_1;
+static TX_EVENT_FLAGS_GROUP group_2;
+
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+UINT _tx_event_flags_performance_info_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG *sets, ULONG *gets,
+ ULONG *suspensions, ULONG *timeouts);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_information_application_define(void *first_unused_memory)
+#endif
+{
+
+INT 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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Information Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0 and 1. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Information Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_event_flags_create(&group_1, "group 1");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Information Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Information Test................................. ERROR #4\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Information Test................................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+CHAR *name;
+ULONG current_flags;
+TX_THREAD *first_suspended;
+ULONG suspended_count;
+TX_EVENT_FLAGS_GROUP *next_group;
+ULONG sets;
+ULONG gets;
+ULONG suspensions;
+ULONG timeouts;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Information Test................................. ");
+
+ /* Event flags should be created now. */
+
+ /* Attempt to get events from an empty event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. OR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. AND CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Set the necessary events. */
+ status = tx_event_flags_set(&group_0, 0x80008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Just for fun, clear bit 15. */
+ status = tx_event_flags_set(&group_0, 0x80000000, TX_AND);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Set bit 15 again. */
+ status = tx_event_flags_set(&group_0, 0x00008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Now attemp to retrieve events... */
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. OR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. AND CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Put event flags back in the group. */
+
+ /* Set the necessary events. */
+ status = tx_event_flags_set(&group_0, 0x80008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x00008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Get information with a NULL pointer. */
+ status = tx_event_flags_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Get information from a non-created group. */
+ group_2.tx_event_flags_group_id = 0;
+ status = tx_event_flags_info_get(&group_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Get information about the event flag group. */
+ status = tx_event_flags_info_get(&group_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_event_flags_info_get(&group_0, &name, &current_flags, &first_suspended, &suspended_count, &next_group);
+
+ /* Check the status. */
+ if ((status != TX_SUCCESS) || (current_flags != group_0.tx_event_flags_group_current) || (first_suspended != TX_NULL) || (suspended_count != 0) || (next_group != &group_1))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
+
+ /* Get performance information with NULL pointer. */
+ status = _tx_event_flags_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check the status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(&group_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_event_flags_performance_info_get(&group_0, &sets, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if ((status != TX_SUCCESS) || (sets != group_0.tx_event_flags_group_performance_set_count) || (gets != group_0.tx_event_flags_group__performance_get_count) ||
+ (suspensions != group_0.tx_event_flags_group___performance_suspension_count) || (timeouts != group_0.tx_event_flags_group____performance_timeout_count))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information on all event flags groups. */
+ status = tx_event_flags_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_event_flags_performance_system_info_get(&sets, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if ((status != TX_SUCCESS) || (sets != _tx_event_flags_performance_set_count) || (gets != _tx_event_flags_performance_get_count) ||
+ (suspensions != _tx_event_flags_performance_suspension_count) || (timeouts != _tx_event_flags_performance_timeout_count))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(&group_0, &sets, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(TX_NULL, &sets, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(TX_NULL, TX_NULL, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information on all event flags groups. */
+ status = tx_event_flags_performance_system_info_get(&sets, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information on all event flags groups. */
+ status = tx_event_flags_performance_system_info_get(TX_NULL, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information on all event flags groups. */
+ status = tx_event_flags_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information on all event flags groups. */
+ status = tx_event_flags_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information on all event flags groups. */
+ status = tx_event_flags_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Delete both event flag groups. */
+ status = tx_event_flags_delete(&group_0);
+
+ /* Check the status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ status = tx_event_flags_delete(&group_1);
+
+ /* Check the status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
diff --git a/test/smp/regression/threadx_event_flag_isr_set_clear_test.c b/test/smp/regression/threadx_event_flag_isr_set_clear_test.c
new file mode 100644
index 00000000..394bd601
--- /dev/null
+++ b/test/smp/regression/threadx_event_flag_isr_set_clear_test.c
@@ -0,0 +1,358 @@
+/* This test is designed to test for simultaneous thread event flag set AND ISR event flag set and clear. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_timer.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+static unsigned long event_flags_set_counter = 0;
+static unsigned long condition_count = 0;
+
+static TX_EVENT_FLAGS_GROUP event_flags_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void timer_0_entry(ULONG timer_input);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+static void test_isr(void)
+{
+
+UINT status;
+ULONG actual;
+static volatile UINT miss_count = 0;
+
+
+ /* Determine if the interrupt occurred when the preempt disable flag was set. */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* Yes this is the condition we are looking for, increment the test condition counter. */
+ condition_count++;
+ }
+
+ /*
+ It is possible for this test to get into a resonance condition in which
+ the ISR never occurs while preemption is disabled (especially if the
+ ISR is installed in the periodic timer interrupt handler, which is
+ conveniently available). Detect this condition and break out of it by
+ perturbing the duration of this ISR a pseudo-random amount of time.
+ */
+ else if (++miss_count > 100)
+ {
+ for (miss_count = _tx_timer_system_clock % 100; miss_count != 0; --miss_count);
+ }
+
+ if (((event_flags_0.tx_event_flags_group_current & 0x3) == 0) &&
+ (event_flags_0.tx_event_flags_group_suspended_count == 2))
+ {
+
+ /* Put the event_flags to wakeup thread 0. */
+ status = tx_event_flags_set(&event_flags_0, 0x3, TX_OR);
+
+ /* Clear the same flags immediately. */
+ status += tx_event_flags_set(&event_flags_0, 0xFFFFFFFC, TX_AND);
+
+ /* Setup some event flags just so we can clear them. */
+ status += tx_event_flags_set(&event_flags_0, 0x30000, TX_OR);
+
+ /* Clear the same flags immediately. */
+ status += tx_event_flags_set(&event_flags_0, 0xFFFEFFFF, TX_AND);
+
+ /* Clear the same flags immediately. */
+ status += tx_event_flags_set(&event_flags_0, 0xFFFDFFFC, TX_AND);
+
+ /* Check for an error. */
+ if (status)
+ return;
+
+ /* Get the events from an ISR. */
+ status = tx_event_flags_get(&event_flags_0, 0x30000, TX_OR, &actual, TX_NO_WAIT);
+
+ /* Check to make sure this results in an error. */
+ if (status != TX_NO_EVENTS)
+ return;
+
+ /* Do a set and a get consume from an ISR. */
+ status = tx_event_flags_set(&event_flags_0, 0x000000C0, TX_OR);
+
+ status += tx_event_flags_get(&event_flags_0, 0x00000080, TX_OR, &actual, TX_NO_WAIT);
+
+ status += tx_event_flags_get(&event_flags_0, 0x000000C0, TX_OR_CLEAR, &actual, TX_NO_WAIT);
+
+ /* Increment the event_flags counter. */
+ if ((status == TX_SUCCESS) && (actual == 0xC4))
+ {
+ event_flags_set_counter++;
+ }
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_isr_set_clear_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_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flags group. */
+ status = tx_event_flags_create(&event_flags_0, "event_flags 0");
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create a timer to ensure a context save is called for every interrupt. */
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&event_flags_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #6\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ");
+
+ /* Setup the test ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Loop to exploit the probability window inside tx_event_flags_set call. */
+ while (condition_count < 40)
+ {
+
+ /* Suspend on the event_flags that is going to be set via the ISR. */
+ status = tx_event_flags_get(&event_flags_0, 2, TX_OR_CLEAR, &actual, 4);
+
+ /* Determine if we have an unexpected result. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Test error! */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Check for the preempt disable flag being set. */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* Test error! */
+ printf("ERROR #9\n");
+ test_control_return(2);
+ }
+
+ /* Determine if we really got the event_flags. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment the thread count. */
+ thread_0_counter++;
+ }
+ }
+
+ /* Setup the test ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Let the other threads run once more... */
+ tx_thread_relinquish();
+
+ /* At this point, check to see if we got all the event_flagss! */
+ if ((thread_0_counter != event_flags_set_counter) ||
+ (thread_1_counter != event_flags_set_counter))
+ {
+
+ /* Test error! */
+ printf("ERROR #10\n");
+ test_control_return(3);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual;
+
+
+ /* Loop to exploit the probability window inside tx_event_flags_set call. */
+ while (1)
+ {
+
+ /* Suspend on the event_flags that is going to be set via the ISR. */
+ status = tx_event_flags_get(&event_flags_0, 1, TX_OR_CLEAR, &actual, 4);
+
+ /* Determine if we have an unexpected result. */
+ if (status != TX_SUCCESS)
+ {
+
+ break;
+ }
+
+ /* Increment this thread's counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Set event flags - not the one needed by threads 0 and 1. */
+ tx_event_flags_set(&event_flags_0, 0x4, TX_OR);
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Let thread 0 run again! */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void timer_0_entry(ULONG input)
+{
+ timer_0_counter++;
+}
+
+
diff --git a/test/smp/regression/threadx_event_flag_isr_wait_abort_test.c b/test/smp/regression/threadx_event_flag_isr_wait_abort_test.c
new file mode 100644
index 00000000..1382ea29
--- /dev/null
+++ b/test/smp/regression/threadx_event_flag_isr_wait_abort_test.c
@@ -0,0 +1,330 @@
+/* This test is designed to test for wait abort from an ISR. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_timer.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+static unsigned long event_flags_wait_abort_counter = 0;
+static unsigned long condition_count = 0;
+
+static TX_EVENT_FLAGS_GROUP event_flags_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void timer_0_entry(ULONG timer_input);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+static void test_isr(void)
+{
+
+UINT status;
+static volatile UINT miss_count = 0;
+
+
+ /* Determine if the interrupt occurred when the preempt disable flag was set. */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* Yes this is the condition we are looking for, increment the test condition counter. */
+ condition_count++;
+ }
+
+ /*
+ It is possible for this test to get into a resonance condition in which
+ the ISR never occurs while preemption is disabled (especially if the
+ ISR is installed in the periodic timer interrupt handler, which is
+ conveniently available). Detect this condition and break out of it by
+ perturbing the duration of this ISR a pseudo-random amount of time.
+ */
+ else if (++miss_count > 100)
+ {
+ for (miss_count = _tx_timer_system_clock % 100; miss_count != 0; --miss_count);
+ }
+
+ if (((event_flags_0.tx_event_flags_group_current & 0x3) == 0) &&
+ (event_flags_0.tx_event_flags_group_suspended_count == 2))
+ {
+
+ /* Set event flags - not the one needed by threads 0 and 1. */
+ status = tx_event_flags_set(&event_flags_0, 0x4, TX_OR);
+
+ /* Abort the threads 1 and 2. */
+ status += tx_thread_wait_abort(&thread_0);
+ status += tx_thread_wait_abort(&thread_1);
+
+ if (status == TX_SUCCESS)
+ {
+
+ event_flags_wait_abort_counter++;
+ }
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_isr_wait_abort_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flags group. */
+ status = tx_event_flags_create(&event_flags_0, "event_flags 0");
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create a timer to ensure a context save is called for every interrupt. */
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&event_flags_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #6\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Wait Abort from ISR Test......................... ");
+
+ /* Setup the test ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Loop to exploit the probability window inside tx_event_flags_set call. */
+ while (condition_count < 40)
+ {
+
+ /* Suspend on the event_flags that is going to be set via the ISR. */
+ status = tx_event_flags_get(&event_flags_0, 2, TX_OR_CLEAR, &actual, 4);
+
+ /* Determine if we have an unexpected result. */
+ if (status != TX_WAIT_ABORTED)
+ {
+
+ /* Test error! */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Check for the preempt disable flag being set. */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* Test error! */
+ printf("ERROR #9\n");
+ test_control_return(2);
+ }
+
+ /* Determine if we really got the event_flags. */
+ if (status == TX_WAIT_ABORTED)
+ {
+
+ /* Increment the thread count. */
+ thread_0_counter++;
+ }
+ }
+
+ /* Setup the test ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Let the other threads run once more... */
+ tx_thread_relinquish();
+
+ /* At this point, check to see if we got all the event_flagss! */
+ if ((thread_0_counter != event_flags_wait_abort_counter) ||
+ (thread_1_counter != event_flags_wait_abort_counter))
+ {
+
+ /* Test error! */
+ printf("ERROR #10\n");
+ test_control_return(3);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual;
+
+
+ /* Loop to exploit the probability window inside tx_event_flags_set call. */
+ while (1)
+ {
+
+ /* Suspend on the event_flags that is going to be set via the ISR. */
+ status = tx_event_flags_get(&event_flags_0, 1, TX_OR_CLEAR, &actual, 4);
+
+ /* Determine if we have an unexpected result. */
+ if (status != TX_WAIT_ABORTED)
+ {
+
+ break;
+ }
+
+ /* Increment this thread's counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Set event flags - not the one needed by threads 0 and 1. */
+ tx_event_flags_set(&event_flags_0, 0x4, TX_OR);
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Let thread 0 run again! */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void timer_0_entry(ULONG input)
+{
+ timer_0_counter++;
+}
diff --git a/test/smp/regression/threadx_event_flag_single_thread_terminate_test.c b/test/smp/regression/threadx_event_flag_single_thread_terminate_test.c
new file mode 100644
index 00000000..a5db6e41
--- /dev/null
+++ b/test/smp/regression/threadx_event_flag_single_thread_terminate_test.c
@@ -0,0 +1,331 @@
+/* This test is designed to test event flag suspension with a single suspended thread
+ being terminated at the same priority level. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+extern UINT _tx_thread_preempt_disable;
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_single_thread_terminate_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Single Thread Terminate Test..................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Single Thread Terminate Test..................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Single Thread Terminate Test..................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Single Thread Terminate Test..................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Single Thread Terminate Test..................... ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Single Thread Terminate Test..................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Single Thread Terminate Test..................... ");
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Sleep to allow lower-priority thread 1 to run. */
+ tx_thread_sleep(5);
+
+ /* Resume Thread 2. */
+ status = tx_thread_resume(&thread_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Now terminate thread 1. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Now sleep to allow Thread 2 to run. */
+ tx_thread_sleep(5);
+
+ /* Set only one of the event flags needed. */
+ status = tx_event_flags_set(&group_0, 0x00080000, TX_OR);
+
+ /* Now sleep to allow thread 2 to run. */
+ tx_thread_sleep(5);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) && (thread_2_counter != 1))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Set the other event flag needed. */
+ status = tx_event_flags_set(&group_0, 0x00800000, TX_OR);
+
+ /* Now sleep to allow thread 2 to run. */
+ tx_thread_sleep(5);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) && (thread_2_counter != 2))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* At this point, thread 2 is suspended on the flags again. Or some flags that are
+ not needed. */
+
+ /* Set an event flag that is not needed. */
+ status = tx_event_flags_set(&group_0, 0x00000001, TX_OR);
+
+ /* Now sleep to allow thread 2 to run. */
+ tx_thread_sleep(5);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) && (thread_2_counter != 2))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Set an event flag that is needed. */
+ status = tx_event_flags_set(&group_0, 0x00080001, TX_OR);
+
+ /* Now sleep to allow thread 2 to run. */
+ tx_thread_sleep(5);
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 3) ||
+ (_tx_thread_preempt_disable))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Terminate thread 2. */
+ status = tx_thread_terminate(&thread_2);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_2_counter != 3))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Self suspend thread. */
+ status = tx_thread_suspend(&thread_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+ thread_1_counter = 0; /* Make an error! */
+ return;
+ }
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x000880000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. OR option. */
+ status = tx_event_flags_get(&group_0, 0x000880000, TX_OR_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x000880000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ return;
+ }
+}
+
diff --git a/test/smp/regression/threadx_event_flag_suspension_consume_test.c b/test/smp/regression/threadx_event_flag_suspension_consume_test.c
new file mode 100644
index 00000000..b83a8123
--- /dev/null
+++ b/test/smp/regression/threadx_event_flag_suspension_consume_test.c
@@ -0,0 +1,281 @@
+/* This test is designed to test event flag suspension and resumption of two threads
+ waiting on the same event flag set with the consumption. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_suspension_consume_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #6\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG event_flag = 1;
+int i;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Suspension/Consumption Test...................... ");
+
+ /* Set all event flags. */
+ for (i = 0; i < 32; i++)
+ {
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Set event flag. */
+ status = tx_event_flags_set(&group_0, event_flag, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Check the thread counters... */
+ if ((i < 31) && ((thread_1_counter != 1) || (thread_2_counter != 1) || (thread_3_counter != 1)))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+ if ((i == 31) && ((thread_1_counter != 2) || (thread_2_counter != 2) || (thread_3_counter != 2)))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Shift event flag up one bit. */
+ event_flag = event_flag << 1;
+
+ /* Check for 0. */
+ if (event_flag == 0)
+ event_flag = 1;
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
+ return;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
+ return;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_3_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
+ return;
+ }
+}
+
diff --git a/test/smp/regression/threadx_event_flag_suspension_different_bits_consume_test.c b/test/smp/regression/threadx_event_flag_suspension_different_bits_consume_test.c
new file mode 100644
index 00000000..fa4a985a
--- /dev/null
+++ b/test/smp/regression/threadx_event_flag_suspension_different_bits_consume_test.c
@@ -0,0 +1,224 @@
+/* This test is designed to test event flag suspension and resumption of two threads
+ waiting on different event flags with consumption. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_suspension_different_bits_consume_application_define(void *first_unused_memory)
+#endif
+{
+
+INT 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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #2\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ");
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Set event flag. */
+ status = tx_event_flags_set(&group_0, 0x80000000, TX_OR);
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2) ||
+ (thread_2_counter != 1))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Set event flag. */
+ status = tx_event_flags_set(&group_0, 0x00008000, TX_OR);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80000000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL))
+ return;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x00008000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x00008000UL))
+ return;
+ }
+}
+
diff --git a/test/smp/regression/threadx_event_flag_suspension_different_bits_test.c b/test/smp/regression/threadx_event_flag_suspension_different_bits_test.c
new file mode 100644
index 00000000..92505744
--- /dev/null
+++ b/test/smp/regression/threadx_event_flag_suspension_different_bits_test.c
@@ -0,0 +1,230 @@
+/* This test is designed to test event flag suspension and resumption of two threads
+ waiting on different event flags. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_suspension_different_bits_application_define(void *first_unused_memory)
+#endif
+{
+
+INT 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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Suspension Unique Bit Test....................... ");
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Set event flag. */
+ status = tx_event_flags_set(&group_0, 0x80000000, TX_OR);
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2) ||
+ (thread_2_counter != 1))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Set event flag. */
+ status = tx_event_flags_set(&group_0, 0x00008000, TX_OR);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80000000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL))
+ return;
+
+ /* Clear the event flags. */
+ tx_event_flags_set(&group_0, 0x7FFFFFFF, TX_AND);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x00008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x00008000UL))
+ return;
+
+ /* Clear the event flags. */
+ tx_event_flags_set(&group_0, 0xFFFF7FFF, TX_AND);
+ }
+}
+
diff --git a/test/smp/regression/threadx_event_flag_suspension_test.c b/test/smp/regression/threadx_event_flag_suspension_test.c
new file mode 100644
index 00000000..3587fadd
--- /dev/null
+++ b/test/smp/regression/threadx_event_flag_suspension_test.c
@@ -0,0 +1,349 @@
+/* This test is designed to test event flag suspension and resumption of three threads
+ waiting on the same event flag set. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_suspension_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #7\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #8\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG event_flag = 1;
+int i;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Suspension Same Bit Test......................... ");
+
+ /* Set all event flags. */
+ for (i = 0; i < 32; i++)
+ {
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Set event flag. */
+ status = tx_event_flags_set(&group_0, event_flag, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Check the thread counters... */
+ if ((i < 31) && ((thread_1_counter != 1) || (thread_2_counter != 1) || (thread_3_counter != 1)))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+ if ((i == 31) && ((thread_1_counter != 2) || (thread_2_counter != 2) || (thread_3_counter != 2)))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Shift event flag up one bit. */
+ event_flag = event_flag << 1;
+
+ /* Check for 0. */
+ if (event_flag == 0)
+ event_flag = 1;
+ }
+
+ /* Set the event flags to 0. */
+ status = tx_event_flags_set(&group_0, 0x0, TX_AND);
+
+ /* Resume thread 4 so it can suspend on the event flag group too. */
+ status += tx_thread_resume(&thread_4);
+
+ /* Determine if there was an error. */
+ if ((status != TX_SUCCESS) || (thread_4_counter != 1))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Now set the event flag that only thread 4 is waiting on to ensure that we are not satisfying the first thread on the list. */
+ status = tx_event_flags_set(&group_0, 0x1, TX_OR);
+
+ /* Determine if there was an error. */
+ if ((status != TX_SUCCESS) || (thread_4_counter != 2))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
+ return;
+
+ /* Clear the event flags. */
+ tx_event_flags_set(&group_0, 0, TX_AND);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
+ return;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_3_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
+ return;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_4_counter++;
+
+ /* Attempt to get events from event flag group. OR option. */
+ status = tx_event_flags_get(&group_0, 0x00000001, TX_OR_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x1UL))
+ return;
+ }
+}
diff --git a/test/smp/regression/threadx_event_flag_suspension_timeout_test.c b/test/smp/regression/threadx_event_flag_suspension_timeout_test.c
new file mode 100644
index 00000000..2fed61c0
--- /dev/null
+++ b/test/smp/regression/threadx_event_flag_suspension_timeout_test.c
@@ -0,0 +1,266 @@
+/* This test is designed to test event flag suspension timeout processing. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_suspension_timeout_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Timeout Test.......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Timeout Test.......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Timeout Test.......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Timeout Test.......................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Timeout Test.......................... ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Suspension Timeout Test.......................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ULONG actual_events;
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Suspension Timeout Test.......................... ");
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Set event flag 0. */
+ tx_event_flags_set(&group_0, 0x00000001, TX_OR);
+
+ /* Resume thread 3. */
+ tx_thread_resume(&thread_3);
+ tx_thread_sleep(1); /* Thread 3 should now be suspended on group 0. */
+ tx_event_flags_set(&group_0, 0x00000002, TX_OR);
+
+ /* Start everything on a new timer. */
+ tx_thread_sleep(2);
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_sleep(1);
+ status = tx_event_flags_get(&group_0, 0x00000001, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check the status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #6a\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for 63 ticks. */
+ tx_thread_sleep(63);
+
+ /* Check the run counters. */
+ if ((thread_1_counter != 33) || (thread_2_counter != 13))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80000000, TX_AND_CLEAR, &actual_events, 2);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ return;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x00008000, TX_AND_CLEAR, &actual_events, 5);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ return;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_3_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x00000002, TX_AND, &actual_events, 5);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ return;
+ }
+}
diff --git a/test/smp/regression/threadx_event_flag_thread_terminate_test.c b/test/smp/regression/threadx_event_flag_thread_terminate_test.c
new file mode 100644
index 00000000..eecb76e6
--- /dev/null
+++ b/test/smp/regression/threadx_event_flag_thread_terminate_test.c
@@ -0,0 +1,234 @@
+/* This test is designed to test event flag suspension with the suspended threads
+ being terminated. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_thread_terminate_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Thread Terminate Test............................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Thread Terminate Test............................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Thread Terminate Test............................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Thread Terminate Test............................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Thread Terminate Test............................ ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Thread Terminate Test............................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Thread Terminate Test............................ ");
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Terminate thread 2. */
+ status = tx_thread_terminate(&thread_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Terminate thread 1. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Set event flags to make sure no threads are suspended. */
+ status = tx_event_flags_set(&group_0, 0xFFFFFFFF, TX_OR);
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80000000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ return;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x00008000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ return;
+ }
+}
+
diff --git a/test/smp/regression/threadx_initialize_kernel_setup_test.c b/test/smp/regression/threadx_initialize_kernel_setup_test.c
new file mode 100644
index 00000000..fbdee6fe
--- /dev/null
+++ b/test/smp/regression/threadx_initialize_kernel_setup_test.c
@@ -0,0 +1,83 @@
+/* This test is designed to test kernel setup functionality in ThreadX. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_initialize.h"
+#include "tx_thread.h"
+
+
+TEST_FLAG test_forced_mutex_timeout;
+TEST_FLAG threadx_mutex_suspension_put_test;
+TEST_FLAG threadx_mutex_suspension_priority_test;
+TEST_FLAG threadx_byte_allocate_loop_test;
+TEST_FLAG test_initialize_flag;
+TEST_FLAG threadx_byte_release_loop_test;
+TEST_FLAG test_stack_analyze_flag;
+
+
+/* Define the test control global variables. */
+
+ULONG test_control_return_status;
+ULONG test_control_successful_tests;
+ULONG test_control_failed_tests;
+ULONG test_control_system_errors;
+
+UINT test_mutex_from_init;
+UINT test_semaphore_from_init;
+UINT test_queue_from_init;
+UINT test_event_flags_from_init;
+UINT test_byte_pool_create_init;
+UINT test_block_pool_create_init;
+UINT test_timer_create_init;
+UINT mutex_priority_change_extension_selection;
+UINT priority_change_extension_selection;
+
+
+__attribute__((weak)) void abort_all_threads_suspended_on_mutex(void)
+{
+}
+
+__attribute__((weak)) void suspend_lowest_priority(void)
+{
+}
+
+__attribute__((weak)) void abort_and_resume_byte_allocating_thread(void)
+{
+}
+
+void main()
+{
+
+ /* Setup the ThreadX kernel. */
+ _tx_initialize_kernel_setup();
+
+ if (_tx_thread_system_state == TX_INITIALIZE_ALMOST_DONE)
+ {
+ printf("Running Initialize Kernel Setup Test................................ SUCCESS!\n");
+ exit(0);
+ }
+ else
+ {
+ printf("Running Initialize Kernel Setup Test................................ ERROR!\n");
+ exit(1);
+ }
+}
+
+void test_application_define(void *first_unused_memory){}
+void tx_application_define(void *first_unused_memory){}
+
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+
+/* Define the deletion of the system timer thread. */
+
+extern TX_THREAD _tx_timer_thread;
+TEST_FLAG threadx_delete_timer_thread;
+void delete_timer_thread(void)
+{
+
+ _tx_thread_terminate(&_tx_timer_thread);
+ _tx_thread_delete(&_tx_timer_thread);
+}
+
+#endif \ No newline at end of file
diff --git a/test/smp/regression/threadx_interrupt_control_test.c b/test/smp/regression/threadx_interrupt_control_test.c
new file mode 100644
index 00000000..d58ceba3
--- /dev/null
+++ b/test/smp/regression/threadx_interrupt_control_test.c
@@ -0,0 +1,94 @@
+/* This test is designed to test the interrupt control service call avaialbe to the
+ application. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+
+/* 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_interrupt_control_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Interrupt Control Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT saved_interrupt_posture;
+
+
+ /* Inform user. */
+ printf("Running Interrupt Control Test...................................... ");
+
+ /* Lockout interrupts. */
+ saved_interrupt_posture = tx_interrupt_control(TX_INT_DISABLE);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Restore interrupts. */
+ saved_interrupt_posture = tx_interrupt_control(saved_interrupt_posture);
+
+ /* Sleep to make sure interrupts now work. */
+ tx_thread_sleep(2);
+
+ /* Check to make sure the returned interrupt type works. */
+ if (saved_interrupt_posture != TX_INT_DISABLE)
+ {
+
+ /* Interrupt control error. */
+ printf("ERROR #2\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
diff --git a/test/smp/regression/threadx_mutex_basic_test.c b/test/smp/regression/threadx_mutex_basic_test.c
new file mode 100644
index 00000000..2e784961
--- /dev/null
+++ b/test/smp/regression/threadx_mutex_basic_test.c
@@ -0,0 +1,767 @@
+/* This test is designed to test the mutex create/delete and immediate
+ return gets and puts. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_mutex.h"
+
+
+typedef struct MUTEX_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_MUTEX mutex;
+ ULONG next_to_last;
+ ULONG last;
+
+} MUTEX_MEMORY_TEST;
+
+static MUTEX_MEMORY_TEST mutex_memory;
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+static unsigned long thread_0_counter = 0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD thread_4;
+
+static TX_MUTEX mutex_0;
+static TX_MUTEX mutex_1;
+static TX_MUTEX mutex_2;
+static TX_MUTEX mutex_3;
+static TX_MUTEX mutex_4;
+static TX_MUTEX mutex_5;
+static TX_MUTEX mutex_6;
+static TX_MUTEX mutex_7;
+static TX_MUTEX mutex_8;
+
+static TX_TIMER timer_0;
+
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+
+UINT _txe_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit, UINT mutex_control_block_size);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+
+ /* Attempt to create a mutex from a timer. */
+ status = tx_mutex_create(&mutex_4, "mutex 4", TX_NO_INHERIT);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a mutex from a timer. */
+ status = tx_mutex_delete(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to get from mutex from a timer with suspension. */
+ status = tx_mutex_get(&mutex_2, 100);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+
+
+ /* Attempt to create a mutex from an ISR. */
+ status = tx_mutex_create(&mutex_4, "mutex 4", TX_NO_INHERIT);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a mutex from an ISR. */
+ status = tx_mutex_delete(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to get from mutex from an ISR with suspension. */
+ status = tx_mutex_get(&mutex_2, 100);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to get from mutex from an ISR without suspension. */
+ status = tx_mutex_get(&mutex_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to put a mutex from an ISR. */
+ status = tx_mutex_put(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+}
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_mutex_basic_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+
+ status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ status += tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ status += tx_thread_create(&thread_4, "thread 4", thread_4_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Basic Test............................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Basic Test............................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_1, "mutex 1", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Basic Test............................................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Basic Test............................................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Basic Test............................................ ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_8, "mutex 8", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Basic Test............................................ ERROR #5a\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Basic Test............................................ ");
+
+ /* Perform mutex memory test. */
+ mutex_memory.first = 0x11223344;
+ mutex_memory.second = 0x55667788;
+ mutex_memory.next_to_last = 0x99aabbcc;
+ mutex_memory.last = 0xddeeff00;
+
+ /* Create the semaphore. */
+ status = tx_mutex_create(&mutex_memory.mutex, "mutex memory", TX_INHERIT);
+ tx_mutex_delete(&mutex_memory.mutex);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (mutex_memory.first != 0x11223344) ||
+ (mutex_memory.second != 0x55667788) ||
+ (mutex_memory.next_to_last != 0x99aabbcc) ||
+ (mutex_memory.last != 0xddeeff00))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to create a mutex with a NULL pointer. */
+ status = tx_mutex_create(TX_NULL, "mutex 2", TX_INHERIT);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a mutex with a bad size. */
+ status = _txe_mutex_create(&mutex_5, "mutex 5", TX_INHERIT, (sizeof(TX_MUTEX)+1));
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a mutex that has already been created. */
+ status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a mutex with a bad inheritance option. */
+ status = tx_mutex_create(&mutex_4, "mutex 4", 14);
+
+ /* Check status. */
+ if (status != TX_INHERIT_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a mutex with a NULL pointer. */
+ status = tx_mutex_delete(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-created mutex. */
+ mutex_4.tx_mutex_id = 0;
+ status = tx_mutex_delete(&mutex_4);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get a mutex with a NULL pointer. */
+ status = tx_mutex_get(TX_NULL, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get a non-created mutex. */
+ mutex_4.tx_mutex_id = 0;
+ status = tx_mutex_get(&mutex_4, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to put a NULL mutex. */
+ status = tx_mutex_put(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to put a non-created mutex. */
+ mutex_4.tx_mutex_id = 0;
+ status = tx_mutex_put(&mutex_4);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Attempt to get from mutex that is available. Should be successful! */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get the same mutex again. Should be successful! */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Put the mutex. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_ownership_count != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Put the mutex again. Should be successful! */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) != (mutex_0.tx_mutex_owner != TX_NULL))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow other thread to get the mutex. */
+ tx_thread_relinquish();
+
+ /* Attempt to get the mutex. Should be unsuccessful. */
+ status = tx_mutex_get(&mutex_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NOT_AVAILABLE)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish again so that the other thread can release it. */
+ tx_thread_relinquish();
+
+ /* Delete mutex. */
+ status = tx_mutex_delete(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ status = tx_mutex_delete(&mutex_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get a priority inheritance mutex. */
+ status = tx_mutex_get(&mutex_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get another priority inheritance mutex. */
+ status = tx_mutex_get(&mutex_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Wakeup thread 2 to get the ISR to take place on top of the thread. */
+ tx_thread_resume(&thread_2);
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Release mutex multiple times. */
+ status = tx_mutex_put(&mutex_2);
+ status += tx_mutex_put(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_NOT_OWNED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to release a mutex that is not owned. */
+ status = _tx_mutex_put(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_NOT_OWNED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Delete mutex. */
+ status = tx_mutex_delete(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Get mutex 8. */
+ status = tx_mutex_get(&mutex_8, TX_WAIT_FOREVER);
+
+ /* Start thread 3 and 4. */
+ status += tx_thread_resume(&thread_3);
+ status += tx_thread_resume(&thread_4);
+
+ /* Sleep to let thread 3 suspend on the mutex. */
+ tx_thread_sleep(2);
+
+ /* Now, put the mutex to give it to thread 3. */
+ status += tx_mutex_put(&mutex_8);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #29a\n");
+ test_control_return(1);
+ }
+
+ status = tx_mutex_delete(&mutex_3);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Attempt to get from mutex that is available. Should be successful! */
+ status = tx_mutex_get(&mutex_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Let other thread run again. */
+ tx_thread_relinquish();
+
+ /* Release mutex! */
+ status = tx_mutex_put(&mutex_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Create and obtain a couple mutexes so the thread completion can release them. */
+ status = tx_mutex_create(&mutex_6, "mutex 6", TX_NO_INHERIT);
+ status += tx_mutex_create(&mutex_7, "mutex 7", TX_NO_INHERIT);
+ status += tx_mutex_get(&mutex_6, TX_NO_WAIT);
+ status += tx_mutex_get(&mutex_7, TX_NO_WAIT);
+ status += tx_mutex_get(&mutex_6, TX_NO_WAIT);
+ status += tx_mutex_get(&mutex_7, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_mutex_get(&mutex_8, TX_WAIT_FOREVER);
+ tx_mutex_put(&mutex_8);
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_mutex_get(&mutex_8, TX_WAIT_FOREVER);
+ tx_mutex_put(&mutex_8);
+ }
+}
diff --git a/test/smp/regression/threadx_mutex_delete_test.c b/test/smp/regression/threadx_mutex_delete_test.c
new file mode 100644
index 00000000..28676f4b
--- /dev/null
+++ b/test/smp/regression/threadx_mutex_delete_test.c
@@ -0,0 +1,194 @@
+/* This test is designed to test the mutex suspension and mutex delete with
+ suspended threads. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_MUTEX mutex_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_mutex_delete_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 Mutex Delete Test........................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Mutex Delete Test........................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_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 Mutex Delete Test........................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Delete Test........................................... ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Delete Test........................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Grab the mutex so it is owned by this thread. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to let other threads run. */
+ tx_thread_relinquish();
+
+ /* Other threads should now be suspended on the mutex. */
+
+ /* Delete the mutex to test it out! */
+ status = tx_mutex_delete(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow other threads to run again before we return. */
+ tx_thread_relinquish();
+
+ /* Now check the run counter of each thread. */
+ if ((thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_DELETED)
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_DELETED)
+ thread_2_counter++;
+}
diff --git a/test/smp/regression/threadx_mutex_information_test.c b/test/smp/regression/threadx_mutex_information_test.c
new file mode 100644
index 00000000..e95c16c6
--- /dev/null
+++ b/test/smp/regression/threadx_mutex_information_test.c
@@ -0,0 +1,592 @@
+/* This test is designed to test the mutex information services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_mutex.h"
+
+
+static unsigned long thread_0_counter = 0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+
+static TX_MUTEX mutex_0;
+static TX_MUTEX mutex_1;
+static TX_MUTEX mutex_2;
+static TX_MUTEX mutex_3;
+static TX_MUTEX mutex_4;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+UINT _tx_mutex_performance_info_get(TX_MUTEX *mutex_ptr, ULONG *puts, ULONG *gets,
+ ULONG *suspensions, ULONG *timeouts, ULONG *inversions, ULONG *inheritances);
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_mutex_information_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Information Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Information Test...................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_1, "mutex 1", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Information Test...................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Information Test...................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Information Test...................................... ERROR #5\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *name;
+ULONG count;
+TX_THREAD *owner;
+TX_THREAD *first_suspended;
+ULONG suspended_count;
+TX_MUTEX *next_mutex;
+ULONG puts;
+ULONG gets;
+ULONG suspensions;
+ULONG timeouts;
+ULONG inversions;
+ULONG inheritances;
+
+
+ /* Inform user. */
+ printf("Running Mutex Information Test...................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Attempt to get from mutex that is available. Should be successful! */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get the same mutex again. Should be successful! */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Put the mutex. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_ownership_count != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Put the mutex again. Should be successful! */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow other thread to get the mutex. */
+ tx_thread_relinquish();
+
+ /* Attempt to get the mutex. Should be unsuccessful. */
+ status = tx_mutex_get(&mutex_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NOT_AVAILABLE)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish again so that the other thread can release it. */
+ tx_thread_relinquish();
+
+ /* Delete mutex. */
+ status = tx_mutex_delete(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ status = tx_mutex_delete(&mutex_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get a priority inheritance mutex. */
+ status = tx_mutex_get(&mutex_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get another priority inheritance mutex. */
+ status = tx_mutex_get(&mutex_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to get mutex info with a NULL pointer. */
+ status = tx_mutex_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get mutex info from a non-created mutex. */
+ mutex_4.tx_mutex_id = 0;
+ status = tx_mutex_info_get(&mutex_4, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Get mutex information. */
+ status = tx_mutex_info_get(&mutex_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_mutex_info_get(&mutex_2, &name, &count, &owner, &first_suspended, &suspended_count, &next_mutex);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (count != mutex_2.tx_mutex_ownership_count) || (owner != mutex_2.tx_mutex_owner) ||
+ (first_suspended != mutex_2.tx_mutex_suspension_list) || (suspended_count != mutex_2.tx_mutex_suspended_count) || (next_mutex != mutex_2.tx_mutex_created_next))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+#ifdef TX_MUTEX_ENABLE_PERFORMANCE_INFO
+
+ /* Call with NULL pointer. */
+ status = _tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(&mutex_2, &puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (puts != mutex_2.tx_mutex_performance_put_count) || (gets != mutex_2.tx_mutex_performance_get_count) ||
+ (suspensions != mutex_2.tx_mutex_performance_suspension_count) || (timeouts != mutex_2.tx_mutex_performance_timeout_count) ||
+ (inversions != mutex_2.tx_mutex_performance_priority_inversion_count) || (inheritances != mutex_2.tx_mutex_performance__priority_inheritance_count))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(&puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (puts != _tx_mutex_performance_put_count) || (gets != _tx_mutex_performance_get_count) ||
+ (suspensions != _tx_mutex_performance_suspension_count) || (timeouts != _tx_mutex_performance_timeout_count) ||
+ (inversions != _tx_mutex_performance_priority_inversion_count) || (inheritances != _tx_mutex_performance__priority_inheritance_count))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(&mutex_2, &puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, &puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(&puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(TX_NULL, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete mutex. */
+ status = tx_mutex_delete(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+ status = tx_mutex_delete(&mutex_3);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Attempt to get from mutex that is available. Should be successful! */
+ status = tx_mutex_get(&mutex_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+
+ /* Let other thread run again. */
+ tx_thread_relinquish();
+
+ /* Release mutex! */
+ status = tx_mutex_put(&mutex_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #39\n");
+ test_control_return(1);
+ }
+}
diff --git a/test/smp/regression/threadx_mutex_nested_priority_inheritance_test.c b/test/smp/regression/threadx_mutex_nested_priority_inheritance_test.c
new file mode 100644
index 00000000..7397b4e2
--- /dev/null
+++ b/test/smp/regression/threadx_mutex_nested_priority_inheritance_test.c
@@ -0,0 +1,701 @@
+/* This test is designed to test multiple mutex priority inheritance situations. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+#define DEMO_STACK_SIZE TEST_STACK_SIZE_PRINTF
+
+
+/* Define the ThreadX object control blocks... */
+
+static TX_THREAD thread_0;
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD thread_4;
+static TX_THREAD thread_5;
+static TX_THREAD thread_6;
+
+static TX_MUTEX mutex_0;
+static TX_MUTEX mutex_1;
+static TX_MUTEX mutex_2;
+static TX_MUTEX mutex_3;
+
+
+/* Define the counters used in the demo application... */
+
+static ULONG thread_0_counter;
+static ULONG thread_1_counter;
+static ULONG thread_2_counter;
+static ULONG thread_3_counter;
+static ULONG thread_4_counter;
+static ULONG thread_5_counter;
+static ULONG thread_6_counter;
+#endif
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+#endif
+
+/* 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_mutex_nested_priority_inheritance_application_define(void *first_unused_memory)
+#endif
+{
+
+CHAR *pointer;
+UINT status;
+
+
+ pointer = (CHAR *) first_unused_memory;
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
+ pointer, DEMO_STACK_SIZE,
+ 16, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, DEMO_STACK_SIZE,
+ 8, 8, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, DEMO_STACK_SIZE,
+ 4, 4, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, DEMO_STACK_SIZE,
+ 30, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, DEMO_STACK_SIZE,
+ 4, 4, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4a\n");
+ test_control_return(1);
+ }
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, DEMO_STACK_SIZE,
+ 2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4b\n");
+ test_control_return(1);
+ }
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, DEMO_STACK_SIZE,
+ 30, 30, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4c\n");
+ test_control_return(1);
+ }
+
+ /* Create the mutexes. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+ status += tx_mutex_create(&mutex_1, "mutex 1", TX_INHERIT);
+ status += tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
+ status += tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #5\n");
+ test_control_return(1);
+ }
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+#ifdef TX_DISABLE_PREEMPTION_THRESHOLD
+
+ /* Preemption threshold is not enabled, skip this test. */
+
+ /* Inform user. */
+ printf("Running Mutex Nested Priority Inheritance Test...................... SUCCESS!\n");
+ test_control_return(0);
+
+#else
+
+UINT test_case = 0;
+UINT loop_count = 0;
+UINT priority;
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Nested Priority Inheritance Test...................... ");
+
+ /* Get the mutex that will be owned always.... */
+ tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ while(loop_count++ < 50)
+ {
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+ tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
+
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_0);
+
+ /* Resume thread thread 3. */
+ tx_thread_resume(&thread_3);
+
+ /* Thread priority should be 4. */
+ if (thread_0.tx_thread_priority != 4)
+ {
+
+ /* Test error! */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Release the mutexes... Depending on the order they are released should dictate
+ the thread's returned to priority. */
+ if (test_case == 0)
+ {
+
+
+ tx_mutex_put(&mutex_2);
+
+ /* Priority should now be returned to priority 8. */
+ if (thread_0.tx_thread_priority != 8)
+ {
+
+ /* Test error! */
+ printf("ERROR #7\n");
+ test_control_return(2);
+ }
+
+ tx_mutex_put(&mutex_1);
+
+ /* Priority should now be returned to priority 15. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #8\n");
+ test_control_return(3);
+ }
+
+ tx_mutex_put(&mutex_0);
+
+ /* No change. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #9\n");
+ test_control_return(4);
+ }
+ }
+ else if (test_case == 1)
+ {
+
+ priority = thread_0.tx_thread_priority;
+ tx_mutex_put(&mutex_0);
+
+ /* Should have no change in priority since nothing was inherited for this mutex. */
+ if (thread_0.tx_thread_priority != priority)
+ {
+
+ /* Test error! */
+ printf("ERROR #10\n");
+ test_control_return(4);
+ }
+
+ tx_mutex_put(&mutex_1);
+
+ /* Should not do anything since mutex 2 elevated to a higher priority. */
+ if (thread_0.tx_thread_priority != priority)
+ {
+
+ /* Test error! */
+ printf("ERROR #11\n");
+ test_control_return(5);
+ }
+
+ tx_mutex_put(&mutex_2);
+
+ /* Should go back to priority 15. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #12\n");
+ test_control_return(6);
+ }
+ }
+ else if (test_case == 2)
+ {
+
+ tx_mutex_put(&mutex_2);
+
+ /* Should go back to priority 8. */
+ if (thread_0.tx_thread_priority != 8)
+ {
+
+ /* Test error! */
+ printf("ERROR #13\n");
+ test_control_return(7);
+ }
+
+ tx_mutex_put(&mutex_0);
+
+ /* Should not do anything. */
+ if (thread_0.tx_thread_priority != 8)
+ {
+
+ /* Test error! */
+ printf("ERROR #14\n");
+ test_control_return(8);
+ }
+
+ tx_mutex_put(&mutex_1);
+
+ /* Should go back to priority 15. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #15\n");
+ test_control_return(9);
+ }
+ }
+ else if (test_case == 3)
+ {
+
+ priority = thread_0.tx_thread_priority;
+ tx_mutex_put(&mutex_1);
+
+ /* Should not do anything since mutex 2 is still owned. */
+ if (thread_0.tx_thread_priority != priority)
+ {
+
+ /* Test error! */
+ printf("ERROR #16\n");
+ test_control_return(10);
+ }
+
+ tx_mutex_put(&mutex_0);
+
+ /* Should not do anything. */
+ if (thread_0.tx_thread_priority != priority)
+ {
+
+ /* Test error! */
+ printf("ERROR #17\n");
+ test_control_return(11);
+ }
+
+ tx_mutex_put(&mutex_2);
+
+ /* Should finally go back to priority 15. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #18\n");
+ test_control_return(12);
+ }
+ }
+ else if (test_case == 4)
+ {
+
+ priority = thread_0.tx_thread_priority;
+ tx_mutex_put(&mutex_1);
+
+ /* Should not do anything since mutex 2 is still owned. */
+ if (thread_0.tx_thread_priority != priority)
+ {
+
+ /* Test error! */
+ printf("ERROR #19\n");
+ test_control_return(13);
+ }
+
+ tx_mutex_put(&mutex_2);
+
+ /* Should reurn us back to priority 15. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #20\n");
+ test_control_return(14);
+ }
+
+ tx_mutex_put(&mutex_0);
+
+ /* Should not do anything. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #21\n");
+ test_control_return(15);
+ }
+ }
+ else if (test_case == 5)
+ {
+
+ priority = thread_0.tx_thread_priority;
+ tx_mutex_put(&mutex_0);
+
+ /* Should not do anything since mutex 2 is still owned. */
+ if (thread_0.tx_thread_priority != priority)
+ {
+
+ /* Test error! */
+ printf("ERROR #22\n");
+ test_control_return(16);
+ }
+
+ tx_mutex_put(&mutex_2);
+
+ /* Should reurn us back to priority 8. */
+ if (thread_0.tx_thread_priority != 8)
+ {
+
+ /* Test error! */
+ printf("ERROR #23\n");
+ test_control_return(17);
+ }
+
+ tx_mutex_put(&mutex_1);
+
+ /* Should return us back to priority 15. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #24\n");
+ test_control_return(18);
+ }
+ }
+
+ test_case++;
+ if (test_case > 5)
+ test_case = 0;
+ }
+
+ /* Check for thread 3 running... this should not happen! */
+ if (thread_3_counter != 50)
+ {
+
+ printf("ERROR #25\n");
+ test_control_return(19);
+ }
+
+ /* At this point, mutex 3 owned by this thread. */
+
+ /* Resume thread 6, lowest priority thread. */
+ status = tx_thread_resume(&thread_6);
+
+ /* Check for an error. */
+ if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 15) || (thread_6_counter != 0))
+ {
+
+ printf("ERROR #27\n");
+ test_control_return(19);
+ }
+
+ /* Now resume thread 4. */
+ status = tx_thread_resume(&thread_4);
+
+ /* Check for an error. */
+ if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 4) || (thread_6_counter != 0))
+ {
+
+ printf("ERROR #28\n");
+ test_control_return(19);
+ }
+
+ /* Now resume thread 5. */
+ status = tx_thread_resume(&thread_5);
+
+ /* Check for an error. */
+ if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 2) || (thread_6_counter != 0))
+ {
+
+ printf("ERROR #29\n");
+ test_control_return(19);
+ }
+
+ /* Sleep to let thread 6 run, which is lower priority. */
+ tx_thread_sleep(1);
+
+ /* Now release the mutex. */
+ status = tx_mutex_put(&mutex_3);
+
+ /* Check for an error. */
+ if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 15) || (thread_6_counter != 0) || (thread_4_counter != 1) || (thread_5_counter != 1))
+ {
+
+ printf("ERROR #30\n");
+ test_control_return(19);
+ }
+
+ /* Sleep to let thread 6 run and release the mutex. */
+ tx_thread_sleep(2);
+
+
+ /* If we get here the test was successful! */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+#endif
+}
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT old_priority;
+UINT old_threshold;
+
+
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Update the thread priority and thread preemption-threshold of thread 0. */
+ tx_thread_priority_change(&thread_0, 15, &old_priority);
+ tx_thread_preemption_change(&thread_0, 14, &old_threshold);
+
+ /* Get mutex. */
+ tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ tx_mutex_put(&mutex_1);
+
+ tx_thread_suspend(&thread_1);
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Update the thread priority and thread preemption-threshold of thread 0. */
+ tx_thread_priority_change(&thread_0, 15, &old_priority);
+ tx_thread_preemption_change(&thread_0, 8, &old_threshold);
+
+ /* Get mutex. */
+ tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ tx_mutex_put(&mutex_1);
+
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT old_priority;
+UINT old_threshold;
+
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Update the thread priority and thread preemption-threshold of thread 0. */
+ tx_thread_priority_change(&thread_0, 15, &old_priority);
+ tx_thread_preemption_change(&thread_0, 14, &old_threshold);
+
+ /* Get mutex. */
+ tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
+ tx_mutex_put(&mutex_2);
+
+ tx_thread_suspend(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Update the thread priority and thread preemption-threshold of thread 0. */
+ tx_thread_priority_change(&thread_0, 15, &old_priority);
+ tx_thread_preemption_change(&thread_0, 8, &old_threshold);
+
+ /* Get mutex. */
+ tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
+ tx_mutex_put(&mutex_2);
+
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+
+ while(1)
+ {
+
+ /* Resume thread 0. */
+ tx_thread_resume(&thread_0);
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_3);
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+
+ while(1)
+ {
+
+ /* Get priority inherit mutex. */
+ tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+
+ /* Release the priority inherit mutex. */
+ tx_mutex_put(&mutex_3);
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_4);
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+
+ while(1)
+ {
+
+ /* Get priority inherit mutex. */
+ tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+
+ /* Release the priority inherit mutex. */
+ tx_mutex_put(&mutex_3);
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_5);
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+
+ while(1)
+ {
+
+ /* Get priority inherit mutex. */
+ tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+
+ /* Release the priority inherit mutex. */
+ tx_mutex_put(&mutex_3);
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_6);
+ }
+}
+#endif
+
+
diff --git a/test/smp/regression/threadx_mutex_no_preemption_test.c b/test/smp/regression/threadx_mutex_no_preemption_test.c
new file mode 100644
index 00000000..c26c3651
--- /dev/null
+++ b/test/smp/regression/threadx_mutex_no_preemption_test.c
@@ -0,0 +1,173 @@
+/* This test is designed to test the mutex suspension and another thread resuming the
+ same priority thread by doing a mutex put. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+
+static TX_MUTEX mutex_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_mutext_no_preemption_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 Mutex Put with No Preemption Test........................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Mutex Put with No Preemption Test........................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Put with No Preemption Test........................... ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Put with No Preemption Test........................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Get the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Should be successful. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to make the other thread suspend on the mutex. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Put the mutex, this should resume the other thread
+ but not preempt this thread. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow the other thread to run. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 2)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+}
+
diff --git a/test/smp/regression/threadx_mutex_preemption_test.c b/test/smp/regression/threadx_mutex_preemption_test.c
new file mode 100644
index 00000000..238dda03
--- /dev/null
+++ b/test/smp/regression/threadx_mutex_preemption_test.c
@@ -0,0 +1,161 @@
+/* This test is designed to test the mutex suspension and another thread resuming the
+ higher priority thread by doing a mutex put. Higher-priority thread should preempt. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+
+static TX_MUTEX mutex_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_mutex_preemption_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 Mutex Put with Preemption Test.............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Put with Preemption Test.............................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Put with Preemption Test.............................. ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Put with Preemption Test.............................. ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Get the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Should be successful. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Now resume the higher priority thread to cause suspension. */
+ tx_thread_resume(&thread_1);
+
+ /* The other thread should now be suspended on the mutex. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Release the mutex, this should cause the other thread
+ to preempt. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status and run counter of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+}
+
diff --git a/test/smp/regression/threadx_mutex_priority_inheritance_test.c b/test/smp/regression/threadx_mutex_priority_inheritance_test.c
new file mode 100644
index 00000000..7a82206f
--- /dev/null
+++ b/test/smp/regression/threadx_mutex_priority_inheritance_test.c
@@ -0,0 +1,607 @@
+/* This test is designed to test the mutex suspension and priority inheritance with another
+ thread resuming the higher priority thread by doing a mutex put. Higher-priority thread should preempt. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static unsigned long thread_7_counter = 0;
+static TX_THREAD thread_7;
+
+static TX_MUTEX mutex_0;
+static TX_MUTEX mutex_1;
+static TX_MUTEX mutex_2;
+static TX_MUTEX mutex_3;
+
+
+extern UINT test_mutex_from_init;
+extern TEST_FLAG test_forced_mutex_timeout;
+
+
+VOID _tx_mutex_priority_change(TX_THREAD *thread_ptr, UINT priority, UINT threshold);
+
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+static void thread_7_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_mutex_priority_inheritance_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;
+
+ /* Test for an error creating/using a mutex from initialization. */
+ if (test_mutex_from_init != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #0\n");
+ test_control_return(1);
+ }
+
+ /* 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 Mutex Priority Inheritance Test............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 14, 14, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a high-priority thread that will get all the priority inheritance mutexes and return from
+ it's entry function in order to test the auto delete feature. */
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 10, 10, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create a higher-priority thread that is used to get thread 4 into a priority inheritance state. */
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 8, 8, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+
+ /* Create a higher-priority thread that is used to suspend on priority inheritance mutex 3. */
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #6\n");
+ test_control_return(1);
+ }
+
+
+ /* Create a higher-priority thread that is used to suspend on priority inheritance mutex 3. */
+ status = tx_thread_create(&thread_7, "thread 7", thread_7_entry, 7,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 7, 7, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_1, "mutex 1", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Drive one path of the internal mutex priority change routine directly for code coverage. */
+ thread_3.tx_thread_user_priority = 1;
+ thread_3.tx_thread_user_preempt_threshold = 1;
+ thread_3.tx_thread_state = 4;
+ _tx_mutex_priority_change(&thread_3, 3, 3);
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Priority Inheritance Test............................. ");
+
+ /* Resume thread 4 to test the automatic release of the mutexes. */
+ tx_thread_resume(&thread_4);
+
+ /* Determine if thread 4 was able to get the mutexes before completion... and
+ have its original priority restored after the priority inheritance. */
+ if ((thread_4_counter != 1) || (thread_5_counter != 1) || (thread_4.tx_thread_priority != 10) ||
+ (thread_4.tx_thread_inherit_priority != TX_MAX_PRIORITIES))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Get all the mutexex. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+ status += tx_mutex_get(&mutex_1, TX_NO_WAIT);
+ status += tx_mutex_get(&mutex_2, TX_NO_WAIT);
+
+ /* Should be successful. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Release mutex 2 to be compatible with original test. */
+ tx_mutex_put(&mutex_2);
+
+ /* Now resume the higher priority thread to cause suspension. */
+ tx_thread_resume(&thread_1);
+
+ /* The other thread should now be suspended on the mutex. */
+ if ((thread_1_counter != 1) || (thread_0.tx_thread_priority != 15))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Release the mutex, this should cause the other thread
+ to preempt. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status and run counter of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2) || (thread_0.tx_thread_priority != 16))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* At this point, get the mutex again. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Should be successful. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Now sleep for 20 ticks in order to test the priority inheritance change of a
+ non-ready thread. */
+ tx_thread_sleep(20);
+
+ /* The other thread should now be suspended on the mutex. */
+ if ((thread_1_counter != 3) || (thread_0.tx_thread_priority != 15))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 2 in order to get two threads suspended on the mutex. */
+ tx_thread_resume(&thread_2);
+
+ /* Now do a mutex put to release both threads suspended on this mutex. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* The other thread should now be suspended on the mutex. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 4) || (thread_2_counter != 2) || (thread_0.tx_thread_priority != 16))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* At this point, get the mutex again. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Should be successful. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Abort the sleep. */
+ tx_thread_wait_abort(&thread_1);
+ tx_thread_wait_abort(&thread_2);
+
+ /* Now both threads are suspended again on mutex... and then terminate them. */
+ tx_thread_terminate(&thread_1);
+ tx_thread_terminate(&thread_2);
+
+ /* Now do a mutex put to release both threads suspended on this mutex. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* The other thread should now be suspended on the mutex. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 3) || (thread_0.tx_thread_priority != 16))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Now test the timeout on the suspension list of a priority inheritance mutex. */
+
+ /* First, obtain priority inheritance mutex 3. */
+ status = tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ /* Next resume threads 6 and 7 so they will block on trying to get this mutex forever. */
+ status += tx_thread_resume(&thread_7);
+ status += tx_thread_resume(&thread_6);
+
+ /* Now set the flag which will cause the last thread in the suspension list to timeout (abort)
+ resulting in a NULL suspension list and covering that branch condition in tx_mutex_put */
+ test_forced_mutex_timeout = 1;
+
+ /* Perform a mutex put to release the mutex. */
+ status += tx_mutex_put(&mutex_3);
+
+ /* Now check for errors. */
+#ifndef TX_MISRA_ENABLE
+#ifndef TX_MANUAL_TEST
+#ifndef TX_NOT_INTERRUPTABLE
+ if ((status != TX_SUCCESS) || (thread_6_counter != 1) || (thread_7_counter != 0))
+#else
+ if ((status != TX_SUCCESS) || (thread_6_counter != 1))
+#endif
+#else
+ if ((status != TX_SUCCESS) || (thread_6_counter != 1))
+#endif
+#else
+ if ((status != TX_SUCCESS) || (thread_6_counter != 1))
+#endif
+ {
+
+ /* Mutex error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while(1)
+ {
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+
+ /* Sleep for 10 ticks... to delay. */
+ tx_thread_sleep(10);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Get mutex to cause additional ownership linked-list processing. */
+ tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
+
+ while(1)
+ {
+
+ /* Increment thread run counter. */
+ thread_2_counter++;
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_2_counter++;
+
+ /* Sleep for 10 ticks... to delay. */
+ tx_thread_sleep(10);
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+UINT old_priority;
+
+
+ /* Get mutex to cause additional ownership linked-list processing. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+ status += tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ status += tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ status += tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ status += tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
+
+ /* Resume thread 5 to get into priority inheritance. */
+ tx_thread_resume(&thread_5);
+
+ /* Determine if all the mutex gets were successful... and we have
+ inherited priority 8. */
+ if ((status == TX_SUCCESS) && (thread_4.tx_thread_priority == 8))
+ {
+
+ /* Yes, increment the thread counter. */
+ thread_4_counter++;
+ }
+
+ /* Now, attempt to manually set this thread's priority to the same priority. */
+ status = tx_thread_priority_change(&thread_4, 8, &old_priority);
+
+ /* Determine if there is an error. */
+ if ((status != TX_SUCCESS) || (thread_4.tx_thread_user_priority != 8) || (old_priority != 10))
+ {
+
+ /* Clear the counter, which will signal an error to the thread above. */
+ thread_4_counter = 0;
+ }
+
+ /* Now attempt to manually set the same thread priority. */
+ status = tx_thread_priority_change(&thread_4, 8, &old_priority);
+
+ /* Determine if there is an error. */
+ if ((status != TX_SUCCESS) || (thread_4.tx_thread_user_priority != 8) || (old_priority != 8))
+ {
+
+ /* Clear the counter, which will signal an error to the thread above. */
+ thread_4_counter = 0;
+ }
+
+ /* Now restore the original user priority of 10. */
+ status = tx_thread_priority_change(&thread_4, 10, &old_priority);
+
+ /* Determine if there is an error. */
+ if ((status != TX_SUCCESS) || (thread_4.tx_thread_user_priority != 10) || (old_priority != 8))
+ {
+
+ /* Clear the counter, which will signal an error to the thread above. */
+ thread_4_counter = 0;
+ }
+
+ /* Now fall through and make sure the mutex cleanup function
+ releases all the mutexes. */
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Get mutex to cause priority inheritance in thread 4. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Determine if all the mutex gets were successful. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Yes, increment the thread counter. */
+ thread_5_counter++;
+ }
+
+ /* Now fall through and make sure the mutex cleanup function
+ releases all the mutexes. */
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Get mutex to cause priority inheritance in thread 0. */
+ status = tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ /* Determine if all the mutex gets were successful. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Yes, increment the thread counter. */
+ thread_6_counter++;
+ }
+
+ /* Now fall through and make sure the mutex cleanup function
+ releases all the mutexes. */
+}
+
+
+static void thread_7_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Get mutex to cause priority inheritance in thread 0. */
+ status = tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ /* Determine if all the mutex gets were successful. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Yes, increment the thread counter. */
+ thread_7_counter++;
+ }
+
+ /* Now fall through and make sure the mutex cleanup function
+ releases all the mutexes. */
+}
+
diff --git a/test/smp/regression/threadx_mutex_proritize_test.c b/test/smp/regression/threadx_mutex_proritize_test.c
new file mode 100644
index 00000000..4e25673f
--- /dev/null
+++ b/test/smp/regression/threadx_mutex_proritize_test.c
@@ -0,0 +1,525 @@
+/* This test is designed to test the mutex suspension prioritization. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+
+static TX_MUTEX mutex_0;
+static TX_MUTEX mutex_1;
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Determine if thread 3 is at the front of the suspension list. */
+ if (mutex_0.tx_mutex_suspension_list == &thread_3)
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+ }
+ else
+ {
+
+ /* Abort the wait of thread 5. */
+ tx_thread_wait_abort(&thread_5);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_mutex_prioritize_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 Mutex Prioritize Test....................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 14, 14, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #8\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Prioritize Test....................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to prioritize a NULL mutex. */
+ status = tx_mutex_prioritize(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to prioritize a non-created mutex. */
+ mutex_1.tx_mutex_id = 0;
+ status = tx_mutex_prioritize(&mutex_1);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Prioritize the mutex with no suspended threads! */
+ status = tx_mutex_prioritize(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Grab the mutex so it is owned by this thread. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Resume other threads run. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Other threads should now be suspended on the mutex. Thread 1 should be
+ in front of thread 2 since it was suspended first. */
+ if (mutex_0.tx_mutex_suspension_list != &thread_1)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the mutex to test it out! */
+ status = tx_mutex_prioritize(&mutex_0);
+
+ /* Check status and make sure thread 2 is now at the front of the list. */
+ if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_2))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the mutex again to make sure nothing has changed! */
+ status = tx_mutex_prioritize(&mutex_0);
+
+ /* Check status and make sure thread 2 is now at the front of the list. */
+ if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_2))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #14a\n");
+ test_control_return(1);
+ }
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_mutex_prioritize(&mutex_0);
+
+ /* Check status and make sure thread 3 is at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_3))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the mutex suspension list. */
+ status = tx_mutex_prioritize(&mutex_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Now determine if thread 4 is at the front of the list... It should be! */
+ if (mutex_0.tx_mutex_suspension_list != &thread_4)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while (1)
+ {
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while (1)
+ {
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_2_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while (1)
+ {
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_3_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_3);
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while (1)
+ {
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_4_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_4);
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while (1)
+ {
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_5_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_5);
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while (1)
+ {
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_6_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_6);
+ }
+}
+
diff --git a/test/smp/regression/threadx_mutex_suspension_timeout_test.c b/test/smp/regression/threadx_mutex_suspension_timeout_test.c
new file mode 100644
index 00000000..8e1b79ea
--- /dev/null
+++ b/test/smp/regression/threadx_mutex_suspension_timeout_test.c
@@ -0,0 +1,474 @@
+/* This test is designed to test the mutex suspension and timeout functionality. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_mutex.h"
+
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD thread_4;
+static TX_THREAD low_priority;
+
+
+static TX_MUTEX mutex_0;
+static TX_MUTEX mutex_1;
+extern UINT mutex_priority_change_extension_selection;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void low_priority_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+extern void test_control_return(UINT status);
+
+
+#ifndef TX_MANUAL_TEST
+
+/* Define test flags for automated test. */
+
+extern TEST_FLAG threadx_mutex_suspension_put_test;
+extern TEST_FLAG threadx_mutex_suspension_priority_test;
+
+#endif
+
+
+/* This test routine is used to get NULL suspension lists in various parts of tx_mutex_put. This is hooked up to IRQ 0 on this simulation and is entered manually at the
+ correct time. */
+void abort_all_threads_suspended_on_mutex(void)
+{
+
+TX_THREAD *thread_ptr;
+
+ thread_ptr = _tx_thread_created_ptr;
+ while (thread_ptr)
+ {
+ if (thread_ptr -> tx_thread_state == TX_MUTEX_SUSP)
+ tx_thread_wait_abort(thread_ptr);
+
+ thread_ptr = thread_ptr -> tx_thread_created_next;
+ if (thread_ptr == _tx_thread_created_ptr)
+ break;
+ }
+}
+
+
+/* This test routine is used to get a thread of a non ready state into _tx_mutex_change, called froim _tx_mutex_put. This is hooked up to IRQ 1 on this simulation and is entered manually at the
+ correct time. */
+void suspend_lowest_priority(void)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+TX_THREAD *thread_ptr;
+
+
+ /* Determine which extension to perform... to get to the different error checks in _tx_mutex_priority_change. */
+ if (mutex_priority_change_extension_selection == 0)
+ {
+
+ /* Setup the thread pointer. */
+ thread_ptr = &thread_0;
+
+ /* Disable interrupts. */
+ TX_DISABLE
+
+ /* Set the state to suspended. */
+ thread_ptr -> tx_thread_state = TX_SUSPENDED;
+
+#ifdef TX_NOT_INTERRUPTABLE
+
+ /* Call actual non-interruptable thread suspension routine. */
+ _tx_thread_system_ni_suspend(thread_ptr, ((ULONG) 0));
+
+ /* Restore interrupts. */
+ TX_RESTORE
+#else
+
+ /* Set the suspending flag. */
+ thread_ptr -> tx_thread_suspending = TX_TRUE;
+
+ /* Setup for no timeout period. */
+ thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks = ((ULONG) 0);
+
+ /* Temporarily disable preemption. */
+ _tx_thread_preempt_disable++;
+
+ /* Restore interrupts. */
+ TX_RESTORE
+
+ /* Call actual thread suspension routine. */
+ _tx_thread_system_suspend(thread_ptr);
+#endif
+ }
+ else if (mutex_priority_change_extension_selection == 1)
+ {
+
+ /* Make the mapped core field to be invalid to exercise the error checking branch for core_index. */
+ thread_0.tx_thread_smp_core_mapped = TX_THREAD_SMP_MAX_CORES;
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_mutex_suspension_timeout_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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 1, 1, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 2, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&low_priority, "low priority", low_priority_entry, 30,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 30, 30, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Suspension Timeout Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create mutexes. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+ status += tx_mutex_create(&mutex_1, "mutex 1", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Suspension Timeout Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Get the mutex to prevent thread from getting it. */
+ tx_mutex_get(&mutex_0, TX_NO_WAIT);
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+TX_THREAD *temp_thread;
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Suspension Timeout Test............................... ");
+
+ /* Sleep for 2 ticks for fresh timer. */
+ tx_thread_sleep(2);
+
+ /* Set clock to 0. */
+ tx_time_set(0);
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, 33);
+
+ /* Did we get the right status at the right time? */
+ if ((status != TX_NOT_AVAILABLE) || (tx_time_get() != 33))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Get the mutex. */
+ status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+
+ /* Make sure the three higher priority threads suspend on the mutex. */
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_1);
+
+
+#ifdef TX_MANUAL_TEST
+
+ /* Set BP hear and step into code and generate appropriate interrupt IRQ 0 by hand right after the prioritize function with interrupts enabled. This is to achieve the empty list branch coverage after the prioritize function. */
+ tx_mutex_put(&mutex_1);
+#else
+
+ /* Set the flag such that generate the condition wehre the empty list condition is satisfied in the branch coverage. */
+ threadx_mutex_suspension_put_test = 1;
+ tx_mutex_put(&mutex_1);
+#endif
+
+ /* Now some hand testing for tx_mutex_priority_change. */
+
+ /* Resume the low priority thread. */
+ tx_thread_resume(&low_priority);
+
+ /* Disable interrupts. */
+ TX_DISABLE
+
+ /* Simulate a call from inside of mutex put, but doing it here makes life easier. */
+ _tx_thread_preempt_disable++;
+
+ /* Move the current thread to a lower priority. */
+ _tx_mutex_priority_change(&thread_0, 15);
+ _tx_mutex_priority_change(&thread_0, 16);
+
+ /* Move the lower priority thread to a higher priority. */
+ _tx_mutex_priority_change(&low_priority, 28);
+ _tx_mutex_priority_change(&low_priority, 29);
+ _tx_mutex_priority_change(&low_priority, 30);
+
+ /* Change the priority of the current thread, such that we should have reverse the preemption-threshold issue. */
+ thread_0.tx_thread_user_priority = 30;
+ thread_0.tx_thread_user_preempt_threshold = 30;
+ _tx_mutex_priority_change(&thread_0, 30);
+
+ /* Change to an even lower priority. */
+ thread_0.tx_thread_user_priority = 31;
+ thread_0.tx_thread_user_preempt_threshold = 31;
+ _tx_mutex_priority_change(&thread_0, 31);
+
+ /* Move back to a higher-priority. */
+ thread_0.tx_thread_user_priority = 30;
+ thread_0.tx_thread_user_preempt_threshold = 30;
+ _tx_mutex_priority_change(&thread_0, 16);
+
+#ifdef TX_MANUAL_TEST
+
+ /* Set BP here and step into code and step through the code until the internal thread resume function returns, then issue an IRQ 1 to cause an ISR to suspend the thread and test the first condition. */
+ _tx_mutex_priority_change(&thread_0, 30);
+#else
+
+ /* Set the flag to suspend the thread and test the first condition after internal resume is called. */
+ mutex_priority_change_extension_selection = 0;
+ threadx_mutex_suspension_priority_test = 1;
+ _tx_mutex_priority_change(&thread_0, 30);
+#endif
+
+ /* Resume this thread. */
+ tx_thread_resume(&thread_0);
+ _tx_mutex_priority_change(&thread_0, 16);
+
+ /* Change to an even lower priority. */
+ thread_0.tx_thread_user_priority = 27;
+ thread_0.tx_thread_user_preempt_threshold = 27;
+ _tx_mutex_priority_change(&thread_0, 28);
+
+ /* Setup the low priority thread infromation. */
+ low_priority.tx_thread_user_priority = 30;
+ low_priority.tx_thread_user_preempt_threshold = 29;
+ _tx_mutex_priority_change(&low_priority, 31);
+
+ /* Change to an even lower priority. */
+ thread_0.tx_thread_user_priority = 30;
+ thread_0.tx_thread_user_preempt_threshold = 29;
+ _tx_mutex_priority_change(&thread_0, 26);
+
+#ifdef TX_MANUAL_TEST
+
+ /* Set BP here and step into code and step through the code until the internal thread resume function returns, and then issue the IRQ that modifies the core mapped. */
+ mutex_priority_change_extension_selection = 1;
+ _tx_mutex_priority_change(&thread_0, 30);
+ thread_0.tx_thread_smp_core_mapped = 0;
+#else
+
+ /* Set the flag to suspend the thread and test the first condition after internal resume is called. */
+ mutex_priority_change_extension_selection = 1;
+ threadx_mutex_suspension_priority_test = 1;
+ _tx_mutex_priority_change(&thread_0, 30);
+ thread_0.tx_thread_smp_core_mapped = 0;
+#endif
+
+ /* Move the thread back to priority 28. */
+ _tx_mutex_priority_change(&thread_0, 28);
+
+#ifdef TX_MANUAL_TEST
+
+ /* Set BP here and step into code and step through the code until the internal thread resume function returns, and then issue the IRQ that modifies the original priority. */
+ mutex_priority_change_extension_selection = 2;
+ _tx_mutex_priority_change(&thread_0, 29);
+#else
+
+ /* Set the flag to suspend the thread and test the first condition after internal resume is called. */
+ mutex_priority_change_extension_selection = 2;
+ threadx_mutex_suspension_priority_test = 1;
+ _tx_mutex_priority_change(&thread_0, 29);
+ _tx_thread_execute_ptr[0] = &thread_0;
+#endif
+
+#ifdef TX_MANUAL_TEST
+
+ /* Set BP here and step into code and step through the code until the internal thread resume function returns, and then issue the IRQ that sets the original_pt_thread to NULL. */
+ mutex_priority_change_extension_selection = 3;
+ _tx_mutex_priority_change(&thread_0, 30);
+#else
+
+ /* Set the flag to suspend the thread and test the first condition after internal resume is called. */
+ mutex_priority_change_extension_selection = 3;
+ threadx_mutex_suspension_priority_test = 1;
+ _tx_mutex_priority_change(&thread_0, 30);
+#endif
+
+#ifdef TX_MANUAL_TEST
+
+ /* Set BP here and step into code and step through the code until the internal thread resume function returns, and then issue the IRQ that sets the _tx_thread_preemption__threshold_scheduled to NULL. */
+ temp_thread = _tx_thread_preemption__threshold_scheduled;
+ mutex_priority_change_extension_selection = 4;
+ _tx_mutex_priority_change(&thread_0, 31);
+ _tx_thread_preemption__threshold_scheduled = temp_thread;
+#else
+
+ /* Set the flag to suspend the thread and test the first condition after internal resume is called. */
+ temp_thread = _tx_thread_preemption__threshold_scheduled;
+ mutex_priority_change_extension_selection = 4;
+ threadx_mutex_suspension_priority_test = 1;
+ _tx_mutex_priority_change(&thread_0, 31);
+ _tx_thread_preemption__threshold_scheduled = temp_thread;
+#endif
+
+ /* Just change to same priority to ensure that path is executed. */
+ mutex_priority_change_extension_selection = 0;
+ suspend_lowest_priority();
+ thread_0.tx_thread_user_priority = 31;
+ thread_0.tx_thread_user_preempt_threshold = 30;
+ thread_0.tx_thread_priority = 31;
+ thread_0.tx_thread_preempt_threshold = 30;
+ _tx_mutex_priority_change(&thread_0, 31);
+ thread_0.tx_thread_user_priority = 31;
+ thread_0.tx_thread_user_preempt_threshold = 31;
+ thread_0.tx_thread_priority = 31;
+ thread_0.tx_thread_preempt_threshold = 31;
+ _tx_mutex_priority_change(&thread_0, 31);
+ tx_thread_resume(&thread_0);
+
+ /* Restore the preempt disable flag. */
+ _tx_thread_preempt_disable--;
+
+ /* Restore interrupts. */
+ TX_RESTORE
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+
+ /* Loop to get the mutex. */
+ while(1)
+ {
+
+ /* Get and release the mutex. */
+ status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ if (status == TX_SUCCESS)
+ tx_mutex_put(&mutex_1);
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Loop to get the mutex. */
+ while(1)
+ {
+
+ /* Get and release the mutex. */
+ status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ if (status == TX_SUCCESS)
+ tx_mutex_put(&mutex_1);
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Loop to get the mutex. */
+ while(1)
+ {
+
+ /* Get and release the mutex. */
+ status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ if (status == TX_SUCCESS)
+ tx_mutex_put(&mutex_1);
+ tx_thread_suspend(&thread_3);
+ }
+}
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Loop to get the mutex. */
+ while(1)
+ {
+
+ /* Get and release the mutex. */
+ status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ if (status == TX_SUCCESS)
+ tx_mutex_put(&mutex_1);
+ tx_thread_suspend(&thread_4);
+ }
+}
+
+
+static void low_priority_entry(ULONG thread_input)
+{
+}
diff --git a/test/smp/regression/threadx_mutex_thread_terminate_test.c b/test/smp/regression/threadx_mutex_thread_terminate_test.c
new file mode 100644
index 00000000..9b552f54
--- /dev/null
+++ b/test/smp/regression/threadx_mutex_thread_terminate_test.c
@@ -0,0 +1,198 @@
+/* This test is designed to test thread terminate calls when threads are suspended on
+ a mutex. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_MUTEX mutex_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_mutex_thread_terminate_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 Mutex Thread Terminate Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Mutex Thread Terminate Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_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 Mutex Thread Terminate Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Thread Terminate Test................................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Get the mutex. */
+ tx_mutex_get(&mutex_0, TX_NO_WAIT);
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Thread Terminate Test................................. ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Relinquish to let other threads run. */
+ tx_thread_relinquish();
+
+ /* Other threads should now be suspended on the mutex. */
+ if ((thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Terminate the other threads to make sure the mutex gets
+ cleaned up. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Terminate the other thread. */
+ status = tx_thread_terminate(&thread_2);
+
+ /* Relinquish just to make sure. */
+ tx_thread_relinquish();
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+//UINT status;
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the mutex. */
+ tx_mutex_get(&mutex_0, 33);
+
+ /* Should never get here! */
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+//UINT status;
+
+ /* Increment thread run counter. */
+ thread_2_counter++;
+
+ /* Suspend on the mutex. */
+ tx_mutex_get(&mutex_0, 44);
+
+ /* Should never get here! */
+ thread_2_counter++;
+}
diff --git a/test/smp/regression/threadx_queue_basic_eight_word_test.c b/test/smp/regression/threadx_queue_basic_eight_word_test.c
new file mode 100644
index 00000000..c201fdee
--- /dev/null
+++ b/test/smp/regression/threadx_queue_basic_eight_word_test.c
@@ -0,0 +1,423 @@
+/* This test is designed to test immediate response queue services including create
+ and delete. This test is for queue sizes of 8 ULONG. Two queues are used one with
+ a capacity of 1 message and another with a capacity of 3 messages. */
+
+#include <stdio.h>
+#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_eight_word_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 Eight Word Queue Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_8_ULONG, pointer, 8*sizeof(ULONG));
+ pointer = pointer + (8*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Eight Word Queue Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_8_ULONG, pointer, 8*3*sizeof(ULONG));
+ pointer = pointer + 8*3*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Eight Word Queue 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[8];
+ULONG dest_message[8];
+ULONG expected_message[8];
+
+
+ /* Inform user. */
+ printf("Running Queue Eight Word Queue Test................................. ");
+
+ source_message[0] = 0x01234567;
+ source_message[7] = 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[7] != dest_message[7]))
+ {
+
+ /* 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[7]++;
+
+ /* 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[7] != dest_message[7]))
+ {
+
+ /* 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[7]++;
+ expected_message[0] = source_message[0];
+ expected_message[7] = source_message[7];
+
+ /* Place something on queue 1. */
+ status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[7]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[7]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[7]++;
+
+
+ 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[7] != dest_message[7]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[7]++;
+
+ /* 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[7] != dest_message[7]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[7]++;
+
+ /* 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[7] != dest_message[7]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[7]++;
+
+ /* 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[7]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[7]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[7]++;
+
+ 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[7] != dest_message[7]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[7]++;
+
+ /* 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[7] != dest_message[7]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[7]++;
+
+ /* 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[7] != dest_message[7]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[7]++;
+
+ /* 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);
+ }
+}
+
+
diff --git a/test/smp/regression/threadx_queue_basic_four_word_test.c b/test/smp/regression/threadx_queue_basic_four_word_test.c
new file mode 100644
index 00000000..5e01bc5b
--- /dev/null
+++ b/test/smp/regression/threadx_queue_basic_four_word_test.c
@@ -0,0 +1,423 @@
+/* This test is designed to test immediate response queue services including create
+ and delete. This test is for queue sizes of 4 ULONG. Two queues are used one with
+ a capacity of 1 message and another with a capacity of 3 messages. */
+
+#include <stdio.h>
+#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_four_word_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 Four Word Test........................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_4_ULONG, pointer, 4*sizeof(ULONG));
+ pointer = pointer + (4*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Four Word Test........................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_4_ULONG, pointer, 4*3*sizeof(ULONG));
+ pointer = pointer + 4*3*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Four Word 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[4];
+ULONG dest_message[4];
+ULONG expected_message[4];
+
+
+ /* Inform user. */
+ printf("Running Queue Four Word Test........................................ ");
+
+ source_message[0] = 0x01234567;
+ source_message[3] = 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[3] != dest_message[3]))
+ {
+
+ /* 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[3]++;
+
+ /* 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[3] != dest_message[3]))
+ {
+
+ /* 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[3]++;
+ expected_message[0] = source_message[0];
+ expected_message[3] = source_message[3];
+
+ /* Place something on queue 1. */
+ status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[3]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[3]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[3]++;
+
+
+ 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[3] != dest_message[3]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[3]++;
+
+ /* 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[3] != dest_message[3]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[3]++;
+
+ /* 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[3] != dest_message[3]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[3]++;
+
+ /* 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[3]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[3]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[3]++;
+
+ 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[3] != dest_message[3]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[3]++;
+
+ /* 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[3] != dest_message[3]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[3]++;
+
+ /* 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[3] != dest_message[3]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[3]++;
+
+ /* 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);
+ }
+}
+
+
diff --git a/test/smp/regression/threadx_queue_basic_one_word_test.c b/test/smp/regression/threadx_queue_basic_one_word_test.c
new file mode 100644
index 00000000..142a9b60
--- /dev/null
+++ b/test/smp/regression/threadx_queue_basic_one_word_test.c
@@ -0,0 +1,867 @@
+/* This test is designed to test immediate response queue services including create
+ and delete. This test is for queue sizes of 1 ULONG. Two queues are used one with
+ a capacity of 1 message and another with a capacity of 3 messages. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+
+
+static TX_TIMER timer_0;
+
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+static TX_QUEUE queue_0;
+static TX_QUEUE queue_1;
+static TX_QUEUE queue_2;
+static TX_QUEUE queue_3;
+
+
+/* Define the external reference to the status for queue create from initialization. */
+
+extern UINT test_queue_from_init;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+UINT _txe_queue_create(TX_QUEUE *queue_ptr, CHAR *name_ptr, UINT message_size,
+ VOID *queue_start, ULONG queue_size, UINT queue_control_block_size);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+CHAR *pointer;
+ULONG source = 1234;
+ULONG destination;
+
+
+ /* Determine if calling queue create from initialization was successful. */
+ if (test_queue_from_init != TX_SUCCESS)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a queue from a timer. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, pointer, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a queue from a timer. */
+ status = tx_queue_delete(&queue_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to send something with suspension from a timer. */
+ status = tx_queue_front_send(&queue_0, &source, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to send something with suspension from a timer. */
+ status = tx_queue_send(&queue_0, &source, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to receive something with suspension from a timer. */
+ status = tx_queue_receive(&queue_0, &destination, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+CHAR *pointer;
+UINT status;
+ULONG source = 1234;
+ULONG destination;
+
+
+ /* Attempt to create a queue from an ISR. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, pointer, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a queue from an ISR. */
+ status = tx_queue_delete(&queue_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to send something with suspension from an ISR. */
+ status = tx_queue_front_send(&queue_0, &source, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to send something with suspension from an ISR. */
+ status = tx_queue_send(&queue_0, &source, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to receive something with suspension from an ISR. */
+ status = tx_queue_receive(&queue_0, &destination, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+}
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_basic_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;
+
+ status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue One Word Queue Test................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, sizeof(ULONG));
+ pointer = pointer + sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue One Word Queue Test................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG));
+ pointer = pointer + 3*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue One Word Queue 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 = 0x12345678UL;
+ULONG dest_message;
+ULONG expected_message;
+#ifndef TX_DISABLE_ERROR_CHECKING
+CHAR *pointer;
+#endif
+
+ /* Inform user. */
+ printf("Running Queue One Word Queue Test................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to create with NULL queue. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_queue_create(TX_NULL, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create with bad sized queue control block. */
+ status = _txe_queue_create(&queue_3, "queue 3", TX_1_ULONG, pointer, 3*sizeof(ULONG), (sizeof(TX_QUEUE)+1));
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create with bad sized message. */
+ status = tx_queue_create(&queue_3, "queue 3", 0, pointer, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a queue that has already been created. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_queue_create(&queue_0, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a queue with an invalid message size. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_queue_create(&queue_2, "queue 2", 47, pointer, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a queue with a NULL queue area. */
+ status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, TX_NULL, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a queue with a too small queue area. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, pointer, 1);
+
+ /* Check for status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a NULL pointer. */
+ status = tx_queue_delete(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-created queue. */
+ queue_2.tx_queue_id = 0;
+ status = tx_queue_delete(&queue_2);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to flush a NULL pointer. */
+ status = tx_queue_flush(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to flush a non-created queue. */
+ queue_2.tx_queue_id = 0;
+ status = tx_queue_flush(&queue_2);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to send something to the front of a non-queue. */
+ status = tx_queue_front_send(TX_NULL, &source_message, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to send something to the front of a non-created queue. */
+ queue_2.tx_queue_id = 0;
+ status = tx_queue_front_send(&queue_2, &source_message, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to send something with a NULL source pointer. */
+ status = tx_queue_front_send(&queue_0, TX_NULL, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to send something to a non-queue. */
+ status = tx_queue_send(TX_NULL, &source_message, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to send something to a non-created queue. */
+ queue_2.tx_queue_id = 0;
+ status = tx_queue_send(&queue_2, &source_message, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to send something with a NULL source pointer. */
+ status = tx_queue_send(&queue_0, TX_NULL, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive something from a non-queue. */
+ status = tx_queue_receive(TX_NULL, &dest_message, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive something from a non-created queue. */
+ queue_2.tx_queue_id = 0;
+ status = tx_queue_receive(&queue_2, &dest_message, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive something to a NULL destination. */
+ status = tx_queue_receive(&queue_0, TX_NULL, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Place something on queue 0. */
+ status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #24\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 #25\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 != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #26\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 #27\n");
+ test_control_return(1);
+ }
+
+ /* Make sure we can do the same thing again! */
+ source_message++;
+
+ /* Place something on queue 0. */
+ status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #28\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 #29\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 != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #30\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 #31\n");
+ test_control_return(1);
+ }
+
+ /* Now we need to do the same thing with the queue with three entries. */
+
+ source_message++;
+ expected_message = source_message;
+
+ /* Place something on queue 1. */
+ status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #32\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 #33\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #34\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #35\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #36\n");
+ test_control_return(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 #37\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++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #38\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 #39\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #40\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #41\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #42\n");
+ test_control_return(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 #43\n");
+ test_control_return(1);
+ }
+
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Resume thread 1 so that we can take an interrupt on top of it. */
+ tx_thread_resume(&thread_1);
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #44\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete the queues. */
+ status = tx_queue_delete(&queue_1);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #45\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_delete(&queue_0);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #46\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+ }
+}
+
diff --git a/test/smp/regression/threadx_queue_basic_sixteen_word_test.c b/test/smp/regression/threadx_queue_basic_sixteen_word_test.c
new file mode 100644
index 00000000..703a1cf4
--- /dev/null
+++ b/test/smp/regression/threadx_queue_basic_sixteen_word_test.c
@@ -0,0 +1,423 @@
+/* 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 <stdio.h>
+#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_sixteen_word_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 Sixteen Word Test..................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_16_ULONG, pointer, 16*sizeof(ULONG));
+ pointer = pointer + (16*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Sixteen Word Test..................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_16_ULONG, pointer, 16*3*sizeof(ULONG));
+ pointer = pointer + 16*3*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Sixteen Word 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[16];
+ULONG dest_message[16];
+ULONG expected_message[16];
+
+
+ /* Inform user. */
+ printf("Running Queue Sixteen Word Test..................................... ");
+
+ source_message[0] = 0x01234567;
+ source_message[15] = 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[15] != dest_message[15]))
+ {
+
+ /* 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[15]++;
+
+ /* 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[15] != dest_message[15]))
+ {
+
+ /* 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[15]++;
+ expected_message[0] = source_message[0];
+ expected_message[15] = source_message[15];
+
+ /* Place something on queue 1. */
+ status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[15]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[15]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[15]++;
+
+
+ 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[15] != dest_message[15]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[15]++;
+
+ /* 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[15] != dest_message[15]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[15]++;
+
+ /* 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[15] != dest_message[15]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[15]++;
+
+ /* 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[15]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[15]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[15]++;
+
+ 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[15] != dest_message[15]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[15]++;
+
+ /* 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[15] != dest_message[15]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[15]++;
+
+ /* 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[15] != dest_message[15]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[15]++;
+
+ /* 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);
+ }
+}
+
+
diff --git a/test/smp/regression/threadx_queue_basic_two_word_test.c b/test/smp/regression/threadx_queue_basic_two_word_test.c
new file mode 100644
index 00000000..ab24d08e
--- /dev/null
+++ b/test/smp/regression/threadx_queue_basic_two_word_test.c
@@ -0,0 +1,463 @@
+/* This test is designed to test immediate response queue services including create
+ and delete. This test is for queue sizes of 2 ULONG. Two queues are used one with
+ a capacity of 1 message and another with a capacity of 3 messages. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+typedef struct QUEUE_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_QUEUE queue;
+ ULONG first_middle;
+ ULONG second_middle;
+ ULONG queue_area[2048/sizeof(ULONG)];
+ ULONG next_to_last;
+ ULONG last;
+
+} QUEUE_MEMORY_TEST;
+
+static QUEUE_MEMORY_TEST queue_memory;
+
+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_two_word_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 Two Word Test......................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 2*sizeof(ULONG));
+ pointer = pointer + (2*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Two Word Test......................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_2_ULONG, pointer, 2*3*sizeof(ULONG));
+ pointer = pointer + 2*3*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Two Word 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[2];
+ULONG dest_message[2];
+ULONG expected_message[2];
+
+
+ /* Inform user. */
+ printf("Running Queue Two Word Test......................................... ");
+
+ /* Perform queue memory test. */
+ queue_memory.first = 0x11223344;
+ queue_memory.second = 0x55667788;
+ queue_memory.first_middle = 0x21314151;
+ queue_memory.second_middle= 0x61718191;
+ queue_memory.next_to_last = 0x99aabbcc;
+ queue_memory.last = 0xddeeff00;
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_memory.queue, "queue memory", TX_2_ULONG, &queue_memory.queue_area[0], (2048*sizeof(ULONG))/sizeof(ULONG));
+ tx_queue_delete(&queue_memory.queue);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (queue_memory.first != 0x11223344) ||
+ (queue_memory.second != 0x55667788) ||
+ (queue_memory.first_middle != 0x21314151) ||
+ (queue_memory.second_middle != 0x61718191) ||
+ (queue_memory.next_to_last != 0x99aabbcc) ||
+ (queue_memory.last != 0xddeeff00))
+ {
+ /* Queue error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ source_message[0] = 0x01234567;
+ source_message[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 #5\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 #6\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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\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 #8\n");
+ test_control_return(1);
+ }
+
+ /* Make sure we can do the same thing again! */
+ source_message[0]++;
+ source_message[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 #9\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 #10\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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #11\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 #12\n");
+ test_control_return(1);
+ }
+
+ /* Now we need to do the same thing with the queue with three entries. */
+
+ source_message[0]++;
+ source_message[1]++;
+ expected_message[0] = source_message[0];
+ expected_message[1] = source_message[1];
+
+ /* Place something on queue 1. */
+ status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[1]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[1]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[1]++;
+
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #13\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 #14\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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[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 #18\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[1]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[1]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[1]++;
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #19\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 #20\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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[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 #24\n");
+ test_control_return(1);
+ }
+
+ /* Delete the queues. */
+ status = tx_queue_delete(&queue_1);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_delete(&queue_0);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
diff --git a/test/smp/regression/threadx_queue_empty_suspension_test.c b/test/smp/regression/threadx_queue_empty_suspension_test.c
new file mode 100644
index 00000000..59d53e70
--- /dev/null
+++ b/test/smp/regression/threadx_queue_empty_suspension_test.c
@@ -0,0 +1,271 @@
+/* This test is designed to test empty queue suspension of queue that supports 3 messages
+ that are each 2 ULONG in size. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_QUEUE queue_0;
+static TX_QUEUE queue_1;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_empty_suspension_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 Empty Suspension Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Empty Suspension Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Empty Suspension Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Empty Suspension Test................................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Empty Suspension Test................................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Empty Suspension Test................................. ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG source_message[2] = {0x12345678, 0};
+
+
+ /* Inform user. */
+ printf("Running Queue Empty Suspension Test................................. ");
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to setup notify on a non-queue. */
+ status = tx_queue_send_notify(TX_NULL, queue_notify);
+
+ /* Check status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to setup notify on a non-created queue. */
+ queue_1.tx_queue_id = 0;
+ status = tx_queue_send_notify(&queue_1, queue_notify);
+
+ /* Check status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Send message that should go directly into the the other thread's
+ destination area! We should also preempt and the queue should
+ be empty by the next time we get around! */
+ status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+
+ /* Check status and run count of other thread - it should have got the
+ message already. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Now resume thread 2 to get another thread suspended on an empty queue. */
+ tx_thread_resume(&thread_2);
+
+ /* Now send 2 messages to wakeup both threads! */
+ source_message[0]++;
+ status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+
+ /* Check status and run count of other thread - it should have got the
+ message already. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2) || (thread_2_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG expected_message[2] = {0x12345678, 0};
+ULONG dest_message[2];
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue with suspension. We should always
+ suspend until thread 0 executes. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
+
+ if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG expected_message[2] = {0x12345679, 0};
+ULONG dest_message[2];
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue with suspension. We should always
+ suspend until thread 0 executes. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
+
+ if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
diff --git a/test/smp/regression/threadx_queue_flush_no_suspension_test.c b/test/smp/regression/threadx_queue_flush_no_suspension_test.c
new file mode 100644
index 00000000..940259f2
--- /dev/null
+++ b/test/smp/regression/threadx_queue_flush_no_suspension_test.c
@@ -0,0 +1,216 @@
+/* This test is designed to test the queue flush operation on a queue that has no threads
+ suspended on it. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static TX_QUEUE queue_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_flush_no_suspension_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush No Suspension Test.............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush No Suspension Test.............................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush No Suspension Test.............................. ERROR #3\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Flush No Suspension Test.............................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ULONG message[2] = {0x12345678, 0};
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Queue Flush No Suspension Test.............................. ");
+
+ /* Fill up the queue. */
+ status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
+
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Flush queue 0 to make more room. */
+ status = tx_queue_flush(&queue_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+
+ /* Fill up the queue. */
+ status = tx_queue_send(&queue_0, &message[2], TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_send(&queue_0, &message[2], TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_send(&queue_0, &message[2], TX_NO_WAIT);
+
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Flush queue again to empty and then flush to test on an empty queue. */
+ status = tx_queue_flush(&queue_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_flush(&queue_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Success if we get here. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+}
+
diff --git a/test/smp/regression/threadx_queue_flush_test.c b/test/smp/regression/threadx_queue_flush_test.c
new file mode 100644
index 00000000..6d65c971
--- /dev/null
+++ b/test/smp/regression/threadx_queue_flush_test.c
@@ -0,0 +1,249 @@
+/* This test is designed to test the queue flush operation on a queue that has two threads
+ suspended on it. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_QUEUE queue_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_flush_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ULONG message[2] = {0x12345678, 0};
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Queue Flush w/Suspended Threads Test........................ ");
+
+ /* Fill up the queue. */
+ status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
+
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to get other threads suspended on the queue full. */
+ tx_thread_relinquish();
+
+ /* Flush queue 0 which has the threads suspended on it. */
+ status = tx_queue_flush(&queue_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to let other threads run and finish! */
+ tx_thread_relinquish();
+
+ /* Determine if the queue flush test was successful. */
+ if ((thread_1_counter == 1) && (thread_2_counter == 1))
+ {
+
+ /* Successful queue flush test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ else
+ {
+
+ /* Queue Flush error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+ULONG message[2] = {0x1, 0};
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_send(&queue_0, &message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+UINT status;
+ULONG message[2] = {0x2, 0};
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_send(&queue_0, &message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+}
+
diff --git a/test/smp/regression/threadx_queue_front_send_test.c b/test/smp/regression/threadx_queue_front_send_test.c
new file mode 100644
index 00000000..5329670b
--- /dev/null
+++ b/test/smp/regression/threadx_queue_front_send_test.c
@@ -0,0 +1,686 @@
+/* This test is designed to test immediate response queue services including queue front send.
+ This test is for queue sizes of 2 ULONG. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static TX_THREAD thread_2;
+
+static TX_QUEUE queue_0;
+
+
+static unsigned long thread_1a_counter = 0;
+static TX_THREAD thread_1a;
+
+static TX_THREAD thread_2a;
+
+static TX_QUEUE queue_0a;
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_1a_entry(ULONG thread_input);
+static void thread_2a_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_front_send_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, 0,
+ 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 Front Test............................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status = tx_thread_create(&thread_1a, "thread 1a", thread_1a_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Front Test............................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status = tx_thread_create(&thread_2a, "thread 2a", thread_2a_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Front Test............................................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 2*2*sizeof(ULONG));
+ pointer = pointer + 2*2*sizeof(ULONG);
+ status = tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, pointer, 2*1*sizeof(ULONG));
+ pointer = pointer + 2*1*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Front Test............................................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Front Test............................................ ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Front Test............................................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG source_message[2] = {0x12345678, 0};
+ULONG dest_message[2];
+ULONG temp[2];
+
+
+ /* Inform user. */
+ printf("Running Queue Front Test............................................ ");
+
+ /* Perform the 1 word queue front send test. */
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Place something on queue 0a. */
+ status = tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #7a\n");
+ test_control_return(1);
+ }
+
+ /* Place a new message on the front of the queue. */
+ temp[0] = 0xF000001;
+ status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #8a\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive something from queue 0a. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be successful and dest_message should equal source. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != temp[0]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #9a\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive something from queue 0a. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be successful and dest_message should equal source. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != source_message[0]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #10a\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive another message from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if (status != TX_QUEUE_EMPTY)
+ {
+
+ /* Queue error. */
+ printf("ERROR #11a\n");
+ test_control_return(1);
+ }
+
+ /* At this point the queue is empty. Resume another thread to
+ suspend on an empty queue. */
+ tx_thread_resume(&thread_1a);
+
+ /* Relinquish to get this thread suspended on the empty queue. */
+ tx_thread_relinquish();
+
+ /* Resume thread 2a to get another thread suspended on the empty queue. */
+ tx_thread_resume(&thread_2a);
+
+ /* Now send something to the front of the queue, which will resume
+ the first waiting thread. */
+ temp[0] = 0xFF00002;
+ status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #12a\n");
+ test_control_return(1);
+ }
+
+ /* Now send something to the front of the queue, which will resume
+ the second waiting thread. */
+ temp[0] = 0xFF00002;
+ status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #13a\n");
+ test_control_return(1);
+ }
+
+ /* Now relinquish again to let the other thread process the message. */
+ tx_thread_relinquish();
+
+ /* At this point, the other thread should have placed 2 messages on the queue
+ so we will now send to the front, but without suspension. */
+ temp[0] = 0xFF00003;
+ status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_QUEUE_FULL)
+ {
+
+ /* Queue error. */
+ printf("ERROR #14a\n");
+ test_control_return(1);
+ }
+
+ /* Now, we will now send to the front, but with suspension. */
+ temp[0] = 0xFF00003;
+ status = tx_queue_front_send(&queue_0a, &temp[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #15a\n");
+ test_control_return(1);
+ }
+
+ /* Now resume thread 2a to get another thread suspended on the queue. */
+ tx_thread_resume(&thread_2a);
+
+ temp[0] = 0xFF00004;
+ status = tx_queue_front_send(&queue_0a, &temp[0], TX_WAIT_FOREVER);
+
+ /* When we get back, the other thread has received all the messages and
+ verified they are in order AND relinquished. */
+ if ((status != TX_SUCCESS) || (thread_1a_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16a\n");
+ test_control_return(1);
+ }
+
+
+ /* Perform the multiword queue front send test. */
+
+
+ /* Increment thread 0 counter. */
+ thread_0_counter = 1;
+
+ /* Reset the source message. */
+ source_message[0] = 0x12345678;
+ source_message[1] = 0;
+
+ /* Place something on queue 0. */
+ status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Place a new message on the front of the queue. */
+ temp[0] = 0xF000001;
+ status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive something from queue 0. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be successful and dest_message should equal source. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != temp[0]))
+ {
+
+ /* 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[0], TX_NO_WAIT);
+
+ /* Should be successful and dest_message should equal source. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != source_message[0]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive another message from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if (status != TX_QUEUE_EMPTY)
+ {
+
+ /* Queue error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* At this point the queue is empty. Resume another thread to
+ suspend on an empty queue. */
+ tx_thread_resume(&thread_1);
+
+ /* Relinquish to get this thread suspended on the empty queue. */
+ tx_thread_relinquish();
+
+ /* Resume thread 2 to get another thread suspended on the empty queue. */
+ tx_thread_resume(&thread_2);
+
+ /* Now send something to the front of the queue, which will resume
+ the first waiting thread. */
+ temp[0] = 0xFF00002;
+ status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Now send something to the front of the queue, which will resume
+ the second waiting thread. */
+ temp[0] = 0xFF00002;
+ status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Now relinquish again to let the other thread process the message. */
+ tx_thread_relinquish();
+
+ /* At this point, the other thread should have placed 2 messages on the queue
+ so we will now send to the front, but without suspension. */
+ temp[0] = 0xFF00003;
+ status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_QUEUE_FULL)
+ {
+
+ /* Queue error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Now, we will now send to the front, but with suspension. */
+ temp[0] = 0xFF00003;
+ status = tx_queue_front_send(&queue_0, &temp[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Now resume thread 2 to get another thread suspended on the queue. */
+ tx_thread_resume(&thread_2);
+
+ temp[0] = 0xFF00004;
+ status = tx_queue_front_send(&queue_0, &temp[0], TX_WAIT_FOREVER);
+
+ /* When we get back, the other thread has received all the messages and
+ verified they are in order AND relinquished. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG source_message[2] = {0xEE000001, 0};
+ULONG dest_message[2];
+
+
+ /* First, suspend on an empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
+
+ /* Determine if the message is good. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00002))
+ return;
+
+ /* Now fill the queue with two messages. */
+ status = tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+ source_message[0]++;
+ status += tx_queue_front_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Now let thread 0 send to the front of the queue with suspension. */
+ tx_thread_relinquish();
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00003))
+ return;
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000002))
+ return;
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000001))
+ return;
+
+ /* At this point, we are going to fill up the queue again. */
+ source_message[0]++;
+ status = tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+ source_message[0]++;
+ status += tx_queue_front_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Now let thread 0 send to the front of the queue with suspension. */
+ tx_thread_relinquish();
+
+ /* Attempt to receive four messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00004))
+ return;
+
+ /* Attempt to receive four messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xDD000001))
+ return;
+
+ /* Attempt to receive four messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000004))
+ return;
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000003))
+ return;
+
+ /* Increment this threads counter. */
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ULONG source_message[2] = {0xDD000001, 0};
+ULONG destination_message[2];
+
+
+ /* Receive message. */
+ tx_queue_receive(&queue_0, &destination_message[0], TX_WAIT_FOREVER);
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_2);
+
+ /* Send another message to the front of the queue. */
+ tx_queue_front_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+}
+
+
+static void thread_1a_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG source_message[2] = {0xEE000001, 0};
+ULONG dest_message[2];
+
+
+ /* First, suspend on an empty queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER);
+
+ /* Determine if the message is good. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00002))
+ return;
+
+ /* Now fill the queue with two messages. */
+ status = tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+ source_message[0]++;
+ status += tx_queue_front_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Now let thread 0 send to the front of the queue with suspension. */
+ tx_thread_relinquish();
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00003))
+ return;
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000002))
+ return;
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000001))
+ return;
+
+ /* At this point, we are going to fill up the queue again. */
+ source_message[0]++;
+ status = tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+ source_message[0]++;
+ status += tx_queue_front_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Now let thread 0 send to the front of the queue with suspension. */
+ tx_thread_relinquish();
+
+ /* Attempt to receive four messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00004))
+ return;
+
+ /* Attempt to receive four messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xDD000001))
+ return;
+
+ /* Attempt to receive four messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000004))
+ return;
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000003))
+ return;
+
+ /* Increment this threads counter. */
+ thread_1a_counter++;
+}
+
+
+static void thread_2a_entry(ULONG thread_input)
+{
+
+ULONG source_message[2] = {0xDD000001, 0};
+ULONG destination_message[2];
+
+
+ /* Receive message. */
+ tx_queue_receive(&queue_0a, &destination_message[0], TX_WAIT_FOREVER);
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_2a);
+
+ /* Send another message to the front of the queue. */
+ tx_queue_front_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+}
diff --git a/test/smp/regression/threadx_queue_full_suspension_test.c b/test/smp/regression/threadx_queue_full_suspension_test.c
new file mode 100644
index 00000000..556a4c77
--- /dev/null
+++ b/test/smp/regression/threadx_queue_full_suspension_test.c
@@ -0,0 +1,368 @@
+/* This test is designed to test queue full suspension of queue that supports 3 messages
+ that are each 2 ULONG in size. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_QUEUE queue_0;
+
+
+static unsigned long thread_1a_counter = 0;
+static TX_THREAD thread_1a;
+
+static unsigned long thread_2a_counter = 0;
+static TX_THREAD thread_2a;
+
+static TX_QUEUE queue_0a;
+
+
+static ULONG queue_area[3];
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_1a_entry(ULONG thread_input);
+static void thread_2a_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_full_suspension_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 Full Suspension Test.................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_1a, "thread 1a", thread_1a_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Full Suspension Test.................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_2a, "thread 2a", thread_2a_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Full Suspension Test.................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+ status += tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, pointer, 3*1*sizeof(ULONG));
+ pointer = pointer + 3*1*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Full Suspension Test.................................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Full Suspension Test.................................. ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Full Suspension Test.................................. ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG source_message[2] = {0x12345678, 0};
+ULONG dest_message[2];
+
+
+ /* Inform user. */
+ printf("Running Queue Full Suspension Test.................................. ");
+
+ /* Perform the one word queue version. */
+
+ /* Suspend to get thread 1a to pend on the queue. */
+ tx_thread_suspend(&thread_0);
+ status = tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+ tx_thread_suspend(&thread_0);
+ tx_thread_resume(&thread_1a);
+ tx_thread_resume(&thread_2a);
+ tx_queue_delete(&queue_0a);
+ status += tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, queue_area, sizeof(queue_area));
+
+
+ /* Fill the queue with an initial 3 messages! */
+ status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+
+ /* Receive two of the messages back to put the first received message at the end
+ of the queue. */
+ status += tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+ status += tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+ status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+
+ /* Check status and run count of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1a_counter != 0))
+ {
+
+ /* Queue error. */
+ printf("ERROR #6a\n");
+ test_control_return(1);
+ }
+
+ /* Send message that should cause this thread to suspend, until the
+ lower priority thread receives a message. */
+ status = tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+
+ /* Check status and run count of other thread - it should have got the
+ message already even though its counter is still 0 (it was preempted
+ in the queue receive call. */
+ if ((status != TX_SUCCESS) || (thread_1a_counter != 5) || (thread_2a_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #7a\n");
+ test_control_return(1);
+ }
+
+ /* Perform the two word queue version. */
+
+ /* Reset the source message. */
+ source_message[0] = 0x12345678;
+ source_message[1] = 0;
+
+ /* Resume threads 1 and 2. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Fill the queue with an initial 3 messages! */
+ status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+
+ /* Receive two of the messages back to put the first received message at the end
+ of the queue. */
+ status += tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+ status += tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+
+ /* Check status and run count of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0))
+ {
+
+ /* Queue error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Send message that should cause this thread to suspend, until the
+ lower priority thread receives a message. */
+ status = tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+
+ /* Check status and run count of other thread - it should have got the
+ message already even though its counter is still 0 (it was preempted
+ in the queue receive call. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+ULONG expected_message[2] = {0x12345678, 0};
+ULONG dest_message[2];
+UINT old_priority;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+ /* Receive messages and suspend. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
+
+ if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
+ break;
+
+ /* Change thread 2 priority. */
+ tx_thread_priority_change(&thread_2, 15, &old_priority);
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ULONG source_message[2] = {0x1234567C, 0};
+
+
+ /* Send one message to the queue. */
+ tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+}
+
+
+static void thread_1a_entry(ULONG thread_input)
+{
+UINT status;
+ULONG expected_message[2] = {0x12345678, 0};
+ULONG dest_message[2];
+UINT old_priority;
+
+
+ /* Receive message and suspend. */
+ status = tx_thread_resume(&thread_0);
+ status += tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER);
+ status += tx_thread_resume(&thread_0);
+ status += tx_thread_suspend(&thread_1a);
+
+ if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]))
+ return;
+
+ /* Loop forever! */
+ while(1)
+ {
+
+ /* Receive messages and suspend. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER);
+
+ if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
+ break;
+
+ /* Change thread 2a priority. */
+ tx_thread_priority_change(&thread_2a, 15, &old_priority);
+
+ /* Increment the thread counter. */
+ thread_1a_counter++;
+ }
+}
+
+
+static void thread_2a_entry(ULONG thread_input)
+{
+
+ULONG source_message[2] = {0x1234567C, 0};
+
+
+ /* Send one message to the queue. */
+ tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+
+ /* Increment the thread counter. */
+ thread_2a_counter++;
+}
diff --git a/test/smp/regression/threadx_queue_information_test.c b/test/smp/regression/threadx_queue_information_test.c
new file mode 100644
index 00000000..c1db82ca
--- /dev/null
+++ b/test/smp/regression/threadx_queue_information_test.c
@@ -0,0 +1,664 @@
+/* This test is designed to test the queue information services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_queue.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static TX_QUEUE queue_0;
+static TX_QUEUE queue_1;
+static TX_QUEUE queue_2;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+UINT _tx_queue_performance_info_get(TX_QUEUE *queue_ptr, ULONG *messages_sent, ULONG *messages_received,
+ ULONG *empty_suspensions, ULONG *full_suspensions, ULONG *full_errors, ULONG *timeouts);
+
+/* 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_information_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 Information Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, sizeof(ULONG));
+ pointer = pointer + sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Information Test...................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG));
+ pointer = pointer + 3*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Information 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 = 0x12345678UL;
+ULONG dest_message;
+ULONG expected_message;
+CHAR *name;
+ULONG enqueued;
+ULONG available_storage;
+TX_THREAD *first_suspended;
+ULONG suspended_count;
+TX_QUEUE *next_queue;
+ULONG messages_sent;
+ULONG messages_received;
+ULONG empty_suspensions;
+ULONG full_suspensions;
+ULONG full_errors;
+ULONG timeouts;
+
+
+ /* Inform user. */
+ printf("Running Queue Information Test...................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to get info from a non-queue. */
+ status = tx_queue_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get info from a non-created queue. */
+ queue_2.tx_queue_id = 0;
+ status = tx_queue_info_get(&queue_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Place something on queue 0. */
+ status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #5\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 #6\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 != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\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 #8\n");
+ test_control_return(1);
+ }
+
+ /* Make sure we can do the same thing again! */
+ source_message++;
+
+ /* Place something on queue 0. */
+ status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #9\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 #10\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 != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #11\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 #12\n");
+ test_control_return(1);
+ }
+
+ /* Now we need to do the same thing with the queue with three entries. */
+
+ source_message++;
+ expected_message = source_message;
+
+ /* Place something on queue 1. */
+ status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #13\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 #14\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #17\n");
+ test_control_return(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 #18\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++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #19\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 #20\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #21\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #22\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #23\n");
+ test_control_return(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 #24\n");
+ test_control_return(1);
+ }
+
+ /* Get queue information. */
+ status = tx_queue_info_get(&queue_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_queue_info_get(&queue_0, &name, &enqueued, &available_storage, &first_suspended, &suspended_count, &next_queue);
+
+ /* Check for errors. */
+ if ((status != TX_SUCCESS) || (enqueued != queue_0.tx_queue_enqueued) || (available_storage != queue_0.tx_queue_available_storage) ||
+ (first_suspended != queue_0.tx_queue_suspension_list) || (suspended_count != queue_0.tx_queue_suspended_count) ||
+ (next_queue != queue_0.tx_queue_created_next))
+ {
+
+ /* Queue error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+#ifdef TX_QUEUE_ENABLE_PERFORMANCE_INFO
+
+ /* Test null pointer for queue performance info get. */
+ status = _tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Should be an error! */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(&queue_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_queue_performance_info_get(&queue_0, &messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Check for errors. */
+ if ((status != TX_SUCCESS) || (messages_sent != queue_0.tx_queue_performance_messages_sent_count) || (messages_received != queue_0.tx_queue_performance_messages_received_count) ||
+ (empty_suspensions != queue_0.tx_queue_performance_empty_suspension_count) || (full_suspensions != queue_0.tx_queue_performance_full_suspension_count) ||
+ (full_errors != queue_0.tx_queue_performance_full_error_count) || (timeouts != queue_0.tx_queue_performance_timeout_count))
+ {
+
+ /* Queue error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_queue_performance_system_info_get(&messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Check for errors. */
+ if ((status != TX_SUCCESS) || (messages_sent != _tx_queue_performance_messages_sent_count) || (messages_received != _tx_queue_performance__messages_received_count) ||
+ (empty_suspensions != _tx_queue_performance_empty_suspension_count) || (full_suspensions != _tx_queue_performance_full_suspension_count) ||
+ (full_errors != _tx_queue_performance_full_error_count) || (timeouts != _tx_queue_performance_timeout_count))
+ {
+
+ /* Queue error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(&queue_0, &messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, &messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, TX_NULL, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(&messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #39\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #40\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #41\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #42\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #43\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete the queues. */
+ status = tx_queue_delete(&queue_1);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #44\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_delete(&queue_0);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #45\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
diff --git a/test/smp/regression/threadx_queue_prioritize.c b/test/smp/regression/threadx_queue_prioritize.c
new file mode 100644
index 00000000..7a9d2b44
--- /dev/null
+++ b/test/smp/regression/threadx_queue_prioritize.c
@@ -0,0 +1,534 @@
+/* This test is designed to test queue prioritize. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static TX_QUEUE queue_0;
+static TX_QUEUE queue_1;
+
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Determine if thread 3 is at the front of the suspension list. */
+ if (queue_0.tx_queue_suspension_list == &thread_3)
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+ }
+ else
+ {
+
+ /* Abort the wait of thread 5. */
+ tx_thread_wait_abort(&thread_5);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_prioritize_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #9\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #10\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Queue Prioritize Test....................................... ");
+
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to prioritize a non-queue. */
+ status = tx_queue_prioritize(TX_NULL);
+
+ /* Check for an error condition. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to prioritize a non-created queue. */
+ queue_1.tx_queue_id = 0;
+ status = tx_queue_prioritize(&queue_1);
+
+ /* Check for an error condition. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Nothing to do here, but check prioritization with no suspended threads. */
+ status = tx_queue_prioritize(&queue_0);
+
+ /* Check for an error condition. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 and 2 are suspended on the queue. */
+ if ((thread_1.tx_thread_state != TX_QUEUE_SUSP) || (thread_2.tx_thread_state != TX_QUEUE_SUSP) ||
+ (queue_0.tx_queue_suspension_list != &thread_1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the queue suspension list. */
+ status = tx_queue_prioritize(&queue_0);
+
+ /* Check status and make sure thread 2 is not at the head of the list. */
+ if ((status != TX_SUCCESS) || (queue_0.tx_queue_suspension_list != &thread_2))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the queue suspension list again, but slightly different path because it was previously prioritized. */
+ status = tx_queue_prioritize(&queue_0);
+
+ /* Check status and make sure thread 2 not at the head of the list. */
+ if ((status != TX_SUCCESS) || (queue_0.tx_queue_suspension_list != &thread_2))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the queue suspension list. */
+ status = tx_queue_prioritize(&queue_0);
+
+ /* Check status and make sure thread 3 is at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (queue_0.tx_queue_suspension_list != &thread_3))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the queue suspension list. */
+ status = tx_queue_prioritize(&queue_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Now determine if thread 4 is at the front of the list... It should be! */
+ if (queue_0.tx_queue_suspension_list != &thread_4)
+ {
+
+ /* Queue error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+ }
+}
+
+
diff --git a/test/smp/regression/threadx_queue_suspension_timeout_test.c b/test/smp/regression/threadx_queue_suspension_timeout_test.c
new file mode 100644
index 00000000..a3c390ed
--- /dev/null
+++ b/test/smp/regression/threadx_queue_suspension_timeout_test.c
@@ -0,0 +1,254 @@
+/* This test is designed to test queue full and empty suspension with timeouts on queues
+ that supports 3 messages that are each 2 ULONG in size. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+
+static TX_THREAD thread_1;
+
+static TX_THREAD thread_2;
+static unsigned long thread_2_counter = 0;
+
+static TX_QUEUE queue_0;
+static TX_QUEUE queue_1;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_suspension_timeout_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #6\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG source_message[2] = {0x12345678, 0};
+
+
+ /* Inform user. */
+ printf("Running Queue Suspension Timeout Test............................... ");
+
+ /* Fill the queue with an initial 3 messages! */
+ status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+
+ /* Check status and run count of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0))
+ {
+
+ /* Queue error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Send message to the front of the queue that should cause this thread to suspend. The timeout
+ should cause it to resume with a TX_QUEUE_FULL error code. */
+ status = tx_queue_front_send(&queue_0, &source_message[0], 3);
+
+ if ((status != TX_QUEUE_FULL) || (thread_1_counter != 0) || (thread_2_counter != 0))
+ {
+
+ /* Queue error. */
+ printf("ERROR #9a\n");
+ test_control_return(1);
+ }
+
+ /* Send message that should cause this thread to suspend. The timeout
+ should cause it to resume with a TX_QUEUE_FULL error code. */
+ status = tx_queue_send(&queue_0, &source_message[0], 32);
+
+ if ((status != TX_QUEUE_FULL) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message[2];
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue with suspension and timeout.
+ We should wakeup after the timeout expires with an empty status. */
+ status = tx_queue_receive(&queue_1, &dest_message[0], 20);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message[2];
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue with suspension and timeout.
+ We should wakeup after the timeout expires with an empty status. */
+ status = tx_queue_receive(&queue_1, &dest_message[0], 20);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
diff --git a/test/smp/regression/threadx_queue_thread_terminate_test.c b/test/smp/regression/threadx_queue_thread_terminate_test.c
new file mode 100644
index 00000000..d0834704
--- /dev/null
+++ b/test/smp/regression/threadx_queue_thread_terminate_test.c
@@ -0,0 +1,183 @@
+/* This test is designed to test thread terminate when the terminated thread is suspeded
+ on a queue. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static TX_QUEUE queue_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_thread_terminate_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Thread Terminate Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Thread Terminate Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Thread Terminate Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Thread Terminate Test................................. ERROR #4\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Thread Terminate Test................................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Queue Thread Terminate Test................................. ");
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 is suspended on the queue. */
+ if (thread_1.tx_thread_state != TX_QUEUE_SUSP)
+ {
+
+ /* Queue error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Terminate thread 1 which is suspended on queue 0. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_TERMINATED) ||
+ (thread_1_counter != 0) || (queue_0.tx_queue_suspended_count))
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message[2];
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
diff --git a/test/smp/regression/threadx_semaphore_basic_test.c b/test/smp/regression/threadx_semaphore_basic_test.c
new file mode 100644
index 00000000..f554257d
--- /dev/null
+++ b/test/smp/regression/threadx_semaphore_basic_test.c
@@ -0,0 +1,545 @@
+/* This test is designed to test the semaphore create/delete and immediate return gets and puts. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+typedef struct SEMAPHORE_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_SEMAPHORE semaphore;
+ ULONG next_to_last;
+ ULONG last;
+
+} SEMAPHORE_MEMORY_TEST;
+
+static SEMAPHORE_MEMORY_TEST semaphore_memory;
+
+
+/* Define the external symbol to obtain the status from a create call in initialization. */
+
+extern UINT test_semaphore_from_init;
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+
+
+static TX_TIMER timer_0;
+
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+
+static TX_SEMAPHORE semaphore_0;
+static TX_SEMAPHORE semaphore_1;
+static TX_SEMAPHORE semaphore_2;
+static TX_SEMAPHORE semaphore_3;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+UINT _txe_semaphore_create(TX_SEMAPHORE *semaphore_ptr, CHAR *name_ptr, ULONG initial_count, UINT semaphore_control_block_size);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+
+
+ /* Determine if calling semaphore create from initialization was successful. */
+ if (test_semaphore_from_init != TX_SUCCESS)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a semaphore from a timer. */
+ status = tx_semaphore_create(&semaphore_2, "semaphore 2", 1);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a semaphore from a timer. */
+ status = tx_semaphore_delete(&semaphore_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to get a semaphore with suspension from a timer. */
+ status = tx_semaphore_get(&semaphore_0, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+
+
+ /* Attempt to create a semaphore from an ISR. */
+ status = tx_semaphore_create(&semaphore_2, "semaphore 2", 1);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a semaphore from an ISR. */
+ status = tx_semaphore_delete(&semaphore_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to get a semaphore with suspension from an ISR. */
+ status = tx_semaphore_get(&semaphore_0, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+}
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_basic_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;
+
+ status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Basic Test........................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 1. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Basic Test........................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_1, "semaphore 1", 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Basic Test........................................ ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Semaphore Basic Test........................................ ");
+
+ /* Perform semaphore memory test. */
+ semaphore_memory.first = 0x11223344;
+ semaphore_memory.second = 0x55667788;
+ semaphore_memory.next_to_last = 0x99aabbcc;
+ semaphore_memory.last = 0xddeeff00;
+
+ /* Create the semaphore. */
+ status = tx_semaphore_create(&semaphore_memory.semaphore, "semaphore memory", 0);
+ tx_semaphore_delete(&semaphore_memory.semaphore);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (semaphore_memory.first != 0x11223344) ||
+ (semaphore_memory.second != 0x55667788) ||
+ (semaphore_memory.next_to_last != 0x99aabbcc) ||
+ (semaphore_memory.last != 0xddeeff00))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to create a non-semaphore. */
+ status = tx_semaphore_create(TX_NULL, "semaphore 0", 1);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a semaphore with a bad sized block. */
+ status = _txe_semaphore_create(&semaphore_3, "semaphore 3", 1, (sizeof(TX_SEMAPHORE)+1));
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create an already created semaphore. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-semaphore. */
+ status = tx_semaphore_delete(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-created semaphore. */
+ semaphore_2.tx_semaphore_id = 0;
+ status = tx_semaphore_delete(&semaphore_2);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get a non-semaphore. */
+ status = tx_semaphore_get(TX_NULL, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get a non-created semaphore. */
+ semaphore_2.tx_semaphore_id = 0;
+ status = tx_semaphore_get(&semaphore_2, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to put a non-semaphore. */
+ status = tx_semaphore_put(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to put a non-created semaphore. */
+ semaphore_2.tx_semaphore_id = 0;
+ status = tx_semaphore_put(&semaphore_2);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to ceiling put a non-semaphore. */
+ status = tx_semaphore_ceiling_put(TX_NULL, 0);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to ceiling put a non-created semaphore. */
+ semaphore_2.tx_semaphore_id = 0;
+ status = tx_semaphore_ceiling_put(&semaphore_2, 0);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to ceiling put with an invalid ceiling of 0. */
+ status = tx_semaphore_ceiling_put(&semaphore_0, 0);
+
+ /* Check for status. */
+ if (status != TX_INVALID_CEILING)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Attempt to get from semaphore with an instance. Should be successful! */
+ status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get from semaphore without an instance. Should be unsuccessful. */
+ status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_INSTANCE)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Put to semaphore that has an instance already. Should now be 2! */
+ status = tx_semaphore_put(&semaphore_1);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (semaphore_1.tx_semaphore_count != 2))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+
+ /* Attempt to get from semaphore with an instance. Should be successful! */
+ status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get from semaphore with an instance. Should be successful. */
+ status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Resume the thread 1 so we can take an interrupt on top of it. */
+ tx_thread_resume(&thread_1);
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete semaphores. */
+ status = tx_semaphore_delete(&semaphore_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ status = tx_semaphore_delete(&semaphore_1);
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+ }
+} \ No newline at end of file
diff --git a/test/smp/regression/threadx_semaphore_ceiling_put_test.c b/test/smp/regression/threadx_semaphore_ceiling_put_test.c
new file mode 100644
index 00000000..5364d2d9
--- /dev/null
+++ b/test/smp/regression/threadx_semaphore_ceiling_put_test.c
@@ -0,0 +1,334 @@
+/* This test is designed to test the semaphore ceiling put. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_SEMAPHORE semaphore_0;
+static TX_SEMAPHORE semaphore_1;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_ceiling_put_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 Semaphore Ceiling Put Test.................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Semaphore Ceiling Put Test.................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Ceiling Put Test.................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+ status += tx_semaphore_create(&semaphore_1, "semaphore 1", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Ceiling Put Test.................................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Ceiling Put Test.................................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Ceiling Put Test.................................. ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Ceiling Put Test.................................. ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Perform semaphore puts in order to exercise the ceiling put logic. */
+ status = tx_semaphore_ceiling_put(&semaphore_0, 2);
+ status += tx_semaphore_ceiling_put(&semaphore_0, 2);
+ status += tx_semaphore_ceiling_put(&semaphore_0, 2);
+ status += tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+ status += tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_CEILING_EXCEEDED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to make the other thread suspend on the semaphore. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Place an instance on the semaphore, this should resume the other thread
+ but not preempt this thread. */
+ status = tx_semaphore_ceiling_put(&semaphore_0, 2);
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow the other thread to run. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 3)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* At this point, we need to resume thread 2 and relinquish in order to get that thread suspended on the
+ semaphore as well. */
+ tx_thread_resume(&thread_2);
+ tx_thread_relinquish();
+
+ /* Perform 2 semaphore put operations to resume both threads. */
+ status = tx_semaphore_ceiling_put(&semaphore_0, 2);
+ status += tx_semaphore_ceiling_put(&semaphore_0, 2);
+
+ /* Let both threads run again. */
+ tx_thread_relinquish();
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 3))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Now turn off the semaphore notification. */
+ status = tx_semaphore_put_notify(&semaphore_0, TX_NULL);
+
+#ifdef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Clear the status since we know this feature is disabled and will return an error. */
+ status = TX_SUCCESS;
+#endif
+
+ /* Put a semaphore on a semaphore that does not have suspension. */
+ status += tx_semaphore_ceiling_put(&semaphore_1, 2);
+
+ /* Repeat the semaphore ceiling put without notification process! */
+
+ /* Place an instance on the semaphore, this should resume the other thread
+ but not preempt this thread. */
+ status += tx_semaphore_ceiling_put(&semaphore_0, 2);
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 5))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #9a\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow the other thread to run. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 7)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #10a\n");
+ test_control_return(1);
+ }
+
+ /* At this point, we need to resume thread 2 and relinquish in order to get that thread suspended on the
+ semaphore as well. */
+ tx_thread_resume(&thread_2);
+ tx_thread_relinquish();
+
+ /* Perform 2 semaphore put operations to resume both threads. */
+ status = tx_semaphore_ceiling_put(&semaphore_0, 2);
+ status += tx_semaphore_ceiling_put(&semaphore_0, 2);
+
+ /* Let both threads run again. */
+ tx_thread_relinquish();
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 9) || (thread_2_counter != 5))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #11a\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ while(1)
+ {
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ while(1)
+ {
+
+ /* Increment thread run counter. */
+ thread_2_counter++;
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_2_counter++;
+ }
+}
diff --git a/test/smp/regression/threadx_semaphore_delete_test.c b/test/smp/regression/threadx_semaphore_delete_test.c
new file mode 100644
index 00000000..f18d31dc
--- /dev/null
+++ b/test/smp/regression/threadx_semaphore_delete_test.c
@@ -0,0 +1,213 @@
+/* This test is designed to test the semaphore suspension and semaphore delete with
+ suspended threads. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_delete_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 Semaphore Delete Test....................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Semaphore Delete Test....................................... ERROR #2!\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_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 Semaphore Delete Test....................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Delete Test....................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Delete Test....................................... ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Delete Test....................................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Delete Test....................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Relinquish to let other threads run. */
+ tx_thread_relinquish();
+
+ /* Other threads should now be suspended on the semaphore. */
+
+ /* Delete the semaphore to test it out! */
+ status = tx_semaphore_delete(&semaphore_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow other threads to run again before we return. */
+ tx_thread_relinquish();
+
+ /* Now check the run counter of each thread. */
+ if ((thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_DELETED)
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_DELETED)
+ thread_2_counter++;
+}
diff --git a/test/smp/regression/threadx_semaphore_information_test.c b/test/smp/regression/threadx_semaphore_information_test.c
new file mode 100644
index 00000000..a8f6d242
--- /dev/null
+++ b/test/smp/regression/threadx_semaphore_information_test.c
@@ -0,0 +1,418 @@
+/* This test is designed to test the semaphore information services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_semaphore.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static TX_SEMAPHORE semaphore_0;
+static TX_SEMAPHORE semaphore_1;
+static TX_SEMAPHORE semaphore_2;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+UINT _tx_semaphore_performance_info_get(TX_SEMAPHORE *semaphore_ptr, ULONG *puts, ULONG *gets,
+ ULONG *suspensions, ULONG *timeouts);
+
+
+/* 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_semaphore_information_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 Semaphore Information Test.................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 1. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Information Test.................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_1, "semaphore 1", 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Information Test.................................. ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *name;
+ULONG current_value;
+TX_THREAD *first_suspended;
+ULONG suspended_count;
+TX_SEMAPHORE *next_semaphore;
+ULONG puts;
+ULONG gets;
+ULONG suspensions;
+ULONG timeouts;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Information Test.................................. ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to get semaphore information from a non-semaphore. */
+ status = tx_semaphore_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get semaphore information from a non-created semaphore. */
+ semaphore_2.tx_semaphore_id = 0;
+ status = tx_semaphore_info_get(&semaphore_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Attempt to get from semaphore with an instance. Should be successful! */
+ status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get from semaphore without an instance. Should be unsuccessful. */
+ status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_INSTANCE)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Put to semaphore that has an instance already. Should now be 2! */
+ status = tx_semaphore_put(&semaphore_1);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (semaphore_1.tx_semaphore_count != 2))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+
+ /* Attempt to get from semaphore with an instance. Should be successful! */
+ status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get from semaphore with an instance. Should be successful. */
+ status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore information. */
+ status = tx_semaphore_info_get(&semaphore_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_semaphore_info_get(&semaphore_0, &name, &current_value, &first_suspended, &suspended_count, &next_semaphore);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (current_value != semaphore_0.tx_semaphore_count) ||
+ (first_suspended != semaphore_0.tx_semaphore_suspension_list) || (suspended_count != semaphore_0.tx_semaphore_suspended_count) ||
+ (next_semaphore != semaphore_0.tx_semaphore_created_next))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+#ifdef TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
+
+ /* Get semaphore performance information with NULL pointer. */
+ status = _tx_semaphore_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(&semaphore_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_semaphore_performance_info_get(&semaphore_0, &puts, &gets, &suspensions, &timeouts);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (puts != semaphore_0.tx_semaphore_performance_put_count) || (gets != semaphore_0.tx_semaphore_performance_get_count) ||
+ (suspensions != semaphore_0.tx_semaphore_performance_suspension_count) || (timeouts != semaphore_0.tx_semaphore_performance_timeout_count))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore system performance information. */
+ status = tx_semaphore_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_semaphore_performance_system_info_get(&puts, &gets, &suspensions, &timeouts);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (puts != _tx_semaphore_performance_put_count) || (gets != _tx_semaphore_performance_get_count) ||
+ (suspensions != _tx_semaphore_performance_suspension_count) || (timeouts != _tx_semaphore_performance_timeout_count))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(&semaphore_0, &puts, &gets, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(TX_NULL, &puts, &gets, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(TX_NULL, TX_NULL, &gets, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore system performance information. */
+ status = tx_semaphore_performance_system_info_get(&puts, &gets, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore system performance information. */
+ status = tx_semaphore_performance_system_info_get(TX_NULL, &gets, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore system performance information. */
+ status = tx_semaphore_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore system performance information. */
+ status = tx_semaphore_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore system performance information. */
+ status = tx_semaphore_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Delete semaphores. */
+ status = tx_semaphore_delete(&semaphore_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ status = tx_semaphore_delete(&semaphore_1);
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
diff --git a/test/smp/regression/threadx_semaphore_non_preemption_test.c b/test/smp/regression/threadx_semaphore_non_preemption_test.c
new file mode 100644
index 00000000..40219546
--- /dev/null
+++ b/test/smp/regression/threadx_semaphore_non_preemption_test.c
@@ -0,0 +1,271 @@
+/* This test is designed to test the semaphore suspension and another thread resuming the
+ same priority thread by doing a semaphore put. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_non_preemption_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 Semaphore Non Preemption Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Semaphore Non Preemption Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Non Preemption Test............................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Non Preemption Test............................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Non Preemption Test............................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Non Preemption Test............................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Non Preemption Test............................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Perform a semaphore put and get, just to exercise the notify path of a non-resumption
+ semaphore put. */
+ status = tx_semaphore_put(&semaphore_0);
+ status += tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to make the other thread suspend on the semaphore. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Place an instance on the semaphore, this should resume the other thread
+ but not preempt this thread. */
+ status = tx_semaphore_put(&semaphore_0);
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow the other thread to run. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 3)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* At this point, we need to resume thread 2 and relinquish in order to get that thread suspended on the
+ semaphore as well. */
+ tx_thread_resume(&thread_2);
+ tx_thread_relinquish();
+
+ /* Perform 2 semaphore put operations to resume both threads. */
+ status = tx_semaphore_put(&semaphore_0);
+ status += tx_semaphore_put(&semaphore_0);
+
+ /* Let both threads run again. */
+ tx_thread_relinquish();
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 3))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ while(1)
+ {
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ while(1)
+ {
+
+ /* Increment thread run counter. */
+ thread_2_counter++;
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_2_counter++;
+ }
+}
+
diff --git a/test/smp/regression/threadx_semaphore_preemption_test.c b/test/smp/regression/threadx_semaphore_preemption_test.c
new file mode 100644
index 00000000..347042bc
--- /dev/null
+++ b/test/smp/regression/threadx_semaphore_preemption_test.c
@@ -0,0 +1,179 @@
+/* This test is designed to test the semaphore suspension and another thread resuming the
+ higher priority thread by doing a semaphore put. Higher-priority thread should preempt. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_preemption_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 Semaphore Preemption Test................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Preemption Test................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Preemption Test................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Preemption Test................................... ERROR #4\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Preemption Test................................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Preemption Test................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* The other thread should now be suspended on the semaphore. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Place an instance on the semaphore, this should cause the other thread
+ to preempt. */
+ status = tx_semaphore_put(&semaphore_0);
+
+ /* Check status and run counter of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+}
+
diff --git a/test/smp/regression/threadx_semaphore_prioritize.c b/test/smp/regression/threadx_semaphore_prioritize.c
new file mode 100644
index 00000000..79622667
--- /dev/null
+++ b/test/smp/regression/threadx_semaphore_prioritize.c
@@ -0,0 +1,525 @@
+/* This test is designed to test semaphore prioritize. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static TX_SEMAPHORE semaphore_0;
+static TX_SEMAPHORE semaphore_1;
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Determine if thread 3 is at the front of the suspension list. */
+ if (semaphore_0.tx_semaphore_suspension_list == &thread_3)
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+ }
+ else
+ {
+
+ /* Abort the wait of thread 5. */
+ tx_thread_wait_abort(&thread_5);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+ }
+}
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_prioritize_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create the semaphore with no instances. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #9\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #10\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Prioritize Test................................... ");
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to prioritize a non-semaphore. */
+ status = tx_semaphore_prioritize(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to prioritize a non-created semaphore. */
+ semaphore_1.tx_semaphore_id = 0;
+ status = tx_semaphore_prioritize(&semaphore_1);
+
+ /* Check status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Prioritize the semaphore suspension list - empty list case! */
+ status = tx_semaphore_prioritize(&semaphore_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != TX_NULL))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 and 2 are suspended on the semaphore. */
+ if ((thread_1.tx_thread_state != TX_SEMAPHORE_SUSP) || (thread_2.tx_thread_state != TX_SEMAPHORE_SUSP) ||
+ (semaphore_0.tx_semaphore_suspension_list != &thread_1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the semaphore suspension list. */
+ status = tx_semaphore_prioritize(&semaphore_0);
+
+ /* Check status and make sure thread 2 is not at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_2))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the semaphore suspension list again - in this case, the list is already prioritized. */
+ status = tx_semaphore_prioritize(&semaphore_0);
+
+ /* Check status and make sure thread 2 is not at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_2))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #15a\n");
+ test_control_return(1);
+ }
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the semaphore suspension list. */
+ status = tx_semaphore_prioritize(&semaphore_0);
+
+ /* Check status and make sure thread 3 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_3))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the semaphore suspension list. */
+ status = tx_semaphore_prioritize(&semaphore_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Check status and make sure thread 3 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_4))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+UINT status;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+UINT status;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+UINT status;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+UINT status;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+UINT status;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+ }
+}
+
diff --git a/test/smp/regression/threadx_semaphore_thread_terminate_test.c b/test/smp/regression/threadx_semaphore_thread_terminate_test.c
new file mode 100644
index 00000000..b8beeff2
--- /dev/null
+++ b/test/smp/regression/threadx_semaphore_thread_terminate_test.c
@@ -0,0 +1,224 @@
+/* This test is designed to test thread terminate calls when threads are suspended on
+ a semaphore. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_thread_terminate_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 Semaphore Thread Terminate Test............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Semaphore Thread Terminate Test............................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_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 Semaphore Thread Terminate Test............................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Thread Terminate Test............................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Thread Terminate Test............................. ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Thread Terminate Test............................. ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Thread Terminate Test............................. ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Relinquish to let other threads run. */
+ tx_thread_relinquish();
+
+ /* Other threads should now be suspended on the semaphore. */
+ if ((thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Terminate the other threads to make sure the semaphore gets
+ cleaned up. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Terminate the other thread. */
+ status = tx_thread_terminate(&thread_2);
+
+ /* Relinquish just to make sure. */
+ tx_thread_relinquish();
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the semaphore. */
+ tx_semaphore_get(&semaphore_0, 33);
+
+ /* Should never get here! */
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Increment thread run counter. */
+ thread_2_counter++;
+
+ /* Suspend on the semaphore. */
+ tx_semaphore_get(&semaphore_0, 44);
+
+ /* Should never get here! */
+ thread_2_counter++;
+}
diff --git a/test/smp/regression/threadx_semaphore_timeout_test.c b/test/smp/regression/threadx_semaphore_timeout_test.c
new file mode 100644
index 00000000..55cd8a96
--- /dev/null
+++ b/test/smp/regression/threadx_semaphore_timeout_test.c
@@ -0,0 +1,165 @@
+/* This test is designed to test the semaphore suspension and timeout functionality. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static TX_SEMAPHORE semaphore_0;
+static TX_SEMAPHORE semaphore_1;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_timeout_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 Semaphore Suspension Timeout Test........................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Suspension Timeout Test........................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Suspension Timeout Test........................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Suspension Timeout Test........................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Semaphore Suspension Timeout Test........................... ");
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to setup semaphore notify callback on non-semaphore. */
+ status = tx_semaphore_put_notify(TX_NULL, put_notify);
+
+ /* Check status */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to setup semaphore notify callback on non-created semaphore. */
+ semaphore_1.tx_semaphore_id = 0;
+ status = tx_semaphore_put_notify(&semaphore_1, put_notify);
+
+ /* Check status */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Sleep for 2 ticks for fresh timer. */
+ tx_thread_sleep(2);
+
+ /* Set clock to 0. */
+ tx_time_set(0);
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, 33);
+
+ /* Did we get the right status at the right time? */
+ if ((status != TX_NO_INSTANCE) || (tx_time_get() != 33))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
diff --git a/test/smp/regression/threadx_smp_multiple_threads_one_core_test.c b/test/smp/regression/threadx_smp_multiple_threads_one_core_test.c
new file mode 100644
index 00000000..2ca5b947
--- /dev/null
+++ b/test/smp/regression/threadx_smp_multiple_threads_one_core_test.c
@@ -0,0 +1,348 @@
+/* Define the ThreadX SMP multiple threads excluded to one core test. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD thread_4;
+static TX_THREAD thread_5;
+static TX_THREAD thread_6;
+static TX_THREAD thread_7;
+
+
+static ULONG thread_0_counter;
+static ULONG thread_1_counter;
+static ULONG thread_2_counter;
+static ULONG thread_3_counter;
+static ULONG thread_4_counter;
+static ULONG thread_5_counter;
+static ULONG thread_6_counter;
+static ULONG thread_7_counter;
+
+
+static unsigned long error = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+static void thread_7_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_smp_multiple_threads_one_core_test(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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Multiple Threads One Core Test.......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_1, 0xD); /* Only core 1! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Multiple Threads One Core Test.......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_2, 0xB); /* Only core 2! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Multiple Threads One Core Test.......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_3, 0x7); /* Only core 3! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Multiple Threads One Core Test.......................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_4, 0xE); /* Only core 0! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Multiple Threads One Core Test.......................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_5, 0xD); /* Only core 1! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Multiple Threads One Core Test.......................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_6, 0xB); /* Only core 2! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Multiple Threads One Core Test.......................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_7, "thread 7", thread_7_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_7, 0x7); /* Only core 3! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Multiple Threads One Core Test.......................... ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 0. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Multiple Threads One Core Test.......................... ERROR #9\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+
+ /* Inform user. */
+ printf("Running SMP Multiple Threads One Core Test.......................... ");
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_1);
+ status += tx_thread_resume(&thread_2);
+ status += tx_thread_resume(&thread_3);
+ status += tx_thread_resume(&thread_4);
+ status += tx_thread_resume(&thread_5);
+ status += tx_thread_resume(&thread_6);
+ status += tx_thread_resume(&thread_7);
+
+ /* Suspend this thread to let the others run. */
+ tx_thread_sleep(5);
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (error) || (thread_1_counter != 1) || (tx_thread_smp_core_get() != 0) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) || (thread_4_counter != 1) ||
+ (thread_5_counter != 1) || (thread_6_counter != 1) || (thread_7_counter != 1))
+ {
+
+ /* Execution error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+ /* Ensure this thread is on the correct core. */
+ if (tx_thread_smp_core_get() != 1)
+ error++;
+
+ thread_1_counter++;
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* Ensure this thread is on the correct core. */
+ if (tx_thread_smp_core_get() != 2)
+ error++;
+
+ thread_2_counter++;
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* Ensure this thread is on the correct core. */
+ if (tx_thread_smp_core_get() != 3)
+ error++;
+
+ thread_3_counter++;
+ tx_thread_suspend(&thread_3);
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* Ensure this thread is on the correct core. */
+ if (tx_thread_smp_core_get() != 0)
+ error++;
+
+ thread_4_counter++;
+ tx_thread_suspend(&thread_4);
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* Ensure this thread is on the correct core. */
+ if (tx_thread_smp_core_get() != 1)
+ error++;
+
+ thread_5_counter++;
+ tx_thread_suspend(&thread_5);
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* Ensure this thread is on the correct core. */
+ if (tx_thread_smp_core_get() != 2)
+ error++;
+
+ thread_6_counter++;
+ tx_thread_suspend(&thread_6);
+ }
+}
+
+
+static void thread_7_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* Ensure this thread is on the correct core. */
+ if (tx_thread_smp_core_get() != 3)
+ error++;
+
+ thread_7_counter++;
+ tx_thread_suspend(&thread_7);
+ }
+}
diff --git a/test/smp/regression/threadx_smp_non_trivial_scheduling_test.c b/test/smp/regression/threadx_smp_non_trivial_scheduling_test.c
new file mode 100644
index 00000000..ded600da
--- /dev/null
+++ b/test/smp/regression/threadx_smp_non_trivial_scheduling_test.c
@@ -0,0 +1,350 @@
+/* Define the ThreadX SMP non-trivial scheduling test. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+
+
+static ULONG thread_0_counter;
+static ULONG thread_1_counter;
+static ULONG thread_2_counter;
+static ULONG thread_3_counter;
+
+
+extern TX_THREAD *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES];
+
+static unsigned long error = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_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_smp_non_trivial_scheduling_test(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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Only allow core 0 for now */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_1, 0x9); /* Exclude core 2 and 1 */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_2, 0xB); /* Exclude core 3, 1 and 0 */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_3, 0xE); /* Exclude core 0 */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 0. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #5\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+UINT original_threshold;
+
+
+ /* Inform user. */
+ printf("Running SMP Non-Trivial Scheduling Test............................. ");
+
+ /* Move enable core 0 and 1. */
+ status = tx_thread_smp_core_exclude(&thread_0, 0xC); /* Allow core 0 and 1 */
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0))
+ {
+
+ /* Execution error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 1. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 2. */
+ status = tx_thread_resume(&thread_2);
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 3. */
+ status = tx_thread_resume(&thread_3);
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread 2 and cause a rebalance of the execution list. */
+ status = tx_thread_suspend(&thread_2);
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_3) || (_tx_thread_execute_ptr[1] != &thread_0)
+ || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #10");
+ test_control_return(1);
+ }
+
+ /* Now suspend threads 3 and 1. */
+ status = tx_thread_suspend(&thread_3);
+ status += tx_thread_suspend(&thread_1);
+
+ /* Use preemption-threshold to test the rebalance routine. */
+ status += tx_thread_preemption_change(&thread_3, 2, &original_threshold);
+
+ /* Move thread 0 back to core 0 and then allow core 1 again. */
+ status += tx_thread_smp_core_exclude(&thread_0, 0xE);
+ status += tx_thread_smp_core_exclude(&thread_0, 0xC);
+
+ /* Make sure threads 1 defaults to core 1. */
+ status += tx_thread_smp_core_exclude(&thread_1, 0xD);
+ status += tx_thread_smp_core_exclude(&thread_1, 0x9);
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #11");
+ test_control_return(1);
+ }
+
+ /* Resume thread 1. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 2. */
+ status = tx_thread_resume(&thread_2);
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 3. */
+ status = tx_thread_resume(&thread_3);
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread 2 and cause a rebalance of the execution list. */
+ status = tx_thread_suspend(&thread_2);
+
+ /* With preemption-threshold disabled, thread_3 can not run since preemption-threshold is set to 0 and there is already a
+ zero priority thread running. */
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_3) || (_tx_thread_execute_ptr[1] != &thread_0)
+ || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL))
+#else
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+#endif
+ {
+
+ /* Execution error. */
+ printf("ERROR #15");
+ test_control_return(1);
+ }
+
+ /* Now suspend threads 3 and 1. */
+ status = tx_thread_suspend(&thread_3);
+ status += tx_thread_suspend(&thread_1);
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != TX_NULL) || (_tx_thread_execute_ptr[1] != &thread_0)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+#else
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+#endif
+ {
+
+ /* Execution error. */
+ printf("ERROR #16");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+ thread_1_counter++;
+ tx_thread_identify();
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+ thread_2_counter++;
+ tx_thread_identify();
+ }
+}
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+ thread_3_counter++;
+ tx_thread_identify();
+ }
+}
+
+
diff --git a/test/smp/regression/threadx_smp_one_thread_dynamic_exclusion_test.c b/test/smp/regression/threadx_smp_one_thread_dynamic_exclusion_test.c
new file mode 100644
index 00000000..82caeefa
--- /dev/null
+++ b/test/smp/regression/threadx_smp_one_thread_dynamic_exclusion_test.c
@@ -0,0 +1,145 @@
+/* Define the ThreadX SMP one thread dynamic thread exclusion test. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+
+static TX_THREAD thread_0;
+
+
+static ULONG thread_0_counter;
+
+
+static unsigned long error = 0;
+
+
+/* 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_smp_one_thread_dynamic_exclusion_test(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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_0, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP One Thread Dynamic Exclusion Test....................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+
+ /* Resume thread 0. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP One Thread Dynamic Exclusion Test....................... ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+
+ /* Inform user. */
+ printf("Running SMP One Thread Dynamic Exclusion Test....................... ");
+
+ /* Move to core 1. */
+ status = tx_thread_smp_core_exclude(&thread_0, 0xD); /* Only core 1! */
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (tx_thread_smp_core_get() != 1))
+ {
+
+ /* Execution error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Move to core 2. */
+ status = tx_thread_smp_core_exclude(&thread_0, 0xB); /* Only core 2! */
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (tx_thread_smp_core_get() != 2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Move to core 3. */
+ status = tx_thread_smp_core_exclude(&thread_0, 0x7); /* Only core 3! */
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (tx_thread_smp_core_get() != 3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Move back to core 0. */
+ status = tx_thread_smp_core_exclude(&thread_0, 0xE); /* Only core 0! */
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (tx_thread_smp_core_get() != 0))
+ {
+
+ /* Execution error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
diff --git a/test/smp/regression/threadx_smp_preemption_threshold_test.c b/test/smp/regression/threadx_smp_preemption_threshold_test.c
new file mode 100644
index 00000000..920c89b1
--- /dev/null
+++ b/test/smp/regression/threadx_smp_preemption_threshold_test.c
@@ -0,0 +1,534 @@
+/* Define the ThreadX SMP preemption-threshold test. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+extern TX_THREAD *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES];
+
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_5;
+static TX_THREAD thread_16;
+static TX_THREAD thread_16_pt5;
+static TX_THREAD thread_18;
+static TX_THREAD thread_23_pt17;
+static TX_THREAD thread_25;
+static TX_THREAD thread_27_pt24;
+static TX_THREAD thread_31;
+
+static ULONG thread_run_counter[10];
+
+
+static unsigned long error = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_entry(ULONG thread_input);
+static void thread_0_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void delay(UINT i)
+{
+
+ /* Wait until the thread runs! */
+ while (thread_run_counter[i] == 0)
+ {
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_smp_preemption_threshold_test(void *first_unused_memory)
+#endif
+{
+
+UINT status;
+CHAR *pointer;
+UINT i;
+
+
+ /* 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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Preemption-Threshold Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_1, 0); /* Any core! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Preemption-Threshold Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_5, 0); /* Any core! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Preemption-Threshold Test............................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_16, "thread 16", thread_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_16, 0); /* Any core! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Preemption-Threshold Test............................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_16_pt5, "thread 16 PT5", thread_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 5, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_16_pt5, 0); /* Any core! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Preemption-Threshold Test............................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_18, "thread 18", thread_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_18, 0); /* Any core! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Preemption-Threshold Test............................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_23_pt17, "thread 23 PT17", thread_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 23, 17, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_23_pt17, 0); /* Any core! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Preemption-Threshold Test............................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_25, "thread 25", thread_entry, 7,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 25, 25, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_25, 0); /* Any core! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Preemption-Threshold Test............................... ERROR #8\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_27_pt24, "thread 27 PT24", thread_entry, 8,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 27, 24, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_27_pt24, 0); /* Any core! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Preemption-Threshold Test............................... ERROR #9\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_31, "thread 31", thread_entry, 9,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31, 0); /* Any core! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Preemption-Threshold Test............................... ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Clear the thread run count array. */
+ for (i = 0; i < 10; i++)
+ {
+ thread_run_counter[i] = 0;
+ }
+
+ /* Resume thread 0. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Preemption-Threshold Test............................... ERROR #11\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+
+ /* Inform user. */
+ printf("Running SMP Preemption-Threshold Test............................... ");
+
+ /* This test is only useful when preemption-threshold is enabled. */
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+ /* Resume thread. */
+ status = tx_thread_resume(&thread_31);
+ delay(9);
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread. */
+ status = tx_thread_resume(&thread_27_pt24);
+ delay(8);
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_27_pt24)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread. */
+ status = tx_thread_resume(&thread_23_pt17);
+ delay(6);
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_23_pt17)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread. */
+ status = tx_thread_resume(&thread_16_pt5);
+ delay(4);
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread. */
+ status = tx_thread_resume(&thread_16);
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread. */
+ status = tx_thread_resume(&thread_25);
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread. */
+ status = tx_thread_resume(&thread_18);
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread. */
+ status = tx_thread_resume(&thread_5);
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread. */
+ status = tx_thread_resume(&thread_1);
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
+ || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Suspend Thread 16 pt5. */
+ status = tx_thread_suspend(&thread_16_pt5);
+
+ delay(2);
+ delay(3);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
+ || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_16))
+ {
+
+ /* Execution error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+
+ /* Suspend Thread 16. */
+ status = tx_thread_suspend(&thread_16);
+
+ delay(6);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
+ || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_23_pt17))
+ {
+
+ /* Execution error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Suspend Thread 23 pt 17. */
+ status = tx_thread_suspend(&thread_23_pt17);
+
+ delay(5);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
+ || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_18))
+ {
+
+ /* Execution error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+
+ /* Suspend Thread 18. */
+ status = tx_thread_suspend(&thread_18);
+
+ delay(8);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
+ || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_27_pt24))
+ {
+
+ /* Execution error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Suspend Thread 27 pt 24. */
+ status = tx_thread_suspend(&thread_27_pt24);
+
+ delay(7);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
+ || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_25))
+ {
+
+ /* Execution error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Suspend Thread 25. */
+ status = tx_thread_suspend(&thread_25);
+
+ delay(9);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
+ || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_31))
+ {
+
+ /* Execution error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 16 pt 5. */
+ status = tx_thread_resume(&thread_16_pt5);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
+ || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_31))
+ {
+
+ /* Execution error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread 16 pt 5. */
+ status = tx_thread_suspend(&thread_16_pt5);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
+ || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_31))
+ {
+
+ /* Execution error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread 31. */
+ status = tx_thread_suspend(&thread_31);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
+ || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread 1. */
+ status = tx_thread_suspend(&thread_1);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread 5. */
+ status = tx_thread_suspend(&thread_5);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+
+ test_control_return(0);
+}
+
+
+static void thread_entry(ULONG thread_input)
+{
+
+ /* Increment the run counter. */
+ thread_run_counter[thread_input]++;
+
+ while(1)
+ {
+
+ tx_thread_identify();
+
+ /* Indicate the thread is running... */
+ thread_run_counter[thread_input]++;
+ }
+}
diff --git a/test/smp/regression/threadx_smp_random_resume_suspend_exclusion_pt_test.c b/test/smp/regression/threadx_smp_random_resume_suspend_exclusion_pt_test.c
new file mode 100644
index 00000000..cc2ecca0
--- /dev/null
+++ b/test/smp/regression/threadx_smp_random_resume_suspend_exclusion_pt_test.c
@@ -0,0 +1,2490 @@
+/* Define the ThreadX SMP random resume/suspend/exclude/pt test. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//#define MAX_PASSES 50000000
+//#define MAX_PASSES 50000
+#define MAX_PASSES 500
+
+
+/* Define the ThreadX object control blocks... Must have 256 priority levels... and assumes 4 cores. */
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD thread_4;
+static TX_THREAD thread_5;
+static TX_THREAD thread_6;
+static TX_THREAD thread_7;
+static TX_THREAD thread_8;
+static TX_THREAD thread_9;
+static TX_THREAD thread_10;
+static TX_THREAD thread_11;
+static TX_THREAD thread_12;
+static TX_THREAD thread_13;
+static TX_THREAD thread_14;
+static TX_THREAD thread_15;
+static TX_THREAD thread_16;
+static TX_THREAD thread_17;
+static TX_THREAD thread_18;
+static TX_THREAD thread_19;
+static TX_THREAD thread_20;
+static TX_THREAD thread_21;
+static TX_THREAD thread_22;
+static TX_THREAD thread_23;
+static TX_THREAD thread_24;
+static TX_THREAD thread_25;
+static TX_THREAD thread_26;
+static TX_THREAD thread_27;
+static TX_THREAD thread_28;
+static TX_THREAD thread_29;
+static TX_THREAD thread_30;
+static TX_THREAD thread_31;
+static TX_THREAD thread_32;
+static TX_THREAD thread_33;
+static TX_THREAD thread_34;
+static TX_THREAD thread_35;
+static TX_THREAD thread_36;
+static TX_THREAD thread_37;
+static TX_THREAD thread_38;
+static TX_THREAD thread_39;
+static TX_THREAD thread_40;
+static TX_THREAD thread_41;
+static TX_THREAD thread_42;
+static TX_THREAD thread_43;
+static TX_THREAD thread_44;
+static TX_THREAD thread_45;
+static TX_THREAD thread_46;
+static TX_THREAD thread_47;
+static TX_THREAD thread_48;
+static TX_THREAD thread_49;
+static TX_THREAD thread_50;
+static TX_THREAD thread_51;
+static TX_THREAD thread_52;
+static TX_THREAD thread_53;
+static TX_THREAD thread_54;
+static TX_THREAD thread_55;
+static TX_THREAD thread_56;
+static TX_THREAD thread_57;
+static TX_THREAD thread_58;
+static TX_THREAD thread_59;
+static TX_THREAD thread_60;
+static TX_THREAD thread_61;
+static TX_THREAD thread_62;
+static TX_THREAD thread_63;
+static TX_THREAD thread_64;
+static TX_THREAD thread_65;
+static TX_THREAD thread_66;
+static TX_THREAD thread_67;
+static TX_THREAD thread_68;
+static TX_THREAD thread_69;
+static TX_THREAD thread_70;
+static TX_THREAD thread_71;
+static TX_THREAD thread_72;
+static TX_THREAD thread_73;
+static TX_THREAD thread_74;
+static TX_THREAD thread_75;
+static TX_THREAD thread_76;
+static TX_THREAD thread_77;
+static TX_THREAD thread_78;
+static TX_THREAD thread_79;
+static TX_THREAD thread_80;
+static TX_THREAD thread_81;
+static TX_THREAD thread_82;
+static TX_THREAD thread_83;
+static TX_THREAD thread_84;
+static TX_THREAD thread_85;
+static TX_THREAD thread_86;
+static TX_THREAD thread_87;
+static TX_THREAD thread_88;
+static TX_THREAD thread_89;
+static TX_THREAD thread_90;
+static TX_THREAD thread_91;
+static TX_THREAD thread_92;
+static TX_THREAD thread_93;
+static TX_THREAD thread_94;
+static TX_THREAD thread_95;
+static TX_THREAD thread_96;
+static TX_THREAD thread_97;
+static TX_THREAD thread_98;
+static TX_THREAD thread_99;
+static TX_THREAD thread_100;
+static TX_THREAD thread_101;
+static TX_THREAD thread_102;
+static TX_THREAD thread_103;
+static TX_THREAD thread_104;
+static TX_THREAD thread_105;
+static TX_THREAD thread_106;
+static TX_THREAD thread_107;
+static TX_THREAD thread_108;
+static TX_THREAD thread_109;
+static TX_THREAD thread_110;
+static TX_THREAD thread_111;
+static TX_THREAD thread_112;
+static TX_THREAD thread_113;
+static TX_THREAD thread_114;
+static TX_THREAD thread_115;
+static TX_THREAD thread_116;
+static TX_THREAD thread_117;
+static TX_THREAD thread_118;
+static TX_THREAD thread_119;
+static TX_THREAD thread_120;
+static TX_THREAD thread_121;
+static TX_THREAD thread_122;
+static TX_THREAD thread_123;
+static TX_THREAD thread_124;
+static TX_THREAD thread_125;
+static TX_THREAD thread_126;
+static TX_THREAD thread_127;
+static TX_THREAD thread_128;
+static TX_THREAD thread_129;
+static TX_THREAD thread_130;
+static TX_THREAD thread_131;
+static TX_THREAD thread_132;
+static TX_THREAD thread_133;
+static TX_THREAD thread_134;
+static TX_THREAD thread_135;
+static TX_THREAD thread_136;
+static TX_THREAD thread_137;
+static TX_THREAD thread_138;
+static TX_THREAD thread_139;
+static TX_THREAD thread_140;
+static TX_THREAD thread_141;
+static TX_THREAD thread_142;
+static TX_THREAD thread_143;
+static TX_THREAD thread_144;
+static TX_THREAD thread_145;
+static TX_THREAD thread_146;
+static TX_THREAD thread_147;
+static TX_THREAD thread_148;
+static TX_THREAD thread_149;
+static TX_THREAD thread_150;
+static TX_THREAD thread_151;
+static TX_THREAD thread_152;
+static TX_THREAD thread_153;
+static TX_THREAD thread_154;
+static TX_THREAD thread_155;
+static TX_THREAD thread_156;
+static TX_THREAD thread_157;
+static TX_THREAD thread_158;
+static TX_THREAD thread_159;
+static TX_THREAD thread_160;
+static TX_THREAD thread_161;
+static TX_THREAD thread_162;
+static TX_THREAD thread_163;
+static TX_THREAD thread_164;
+static TX_THREAD thread_165;
+static TX_THREAD thread_166;
+static TX_THREAD thread_167;
+static TX_THREAD thread_168;
+static TX_THREAD thread_169;
+static TX_THREAD thread_170;
+static TX_THREAD thread_171;
+static TX_THREAD thread_172;
+static TX_THREAD thread_173;
+static TX_THREAD thread_174;
+static TX_THREAD thread_175;
+static TX_THREAD thread_176;
+static TX_THREAD thread_177;
+static TX_THREAD thread_178;
+static TX_THREAD thread_179;
+static TX_THREAD thread_180;
+static TX_THREAD thread_181;
+static TX_THREAD thread_182;
+static TX_THREAD thread_183;
+static TX_THREAD thread_184;
+static TX_THREAD thread_185;
+static TX_THREAD thread_186;
+static TX_THREAD thread_187;
+static TX_THREAD thread_188;
+static TX_THREAD thread_189;
+static TX_THREAD thread_190;
+static TX_THREAD thread_191;
+static TX_THREAD thread_192;
+static TX_THREAD thread_193;
+static TX_THREAD thread_194;
+static TX_THREAD thread_195;
+static TX_THREAD thread_196;
+static TX_THREAD thread_197;
+static TX_THREAD thread_198;
+static TX_THREAD thread_199;
+static TX_THREAD thread_200;
+static TX_THREAD thread_201;
+static TX_THREAD thread_202;
+static TX_THREAD thread_203;
+static TX_THREAD thread_204;
+static TX_THREAD thread_205;
+static TX_THREAD thread_206;
+static TX_THREAD thread_207;
+static TX_THREAD thread_208;
+static TX_THREAD thread_209;
+static TX_THREAD thread_210;
+static TX_THREAD thread_211;
+static TX_THREAD thread_212;
+static TX_THREAD thread_213;
+static TX_THREAD thread_214;
+static TX_THREAD thread_215;
+static TX_THREAD thread_216;
+static TX_THREAD thread_217;
+static TX_THREAD thread_218;
+static TX_THREAD thread_219;
+static TX_THREAD thread_220;
+static TX_THREAD thread_221;
+static TX_THREAD thread_222;
+static TX_THREAD thread_223;
+static TX_THREAD thread_224;
+static TX_THREAD thread_225;
+static TX_THREAD thread_226;
+static TX_THREAD thread_227;
+static TX_THREAD thread_228;
+static TX_THREAD thread_229;
+static TX_THREAD thread_230;
+static TX_THREAD thread_231;
+static TX_THREAD thread_232;
+static TX_THREAD thread_233;
+static TX_THREAD thread_234;
+static TX_THREAD thread_235;
+static TX_THREAD thread_236;
+static TX_THREAD thread_237;
+static TX_THREAD thread_238;
+static TX_THREAD thread_239;
+static TX_THREAD thread_240;
+static TX_THREAD thread_241;
+static TX_THREAD thread_242;
+static TX_THREAD thread_243;
+static TX_THREAD thread_244;
+static TX_THREAD thread_245;
+static TX_THREAD thread_246;
+static TX_THREAD thread_247;
+static TX_THREAD thread_248;
+static TX_THREAD thread_249;
+static TX_THREAD thread_250;
+static TX_THREAD thread_251;
+static TX_THREAD thread_252;
+static TX_THREAD thread_253;
+static TX_THREAD thread_254;
+static TX_THREAD thread_255;
+
+static TX_THREAD thread_0_1;
+static TX_THREAD thread_1_1;
+static TX_THREAD thread_2_1;
+static TX_THREAD thread_3_1;
+static TX_THREAD thread_4_1;
+static TX_THREAD thread_5_1;
+static TX_THREAD thread_6_1;
+static TX_THREAD thread_7_1;
+static TX_THREAD thread_8_1;
+static TX_THREAD thread_9_1;
+static TX_THREAD thread_10_1;
+static TX_THREAD thread_11_1;
+static TX_THREAD thread_12_1;
+static TX_THREAD thread_13_1;
+static TX_THREAD thread_14_1;
+static TX_THREAD thread_15_1;
+static TX_THREAD thread_16_1;
+static TX_THREAD thread_17_1;
+static TX_THREAD thread_18_1;
+static TX_THREAD thread_19_1;
+static TX_THREAD thread_20_1;
+static TX_THREAD thread_21_1;
+static TX_THREAD thread_22_1;
+static TX_THREAD thread_23_1;
+static TX_THREAD thread_24_1;
+static TX_THREAD thread_25_1;
+static TX_THREAD thread_26_1;
+static TX_THREAD thread_27_1;
+static TX_THREAD thread_28_1;
+static TX_THREAD thread_29_1;
+static TX_THREAD thread_30_1;
+static TX_THREAD thread_31_1;
+static TX_THREAD thread_32_1;
+static TX_THREAD thread_33_1;
+static TX_THREAD thread_34_1;
+static TX_THREAD thread_35_1;
+static TX_THREAD thread_36_1;
+static TX_THREAD thread_37_1;
+static TX_THREAD thread_38_1;
+static TX_THREAD thread_39_1;
+static TX_THREAD thread_40_1;
+static TX_THREAD thread_41_1;
+static TX_THREAD thread_42_1;
+static TX_THREAD thread_43_1;
+static TX_THREAD thread_44_1;
+static TX_THREAD thread_45_1;
+static TX_THREAD thread_46_1;
+static TX_THREAD thread_47_1;
+static TX_THREAD thread_48_1;
+static TX_THREAD thread_49_1;
+static TX_THREAD thread_50_1;
+static TX_THREAD thread_51_1;
+static TX_THREAD thread_52_1;
+static TX_THREAD thread_53_1;
+static TX_THREAD thread_54_1;
+static TX_THREAD thread_55_1;
+static TX_THREAD thread_56_1;
+static TX_THREAD thread_57_1;
+static TX_THREAD thread_58_1;
+static TX_THREAD thread_59_1;
+static TX_THREAD thread_60_1;
+static TX_THREAD thread_61_1;
+static TX_THREAD thread_62_1;
+static TX_THREAD thread_63_1;
+static TX_THREAD thread_64_1;
+static TX_THREAD thread_65_1;
+static TX_THREAD thread_66_1;
+static TX_THREAD thread_67_1;
+static TX_THREAD thread_68_1;
+static TX_THREAD thread_69_1;
+static TX_THREAD thread_70_1;
+static TX_THREAD thread_71_1;
+static TX_THREAD thread_72_1;
+static TX_THREAD thread_73_1;
+static TX_THREAD thread_74_1;
+static TX_THREAD thread_75_1;
+static TX_THREAD thread_76_1;
+static TX_THREAD thread_77_1;
+static TX_THREAD thread_78_1;
+static TX_THREAD thread_79_1;
+static TX_THREAD thread_80_1;
+static TX_THREAD thread_81_1;
+static TX_THREAD thread_82_1;
+static TX_THREAD thread_83_1;
+static TX_THREAD thread_84_1;
+static TX_THREAD thread_85_1;
+static TX_THREAD thread_86_1;
+static TX_THREAD thread_87_1;
+static TX_THREAD thread_88_1;
+static TX_THREAD thread_89_1;
+static TX_THREAD thread_90_1;
+static TX_THREAD thread_91_1;
+static TX_THREAD thread_92_1;
+static TX_THREAD thread_93_1;
+static TX_THREAD thread_94_1;
+static TX_THREAD thread_95_1;
+static TX_THREAD thread_96_1;
+static TX_THREAD thread_97_1;
+static TX_THREAD thread_98_1;
+static TX_THREAD thread_99_1;
+static TX_THREAD thread_100_1;
+static TX_THREAD thread_101_1;
+static TX_THREAD thread_102_1;
+static TX_THREAD thread_103_1;
+static TX_THREAD thread_104_1;
+static TX_THREAD thread_105_1;
+static TX_THREAD thread_106_1;
+static TX_THREAD thread_107_1;
+static TX_THREAD thread_108_1;
+static TX_THREAD thread_109_1;
+static TX_THREAD thread_110_1;
+static TX_THREAD thread_111_1;
+static TX_THREAD thread_112_1;
+static TX_THREAD thread_113_1;
+static TX_THREAD thread_114_1;
+static TX_THREAD thread_115_1;
+static TX_THREAD thread_116_1;
+static TX_THREAD thread_117_1;
+static TX_THREAD thread_118_1;
+static TX_THREAD thread_119_1;
+static TX_THREAD thread_120_1;
+static TX_THREAD thread_121_1;
+static TX_THREAD thread_122_1;
+static TX_THREAD thread_123_1;
+static TX_THREAD thread_124_1;
+static TX_THREAD thread_125_1;
+static TX_THREAD thread_126_1;
+static TX_THREAD thread_127_1;
+static TX_THREAD thread_128_1;
+static TX_THREAD thread_129_1;
+static TX_THREAD thread_130_1;
+static TX_THREAD thread_131_1;
+static TX_THREAD thread_132_1;
+static TX_THREAD thread_133_1;
+static TX_THREAD thread_134_1;
+static TX_THREAD thread_135_1;
+static TX_THREAD thread_136_1;
+static TX_THREAD thread_137_1;
+static TX_THREAD thread_138_1;
+static TX_THREAD thread_139_1;
+static TX_THREAD thread_140_1;
+static TX_THREAD thread_141_1;
+static TX_THREAD thread_142_1;
+static TX_THREAD thread_143_1;
+static TX_THREAD thread_144_1;
+static TX_THREAD thread_145_1;
+static TX_THREAD thread_146_1;
+static TX_THREAD thread_147_1;
+static TX_THREAD thread_148_1;
+static TX_THREAD thread_149_1;
+static TX_THREAD thread_150_1;
+static TX_THREAD thread_151_1;
+static TX_THREAD thread_152_1;
+static TX_THREAD thread_153_1;
+static TX_THREAD thread_154_1;
+static TX_THREAD thread_155_1;
+static TX_THREAD thread_156_1;
+static TX_THREAD thread_157_1;
+static TX_THREAD thread_158_1;
+static TX_THREAD thread_159_1;
+static TX_THREAD thread_160_1;
+static TX_THREAD thread_161_1;
+static TX_THREAD thread_162_1;
+static TX_THREAD thread_163_1;
+static TX_THREAD thread_164_1;
+static TX_THREAD thread_165_1;
+static TX_THREAD thread_166_1;
+static TX_THREAD thread_167_1;
+static TX_THREAD thread_168_1;
+static TX_THREAD thread_169_1;
+static TX_THREAD thread_170_1;
+static TX_THREAD thread_171_1;
+static TX_THREAD thread_172_1;
+static TX_THREAD thread_173_1;
+static TX_THREAD thread_174_1;
+static TX_THREAD thread_175_1;
+static TX_THREAD thread_176_1;
+static TX_THREAD thread_177_1;
+static TX_THREAD thread_178_1;
+static TX_THREAD thread_179_1;
+static TX_THREAD thread_180_1;
+static TX_THREAD thread_181_1;
+static TX_THREAD thread_182_1;
+static TX_THREAD thread_183_1;
+static TX_THREAD thread_184_1;
+static TX_THREAD thread_185_1;
+static TX_THREAD thread_186_1;
+static TX_THREAD thread_187_1;
+static TX_THREAD thread_188_1;
+static TX_THREAD thread_189_1;
+static TX_THREAD thread_190_1;
+static TX_THREAD thread_191_1;
+static TX_THREAD thread_192_1;
+static TX_THREAD thread_193_1;
+static TX_THREAD thread_194_1;
+static TX_THREAD thread_195_1;
+static TX_THREAD thread_196_1;
+static TX_THREAD thread_197_1;
+static TX_THREAD thread_198_1;
+static TX_THREAD thread_199_1;
+static TX_THREAD thread_200_1;
+static TX_THREAD thread_201_1;
+static TX_THREAD thread_202_1;
+static TX_THREAD thread_203_1;
+static TX_THREAD thread_204_1;
+static TX_THREAD thread_205_1;
+static TX_THREAD thread_206_1;
+static TX_THREAD thread_207_1;
+static TX_THREAD thread_208_1;
+static TX_THREAD thread_209_1;
+static TX_THREAD thread_210_1;
+static TX_THREAD thread_211_1;
+static TX_THREAD thread_212_1;
+static TX_THREAD thread_213_1;
+static TX_THREAD thread_214_1;
+static TX_THREAD thread_215_1;
+static TX_THREAD thread_216_1;
+static TX_THREAD thread_217_1;
+static TX_THREAD thread_218_1;
+static TX_THREAD thread_219_1;
+static TX_THREAD thread_220_1;
+static TX_THREAD thread_221_1;
+static TX_THREAD thread_222_1;
+static TX_THREAD thread_223_1;
+static TX_THREAD thread_224_1;
+static TX_THREAD thread_225_1;
+static TX_THREAD thread_226_1;
+static TX_THREAD thread_227_1;
+static TX_THREAD thread_228_1;
+static TX_THREAD thread_229_1;
+static TX_THREAD thread_230_1;
+static TX_THREAD thread_231_1;
+static TX_THREAD thread_232_1;
+static TX_THREAD thread_233_1;
+static TX_THREAD thread_234_1;
+static TX_THREAD thread_235_1;
+static TX_THREAD thread_236_1;
+static TX_THREAD thread_237_1;
+static TX_THREAD thread_238_1;
+static TX_THREAD thread_239_1;
+static TX_THREAD thread_240_1;
+static TX_THREAD thread_241_1;
+static TX_THREAD thread_242_1;
+static TX_THREAD thread_243_1;
+static TX_THREAD thread_244_1;
+static TX_THREAD thread_245_1;
+static TX_THREAD thread_246_1;
+static TX_THREAD thread_247_1;
+static TX_THREAD thread_248_1;
+static TX_THREAD thread_249_1;
+static TX_THREAD thread_250_1;
+static TX_THREAD thread_251_1;
+static TX_THREAD thread_252_1;
+static TX_THREAD thread_253_1;
+static TX_THREAD thread_254_1;
+static TX_THREAD thread_255_1;
+
+static TX_THREAD thread_0_2;
+static TX_THREAD thread_1_2;
+static TX_THREAD thread_2_2;
+static TX_THREAD thread_3_2;
+static TX_THREAD thread_4_2;
+static TX_THREAD thread_5_2;
+static TX_THREAD thread_6_2;
+static TX_THREAD thread_7_2;
+static TX_THREAD thread_8_2;
+static TX_THREAD thread_9_2;
+static TX_THREAD thread_10_2;
+static TX_THREAD thread_11_2;
+static TX_THREAD thread_12_2;
+static TX_THREAD thread_13_2;
+static TX_THREAD thread_14_2;
+static TX_THREAD thread_15_2;
+static TX_THREAD thread_16_2;
+static TX_THREAD thread_17_2;
+static TX_THREAD thread_18_2;
+static TX_THREAD thread_19_2;
+static TX_THREAD thread_20_2;
+static TX_THREAD thread_21_2;
+static TX_THREAD thread_22_2;
+static TX_THREAD thread_23_2;
+static TX_THREAD thread_24_2;
+static TX_THREAD thread_25_2;
+static TX_THREAD thread_26_2;
+static TX_THREAD thread_27_2;
+static TX_THREAD thread_28_2;
+static TX_THREAD thread_29_2;
+static TX_THREAD thread_30_2;
+static TX_THREAD thread_31_2;
+static TX_THREAD thread_32_2;
+static TX_THREAD thread_33_2;
+static TX_THREAD thread_34_2;
+static TX_THREAD thread_35_2;
+static TX_THREAD thread_36_2;
+static TX_THREAD thread_37_2;
+static TX_THREAD thread_38_2;
+static TX_THREAD thread_39_2;
+static TX_THREAD thread_40_2;
+static TX_THREAD thread_41_2;
+static TX_THREAD thread_42_2;
+static TX_THREAD thread_43_2;
+static TX_THREAD thread_44_2;
+static TX_THREAD thread_45_2;
+static TX_THREAD thread_46_2;
+static TX_THREAD thread_47_2;
+static TX_THREAD thread_48_2;
+static TX_THREAD thread_49_2;
+static TX_THREAD thread_50_2;
+static TX_THREAD thread_51_2;
+static TX_THREAD thread_52_2;
+static TX_THREAD thread_53_2;
+static TX_THREAD thread_54_2;
+static TX_THREAD thread_55_2;
+static TX_THREAD thread_56_2;
+static TX_THREAD thread_57_2;
+static TX_THREAD thread_58_2;
+static TX_THREAD thread_59_2;
+static TX_THREAD thread_60_2;
+static TX_THREAD thread_61_2;
+static TX_THREAD thread_62_2;
+static TX_THREAD thread_63_2;
+static TX_THREAD thread_64_2;
+static TX_THREAD thread_65_2;
+static TX_THREAD thread_66_2;
+static TX_THREAD thread_67_2;
+static TX_THREAD thread_68_2;
+static TX_THREAD thread_69_2;
+static TX_THREAD thread_70_2;
+static TX_THREAD thread_71_2;
+static TX_THREAD thread_72_2;
+static TX_THREAD thread_73_2;
+static TX_THREAD thread_74_2;
+static TX_THREAD thread_75_2;
+static TX_THREAD thread_76_2;
+static TX_THREAD thread_77_2;
+static TX_THREAD thread_78_2;
+static TX_THREAD thread_79_2;
+static TX_THREAD thread_80_2;
+static TX_THREAD thread_81_2;
+static TX_THREAD thread_82_2;
+static TX_THREAD thread_83_2;
+static TX_THREAD thread_84_2;
+static TX_THREAD thread_85_2;
+static TX_THREAD thread_86_2;
+static TX_THREAD thread_87_2;
+static TX_THREAD thread_88_2;
+static TX_THREAD thread_89_2;
+static TX_THREAD thread_90_2;
+static TX_THREAD thread_91_2;
+static TX_THREAD thread_92_2;
+static TX_THREAD thread_93_2;
+static TX_THREAD thread_94_2;
+static TX_THREAD thread_95_2;
+static TX_THREAD thread_96_2;
+static TX_THREAD thread_97_2;
+static TX_THREAD thread_98_2;
+static TX_THREAD thread_99_2;
+static TX_THREAD thread_100_2;
+static TX_THREAD thread_101_2;
+static TX_THREAD thread_102_2;
+static TX_THREAD thread_103_2;
+static TX_THREAD thread_104_2;
+static TX_THREAD thread_105_2;
+static TX_THREAD thread_106_2;
+static TX_THREAD thread_107_2;
+static TX_THREAD thread_108_2;
+static TX_THREAD thread_109_2;
+static TX_THREAD thread_110_2;
+static TX_THREAD thread_111_2;
+static TX_THREAD thread_112_2;
+static TX_THREAD thread_113_2;
+static TX_THREAD thread_114_2;
+static TX_THREAD thread_115_2;
+static TX_THREAD thread_116_2;
+static TX_THREAD thread_117_2;
+static TX_THREAD thread_118_2;
+static TX_THREAD thread_119_2;
+static TX_THREAD thread_120_2;
+static TX_THREAD thread_121_2;
+static TX_THREAD thread_122_2;
+static TX_THREAD thread_123_2;
+static TX_THREAD thread_124_2;
+static TX_THREAD thread_125_2;
+static TX_THREAD thread_126_2;
+static TX_THREAD thread_127_2;
+static TX_THREAD thread_128_2;
+static TX_THREAD thread_129_2;
+static TX_THREAD thread_130_2;
+static TX_THREAD thread_131_2;
+static TX_THREAD thread_132_2;
+static TX_THREAD thread_133_2;
+static TX_THREAD thread_134_2;
+static TX_THREAD thread_135_2;
+static TX_THREAD thread_136_2;
+static TX_THREAD thread_137_2;
+static TX_THREAD thread_138_2;
+static TX_THREAD thread_139_2;
+static TX_THREAD thread_140_2;
+static TX_THREAD thread_141_2;
+static TX_THREAD thread_142_2;
+static TX_THREAD thread_143_2;
+static TX_THREAD thread_144_2;
+static TX_THREAD thread_145_2;
+static TX_THREAD thread_146_2;
+static TX_THREAD thread_147_2;
+static TX_THREAD thread_148_2;
+static TX_THREAD thread_149_2;
+static TX_THREAD thread_150_2;
+static TX_THREAD thread_151_2;
+static TX_THREAD thread_152_2;
+static TX_THREAD thread_153_2;
+static TX_THREAD thread_154_2;
+static TX_THREAD thread_155_2;
+static TX_THREAD thread_156_2;
+static TX_THREAD thread_157_2;
+static TX_THREAD thread_158_2;
+static TX_THREAD thread_159_2;
+static TX_THREAD thread_160_2;
+static TX_THREAD thread_161_2;
+static TX_THREAD thread_162_2;
+static TX_THREAD thread_163_2;
+static TX_THREAD thread_164_2;
+static TX_THREAD thread_165_2;
+static TX_THREAD thread_166_2;
+static TX_THREAD thread_167_2;
+static TX_THREAD thread_168_2;
+static TX_THREAD thread_169_2;
+static TX_THREAD thread_170_2;
+static TX_THREAD thread_171_2;
+static TX_THREAD thread_172_2;
+static TX_THREAD thread_173_2;
+static TX_THREAD thread_174_2;
+static TX_THREAD thread_175_2;
+static TX_THREAD thread_176_2;
+static TX_THREAD thread_177_2;
+static TX_THREAD thread_178_2;
+static TX_THREAD thread_179_2;
+static TX_THREAD thread_180_2;
+static TX_THREAD thread_181_2;
+static TX_THREAD thread_182_2;
+static TX_THREAD thread_183_2;
+static TX_THREAD thread_184_2;
+static TX_THREAD thread_185_2;
+static TX_THREAD thread_186_2;
+static TX_THREAD thread_187_2;
+static TX_THREAD thread_188_2;
+static TX_THREAD thread_189_2;
+static TX_THREAD thread_190_2;
+static TX_THREAD thread_191_2;
+static TX_THREAD thread_192_2;
+static TX_THREAD thread_193_2;
+static TX_THREAD thread_194_2;
+static TX_THREAD thread_195_2;
+static TX_THREAD thread_196_2;
+static TX_THREAD thread_197_2;
+static TX_THREAD thread_198_2;
+static TX_THREAD thread_199_2;
+static TX_THREAD thread_200_2;
+static TX_THREAD thread_201_2;
+static TX_THREAD thread_202_2;
+static TX_THREAD thread_203_2;
+static TX_THREAD thread_204_2;
+static TX_THREAD thread_205_2;
+static TX_THREAD thread_206_2;
+static TX_THREAD thread_207_2;
+static TX_THREAD thread_208_2;
+static TX_THREAD thread_209_2;
+static TX_THREAD thread_210_2;
+static TX_THREAD thread_211_2;
+static TX_THREAD thread_212_2;
+static TX_THREAD thread_213_2;
+static TX_THREAD thread_214_2;
+static TX_THREAD thread_215_2;
+static TX_THREAD thread_216_2;
+static TX_THREAD thread_217_2;
+static TX_THREAD thread_218_2;
+static TX_THREAD thread_219_2;
+static TX_THREAD thread_220_2;
+static TX_THREAD thread_221_2;
+static TX_THREAD thread_222_2;
+static TX_THREAD thread_223_2;
+static TX_THREAD thread_224_2;
+static TX_THREAD thread_225_2;
+static TX_THREAD thread_226_2;
+static TX_THREAD thread_227_2;
+static TX_THREAD thread_228_2;
+static TX_THREAD thread_229_2;
+static TX_THREAD thread_230_2;
+static TX_THREAD thread_231_2;
+static TX_THREAD thread_232_2;
+static TX_THREAD thread_233_2;
+static TX_THREAD thread_234_2;
+static TX_THREAD thread_235_2;
+static TX_THREAD thread_236_2;
+static TX_THREAD thread_237_2;
+static TX_THREAD thread_238_2;
+static TX_THREAD thread_239_2;
+static TX_THREAD thread_240_2;
+static TX_THREAD thread_241_2;
+static TX_THREAD thread_242_2;
+static TX_THREAD thread_243_2;
+static TX_THREAD thread_244_2;
+static TX_THREAD thread_245_2;
+static TX_THREAD thread_246_2;
+static TX_THREAD thread_247_2;
+static TX_THREAD thread_248_2;
+static TX_THREAD thread_249_2;
+static TX_THREAD thread_250_2;
+static TX_THREAD thread_251_2;
+static TX_THREAD thread_252_2;
+static TX_THREAD thread_253_2;
+static TX_THREAD thread_254_2;
+static TX_THREAD thread_255_2;
+
+static TX_THREAD thread_0_3;
+static TX_THREAD thread_1_3;
+static TX_THREAD thread_2_3;
+static TX_THREAD thread_3_3;
+static TX_THREAD thread_4_3;
+static TX_THREAD thread_5_3;
+static TX_THREAD thread_6_3;
+static TX_THREAD thread_7_3;
+static TX_THREAD thread_8_3;
+static TX_THREAD thread_9_3;
+static TX_THREAD thread_10_3;
+static TX_THREAD thread_11_3;
+static TX_THREAD thread_12_3;
+static TX_THREAD thread_13_3;
+static TX_THREAD thread_14_3;
+static TX_THREAD thread_15_3;
+static TX_THREAD thread_16_3;
+static TX_THREAD thread_17_3;
+static TX_THREAD thread_18_3;
+static TX_THREAD thread_19_3;
+static TX_THREAD thread_20_3;
+static TX_THREAD thread_21_3;
+static TX_THREAD thread_22_3;
+static TX_THREAD thread_23_3;
+static TX_THREAD thread_24_3;
+static TX_THREAD thread_25_3;
+static TX_THREAD thread_26_3;
+static TX_THREAD thread_27_3;
+static TX_THREAD thread_28_3;
+static TX_THREAD thread_29_3;
+static TX_THREAD thread_30_3;
+static TX_THREAD thread_31_3;
+static TX_THREAD thread_32_3;
+static TX_THREAD thread_33_3;
+static TX_THREAD thread_34_3;
+static TX_THREAD thread_35_3;
+static TX_THREAD thread_36_3;
+static TX_THREAD thread_37_3;
+static TX_THREAD thread_38_3;
+static TX_THREAD thread_39_3;
+static TX_THREAD thread_40_3;
+static TX_THREAD thread_41_3;
+static TX_THREAD thread_42_3;
+static TX_THREAD thread_43_3;
+static TX_THREAD thread_44_3;
+static TX_THREAD thread_45_3;
+static TX_THREAD thread_46_3;
+static TX_THREAD thread_47_3;
+static TX_THREAD thread_48_3;
+static TX_THREAD thread_49_3;
+static TX_THREAD thread_50_3;
+static TX_THREAD thread_51_3;
+static TX_THREAD thread_52_3;
+static TX_THREAD thread_53_3;
+static TX_THREAD thread_54_3;
+static TX_THREAD thread_55_3;
+static TX_THREAD thread_56_3;
+static TX_THREAD thread_57_3;
+static TX_THREAD thread_58_3;
+static TX_THREAD thread_59_3;
+static TX_THREAD thread_60_3;
+static TX_THREAD thread_61_3;
+static TX_THREAD thread_62_3;
+static TX_THREAD thread_63_3;
+static TX_THREAD thread_64_3;
+static TX_THREAD thread_65_3;
+static TX_THREAD thread_66_3;
+static TX_THREAD thread_67_3;
+static TX_THREAD thread_68_3;
+static TX_THREAD thread_69_3;
+static TX_THREAD thread_70_3;
+static TX_THREAD thread_71_3;
+static TX_THREAD thread_72_3;
+static TX_THREAD thread_73_3;
+static TX_THREAD thread_74_3;
+static TX_THREAD thread_75_3;
+static TX_THREAD thread_76_3;
+static TX_THREAD thread_77_3;
+static TX_THREAD thread_78_3;
+static TX_THREAD thread_79_3;
+static TX_THREAD thread_80_3;
+static TX_THREAD thread_81_3;
+static TX_THREAD thread_82_3;
+static TX_THREAD thread_83_3;
+static TX_THREAD thread_84_3;
+static TX_THREAD thread_85_3;
+static TX_THREAD thread_86_3;
+static TX_THREAD thread_87_3;
+static TX_THREAD thread_88_3;
+static TX_THREAD thread_89_3;
+static TX_THREAD thread_90_3;
+static TX_THREAD thread_91_3;
+static TX_THREAD thread_92_3;
+static TX_THREAD thread_93_3;
+static TX_THREAD thread_94_3;
+static TX_THREAD thread_95_3;
+static TX_THREAD thread_96_3;
+static TX_THREAD thread_97_3;
+static TX_THREAD thread_98_3;
+static TX_THREAD thread_99_3;
+static TX_THREAD thread_100_3;
+static TX_THREAD thread_101_3;
+static TX_THREAD thread_102_3;
+static TX_THREAD thread_103_3;
+static TX_THREAD thread_104_3;
+static TX_THREAD thread_105_3;
+static TX_THREAD thread_106_3;
+static TX_THREAD thread_107_3;
+static TX_THREAD thread_108_3;
+static TX_THREAD thread_109_3;
+static TX_THREAD thread_110_3;
+static TX_THREAD thread_111_3;
+static TX_THREAD thread_112_3;
+static TX_THREAD thread_113_3;
+static TX_THREAD thread_114_3;
+static TX_THREAD thread_115_3;
+static TX_THREAD thread_116_3;
+static TX_THREAD thread_117_3;
+static TX_THREAD thread_118_3;
+static TX_THREAD thread_119_3;
+static TX_THREAD thread_120_3;
+static TX_THREAD thread_121_3;
+static TX_THREAD thread_122_3;
+static TX_THREAD thread_123_3;
+static TX_THREAD thread_124_3;
+static TX_THREAD thread_125_3;
+static TX_THREAD thread_126_3;
+static TX_THREAD thread_127_3;
+static TX_THREAD thread_128_3;
+static TX_THREAD thread_129_3;
+static TX_THREAD thread_130_3;
+static TX_THREAD thread_131_3;
+static TX_THREAD thread_132_3;
+static TX_THREAD thread_133_3;
+static TX_THREAD thread_134_3;
+static TX_THREAD thread_135_3;
+static TX_THREAD thread_136_3;
+static TX_THREAD thread_137_3;
+static TX_THREAD thread_138_3;
+static TX_THREAD thread_139_3;
+static TX_THREAD thread_140_3;
+static TX_THREAD thread_141_3;
+static TX_THREAD thread_142_3;
+static TX_THREAD thread_143_3;
+static TX_THREAD thread_144_3;
+static TX_THREAD thread_145_3;
+static TX_THREAD thread_146_3;
+static TX_THREAD thread_147_3;
+static TX_THREAD thread_148_3;
+static TX_THREAD thread_149_3;
+static TX_THREAD thread_150_3;
+static TX_THREAD thread_151_3;
+static TX_THREAD thread_152_3;
+static TX_THREAD thread_153_3;
+static TX_THREAD thread_154_3;
+static TX_THREAD thread_155_3;
+static TX_THREAD thread_156_3;
+static TX_THREAD thread_157_3;
+static TX_THREAD thread_158_3;
+static TX_THREAD thread_159_3;
+static TX_THREAD thread_160_3;
+static TX_THREAD thread_161_3;
+static TX_THREAD thread_162_3;
+static TX_THREAD thread_163_3;
+static TX_THREAD thread_164_3;
+static TX_THREAD thread_165_3;
+static TX_THREAD thread_166_3;
+static TX_THREAD thread_167_3;
+static TX_THREAD thread_168_3;
+static TX_THREAD thread_169_3;
+static TX_THREAD thread_170_3;
+static TX_THREAD thread_171_3;
+static TX_THREAD thread_172_3;
+static TX_THREAD thread_173_3;
+static TX_THREAD thread_174_3;
+static TX_THREAD thread_175_3;
+static TX_THREAD thread_176_3;
+static TX_THREAD thread_177_3;
+static TX_THREAD thread_178_3;
+static TX_THREAD thread_179_3;
+static TX_THREAD thread_180_3;
+static TX_THREAD thread_181_3;
+static TX_THREAD thread_182_3;
+static TX_THREAD thread_183_3;
+static TX_THREAD thread_184_3;
+static TX_THREAD thread_185_3;
+static TX_THREAD thread_186_3;
+static TX_THREAD thread_187_3;
+static TX_THREAD thread_188_3;
+static TX_THREAD thread_189_3;
+static TX_THREAD thread_190_3;
+static TX_THREAD thread_191_3;
+static TX_THREAD thread_192_3;
+static TX_THREAD thread_193_3;
+static TX_THREAD thread_194_3;
+static TX_THREAD thread_195_3;
+static TX_THREAD thread_196_3;
+static TX_THREAD thread_197_3;
+static TX_THREAD thread_198_3;
+static TX_THREAD thread_199_3;
+static TX_THREAD thread_200_3;
+static TX_THREAD thread_201_3;
+static TX_THREAD thread_202_3;
+static TX_THREAD thread_203_3;
+static TX_THREAD thread_204_3;
+static TX_THREAD thread_205_3;
+static TX_THREAD thread_206_3;
+static TX_THREAD thread_207_3;
+static TX_THREAD thread_208_3;
+static TX_THREAD thread_209_3;
+static TX_THREAD thread_210_3;
+static TX_THREAD thread_211_3;
+static TX_THREAD thread_212_3;
+static TX_THREAD thread_213_3;
+static TX_THREAD thread_214_3;
+static TX_THREAD thread_215_3;
+static TX_THREAD thread_216_3;
+static TX_THREAD thread_217_3;
+static TX_THREAD thread_218_3;
+static TX_THREAD thread_219_3;
+static TX_THREAD thread_220_3;
+static TX_THREAD thread_221_3;
+static TX_THREAD thread_222_3;
+static TX_THREAD thread_223_3;
+static TX_THREAD thread_224_3;
+static TX_THREAD thread_225_3;
+static TX_THREAD thread_226_3;
+static TX_THREAD thread_227_3;
+static TX_THREAD thread_228_3;
+static TX_THREAD thread_229_3;
+static TX_THREAD thread_230_3;
+static TX_THREAD thread_231_3;
+static TX_THREAD thread_232_3;
+static TX_THREAD thread_233_3;
+static TX_THREAD thread_234_3;
+static TX_THREAD thread_235_3;
+static TX_THREAD thread_236_3;
+static TX_THREAD thread_237_3;
+static TX_THREAD thread_238_3;
+static TX_THREAD thread_239_3;
+static TX_THREAD thread_240_3;
+static TX_THREAD thread_241_3;
+static TX_THREAD thread_242_3;
+static TX_THREAD thread_243_3;
+static TX_THREAD thread_244_3;
+static TX_THREAD thread_245_3;
+static TX_THREAD thread_246_3;
+static TX_THREAD thread_247_3;
+static TX_THREAD thread_248_3;
+static TX_THREAD thread_249_3;
+static TX_THREAD thread_250_3;
+static TX_THREAD thread_251_3;
+static TX_THREAD thread_252_3;
+static TX_THREAD thread_253_3;
+static TX_THREAD thread_254_3;
+static TX_THREAD thread_255_3;
+
+/* Define test array. */
+
+static TX_THREAD *_smp_randomized_source_array[] = {
+{&thread_0},
+{&thread_1},
+{&thread_2},
+{&thread_3},
+{&thread_4},
+{&thread_5},
+{&thread_6},
+{&thread_7},
+{&thread_8},
+{&thread_9},
+{&thread_10},
+{&thread_11},
+{&thread_12},
+{&thread_13},
+{&thread_14},
+{&thread_15},
+{&thread_16},
+{&thread_17},
+{&thread_18},
+{&thread_19},
+{&thread_20},
+{&thread_21},
+{&thread_22},
+{&thread_23},
+{&thread_24},
+{&thread_25},
+{&thread_26},
+{&thread_27},
+{&thread_28},
+{&thread_29},
+{&thread_30},
+{&thread_31},
+{&thread_32},
+{&thread_33},
+{&thread_34},
+{&thread_35},
+{&thread_36},
+{&thread_37},
+{&thread_38},
+{&thread_39},
+{&thread_40},
+{&thread_41},
+{&thread_42},
+{&thread_43},
+{&thread_44},
+{&thread_45},
+{&thread_46},
+{&thread_47},
+{&thread_48},
+{&thread_49},
+{&thread_50},
+{&thread_51},
+{&thread_52},
+{&thread_53},
+{&thread_54},
+{&thread_55},
+{&thread_56},
+{&thread_57},
+{&thread_58},
+{&thread_59},
+{&thread_60},
+{&thread_61},
+{&thread_62},
+{&thread_63},
+{&thread_64},
+{&thread_65},
+{&thread_66},
+{&thread_67},
+{&thread_68},
+{&thread_69},
+{&thread_70},
+{&thread_71},
+{&thread_72},
+{&thread_73},
+{&thread_74},
+{&thread_75},
+{&thread_76},
+{&thread_77},
+{&thread_78},
+{&thread_79},
+{&thread_80},
+{&thread_81},
+{&thread_82},
+{&thread_83},
+{&thread_84},
+{&thread_85},
+{&thread_86},
+{&thread_87},
+{&thread_88},
+{&thread_89},
+{&thread_90},
+{&thread_91},
+{&thread_92},
+{&thread_93},
+{&thread_94},
+{&thread_95},
+{&thread_96},
+{&thread_97},
+{&thread_98},
+{&thread_99},
+{&thread_100},
+{&thread_101},
+{&thread_102},
+{&thread_103},
+{&thread_104},
+{&thread_105},
+{&thread_106},
+{&thread_107},
+{&thread_108},
+{&thread_109},
+{&thread_110},
+{&thread_111},
+{&thread_112},
+{&thread_113},
+{&thread_114},
+{&thread_115},
+{&thread_116},
+{&thread_117},
+{&thread_118},
+{&thread_119},
+{&thread_120},
+{&thread_121},
+{&thread_122},
+{&thread_123},
+{&thread_124},
+{&thread_125},
+{&thread_126},
+{&thread_127},
+{&thread_128},
+{&thread_129},
+{&thread_130},
+{&thread_131},
+{&thread_132},
+{&thread_133},
+{&thread_134},
+{&thread_135},
+{&thread_136},
+{&thread_137},
+{&thread_138},
+{&thread_139},
+{&thread_140},
+{&thread_141},
+{&thread_142},
+{&thread_143},
+{&thread_144},
+{&thread_145},
+{&thread_146},
+{&thread_147},
+{&thread_148},
+{&thread_149},
+{&thread_150},
+{&thread_151},
+{&thread_152},
+{&thread_153},
+{&thread_154},
+{&thread_155},
+{&thread_156},
+{&thread_157},
+{&thread_158},
+{&thread_159},
+{&thread_160},
+{&thread_161},
+{&thread_162},
+{&thread_163},
+{&thread_164},
+{&thread_165},
+{&thread_166},
+{&thread_167},
+{&thread_168},
+{&thread_169},
+{&thread_170},
+{&thread_171},
+{&thread_172},
+{&thread_173},
+{&thread_174},
+{&thread_175},
+{&thread_176},
+{&thread_177},
+{&thread_178},
+{&thread_179},
+{&thread_180},
+{&thread_181},
+{&thread_182},
+{&thread_183},
+{&thread_184},
+{&thread_185},
+{&thread_186},
+{&thread_187},
+{&thread_188},
+{&thread_189},
+{&thread_190},
+{&thread_191},
+{&thread_192},
+{&thread_193},
+{&thread_194},
+{&thread_195},
+{&thread_196},
+{&thread_197},
+{&thread_198},
+{&thread_199},
+{&thread_200},
+{&thread_201},
+{&thread_202},
+{&thread_203},
+{&thread_204},
+{&thread_205},
+{&thread_206},
+{&thread_207},
+{&thread_208},
+{&thread_209},
+{&thread_210},
+{&thread_211},
+{&thread_212},
+{&thread_213},
+{&thread_214},
+{&thread_215},
+{&thread_216},
+{&thread_217},
+{&thread_218},
+{&thread_219},
+{&thread_220},
+{&thread_221},
+{&thread_222},
+{&thread_223},
+{&thread_224},
+{&thread_225},
+{&thread_226},
+{&thread_227},
+{&thread_228},
+{&thread_229},
+{&thread_230},
+{&thread_231},
+{&thread_232},
+{&thread_233},
+{&thread_234},
+{&thread_235},
+{&thread_236},
+{&thread_237},
+{&thread_238},
+{&thread_239},
+{&thread_240},
+{&thread_241},
+{&thread_242},
+{&thread_243},
+{&thread_244},
+{&thread_245},
+{&thread_246},
+{&thread_247},
+{&thread_248},
+{&thread_249},
+{&thread_250},
+{&thread_251},
+{&thread_252},
+{&thread_253},
+{&thread_254},
+{&thread_255},
+
+{&thread_0_1},
+{&thread_1_1},
+{&thread_2_1},
+{&thread_3_1},
+{&thread_4_1},
+{&thread_5_1},
+{&thread_6_1},
+{&thread_7_1},
+{&thread_8_1},
+{&thread_9_1},
+{&thread_10_1},
+{&thread_11_1},
+{&thread_12_1},
+{&thread_13_1},
+{&thread_14_1},
+{&thread_15_1},
+{&thread_16_1},
+{&thread_17_1},
+{&thread_18_1},
+{&thread_19_1},
+{&thread_20_1},
+{&thread_21_1},
+{&thread_22_1},
+{&thread_23_1},
+{&thread_24_1},
+{&thread_25_1},
+{&thread_26_1},
+{&thread_27_1},
+{&thread_28_1},
+{&thread_29_1},
+{&thread_30_1},
+{&thread_31_1},
+{&thread_32_1},
+{&thread_33_1},
+{&thread_34_1},
+{&thread_35_1},
+{&thread_36_1},
+{&thread_37_1},
+{&thread_38_1},
+{&thread_39_1},
+{&thread_40_1},
+{&thread_41_1},
+{&thread_42_1},
+{&thread_43_1},
+{&thread_44_1},
+{&thread_45_1},
+{&thread_46_1},
+{&thread_47_1},
+{&thread_48_1},
+{&thread_49_1},
+{&thread_50_1},
+{&thread_51_1},
+{&thread_52_1},
+{&thread_53_1},
+{&thread_54_1},
+{&thread_55_1},
+{&thread_56_1},
+{&thread_57_1},
+{&thread_58_1},
+{&thread_59_1},
+{&thread_60_1},
+{&thread_61_1},
+{&thread_62_1},
+{&thread_63_1},
+{&thread_64_1},
+{&thread_65_1},
+{&thread_66_1},
+{&thread_67_1},
+{&thread_68_1},
+{&thread_69_1},
+{&thread_70_1},
+{&thread_71_1},
+{&thread_72_1},
+{&thread_73_1},
+{&thread_74_1},
+{&thread_75_1},
+{&thread_76_1},
+{&thread_77_1},
+{&thread_78_1},
+{&thread_79_1},
+{&thread_80_1},
+{&thread_81_1},
+{&thread_82_1},
+{&thread_83_1},
+{&thread_84_1},
+{&thread_85_1},
+{&thread_86_1},
+{&thread_87_1},
+{&thread_88_1},
+{&thread_89_1},
+{&thread_90_1},
+{&thread_91_1},
+{&thread_92_1},
+{&thread_93_1},
+{&thread_94_1},
+{&thread_95_1},
+{&thread_96_1},
+{&thread_97_1},
+{&thread_98_1},
+{&thread_99_1},
+{&thread_100_1},
+{&thread_101_1},
+{&thread_102_1},
+{&thread_103_1},
+{&thread_104_1},
+{&thread_105_1},
+{&thread_106_1},
+{&thread_107_1},
+{&thread_108_1},
+{&thread_109_1},
+{&thread_110_1},
+{&thread_111_1},
+{&thread_112_1},
+{&thread_113_1},
+{&thread_114_1},
+{&thread_115_1},
+{&thread_116_1},
+{&thread_117_1},
+{&thread_118_1},
+{&thread_119_1},
+{&thread_120_1},
+{&thread_121_1},
+{&thread_122_1},
+{&thread_123_1},
+{&thread_124_1},
+{&thread_125_1},
+{&thread_126_1},
+{&thread_127_1},
+{&thread_128_1},
+{&thread_129_1},
+{&thread_130_1},
+{&thread_131_1},
+{&thread_132_1},
+{&thread_133_1},
+{&thread_134_1},
+{&thread_135_1},
+{&thread_136_1},
+{&thread_137_1},
+{&thread_138_1},
+{&thread_139_1},
+{&thread_140_1},
+{&thread_141_1},
+{&thread_142_1},
+{&thread_143_1},
+{&thread_144_1},
+{&thread_145_1},
+{&thread_146_1},
+{&thread_147_1},
+{&thread_148_1},
+{&thread_149_1},
+{&thread_150_1},
+{&thread_151_1},
+{&thread_152_1},
+{&thread_153_1},
+{&thread_154_1},
+{&thread_155_1},
+{&thread_156_1},
+{&thread_157_1},
+{&thread_158_1},
+{&thread_159_1},
+{&thread_160_1},
+{&thread_161_1},
+{&thread_162_1},
+{&thread_163_1},
+{&thread_164_1},
+{&thread_165_1},
+{&thread_166_1},
+{&thread_167_1},
+{&thread_168_1},
+{&thread_169_1},
+{&thread_170_1},
+{&thread_171_1},
+{&thread_172_1},
+{&thread_173_1},
+{&thread_174_1},
+{&thread_175_1},
+{&thread_176_1},
+{&thread_177_1},
+{&thread_178_1},
+{&thread_179_1},
+{&thread_180_1},
+{&thread_181_1},
+{&thread_182_1},
+{&thread_183_1},
+{&thread_184_1},
+{&thread_185_1},
+{&thread_186_1},
+{&thread_187_1},
+{&thread_188_1},
+{&thread_189_1},
+{&thread_190_1},
+{&thread_191_1},
+{&thread_192_1},
+{&thread_193_1},
+{&thread_194_1},
+{&thread_195_1},
+{&thread_196_1},
+{&thread_197_1},
+{&thread_198_1},
+{&thread_199_1},
+{&thread_200_1},
+{&thread_201_1},
+{&thread_202_1},
+{&thread_203_1},
+{&thread_204_1},
+{&thread_205_1},
+{&thread_206_1},
+{&thread_207_1},
+{&thread_208_1},
+{&thread_209_1},
+{&thread_210_1},
+{&thread_211_1},
+{&thread_212_1},
+{&thread_213_1},
+{&thread_214_1},
+{&thread_215_1},
+{&thread_216_1},
+{&thread_217_1},
+{&thread_218_1},
+{&thread_219_1},
+{&thread_220_1},
+{&thread_221_1},
+{&thread_222_1},
+{&thread_223_1},
+{&thread_224_1},
+{&thread_225_1},
+{&thread_226_1},
+{&thread_227_1},
+{&thread_228_1},
+{&thread_229_1},
+{&thread_230_1},
+{&thread_231_1},
+{&thread_232_1},
+{&thread_233_1},
+{&thread_234_1},
+{&thread_235_1},
+{&thread_236_1},
+{&thread_237_1},
+{&thread_238_1},
+{&thread_239_1},
+{&thread_240_1},
+{&thread_241_1},
+{&thread_242_1},
+{&thread_243_1},
+{&thread_244_1},
+{&thread_245_1},
+{&thread_246_1},
+{&thread_247_1},
+{&thread_248_1},
+{&thread_249_1},
+{&thread_250_1},
+{&thread_251_1},
+{&thread_252_1},
+{&thread_253_1},
+{&thread_254_1},
+{&thread_255_1},
+
+{&thread_0_2},
+{&thread_1_2},
+{&thread_2_2},
+{&thread_3_2},
+{&thread_4_2},
+{&thread_5_2},
+{&thread_6_2},
+{&thread_7_2},
+{&thread_8_2},
+{&thread_9_2},
+{&thread_10_2},
+{&thread_11_2},
+{&thread_12_2},
+{&thread_13_2},
+{&thread_14_2},
+{&thread_15_2},
+{&thread_16_2},
+{&thread_17_2},
+{&thread_18_2},
+{&thread_19_2},
+{&thread_20_2},
+{&thread_21_2},
+{&thread_22_2},
+{&thread_23_2},
+{&thread_24_2},
+{&thread_25_2},
+{&thread_26_2},
+{&thread_27_2},
+{&thread_28_2},
+{&thread_29_2},
+{&thread_30_2},
+{&thread_31_2},
+{&thread_32_2},
+{&thread_33_2},
+{&thread_34_2},
+{&thread_35_2},
+{&thread_36_2},
+{&thread_37_2},
+{&thread_38_2},
+{&thread_39_2},
+{&thread_40_2},
+{&thread_41_2},
+{&thread_42_2},
+{&thread_43_2},
+{&thread_44_2},
+{&thread_45_2},
+{&thread_46_2},
+{&thread_47_2},
+{&thread_48_2},
+{&thread_49_2},
+{&thread_50_2},
+{&thread_51_2},
+{&thread_52_2},
+{&thread_53_2},
+{&thread_54_2},
+{&thread_55_2},
+{&thread_56_2},
+{&thread_57_2},
+{&thread_58_2},
+{&thread_59_2},
+{&thread_60_2},
+{&thread_61_2},
+{&thread_62_2},
+{&thread_63_2},
+{&thread_64_2},
+{&thread_65_2},
+{&thread_66_2},
+{&thread_67_2},
+{&thread_68_2},
+{&thread_69_2},
+{&thread_70_2},
+{&thread_71_2},
+{&thread_72_2},
+{&thread_73_2},
+{&thread_74_2},
+{&thread_75_2},
+{&thread_76_2},
+{&thread_77_2},
+{&thread_78_2},
+{&thread_79_2},
+{&thread_80_2},
+{&thread_81_2},
+{&thread_82_2},
+{&thread_83_2},
+{&thread_84_2},
+{&thread_85_2},
+{&thread_86_2},
+{&thread_87_2},
+{&thread_88_2},
+{&thread_89_2},
+{&thread_90_2},
+{&thread_91_2},
+{&thread_92_2},
+{&thread_93_2},
+{&thread_94_2},
+{&thread_95_2},
+{&thread_96_2},
+{&thread_97_2},
+{&thread_98_2},
+{&thread_99_2},
+{&thread_100_2},
+{&thread_101_2},
+{&thread_102_2},
+{&thread_103_2},
+{&thread_104_2},
+{&thread_105_2},
+{&thread_106_2},
+{&thread_107_2},
+{&thread_108_2},
+{&thread_109_2},
+{&thread_110_2},
+{&thread_111_2},
+{&thread_112_2},
+{&thread_113_2},
+{&thread_114_2},
+{&thread_115_2},
+{&thread_116_2},
+{&thread_117_2},
+{&thread_118_2},
+{&thread_119_2},
+{&thread_120_2},
+{&thread_121_2},
+{&thread_122_2},
+{&thread_123_2},
+{&thread_124_2},
+{&thread_125_2},
+{&thread_126_2},
+{&thread_127_2},
+{&thread_128_2},
+{&thread_129_2},
+{&thread_130_2},
+{&thread_131_2},
+{&thread_132_2},
+{&thread_133_2},
+{&thread_134_2},
+{&thread_135_2},
+{&thread_136_2},
+{&thread_137_2},
+{&thread_138_2},
+{&thread_139_2},
+{&thread_140_2},
+{&thread_141_2},
+{&thread_142_2},
+{&thread_143_2},
+{&thread_144_2},
+{&thread_145_2},
+{&thread_146_2},
+{&thread_147_2},
+{&thread_148_2},
+{&thread_149_2},
+{&thread_150_2},
+{&thread_151_2},
+{&thread_152_2},
+{&thread_153_2},
+{&thread_154_2},
+{&thread_155_2},
+{&thread_156_2},
+{&thread_157_2},
+{&thread_158_2},
+{&thread_159_2},
+{&thread_160_2},
+{&thread_161_2},
+{&thread_162_2},
+{&thread_163_2},
+{&thread_164_2},
+{&thread_165_2},
+{&thread_166_2},
+{&thread_167_2},
+{&thread_168_2},
+{&thread_169_2},
+{&thread_170_2},
+{&thread_171_2},
+{&thread_172_2},
+{&thread_173_2},
+{&thread_174_2},
+{&thread_175_2},
+{&thread_176_2},
+{&thread_177_2},
+{&thread_178_2},
+{&thread_179_2},
+{&thread_180_2},
+{&thread_181_2},
+{&thread_182_2},
+{&thread_183_2},
+{&thread_184_2},
+{&thread_185_2},
+{&thread_186_2},
+{&thread_187_2},
+{&thread_188_2},
+{&thread_189_2},
+{&thread_190_2},
+{&thread_191_2},
+{&thread_192_2},
+{&thread_193_2},
+{&thread_194_2},
+{&thread_195_2},
+{&thread_196_2},
+{&thread_197_2},
+{&thread_198_2},
+{&thread_199_2},
+{&thread_200_2},
+{&thread_201_2},
+{&thread_202_2},
+{&thread_203_2},
+{&thread_204_2},
+{&thread_205_2},
+{&thread_206_2},
+{&thread_207_2},
+{&thread_208_2},
+{&thread_209_2},
+{&thread_210_2},
+{&thread_211_2},
+{&thread_212_2},
+{&thread_213_2},
+{&thread_214_2},
+{&thread_215_2},
+{&thread_216_2},
+{&thread_217_2},
+{&thread_218_2},
+{&thread_219_2},
+{&thread_220_2},
+{&thread_221_2},
+{&thread_222_2},
+{&thread_223_2},
+{&thread_224_2},
+{&thread_225_2},
+{&thread_226_2},
+{&thread_227_2},
+{&thread_228_2},
+{&thread_229_2},
+{&thread_230_2},
+{&thread_231_2},
+{&thread_232_2},
+{&thread_233_2},
+{&thread_234_2},
+{&thread_235_2},
+{&thread_236_2},
+{&thread_237_2},
+{&thread_238_2},
+{&thread_239_2},
+{&thread_240_2},
+{&thread_241_2},
+{&thread_242_2},
+{&thread_243_2},
+{&thread_244_2},
+{&thread_245_2},
+{&thread_246_2},
+{&thread_247_2},
+{&thread_248_2},
+{&thread_249_2},
+{&thread_250_2},
+{&thread_251_2},
+{&thread_252_2},
+{&thread_253_2},
+{&thread_254_2},
+{&thread_255_2},
+
+{&thread_0_3},
+{&thread_1_3},
+{&thread_2_3},
+{&thread_3_3},
+{&thread_4_3},
+{&thread_5_3},
+{&thread_6_3},
+{&thread_7_3},
+{&thread_8_3},
+{&thread_9_3},
+{&thread_10_3},
+{&thread_11_3},
+{&thread_12_3},
+{&thread_13_3},
+{&thread_14_3},
+{&thread_15_3},
+{&thread_16_3},
+{&thread_17_3},
+{&thread_18_3},
+{&thread_19_3},
+{&thread_20_3},
+{&thread_21_3},
+{&thread_22_3},
+{&thread_23_3},
+{&thread_24_3},
+{&thread_25_3},
+{&thread_26_3},
+{&thread_27_3},
+{&thread_28_3},
+{&thread_29_3},
+{&thread_30_3},
+{&thread_31_3},
+{&thread_32_3},
+{&thread_33_3},
+{&thread_34_3},
+{&thread_35_3},
+{&thread_36_3},
+{&thread_37_3},
+{&thread_38_3},
+{&thread_39_3},
+{&thread_40_3},
+{&thread_41_3},
+{&thread_42_3},
+{&thread_43_3},
+{&thread_44_3},
+{&thread_45_3},
+{&thread_46_3},
+{&thread_47_3},
+{&thread_48_3},
+{&thread_49_3},
+{&thread_50_3},
+{&thread_51_3},
+{&thread_52_3},
+{&thread_53_3},
+{&thread_54_3},
+{&thread_55_3},
+{&thread_56_3},
+{&thread_57_3},
+{&thread_58_3},
+{&thread_59_3},
+{&thread_60_3},
+{&thread_61_3},
+{&thread_62_3},
+{&thread_63_3},
+{&thread_64_3},
+{&thread_65_3},
+{&thread_66_3},
+{&thread_67_3},
+{&thread_68_3},
+{&thread_69_3},
+{&thread_70_3},
+{&thread_71_3},
+{&thread_72_3},
+{&thread_73_3},
+{&thread_74_3},
+{&thread_75_3},
+{&thread_76_3},
+{&thread_77_3},
+{&thread_78_3},
+{&thread_79_3},
+{&thread_80_3},
+{&thread_81_3},
+{&thread_82_3},
+{&thread_83_3},
+{&thread_84_3},
+{&thread_85_3},
+{&thread_86_3},
+{&thread_87_3},
+{&thread_88_3},
+{&thread_89_3},
+{&thread_90_3},
+{&thread_91_3},
+{&thread_92_3},
+{&thread_93_3},
+{&thread_94_3},
+{&thread_95_3},
+{&thread_96_3},
+{&thread_97_3},
+{&thread_98_3},
+{&thread_99_3},
+{&thread_100_3},
+{&thread_101_3},
+{&thread_102_3},
+{&thread_103_3},
+{&thread_104_3},
+{&thread_105_3},
+{&thread_106_3},
+{&thread_107_3},
+{&thread_108_3},
+{&thread_109_3},
+{&thread_110_3},
+{&thread_111_3},
+{&thread_112_3},
+{&thread_113_3},
+{&thread_114_3},
+{&thread_115_3},
+{&thread_116_3},
+{&thread_117_3},
+{&thread_118_3},
+{&thread_119_3},
+{&thread_120_3},
+{&thread_121_3},
+{&thread_122_3},
+{&thread_123_3},
+{&thread_124_3},
+{&thread_125_3},
+{&thread_126_3},
+{&thread_127_3},
+{&thread_128_3},
+{&thread_129_3},
+{&thread_130_3},
+{&thread_131_3},
+{&thread_132_3},
+{&thread_133_3},
+{&thread_134_3},
+{&thread_135_3},
+{&thread_136_3},
+{&thread_137_3},
+{&thread_138_3},
+{&thread_139_3},
+{&thread_140_3},
+{&thread_141_3},
+{&thread_142_3},
+{&thread_143_3},
+{&thread_144_3},
+{&thread_145_3},
+{&thread_146_3},
+{&thread_147_3},
+{&thread_148_3},
+{&thread_149_3},
+{&thread_150_3},
+{&thread_151_3},
+{&thread_152_3},
+{&thread_153_3},
+{&thread_154_3},
+{&thread_155_3},
+{&thread_156_3},
+{&thread_157_3},
+{&thread_158_3},
+{&thread_159_3},
+{&thread_160_3},
+{&thread_161_3},
+{&thread_162_3},
+{&thread_163_3},
+{&thread_164_3},
+{&thread_165_3},
+{&thread_166_3},
+{&thread_167_3},
+{&thread_168_3},
+{&thread_169_3},
+{&thread_170_3},
+{&thread_171_3},
+{&thread_172_3},
+{&thread_173_3},
+{&thread_174_3},
+{&thread_175_3},
+{&thread_176_3},
+{&thread_177_3},
+{&thread_178_3},
+{&thread_179_3},
+{&thread_180_3},
+{&thread_181_3},
+{&thread_182_3},
+{&thread_183_3},
+{&thread_184_3},
+{&thread_185_3},
+{&thread_186_3},
+{&thread_187_3},
+{&thread_188_3},
+{&thread_189_3},
+{&thread_190_3},
+{&thread_191_3},
+{&thread_192_3},
+{&thread_193_3},
+{&thread_194_3},
+{&thread_195_3},
+{&thread_196_3},
+{&thread_197_3},
+{&thread_198_3},
+{&thread_199_3},
+{&thread_200_3},
+{&thread_201_3},
+{&thread_202_3},
+{&thread_203_3},
+{&thread_204_3},
+{&thread_205_3},
+{&thread_206_3},
+{&thread_207_3},
+{&thread_208_3},
+{&thread_209_3},
+{&thread_210_3},
+{&thread_211_3},
+{&thread_212_3},
+{&thread_213_3},
+{&thread_214_3},
+{&thread_215_3},
+{&thread_216_3},
+{&thread_217_3},
+{&thread_218_3},
+{&thread_219_3},
+{&thread_220_3},
+{&thread_221_3},
+{&thread_222_3},
+{&thread_223_3},
+{&thread_224_3},
+{&thread_225_3},
+{&thread_226_3},
+{&thread_227_3},
+{&thread_228_3},
+{&thread_229_3},
+{&thread_230_3},
+{&thread_231_3},
+{&thread_232_3},
+{&thread_233_3},
+{&thread_234_3},
+{&thread_235_3},
+{&thread_236_3},
+{&thread_237_3},
+{&thread_238_3},
+{&thread_239_3},
+{&thread_240_3},
+{&thread_241_3},
+{&thread_242_3},
+{&thread_243_3},
+{&thread_244_3},
+{&thread_245_3},
+{&thread_246_3},
+{&thread_247_3},
+{&thread_248_3},
+{&thread_249_3},
+{&thread_250_3},
+{&thread_251_3},
+{&thread_252_3},
+{&thread_253_3},
+{&thread_254_3},
+{&thread_255_3}
+};
+
+/* Define the test array. This used to store the randomized test. */
+
+static TX_THREAD *_smp_randomized_test_array[TX_THREAD_SMP_MAX_CORES*2];
+
+
+/* Define thread entry prototype. Since it won't be used it can be the same. */
+
+static void control_thread_entry(ULONG thread_input);
+static void thread_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+
+static UINT pass;
+static UINT start_pass;
+static UINT end_pass;
+static UINT mapping_error;
+static UINT preemption_threshold_error;
+
+
+extern TX_THREAD *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES];
+
+
+/* Create a test control thread. */
+
+static TX_THREAD control_thread;
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_smp_random_resume_suspend_exclusion_pt_test(void *first_unused_memory)
+#endif
+{
+
+CHAR *pointer;
+UINT status;
+
+ /* Put first available memory address into a character pointer. */
+ pointer = (CHAR *) first_unused_memory;
+
+ /* Create a control thread to run the test. */
+ status = tx_thread_create(&control_thread, "control thread", control_thread_entry, 0,
+ pointer, 1024,
+ 0, 0, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+ printf("Running SMP Random Suspensions/Resumptions/Exclusions/PT Test....... ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+static void control_thread_entry(ULONG thread_input)
+{
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+TX_INTERRUPT_SAVE_AREA
+
+UINT i, j;
+UINT priority;
+UINT source_index;
+UINT successful_tests = 0;
+UINT test_errors = 0;
+TX_THREAD *thread_ptr;
+TX_THREAD *current_thread;
+UINT original_priority;
+UINT original_threshold;
+ULONG exclusions;
+UINT status;
+
+
+ /* Clear mapping error flag. */
+ mapping_error = TX_FALSE;
+
+ /* Clear the preemption-threshold error flag. */
+ preemption_threshold_error = TX_FALSE;
+
+ /* Pickup the current thread pointer. */
+ current_thread = tx_thread_identify();
+
+ /* Loop to create all the threads. */
+ i = 0;
+ priority = 0;
+ status = TX_SUCCESS;
+ while (i < 1024)
+ {
+
+ /* Create each thread. */
+ status += tx_thread_create(_smp_randomized_source_array[i], "test thread", thread_entry, i,
+// (void *) pointer, 512,
+ malloc(1024), 1024,
+ priority, priority, TX_NO_TIME_SLICE, TX_DONT_START);
+// pointer = pointer + 512;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Random Suspensions/Resumptions/Exclusions/PT Test....... ERROR #2\n");
+ test_control_return(1);
+ break;
+ }
+
+ /* Move to next entry/priority. */
+ i++;
+ priority++;
+
+ /* Should priority be reset? */
+ if (priority >= TX_MAX_PRIORITIES)
+ {
+
+ /* Yes, reset the priority. */
+ priority = 0;
+ }
+ }
+
+ /* Start random test. */
+ printf("Running SMP Random Suspensions/Resumptions/Exclusions/PT Test....... ");
+
+ /* Special test for specific path in rebalance. */
+ status = tx_thread_smp_core_exclude(&thread_2, 0x7);
+ status += tx_thread_smp_core_exclude(&thread_4, 0x7);
+ status += tx_thread_smp_core_exclude(&thread_16, 0x7);
+ status += tx_thread_smp_core_exclude(&thread_22, 0);
+ status += tx_thread_preemption_change(&thread_16, 8, &original_threshold);
+ status += tx_thread_resume(&thread_16);
+ status += tx_thread_resume(&thread_4);
+ status += tx_thread_resume(&thread_22);
+ status += tx_thread_resume(&thread_2);
+
+ /* Call rebalance directly. */
+ TX_DISABLE
+ _tx_thread_smp_rebalance_execute_list(0);
+ TX_RESTORE
+
+ status += tx_thread_sleep(4);
+
+ /* Check status and make sure all the threads ran and suspended. */
+ if ((status != TX_SUCCESS) || (thread_2.tx_thread_run_count == 0) ||
+ (thread_4.tx_thread_run_count == 0) ||
+ (thread_16.tx_thread_run_count == 0) ||
+ (thread_22.tx_thread_run_count == 0))
+ {
+
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Clean everything up. */
+ status = tx_thread_smp_core_exclude(&thread_2, 0);
+ status += tx_thread_smp_core_exclude(&thread_4, 0);
+ status += tx_thread_smp_core_exclude(&thread_16, 0);
+ status += tx_thread_smp_core_exclude(&thread_22, 0);
+ status += tx_thread_preemption_change(&thread_4, 4, &original_threshold);
+ status += tx_thread_preemption_change(&thread_16, 16, &original_threshold);
+
+ /* Clear the run counters. */
+ thread_2.tx_thread_run_count = 0;
+ thread_4.tx_thread_run_count = 0;
+ thread_16.tx_thread_run_count = 0;
+ thread_22.tx_thread_run_count = 0;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Clear system counters. */
+ pass = 0;
+ start_pass = 0;
+ end_pass = start_pass + MAX_PASSES;
+ do
+ {
+
+ /* Clear the randomized test array. */
+ for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++)
+ {
+ _smp_randomized_test_array[i] = TX_NULL;
+ }
+
+ /* Build the randomized test array. */
+ for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++)
+ {
+ do
+ {
+ source_index = (rand())%1024;
+
+ /* Determine if this index has repeated. */
+ thread_ptr = _smp_randomized_source_array[source_index];
+
+ /* Is this thread already in the test array? */
+ j = 0;
+ while (j < TX_THREAD_SMP_MAX_CORES*2)
+ {
+ /* Is the entry NULL? */
+ if (_smp_randomized_test_array[j] == TX_NULL)
+ {
+ j = (TX_THREAD_SMP_MAX_CORES*2);
+ }
+
+ /* Determine if we have a duplicate. */
+ if (_smp_randomized_test_array[j] == thread_ptr)
+ thread_ptr = TX_NULL;
+
+ j++;
+ }
+
+ } while (thread_ptr == TX_NULL);
+
+ /* Clear run counter. */
+ thread_ptr -> tx_thread_run_count = 0;
+
+ /* Setup the exclusion for this thread. */
+ exclusions = (ULONG) (rand()%15);
+ tx_thread_smp_core_exclude(thread_ptr, exclusions);
+
+ /* See if we should setup a preemption-threshold. */
+ if ((thread_ptr -> tx_thread_priority > 40) &&
+ (exclusions & 1))
+ {
+ /* Change preemption-threshold to enable it. */
+ tx_thread_preemption_change(thread_ptr, thread_ptr -> tx_thread_priority - 20, &original_threshold);
+ }
+
+ /* Save the thread pointer. */
+ _smp_randomized_test_array[i] = thread_ptr;
+ }
+
+ /* Now make all the random threads ready. */
+ for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++)
+ {
+ status = tx_thread_resume(_smp_randomized_test_array[i]);
+
+ /* Check for an error. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #5\n");
+ test_control_return(1);
+ break;
+ }
+ }
+
+ /* Check the status. */
+ if (status)
+ break;
+
+ /* Move to the lowest priority. */
+ status += tx_thread_priority_change(current_thread, TX_MAX_PRIORITIES-1, &original_priority);
+ tx_thread_relinquish();
+
+ /* At this point all the threads have run, or should have. */
+
+ /* Restore priority. */
+ status += tx_thread_priority_change(current_thread, original_priority, &original_priority);
+
+ /* Was there an error? */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #6\n");
+ test_control_return(1);
+ break;
+ }
+
+ /* Determine if all the threads in the the random sample ran. */
+ for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++)
+ {
+
+ /* Pickup the thread pointer. */
+ thread_ptr = _smp_randomized_test_array[i];
+
+ /* Check to see if each thread has run. */
+ if (thread_ptr -> tx_thread_run_count == 0)
+ {
+
+ /* First, try to sleep to see if this helps! */
+ tx_thread_sleep(1);
+ }
+
+ /* Has the run count incremented? */
+ if (thread_ptr -> tx_thread_run_count == 0)
+ {
+
+ /* No, this thread didn't really run! */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ break;
+ }
+
+ /* Make sure this thread suspended. */
+ while (thread_ptr -> tx_thread_state != TX_SUSPENDED)
+ {
+ /* Wait for the thread to complete! */
+ tx_thread_relinquish();
+ }
+
+ /* Reset the exclusion for this thread. */
+ tx_thread_smp_core_exclude(thread_ptr, 0);
+
+ /* Reset preemption-threshold if needed. */
+ if (thread_ptr -> tx_thread_priority != thread_ptr -> tx_thread_preempt_threshold)
+ {
+
+ /* Change preemption-threshold to enable it. */
+ tx_thread_preemption_change(thread_ptr, thread_ptr -> tx_thread_priority, &original_threshold);
+ }
+
+ /* Check for mapping error. */
+ if (mapping_error)
+ {
+
+ /* No, a thread ran on inccorect core! */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ break;
+ }
+
+ /* Check for preemption-threshold error. */
+ if (preemption_threshold_error)
+ {
+
+ /* No, a thread's preemption-threshold was violated! */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ break;
+ }
+
+ }
+
+ /* Increment the pass counter. */
+ pass++;
+
+ } while (pass < end_pass);
+
+ /* Test is successful! */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+#else
+ printf("Running SMP Random Suspensions/Resumptions/Exclusions/PT Test....... SUCCESS!\n");
+ test_control_return(0);
+#endif
+}
+
+
+static void thread_entry(ULONG id)
+{
+
+UINT core;
+ULONG core_bit_map;
+TX_THREAD *thread_ptr;
+UINT i;
+TX_THREAD *other_thread;
+
+
+ /* While forever loop! */
+ while(1)
+ {
+
+ /* Get thread. */
+ thread_ptr = _smp_randomized_source_array[id];
+
+ /* Determine if this thread is running on a valid core. */
+ core = tx_thread_smp_core_get();
+
+ /* Build a bit map for this core. */
+ core_bit_map = (((ULONG) 1) << core);
+
+ /* Is this a valid core? */
+ if (core_bit_map & thread_ptr -> tx_thread_smp_cores_excluded)
+ {
+
+ /* Invalid core, set error flag. */
+ mapping_error = TX_TRUE;
+ }
+
+ /* Now check for a preemption-threshold error. */
+ if (thread_ptr -> tx_thread_priority != thread_ptr -> tx_thread_preempt_threshold)
+ {
+
+ /* Loop through the execute list to determine if any other threads have a priority or preemption-threshold less than this thread. */
+ for (i = 0; i < TX_THREAD_SMP_MAX_CORES; i++)
+ {
+
+ /* Pickup thread for the core. */
+ other_thread = _tx_thread_execute_ptr[i];
+
+ /* Is it this thread? */
+ if ((other_thread == TX_NULL) || (other_thread == thread_ptr))
+ continue;
+
+ /* Does this thread violate the preemption-thread of the current thread? */
+ if (other_thread -> tx_thread_preempt_threshold >= thread_ptr -> tx_thread_preempt_threshold)
+ {
+
+ /* This violated preemption-threshold. Set the flag. */
+ preemption_threshold_error = TX_TRUE;
+ }
+ }
+ }
+
+ /* Suspend thread! */
+ tx_thread_suspend(thread_ptr);
+ }
+}
diff --git a/test/smp/regression/threadx_smp_random_resume_suspend_exclusion_test.c b/test/smp/regression/threadx_smp_random_resume_suspend_exclusion_test.c
new file mode 100644
index 00000000..6c2f885f
--- /dev/null
+++ b/test/smp/regression/threadx_smp_random_resume_suspend_exclusion_test.c
@@ -0,0 +1,2373 @@
+/* Define the ThreadX SMP random resume/suspend/exclude test. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//#define MAX_PASSES 50000000
+//#define MAX_PASSES 50000
+#define MAX_PASSES 500
+
+
+/* Define the ThreadX object control blocks... Must have 256 priority levels... and assumes 4 cores. */
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD thread_4;
+static TX_THREAD thread_5;
+static TX_THREAD thread_6;
+static TX_THREAD thread_7;
+static TX_THREAD thread_8;
+static TX_THREAD thread_9;
+static TX_THREAD thread_10;
+static TX_THREAD thread_11;
+static TX_THREAD thread_12;
+static TX_THREAD thread_13;
+static TX_THREAD thread_14;
+static TX_THREAD thread_15;
+static TX_THREAD thread_16;
+static TX_THREAD thread_17;
+static TX_THREAD thread_18;
+static TX_THREAD thread_19;
+static TX_THREAD thread_20;
+static TX_THREAD thread_21;
+static TX_THREAD thread_22;
+static TX_THREAD thread_23;
+static TX_THREAD thread_24;
+static TX_THREAD thread_25;
+static TX_THREAD thread_26;
+static TX_THREAD thread_27;
+static TX_THREAD thread_28;
+static TX_THREAD thread_29;
+static TX_THREAD thread_30;
+static TX_THREAD thread_31;
+static TX_THREAD thread_32;
+static TX_THREAD thread_33;
+static TX_THREAD thread_34;
+static TX_THREAD thread_35;
+static TX_THREAD thread_36;
+static TX_THREAD thread_37;
+static TX_THREAD thread_38;
+static TX_THREAD thread_39;
+static TX_THREAD thread_40;
+static TX_THREAD thread_41;
+static TX_THREAD thread_42;
+static TX_THREAD thread_43;
+static TX_THREAD thread_44;
+static TX_THREAD thread_45;
+static TX_THREAD thread_46;
+static TX_THREAD thread_47;
+static TX_THREAD thread_48;
+static TX_THREAD thread_49;
+static TX_THREAD thread_50;
+static TX_THREAD thread_51;
+static TX_THREAD thread_52;
+static TX_THREAD thread_53;
+static TX_THREAD thread_54;
+static TX_THREAD thread_55;
+static TX_THREAD thread_56;
+static TX_THREAD thread_57;
+static TX_THREAD thread_58;
+static TX_THREAD thread_59;
+static TX_THREAD thread_60;
+static TX_THREAD thread_61;
+static TX_THREAD thread_62;
+static TX_THREAD thread_63;
+static TX_THREAD thread_64;
+static TX_THREAD thread_65;
+static TX_THREAD thread_66;
+static TX_THREAD thread_67;
+static TX_THREAD thread_68;
+static TX_THREAD thread_69;
+static TX_THREAD thread_70;
+static TX_THREAD thread_71;
+static TX_THREAD thread_72;
+static TX_THREAD thread_73;
+static TX_THREAD thread_74;
+static TX_THREAD thread_75;
+static TX_THREAD thread_76;
+static TX_THREAD thread_77;
+static TX_THREAD thread_78;
+static TX_THREAD thread_79;
+static TX_THREAD thread_80;
+static TX_THREAD thread_81;
+static TX_THREAD thread_82;
+static TX_THREAD thread_83;
+static TX_THREAD thread_84;
+static TX_THREAD thread_85;
+static TX_THREAD thread_86;
+static TX_THREAD thread_87;
+static TX_THREAD thread_88;
+static TX_THREAD thread_89;
+static TX_THREAD thread_90;
+static TX_THREAD thread_91;
+static TX_THREAD thread_92;
+static TX_THREAD thread_93;
+static TX_THREAD thread_94;
+static TX_THREAD thread_95;
+static TX_THREAD thread_96;
+static TX_THREAD thread_97;
+static TX_THREAD thread_98;
+static TX_THREAD thread_99;
+static TX_THREAD thread_100;
+static TX_THREAD thread_101;
+static TX_THREAD thread_102;
+static TX_THREAD thread_103;
+static TX_THREAD thread_104;
+static TX_THREAD thread_105;
+static TX_THREAD thread_106;
+static TX_THREAD thread_107;
+static TX_THREAD thread_108;
+static TX_THREAD thread_109;
+static TX_THREAD thread_110;
+static TX_THREAD thread_111;
+static TX_THREAD thread_112;
+static TX_THREAD thread_113;
+static TX_THREAD thread_114;
+static TX_THREAD thread_115;
+static TX_THREAD thread_116;
+static TX_THREAD thread_117;
+static TX_THREAD thread_118;
+static TX_THREAD thread_119;
+static TX_THREAD thread_120;
+static TX_THREAD thread_121;
+static TX_THREAD thread_122;
+static TX_THREAD thread_123;
+static TX_THREAD thread_124;
+static TX_THREAD thread_125;
+static TX_THREAD thread_126;
+static TX_THREAD thread_127;
+static TX_THREAD thread_128;
+static TX_THREAD thread_129;
+static TX_THREAD thread_130;
+static TX_THREAD thread_131;
+static TX_THREAD thread_132;
+static TX_THREAD thread_133;
+static TX_THREAD thread_134;
+static TX_THREAD thread_135;
+static TX_THREAD thread_136;
+static TX_THREAD thread_137;
+static TX_THREAD thread_138;
+static TX_THREAD thread_139;
+static TX_THREAD thread_140;
+static TX_THREAD thread_141;
+static TX_THREAD thread_142;
+static TX_THREAD thread_143;
+static TX_THREAD thread_144;
+static TX_THREAD thread_145;
+static TX_THREAD thread_146;
+static TX_THREAD thread_147;
+static TX_THREAD thread_148;
+static TX_THREAD thread_149;
+static TX_THREAD thread_150;
+static TX_THREAD thread_151;
+static TX_THREAD thread_152;
+static TX_THREAD thread_153;
+static TX_THREAD thread_154;
+static TX_THREAD thread_155;
+static TX_THREAD thread_156;
+static TX_THREAD thread_157;
+static TX_THREAD thread_158;
+static TX_THREAD thread_159;
+static TX_THREAD thread_160;
+static TX_THREAD thread_161;
+static TX_THREAD thread_162;
+static TX_THREAD thread_163;
+static TX_THREAD thread_164;
+static TX_THREAD thread_165;
+static TX_THREAD thread_166;
+static TX_THREAD thread_167;
+static TX_THREAD thread_168;
+static TX_THREAD thread_169;
+static TX_THREAD thread_170;
+static TX_THREAD thread_171;
+static TX_THREAD thread_172;
+static TX_THREAD thread_173;
+static TX_THREAD thread_174;
+static TX_THREAD thread_175;
+static TX_THREAD thread_176;
+static TX_THREAD thread_177;
+static TX_THREAD thread_178;
+static TX_THREAD thread_179;
+static TX_THREAD thread_180;
+static TX_THREAD thread_181;
+static TX_THREAD thread_182;
+static TX_THREAD thread_183;
+static TX_THREAD thread_184;
+static TX_THREAD thread_185;
+static TX_THREAD thread_186;
+static TX_THREAD thread_187;
+static TX_THREAD thread_188;
+static TX_THREAD thread_189;
+static TX_THREAD thread_190;
+static TX_THREAD thread_191;
+static TX_THREAD thread_192;
+static TX_THREAD thread_193;
+static TX_THREAD thread_194;
+static TX_THREAD thread_195;
+static TX_THREAD thread_196;
+static TX_THREAD thread_197;
+static TX_THREAD thread_198;
+static TX_THREAD thread_199;
+static TX_THREAD thread_200;
+static TX_THREAD thread_201;
+static TX_THREAD thread_202;
+static TX_THREAD thread_203;
+static TX_THREAD thread_204;
+static TX_THREAD thread_205;
+static TX_THREAD thread_206;
+static TX_THREAD thread_207;
+static TX_THREAD thread_208;
+static TX_THREAD thread_209;
+static TX_THREAD thread_210;
+static TX_THREAD thread_211;
+static TX_THREAD thread_212;
+static TX_THREAD thread_213;
+static TX_THREAD thread_214;
+static TX_THREAD thread_215;
+static TX_THREAD thread_216;
+static TX_THREAD thread_217;
+static TX_THREAD thread_218;
+static TX_THREAD thread_219;
+static TX_THREAD thread_220;
+static TX_THREAD thread_221;
+static TX_THREAD thread_222;
+static TX_THREAD thread_223;
+static TX_THREAD thread_224;
+static TX_THREAD thread_225;
+static TX_THREAD thread_226;
+static TX_THREAD thread_227;
+static TX_THREAD thread_228;
+static TX_THREAD thread_229;
+static TX_THREAD thread_230;
+static TX_THREAD thread_231;
+static TX_THREAD thread_232;
+static TX_THREAD thread_233;
+static TX_THREAD thread_234;
+static TX_THREAD thread_235;
+static TX_THREAD thread_236;
+static TX_THREAD thread_237;
+static TX_THREAD thread_238;
+static TX_THREAD thread_239;
+static TX_THREAD thread_240;
+static TX_THREAD thread_241;
+static TX_THREAD thread_242;
+static TX_THREAD thread_243;
+static TX_THREAD thread_244;
+static TX_THREAD thread_245;
+static TX_THREAD thread_246;
+static TX_THREAD thread_247;
+static TX_THREAD thread_248;
+static TX_THREAD thread_249;
+static TX_THREAD thread_250;
+static TX_THREAD thread_251;
+static TX_THREAD thread_252;
+static TX_THREAD thread_253;
+static TX_THREAD thread_254;
+static TX_THREAD thread_255;
+
+static TX_THREAD thread_0_1;
+static TX_THREAD thread_1_1;
+static TX_THREAD thread_2_1;
+static TX_THREAD thread_3_1;
+static TX_THREAD thread_4_1;
+static TX_THREAD thread_5_1;
+static TX_THREAD thread_6_1;
+static TX_THREAD thread_7_1;
+static TX_THREAD thread_8_1;
+static TX_THREAD thread_9_1;
+static TX_THREAD thread_10_1;
+static TX_THREAD thread_11_1;
+static TX_THREAD thread_12_1;
+static TX_THREAD thread_13_1;
+static TX_THREAD thread_14_1;
+static TX_THREAD thread_15_1;
+static TX_THREAD thread_16_1;
+static TX_THREAD thread_17_1;
+static TX_THREAD thread_18_1;
+static TX_THREAD thread_19_1;
+static TX_THREAD thread_20_1;
+static TX_THREAD thread_21_1;
+static TX_THREAD thread_22_1;
+static TX_THREAD thread_23_1;
+static TX_THREAD thread_24_1;
+static TX_THREAD thread_25_1;
+static TX_THREAD thread_26_1;
+static TX_THREAD thread_27_1;
+static TX_THREAD thread_28_1;
+static TX_THREAD thread_29_1;
+static TX_THREAD thread_30_1;
+static TX_THREAD thread_31_1;
+static TX_THREAD thread_32_1;
+static TX_THREAD thread_33_1;
+static TX_THREAD thread_34_1;
+static TX_THREAD thread_35_1;
+static TX_THREAD thread_36_1;
+static TX_THREAD thread_37_1;
+static TX_THREAD thread_38_1;
+static TX_THREAD thread_39_1;
+static TX_THREAD thread_40_1;
+static TX_THREAD thread_41_1;
+static TX_THREAD thread_42_1;
+static TX_THREAD thread_43_1;
+static TX_THREAD thread_44_1;
+static TX_THREAD thread_45_1;
+static TX_THREAD thread_46_1;
+static TX_THREAD thread_47_1;
+static TX_THREAD thread_48_1;
+static TX_THREAD thread_49_1;
+static TX_THREAD thread_50_1;
+static TX_THREAD thread_51_1;
+static TX_THREAD thread_52_1;
+static TX_THREAD thread_53_1;
+static TX_THREAD thread_54_1;
+static TX_THREAD thread_55_1;
+static TX_THREAD thread_56_1;
+static TX_THREAD thread_57_1;
+static TX_THREAD thread_58_1;
+static TX_THREAD thread_59_1;
+static TX_THREAD thread_60_1;
+static TX_THREAD thread_61_1;
+static TX_THREAD thread_62_1;
+static TX_THREAD thread_63_1;
+static TX_THREAD thread_64_1;
+static TX_THREAD thread_65_1;
+static TX_THREAD thread_66_1;
+static TX_THREAD thread_67_1;
+static TX_THREAD thread_68_1;
+static TX_THREAD thread_69_1;
+static TX_THREAD thread_70_1;
+static TX_THREAD thread_71_1;
+static TX_THREAD thread_72_1;
+static TX_THREAD thread_73_1;
+static TX_THREAD thread_74_1;
+static TX_THREAD thread_75_1;
+static TX_THREAD thread_76_1;
+static TX_THREAD thread_77_1;
+static TX_THREAD thread_78_1;
+static TX_THREAD thread_79_1;
+static TX_THREAD thread_80_1;
+static TX_THREAD thread_81_1;
+static TX_THREAD thread_82_1;
+static TX_THREAD thread_83_1;
+static TX_THREAD thread_84_1;
+static TX_THREAD thread_85_1;
+static TX_THREAD thread_86_1;
+static TX_THREAD thread_87_1;
+static TX_THREAD thread_88_1;
+static TX_THREAD thread_89_1;
+static TX_THREAD thread_90_1;
+static TX_THREAD thread_91_1;
+static TX_THREAD thread_92_1;
+static TX_THREAD thread_93_1;
+static TX_THREAD thread_94_1;
+static TX_THREAD thread_95_1;
+static TX_THREAD thread_96_1;
+static TX_THREAD thread_97_1;
+static TX_THREAD thread_98_1;
+static TX_THREAD thread_99_1;
+static TX_THREAD thread_100_1;
+static TX_THREAD thread_101_1;
+static TX_THREAD thread_102_1;
+static TX_THREAD thread_103_1;
+static TX_THREAD thread_104_1;
+static TX_THREAD thread_105_1;
+static TX_THREAD thread_106_1;
+static TX_THREAD thread_107_1;
+static TX_THREAD thread_108_1;
+static TX_THREAD thread_109_1;
+static TX_THREAD thread_110_1;
+static TX_THREAD thread_111_1;
+static TX_THREAD thread_112_1;
+static TX_THREAD thread_113_1;
+static TX_THREAD thread_114_1;
+static TX_THREAD thread_115_1;
+static TX_THREAD thread_116_1;
+static TX_THREAD thread_117_1;
+static TX_THREAD thread_118_1;
+static TX_THREAD thread_119_1;
+static TX_THREAD thread_120_1;
+static TX_THREAD thread_121_1;
+static TX_THREAD thread_122_1;
+static TX_THREAD thread_123_1;
+static TX_THREAD thread_124_1;
+static TX_THREAD thread_125_1;
+static TX_THREAD thread_126_1;
+static TX_THREAD thread_127_1;
+static TX_THREAD thread_128_1;
+static TX_THREAD thread_129_1;
+static TX_THREAD thread_130_1;
+static TX_THREAD thread_131_1;
+static TX_THREAD thread_132_1;
+static TX_THREAD thread_133_1;
+static TX_THREAD thread_134_1;
+static TX_THREAD thread_135_1;
+static TX_THREAD thread_136_1;
+static TX_THREAD thread_137_1;
+static TX_THREAD thread_138_1;
+static TX_THREAD thread_139_1;
+static TX_THREAD thread_140_1;
+static TX_THREAD thread_141_1;
+static TX_THREAD thread_142_1;
+static TX_THREAD thread_143_1;
+static TX_THREAD thread_144_1;
+static TX_THREAD thread_145_1;
+static TX_THREAD thread_146_1;
+static TX_THREAD thread_147_1;
+static TX_THREAD thread_148_1;
+static TX_THREAD thread_149_1;
+static TX_THREAD thread_150_1;
+static TX_THREAD thread_151_1;
+static TX_THREAD thread_152_1;
+static TX_THREAD thread_153_1;
+static TX_THREAD thread_154_1;
+static TX_THREAD thread_155_1;
+static TX_THREAD thread_156_1;
+static TX_THREAD thread_157_1;
+static TX_THREAD thread_158_1;
+static TX_THREAD thread_159_1;
+static TX_THREAD thread_160_1;
+static TX_THREAD thread_161_1;
+static TX_THREAD thread_162_1;
+static TX_THREAD thread_163_1;
+static TX_THREAD thread_164_1;
+static TX_THREAD thread_165_1;
+static TX_THREAD thread_166_1;
+static TX_THREAD thread_167_1;
+static TX_THREAD thread_168_1;
+static TX_THREAD thread_169_1;
+static TX_THREAD thread_170_1;
+static TX_THREAD thread_171_1;
+static TX_THREAD thread_172_1;
+static TX_THREAD thread_173_1;
+static TX_THREAD thread_174_1;
+static TX_THREAD thread_175_1;
+static TX_THREAD thread_176_1;
+static TX_THREAD thread_177_1;
+static TX_THREAD thread_178_1;
+static TX_THREAD thread_179_1;
+static TX_THREAD thread_180_1;
+static TX_THREAD thread_181_1;
+static TX_THREAD thread_182_1;
+static TX_THREAD thread_183_1;
+static TX_THREAD thread_184_1;
+static TX_THREAD thread_185_1;
+static TX_THREAD thread_186_1;
+static TX_THREAD thread_187_1;
+static TX_THREAD thread_188_1;
+static TX_THREAD thread_189_1;
+static TX_THREAD thread_190_1;
+static TX_THREAD thread_191_1;
+static TX_THREAD thread_192_1;
+static TX_THREAD thread_193_1;
+static TX_THREAD thread_194_1;
+static TX_THREAD thread_195_1;
+static TX_THREAD thread_196_1;
+static TX_THREAD thread_197_1;
+static TX_THREAD thread_198_1;
+static TX_THREAD thread_199_1;
+static TX_THREAD thread_200_1;
+static TX_THREAD thread_201_1;
+static TX_THREAD thread_202_1;
+static TX_THREAD thread_203_1;
+static TX_THREAD thread_204_1;
+static TX_THREAD thread_205_1;
+static TX_THREAD thread_206_1;
+static TX_THREAD thread_207_1;
+static TX_THREAD thread_208_1;
+static TX_THREAD thread_209_1;
+static TX_THREAD thread_210_1;
+static TX_THREAD thread_211_1;
+static TX_THREAD thread_212_1;
+static TX_THREAD thread_213_1;
+static TX_THREAD thread_214_1;
+static TX_THREAD thread_215_1;
+static TX_THREAD thread_216_1;
+static TX_THREAD thread_217_1;
+static TX_THREAD thread_218_1;
+static TX_THREAD thread_219_1;
+static TX_THREAD thread_220_1;
+static TX_THREAD thread_221_1;
+static TX_THREAD thread_222_1;
+static TX_THREAD thread_223_1;
+static TX_THREAD thread_224_1;
+static TX_THREAD thread_225_1;
+static TX_THREAD thread_226_1;
+static TX_THREAD thread_227_1;
+static TX_THREAD thread_228_1;
+static TX_THREAD thread_229_1;
+static TX_THREAD thread_230_1;
+static TX_THREAD thread_231_1;
+static TX_THREAD thread_232_1;
+static TX_THREAD thread_233_1;
+static TX_THREAD thread_234_1;
+static TX_THREAD thread_235_1;
+static TX_THREAD thread_236_1;
+static TX_THREAD thread_237_1;
+static TX_THREAD thread_238_1;
+static TX_THREAD thread_239_1;
+static TX_THREAD thread_240_1;
+static TX_THREAD thread_241_1;
+static TX_THREAD thread_242_1;
+static TX_THREAD thread_243_1;
+static TX_THREAD thread_244_1;
+static TX_THREAD thread_245_1;
+static TX_THREAD thread_246_1;
+static TX_THREAD thread_247_1;
+static TX_THREAD thread_248_1;
+static TX_THREAD thread_249_1;
+static TX_THREAD thread_250_1;
+static TX_THREAD thread_251_1;
+static TX_THREAD thread_252_1;
+static TX_THREAD thread_253_1;
+static TX_THREAD thread_254_1;
+static TX_THREAD thread_255_1;
+
+static TX_THREAD thread_0_2;
+static TX_THREAD thread_1_2;
+static TX_THREAD thread_2_2;
+static TX_THREAD thread_3_2;
+static TX_THREAD thread_4_2;
+static TX_THREAD thread_5_2;
+static TX_THREAD thread_6_2;
+static TX_THREAD thread_7_2;
+static TX_THREAD thread_8_2;
+static TX_THREAD thread_9_2;
+static TX_THREAD thread_10_2;
+static TX_THREAD thread_11_2;
+static TX_THREAD thread_12_2;
+static TX_THREAD thread_13_2;
+static TX_THREAD thread_14_2;
+static TX_THREAD thread_15_2;
+static TX_THREAD thread_16_2;
+static TX_THREAD thread_17_2;
+static TX_THREAD thread_18_2;
+static TX_THREAD thread_19_2;
+static TX_THREAD thread_20_2;
+static TX_THREAD thread_21_2;
+static TX_THREAD thread_22_2;
+static TX_THREAD thread_23_2;
+static TX_THREAD thread_24_2;
+static TX_THREAD thread_25_2;
+static TX_THREAD thread_26_2;
+static TX_THREAD thread_27_2;
+static TX_THREAD thread_28_2;
+static TX_THREAD thread_29_2;
+static TX_THREAD thread_30_2;
+static TX_THREAD thread_31_2;
+static TX_THREAD thread_32_2;
+static TX_THREAD thread_33_2;
+static TX_THREAD thread_34_2;
+static TX_THREAD thread_35_2;
+static TX_THREAD thread_36_2;
+static TX_THREAD thread_37_2;
+static TX_THREAD thread_38_2;
+static TX_THREAD thread_39_2;
+static TX_THREAD thread_40_2;
+static TX_THREAD thread_41_2;
+static TX_THREAD thread_42_2;
+static TX_THREAD thread_43_2;
+static TX_THREAD thread_44_2;
+static TX_THREAD thread_45_2;
+static TX_THREAD thread_46_2;
+static TX_THREAD thread_47_2;
+static TX_THREAD thread_48_2;
+static TX_THREAD thread_49_2;
+static TX_THREAD thread_50_2;
+static TX_THREAD thread_51_2;
+static TX_THREAD thread_52_2;
+static TX_THREAD thread_53_2;
+static TX_THREAD thread_54_2;
+static TX_THREAD thread_55_2;
+static TX_THREAD thread_56_2;
+static TX_THREAD thread_57_2;
+static TX_THREAD thread_58_2;
+static TX_THREAD thread_59_2;
+static TX_THREAD thread_60_2;
+static TX_THREAD thread_61_2;
+static TX_THREAD thread_62_2;
+static TX_THREAD thread_63_2;
+static TX_THREAD thread_64_2;
+static TX_THREAD thread_65_2;
+static TX_THREAD thread_66_2;
+static TX_THREAD thread_67_2;
+static TX_THREAD thread_68_2;
+static TX_THREAD thread_69_2;
+static TX_THREAD thread_70_2;
+static TX_THREAD thread_71_2;
+static TX_THREAD thread_72_2;
+static TX_THREAD thread_73_2;
+static TX_THREAD thread_74_2;
+static TX_THREAD thread_75_2;
+static TX_THREAD thread_76_2;
+static TX_THREAD thread_77_2;
+static TX_THREAD thread_78_2;
+static TX_THREAD thread_79_2;
+static TX_THREAD thread_80_2;
+static TX_THREAD thread_81_2;
+static TX_THREAD thread_82_2;
+static TX_THREAD thread_83_2;
+static TX_THREAD thread_84_2;
+static TX_THREAD thread_85_2;
+static TX_THREAD thread_86_2;
+static TX_THREAD thread_87_2;
+static TX_THREAD thread_88_2;
+static TX_THREAD thread_89_2;
+static TX_THREAD thread_90_2;
+static TX_THREAD thread_91_2;
+static TX_THREAD thread_92_2;
+static TX_THREAD thread_93_2;
+static TX_THREAD thread_94_2;
+static TX_THREAD thread_95_2;
+static TX_THREAD thread_96_2;
+static TX_THREAD thread_97_2;
+static TX_THREAD thread_98_2;
+static TX_THREAD thread_99_2;
+static TX_THREAD thread_100_2;
+static TX_THREAD thread_101_2;
+static TX_THREAD thread_102_2;
+static TX_THREAD thread_103_2;
+static TX_THREAD thread_104_2;
+static TX_THREAD thread_105_2;
+static TX_THREAD thread_106_2;
+static TX_THREAD thread_107_2;
+static TX_THREAD thread_108_2;
+static TX_THREAD thread_109_2;
+static TX_THREAD thread_110_2;
+static TX_THREAD thread_111_2;
+static TX_THREAD thread_112_2;
+static TX_THREAD thread_113_2;
+static TX_THREAD thread_114_2;
+static TX_THREAD thread_115_2;
+static TX_THREAD thread_116_2;
+static TX_THREAD thread_117_2;
+static TX_THREAD thread_118_2;
+static TX_THREAD thread_119_2;
+static TX_THREAD thread_120_2;
+static TX_THREAD thread_121_2;
+static TX_THREAD thread_122_2;
+static TX_THREAD thread_123_2;
+static TX_THREAD thread_124_2;
+static TX_THREAD thread_125_2;
+static TX_THREAD thread_126_2;
+static TX_THREAD thread_127_2;
+static TX_THREAD thread_128_2;
+static TX_THREAD thread_129_2;
+static TX_THREAD thread_130_2;
+static TX_THREAD thread_131_2;
+static TX_THREAD thread_132_2;
+static TX_THREAD thread_133_2;
+static TX_THREAD thread_134_2;
+static TX_THREAD thread_135_2;
+static TX_THREAD thread_136_2;
+static TX_THREAD thread_137_2;
+static TX_THREAD thread_138_2;
+static TX_THREAD thread_139_2;
+static TX_THREAD thread_140_2;
+static TX_THREAD thread_141_2;
+static TX_THREAD thread_142_2;
+static TX_THREAD thread_143_2;
+static TX_THREAD thread_144_2;
+static TX_THREAD thread_145_2;
+static TX_THREAD thread_146_2;
+static TX_THREAD thread_147_2;
+static TX_THREAD thread_148_2;
+static TX_THREAD thread_149_2;
+static TX_THREAD thread_150_2;
+static TX_THREAD thread_151_2;
+static TX_THREAD thread_152_2;
+static TX_THREAD thread_153_2;
+static TX_THREAD thread_154_2;
+static TX_THREAD thread_155_2;
+static TX_THREAD thread_156_2;
+static TX_THREAD thread_157_2;
+static TX_THREAD thread_158_2;
+static TX_THREAD thread_159_2;
+static TX_THREAD thread_160_2;
+static TX_THREAD thread_161_2;
+static TX_THREAD thread_162_2;
+static TX_THREAD thread_163_2;
+static TX_THREAD thread_164_2;
+static TX_THREAD thread_165_2;
+static TX_THREAD thread_166_2;
+static TX_THREAD thread_167_2;
+static TX_THREAD thread_168_2;
+static TX_THREAD thread_169_2;
+static TX_THREAD thread_170_2;
+static TX_THREAD thread_171_2;
+static TX_THREAD thread_172_2;
+static TX_THREAD thread_173_2;
+static TX_THREAD thread_174_2;
+static TX_THREAD thread_175_2;
+static TX_THREAD thread_176_2;
+static TX_THREAD thread_177_2;
+static TX_THREAD thread_178_2;
+static TX_THREAD thread_179_2;
+static TX_THREAD thread_180_2;
+static TX_THREAD thread_181_2;
+static TX_THREAD thread_182_2;
+static TX_THREAD thread_183_2;
+static TX_THREAD thread_184_2;
+static TX_THREAD thread_185_2;
+static TX_THREAD thread_186_2;
+static TX_THREAD thread_187_2;
+static TX_THREAD thread_188_2;
+static TX_THREAD thread_189_2;
+static TX_THREAD thread_190_2;
+static TX_THREAD thread_191_2;
+static TX_THREAD thread_192_2;
+static TX_THREAD thread_193_2;
+static TX_THREAD thread_194_2;
+static TX_THREAD thread_195_2;
+static TX_THREAD thread_196_2;
+static TX_THREAD thread_197_2;
+static TX_THREAD thread_198_2;
+static TX_THREAD thread_199_2;
+static TX_THREAD thread_200_2;
+static TX_THREAD thread_201_2;
+static TX_THREAD thread_202_2;
+static TX_THREAD thread_203_2;
+static TX_THREAD thread_204_2;
+static TX_THREAD thread_205_2;
+static TX_THREAD thread_206_2;
+static TX_THREAD thread_207_2;
+static TX_THREAD thread_208_2;
+static TX_THREAD thread_209_2;
+static TX_THREAD thread_210_2;
+static TX_THREAD thread_211_2;
+static TX_THREAD thread_212_2;
+static TX_THREAD thread_213_2;
+static TX_THREAD thread_214_2;
+static TX_THREAD thread_215_2;
+static TX_THREAD thread_216_2;
+static TX_THREAD thread_217_2;
+static TX_THREAD thread_218_2;
+static TX_THREAD thread_219_2;
+static TX_THREAD thread_220_2;
+static TX_THREAD thread_221_2;
+static TX_THREAD thread_222_2;
+static TX_THREAD thread_223_2;
+static TX_THREAD thread_224_2;
+static TX_THREAD thread_225_2;
+static TX_THREAD thread_226_2;
+static TX_THREAD thread_227_2;
+static TX_THREAD thread_228_2;
+static TX_THREAD thread_229_2;
+static TX_THREAD thread_230_2;
+static TX_THREAD thread_231_2;
+static TX_THREAD thread_232_2;
+static TX_THREAD thread_233_2;
+static TX_THREAD thread_234_2;
+static TX_THREAD thread_235_2;
+static TX_THREAD thread_236_2;
+static TX_THREAD thread_237_2;
+static TX_THREAD thread_238_2;
+static TX_THREAD thread_239_2;
+static TX_THREAD thread_240_2;
+static TX_THREAD thread_241_2;
+static TX_THREAD thread_242_2;
+static TX_THREAD thread_243_2;
+static TX_THREAD thread_244_2;
+static TX_THREAD thread_245_2;
+static TX_THREAD thread_246_2;
+static TX_THREAD thread_247_2;
+static TX_THREAD thread_248_2;
+static TX_THREAD thread_249_2;
+static TX_THREAD thread_250_2;
+static TX_THREAD thread_251_2;
+static TX_THREAD thread_252_2;
+static TX_THREAD thread_253_2;
+static TX_THREAD thread_254_2;
+static TX_THREAD thread_255_2;
+
+static TX_THREAD thread_0_3;
+static TX_THREAD thread_1_3;
+static TX_THREAD thread_2_3;
+static TX_THREAD thread_3_3;
+static TX_THREAD thread_4_3;
+static TX_THREAD thread_5_3;
+static TX_THREAD thread_6_3;
+static TX_THREAD thread_7_3;
+static TX_THREAD thread_8_3;
+static TX_THREAD thread_9_3;
+static TX_THREAD thread_10_3;
+static TX_THREAD thread_11_3;
+static TX_THREAD thread_12_3;
+static TX_THREAD thread_13_3;
+static TX_THREAD thread_14_3;
+static TX_THREAD thread_15_3;
+static TX_THREAD thread_16_3;
+static TX_THREAD thread_17_3;
+static TX_THREAD thread_18_3;
+static TX_THREAD thread_19_3;
+static TX_THREAD thread_20_3;
+static TX_THREAD thread_21_3;
+static TX_THREAD thread_22_3;
+static TX_THREAD thread_23_3;
+static TX_THREAD thread_24_3;
+static TX_THREAD thread_25_3;
+static TX_THREAD thread_26_3;
+static TX_THREAD thread_27_3;
+static TX_THREAD thread_28_3;
+static TX_THREAD thread_29_3;
+static TX_THREAD thread_30_3;
+static TX_THREAD thread_31_3;
+static TX_THREAD thread_32_3;
+static TX_THREAD thread_33_3;
+static TX_THREAD thread_34_3;
+static TX_THREAD thread_35_3;
+static TX_THREAD thread_36_3;
+static TX_THREAD thread_37_3;
+static TX_THREAD thread_38_3;
+static TX_THREAD thread_39_3;
+static TX_THREAD thread_40_3;
+static TX_THREAD thread_41_3;
+static TX_THREAD thread_42_3;
+static TX_THREAD thread_43_3;
+static TX_THREAD thread_44_3;
+static TX_THREAD thread_45_3;
+static TX_THREAD thread_46_3;
+static TX_THREAD thread_47_3;
+static TX_THREAD thread_48_3;
+static TX_THREAD thread_49_3;
+static TX_THREAD thread_50_3;
+static TX_THREAD thread_51_3;
+static TX_THREAD thread_52_3;
+static TX_THREAD thread_53_3;
+static TX_THREAD thread_54_3;
+static TX_THREAD thread_55_3;
+static TX_THREAD thread_56_3;
+static TX_THREAD thread_57_3;
+static TX_THREAD thread_58_3;
+static TX_THREAD thread_59_3;
+static TX_THREAD thread_60_3;
+static TX_THREAD thread_61_3;
+static TX_THREAD thread_62_3;
+static TX_THREAD thread_63_3;
+static TX_THREAD thread_64_3;
+static TX_THREAD thread_65_3;
+static TX_THREAD thread_66_3;
+static TX_THREAD thread_67_3;
+static TX_THREAD thread_68_3;
+static TX_THREAD thread_69_3;
+static TX_THREAD thread_70_3;
+static TX_THREAD thread_71_3;
+static TX_THREAD thread_72_3;
+static TX_THREAD thread_73_3;
+static TX_THREAD thread_74_3;
+static TX_THREAD thread_75_3;
+static TX_THREAD thread_76_3;
+static TX_THREAD thread_77_3;
+static TX_THREAD thread_78_3;
+static TX_THREAD thread_79_3;
+static TX_THREAD thread_80_3;
+static TX_THREAD thread_81_3;
+static TX_THREAD thread_82_3;
+static TX_THREAD thread_83_3;
+static TX_THREAD thread_84_3;
+static TX_THREAD thread_85_3;
+static TX_THREAD thread_86_3;
+static TX_THREAD thread_87_3;
+static TX_THREAD thread_88_3;
+static TX_THREAD thread_89_3;
+static TX_THREAD thread_90_3;
+static TX_THREAD thread_91_3;
+static TX_THREAD thread_92_3;
+static TX_THREAD thread_93_3;
+static TX_THREAD thread_94_3;
+static TX_THREAD thread_95_3;
+static TX_THREAD thread_96_3;
+static TX_THREAD thread_97_3;
+static TX_THREAD thread_98_3;
+static TX_THREAD thread_99_3;
+static TX_THREAD thread_100_3;
+static TX_THREAD thread_101_3;
+static TX_THREAD thread_102_3;
+static TX_THREAD thread_103_3;
+static TX_THREAD thread_104_3;
+static TX_THREAD thread_105_3;
+static TX_THREAD thread_106_3;
+static TX_THREAD thread_107_3;
+static TX_THREAD thread_108_3;
+static TX_THREAD thread_109_3;
+static TX_THREAD thread_110_3;
+static TX_THREAD thread_111_3;
+static TX_THREAD thread_112_3;
+static TX_THREAD thread_113_3;
+static TX_THREAD thread_114_3;
+static TX_THREAD thread_115_3;
+static TX_THREAD thread_116_3;
+static TX_THREAD thread_117_3;
+static TX_THREAD thread_118_3;
+static TX_THREAD thread_119_3;
+static TX_THREAD thread_120_3;
+static TX_THREAD thread_121_3;
+static TX_THREAD thread_122_3;
+static TX_THREAD thread_123_3;
+static TX_THREAD thread_124_3;
+static TX_THREAD thread_125_3;
+static TX_THREAD thread_126_3;
+static TX_THREAD thread_127_3;
+static TX_THREAD thread_128_3;
+static TX_THREAD thread_129_3;
+static TX_THREAD thread_130_3;
+static TX_THREAD thread_131_3;
+static TX_THREAD thread_132_3;
+static TX_THREAD thread_133_3;
+static TX_THREAD thread_134_3;
+static TX_THREAD thread_135_3;
+static TX_THREAD thread_136_3;
+static TX_THREAD thread_137_3;
+static TX_THREAD thread_138_3;
+static TX_THREAD thread_139_3;
+static TX_THREAD thread_140_3;
+static TX_THREAD thread_141_3;
+static TX_THREAD thread_142_3;
+static TX_THREAD thread_143_3;
+static TX_THREAD thread_144_3;
+static TX_THREAD thread_145_3;
+static TX_THREAD thread_146_3;
+static TX_THREAD thread_147_3;
+static TX_THREAD thread_148_3;
+static TX_THREAD thread_149_3;
+static TX_THREAD thread_150_3;
+static TX_THREAD thread_151_3;
+static TX_THREAD thread_152_3;
+static TX_THREAD thread_153_3;
+static TX_THREAD thread_154_3;
+static TX_THREAD thread_155_3;
+static TX_THREAD thread_156_3;
+static TX_THREAD thread_157_3;
+static TX_THREAD thread_158_3;
+static TX_THREAD thread_159_3;
+static TX_THREAD thread_160_3;
+static TX_THREAD thread_161_3;
+static TX_THREAD thread_162_3;
+static TX_THREAD thread_163_3;
+static TX_THREAD thread_164_3;
+static TX_THREAD thread_165_3;
+static TX_THREAD thread_166_3;
+static TX_THREAD thread_167_3;
+static TX_THREAD thread_168_3;
+static TX_THREAD thread_169_3;
+static TX_THREAD thread_170_3;
+static TX_THREAD thread_171_3;
+static TX_THREAD thread_172_3;
+static TX_THREAD thread_173_3;
+static TX_THREAD thread_174_3;
+static TX_THREAD thread_175_3;
+static TX_THREAD thread_176_3;
+static TX_THREAD thread_177_3;
+static TX_THREAD thread_178_3;
+static TX_THREAD thread_179_3;
+static TX_THREAD thread_180_3;
+static TX_THREAD thread_181_3;
+static TX_THREAD thread_182_3;
+static TX_THREAD thread_183_3;
+static TX_THREAD thread_184_3;
+static TX_THREAD thread_185_3;
+static TX_THREAD thread_186_3;
+static TX_THREAD thread_187_3;
+static TX_THREAD thread_188_3;
+static TX_THREAD thread_189_3;
+static TX_THREAD thread_190_3;
+static TX_THREAD thread_191_3;
+static TX_THREAD thread_192_3;
+static TX_THREAD thread_193_3;
+static TX_THREAD thread_194_3;
+static TX_THREAD thread_195_3;
+static TX_THREAD thread_196_3;
+static TX_THREAD thread_197_3;
+static TX_THREAD thread_198_3;
+static TX_THREAD thread_199_3;
+static TX_THREAD thread_200_3;
+static TX_THREAD thread_201_3;
+static TX_THREAD thread_202_3;
+static TX_THREAD thread_203_3;
+static TX_THREAD thread_204_3;
+static TX_THREAD thread_205_3;
+static TX_THREAD thread_206_3;
+static TX_THREAD thread_207_3;
+static TX_THREAD thread_208_3;
+static TX_THREAD thread_209_3;
+static TX_THREAD thread_210_3;
+static TX_THREAD thread_211_3;
+static TX_THREAD thread_212_3;
+static TX_THREAD thread_213_3;
+static TX_THREAD thread_214_3;
+static TX_THREAD thread_215_3;
+static TX_THREAD thread_216_3;
+static TX_THREAD thread_217_3;
+static TX_THREAD thread_218_3;
+static TX_THREAD thread_219_3;
+static TX_THREAD thread_220_3;
+static TX_THREAD thread_221_3;
+static TX_THREAD thread_222_3;
+static TX_THREAD thread_223_3;
+static TX_THREAD thread_224_3;
+static TX_THREAD thread_225_3;
+static TX_THREAD thread_226_3;
+static TX_THREAD thread_227_3;
+static TX_THREAD thread_228_3;
+static TX_THREAD thread_229_3;
+static TX_THREAD thread_230_3;
+static TX_THREAD thread_231_3;
+static TX_THREAD thread_232_3;
+static TX_THREAD thread_233_3;
+static TX_THREAD thread_234_3;
+static TX_THREAD thread_235_3;
+static TX_THREAD thread_236_3;
+static TX_THREAD thread_237_3;
+static TX_THREAD thread_238_3;
+static TX_THREAD thread_239_3;
+static TX_THREAD thread_240_3;
+static TX_THREAD thread_241_3;
+static TX_THREAD thread_242_3;
+static TX_THREAD thread_243_3;
+static TX_THREAD thread_244_3;
+static TX_THREAD thread_245_3;
+static TX_THREAD thread_246_3;
+static TX_THREAD thread_247_3;
+static TX_THREAD thread_248_3;
+static TX_THREAD thread_249_3;
+static TX_THREAD thread_250_3;
+static TX_THREAD thread_251_3;
+static TX_THREAD thread_252_3;
+static TX_THREAD thread_253_3;
+static TX_THREAD thread_254_3;
+static TX_THREAD thread_255_3;
+
+/* Define test array. */
+
+static TX_THREAD *_smp_randomized_source_array[] = {
+{&thread_0},
+{&thread_1},
+{&thread_2},
+{&thread_3},
+{&thread_4},
+{&thread_5},
+{&thread_6},
+{&thread_7},
+{&thread_8},
+{&thread_9},
+{&thread_10},
+{&thread_11},
+{&thread_12},
+{&thread_13},
+{&thread_14},
+{&thread_15},
+{&thread_16},
+{&thread_17},
+{&thread_18},
+{&thread_19},
+{&thread_20},
+{&thread_21},
+{&thread_22},
+{&thread_23},
+{&thread_24},
+{&thread_25},
+{&thread_26},
+{&thread_27},
+{&thread_28},
+{&thread_29},
+{&thread_30},
+{&thread_31},
+{&thread_32},
+{&thread_33},
+{&thread_34},
+{&thread_35},
+{&thread_36},
+{&thread_37},
+{&thread_38},
+{&thread_39},
+{&thread_40},
+{&thread_41},
+{&thread_42},
+{&thread_43},
+{&thread_44},
+{&thread_45},
+{&thread_46},
+{&thread_47},
+{&thread_48},
+{&thread_49},
+{&thread_50},
+{&thread_51},
+{&thread_52},
+{&thread_53},
+{&thread_54},
+{&thread_55},
+{&thread_56},
+{&thread_57},
+{&thread_58},
+{&thread_59},
+{&thread_60},
+{&thread_61},
+{&thread_62},
+{&thread_63},
+{&thread_64},
+{&thread_65},
+{&thread_66},
+{&thread_67},
+{&thread_68},
+{&thread_69},
+{&thread_70},
+{&thread_71},
+{&thread_72},
+{&thread_73},
+{&thread_74},
+{&thread_75},
+{&thread_76},
+{&thread_77},
+{&thread_78},
+{&thread_79},
+{&thread_80},
+{&thread_81},
+{&thread_82},
+{&thread_83},
+{&thread_84},
+{&thread_85},
+{&thread_86},
+{&thread_87},
+{&thread_88},
+{&thread_89},
+{&thread_90},
+{&thread_91},
+{&thread_92},
+{&thread_93},
+{&thread_94},
+{&thread_95},
+{&thread_96},
+{&thread_97},
+{&thread_98},
+{&thread_99},
+{&thread_100},
+{&thread_101},
+{&thread_102},
+{&thread_103},
+{&thread_104},
+{&thread_105},
+{&thread_106},
+{&thread_107},
+{&thread_108},
+{&thread_109},
+{&thread_110},
+{&thread_111},
+{&thread_112},
+{&thread_113},
+{&thread_114},
+{&thread_115},
+{&thread_116},
+{&thread_117},
+{&thread_118},
+{&thread_119},
+{&thread_120},
+{&thread_121},
+{&thread_122},
+{&thread_123},
+{&thread_124},
+{&thread_125},
+{&thread_126},
+{&thread_127},
+{&thread_128},
+{&thread_129},
+{&thread_130},
+{&thread_131},
+{&thread_132},
+{&thread_133},
+{&thread_134},
+{&thread_135},
+{&thread_136},
+{&thread_137},
+{&thread_138},
+{&thread_139},
+{&thread_140},
+{&thread_141},
+{&thread_142},
+{&thread_143},
+{&thread_144},
+{&thread_145},
+{&thread_146},
+{&thread_147},
+{&thread_148},
+{&thread_149},
+{&thread_150},
+{&thread_151},
+{&thread_152},
+{&thread_153},
+{&thread_154},
+{&thread_155},
+{&thread_156},
+{&thread_157},
+{&thread_158},
+{&thread_159},
+{&thread_160},
+{&thread_161},
+{&thread_162},
+{&thread_163},
+{&thread_164},
+{&thread_165},
+{&thread_166},
+{&thread_167},
+{&thread_168},
+{&thread_169},
+{&thread_170},
+{&thread_171},
+{&thread_172},
+{&thread_173},
+{&thread_174},
+{&thread_175},
+{&thread_176},
+{&thread_177},
+{&thread_178},
+{&thread_179},
+{&thread_180},
+{&thread_181},
+{&thread_182},
+{&thread_183},
+{&thread_184},
+{&thread_185},
+{&thread_186},
+{&thread_187},
+{&thread_188},
+{&thread_189},
+{&thread_190},
+{&thread_191},
+{&thread_192},
+{&thread_193},
+{&thread_194},
+{&thread_195},
+{&thread_196},
+{&thread_197},
+{&thread_198},
+{&thread_199},
+{&thread_200},
+{&thread_201},
+{&thread_202},
+{&thread_203},
+{&thread_204},
+{&thread_205},
+{&thread_206},
+{&thread_207},
+{&thread_208},
+{&thread_209},
+{&thread_210},
+{&thread_211},
+{&thread_212},
+{&thread_213},
+{&thread_214},
+{&thread_215},
+{&thread_216},
+{&thread_217},
+{&thread_218},
+{&thread_219},
+{&thread_220},
+{&thread_221},
+{&thread_222},
+{&thread_223},
+{&thread_224},
+{&thread_225},
+{&thread_226},
+{&thread_227},
+{&thread_228},
+{&thread_229},
+{&thread_230},
+{&thread_231},
+{&thread_232},
+{&thread_233},
+{&thread_234},
+{&thread_235},
+{&thread_236},
+{&thread_237},
+{&thread_238},
+{&thread_239},
+{&thread_240},
+{&thread_241},
+{&thread_242},
+{&thread_243},
+{&thread_244},
+{&thread_245},
+{&thread_246},
+{&thread_247},
+{&thread_248},
+{&thread_249},
+{&thread_250},
+{&thread_251},
+{&thread_252},
+{&thread_253},
+{&thread_254},
+{&thread_255},
+
+{&thread_0_1},
+{&thread_1_1},
+{&thread_2_1},
+{&thread_3_1},
+{&thread_4_1},
+{&thread_5_1},
+{&thread_6_1},
+{&thread_7_1},
+{&thread_8_1},
+{&thread_9_1},
+{&thread_10_1},
+{&thread_11_1},
+{&thread_12_1},
+{&thread_13_1},
+{&thread_14_1},
+{&thread_15_1},
+{&thread_16_1},
+{&thread_17_1},
+{&thread_18_1},
+{&thread_19_1},
+{&thread_20_1},
+{&thread_21_1},
+{&thread_22_1},
+{&thread_23_1},
+{&thread_24_1},
+{&thread_25_1},
+{&thread_26_1},
+{&thread_27_1},
+{&thread_28_1},
+{&thread_29_1},
+{&thread_30_1},
+{&thread_31_1},
+{&thread_32_1},
+{&thread_33_1},
+{&thread_34_1},
+{&thread_35_1},
+{&thread_36_1},
+{&thread_37_1},
+{&thread_38_1},
+{&thread_39_1},
+{&thread_40_1},
+{&thread_41_1},
+{&thread_42_1},
+{&thread_43_1},
+{&thread_44_1},
+{&thread_45_1},
+{&thread_46_1},
+{&thread_47_1},
+{&thread_48_1},
+{&thread_49_1},
+{&thread_50_1},
+{&thread_51_1},
+{&thread_52_1},
+{&thread_53_1},
+{&thread_54_1},
+{&thread_55_1},
+{&thread_56_1},
+{&thread_57_1},
+{&thread_58_1},
+{&thread_59_1},
+{&thread_60_1},
+{&thread_61_1},
+{&thread_62_1},
+{&thread_63_1},
+{&thread_64_1},
+{&thread_65_1},
+{&thread_66_1},
+{&thread_67_1},
+{&thread_68_1},
+{&thread_69_1},
+{&thread_70_1},
+{&thread_71_1},
+{&thread_72_1},
+{&thread_73_1},
+{&thread_74_1},
+{&thread_75_1},
+{&thread_76_1},
+{&thread_77_1},
+{&thread_78_1},
+{&thread_79_1},
+{&thread_80_1},
+{&thread_81_1},
+{&thread_82_1},
+{&thread_83_1},
+{&thread_84_1},
+{&thread_85_1},
+{&thread_86_1},
+{&thread_87_1},
+{&thread_88_1},
+{&thread_89_1},
+{&thread_90_1},
+{&thread_91_1},
+{&thread_92_1},
+{&thread_93_1},
+{&thread_94_1},
+{&thread_95_1},
+{&thread_96_1},
+{&thread_97_1},
+{&thread_98_1},
+{&thread_99_1},
+{&thread_100_1},
+{&thread_101_1},
+{&thread_102_1},
+{&thread_103_1},
+{&thread_104_1},
+{&thread_105_1},
+{&thread_106_1},
+{&thread_107_1},
+{&thread_108_1},
+{&thread_109_1},
+{&thread_110_1},
+{&thread_111_1},
+{&thread_112_1},
+{&thread_113_1},
+{&thread_114_1},
+{&thread_115_1},
+{&thread_116_1},
+{&thread_117_1},
+{&thread_118_1},
+{&thread_119_1},
+{&thread_120_1},
+{&thread_121_1},
+{&thread_122_1},
+{&thread_123_1},
+{&thread_124_1},
+{&thread_125_1},
+{&thread_126_1},
+{&thread_127_1},
+{&thread_128_1},
+{&thread_129_1},
+{&thread_130_1},
+{&thread_131_1},
+{&thread_132_1},
+{&thread_133_1},
+{&thread_134_1},
+{&thread_135_1},
+{&thread_136_1},
+{&thread_137_1},
+{&thread_138_1},
+{&thread_139_1},
+{&thread_140_1},
+{&thread_141_1},
+{&thread_142_1},
+{&thread_143_1},
+{&thread_144_1},
+{&thread_145_1},
+{&thread_146_1},
+{&thread_147_1},
+{&thread_148_1},
+{&thread_149_1},
+{&thread_150_1},
+{&thread_151_1},
+{&thread_152_1},
+{&thread_153_1},
+{&thread_154_1},
+{&thread_155_1},
+{&thread_156_1},
+{&thread_157_1},
+{&thread_158_1},
+{&thread_159_1},
+{&thread_160_1},
+{&thread_161_1},
+{&thread_162_1},
+{&thread_163_1},
+{&thread_164_1},
+{&thread_165_1},
+{&thread_166_1},
+{&thread_167_1},
+{&thread_168_1},
+{&thread_169_1},
+{&thread_170_1},
+{&thread_171_1},
+{&thread_172_1},
+{&thread_173_1},
+{&thread_174_1},
+{&thread_175_1},
+{&thread_176_1},
+{&thread_177_1},
+{&thread_178_1},
+{&thread_179_1},
+{&thread_180_1},
+{&thread_181_1},
+{&thread_182_1},
+{&thread_183_1},
+{&thread_184_1},
+{&thread_185_1},
+{&thread_186_1},
+{&thread_187_1},
+{&thread_188_1},
+{&thread_189_1},
+{&thread_190_1},
+{&thread_191_1},
+{&thread_192_1},
+{&thread_193_1},
+{&thread_194_1},
+{&thread_195_1},
+{&thread_196_1},
+{&thread_197_1},
+{&thread_198_1},
+{&thread_199_1},
+{&thread_200_1},
+{&thread_201_1},
+{&thread_202_1},
+{&thread_203_1},
+{&thread_204_1},
+{&thread_205_1},
+{&thread_206_1},
+{&thread_207_1},
+{&thread_208_1},
+{&thread_209_1},
+{&thread_210_1},
+{&thread_211_1},
+{&thread_212_1},
+{&thread_213_1},
+{&thread_214_1},
+{&thread_215_1},
+{&thread_216_1},
+{&thread_217_1},
+{&thread_218_1},
+{&thread_219_1},
+{&thread_220_1},
+{&thread_221_1},
+{&thread_222_1},
+{&thread_223_1},
+{&thread_224_1},
+{&thread_225_1},
+{&thread_226_1},
+{&thread_227_1},
+{&thread_228_1},
+{&thread_229_1},
+{&thread_230_1},
+{&thread_231_1},
+{&thread_232_1},
+{&thread_233_1},
+{&thread_234_1},
+{&thread_235_1},
+{&thread_236_1},
+{&thread_237_1},
+{&thread_238_1},
+{&thread_239_1},
+{&thread_240_1},
+{&thread_241_1},
+{&thread_242_1},
+{&thread_243_1},
+{&thread_244_1},
+{&thread_245_1},
+{&thread_246_1},
+{&thread_247_1},
+{&thread_248_1},
+{&thread_249_1},
+{&thread_250_1},
+{&thread_251_1},
+{&thread_252_1},
+{&thread_253_1},
+{&thread_254_1},
+{&thread_255_1},
+
+{&thread_0_2},
+{&thread_1_2},
+{&thread_2_2},
+{&thread_3_2},
+{&thread_4_2},
+{&thread_5_2},
+{&thread_6_2},
+{&thread_7_2},
+{&thread_8_2},
+{&thread_9_2},
+{&thread_10_2},
+{&thread_11_2},
+{&thread_12_2},
+{&thread_13_2},
+{&thread_14_2},
+{&thread_15_2},
+{&thread_16_2},
+{&thread_17_2},
+{&thread_18_2},
+{&thread_19_2},
+{&thread_20_2},
+{&thread_21_2},
+{&thread_22_2},
+{&thread_23_2},
+{&thread_24_2},
+{&thread_25_2},
+{&thread_26_2},
+{&thread_27_2},
+{&thread_28_2},
+{&thread_29_2},
+{&thread_30_2},
+{&thread_31_2},
+{&thread_32_2},
+{&thread_33_2},
+{&thread_34_2},
+{&thread_35_2},
+{&thread_36_2},
+{&thread_37_2},
+{&thread_38_2},
+{&thread_39_2},
+{&thread_40_2},
+{&thread_41_2},
+{&thread_42_2},
+{&thread_43_2},
+{&thread_44_2},
+{&thread_45_2},
+{&thread_46_2},
+{&thread_47_2},
+{&thread_48_2},
+{&thread_49_2},
+{&thread_50_2},
+{&thread_51_2},
+{&thread_52_2},
+{&thread_53_2},
+{&thread_54_2},
+{&thread_55_2},
+{&thread_56_2},
+{&thread_57_2},
+{&thread_58_2},
+{&thread_59_2},
+{&thread_60_2},
+{&thread_61_2},
+{&thread_62_2},
+{&thread_63_2},
+{&thread_64_2},
+{&thread_65_2},
+{&thread_66_2},
+{&thread_67_2},
+{&thread_68_2},
+{&thread_69_2},
+{&thread_70_2},
+{&thread_71_2},
+{&thread_72_2},
+{&thread_73_2},
+{&thread_74_2},
+{&thread_75_2},
+{&thread_76_2},
+{&thread_77_2},
+{&thread_78_2},
+{&thread_79_2},
+{&thread_80_2},
+{&thread_81_2},
+{&thread_82_2},
+{&thread_83_2},
+{&thread_84_2},
+{&thread_85_2},
+{&thread_86_2},
+{&thread_87_2},
+{&thread_88_2},
+{&thread_89_2},
+{&thread_90_2},
+{&thread_91_2},
+{&thread_92_2},
+{&thread_93_2},
+{&thread_94_2},
+{&thread_95_2},
+{&thread_96_2},
+{&thread_97_2},
+{&thread_98_2},
+{&thread_99_2},
+{&thread_100_2},
+{&thread_101_2},
+{&thread_102_2},
+{&thread_103_2},
+{&thread_104_2},
+{&thread_105_2},
+{&thread_106_2},
+{&thread_107_2},
+{&thread_108_2},
+{&thread_109_2},
+{&thread_110_2},
+{&thread_111_2},
+{&thread_112_2},
+{&thread_113_2},
+{&thread_114_2},
+{&thread_115_2},
+{&thread_116_2},
+{&thread_117_2},
+{&thread_118_2},
+{&thread_119_2},
+{&thread_120_2},
+{&thread_121_2},
+{&thread_122_2},
+{&thread_123_2},
+{&thread_124_2},
+{&thread_125_2},
+{&thread_126_2},
+{&thread_127_2},
+{&thread_128_2},
+{&thread_129_2},
+{&thread_130_2},
+{&thread_131_2},
+{&thread_132_2},
+{&thread_133_2},
+{&thread_134_2},
+{&thread_135_2},
+{&thread_136_2},
+{&thread_137_2},
+{&thread_138_2},
+{&thread_139_2},
+{&thread_140_2},
+{&thread_141_2},
+{&thread_142_2},
+{&thread_143_2},
+{&thread_144_2},
+{&thread_145_2},
+{&thread_146_2},
+{&thread_147_2},
+{&thread_148_2},
+{&thread_149_2},
+{&thread_150_2},
+{&thread_151_2},
+{&thread_152_2},
+{&thread_153_2},
+{&thread_154_2},
+{&thread_155_2},
+{&thread_156_2},
+{&thread_157_2},
+{&thread_158_2},
+{&thread_159_2},
+{&thread_160_2},
+{&thread_161_2},
+{&thread_162_2},
+{&thread_163_2},
+{&thread_164_2},
+{&thread_165_2},
+{&thread_166_2},
+{&thread_167_2},
+{&thread_168_2},
+{&thread_169_2},
+{&thread_170_2},
+{&thread_171_2},
+{&thread_172_2},
+{&thread_173_2},
+{&thread_174_2},
+{&thread_175_2},
+{&thread_176_2},
+{&thread_177_2},
+{&thread_178_2},
+{&thread_179_2},
+{&thread_180_2},
+{&thread_181_2},
+{&thread_182_2},
+{&thread_183_2},
+{&thread_184_2},
+{&thread_185_2},
+{&thread_186_2},
+{&thread_187_2},
+{&thread_188_2},
+{&thread_189_2},
+{&thread_190_2},
+{&thread_191_2},
+{&thread_192_2},
+{&thread_193_2},
+{&thread_194_2},
+{&thread_195_2},
+{&thread_196_2},
+{&thread_197_2},
+{&thread_198_2},
+{&thread_199_2},
+{&thread_200_2},
+{&thread_201_2},
+{&thread_202_2},
+{&thread_203_2},
+{&thread_204_2},
+{&thread_205_2},
+{&thread_206_2},
+{&thread_207_2},
+{&thread_208_2},
+{&thread_209_2},
+{&thread_210_2},
+{&thread_211_2},
+{&thread_212_2},
+{&thread_213_2},
+{&thread_214_2},
+{&thread_215_2},
+{&thread_216_2},
+{&thread_217_2},
+{&thread_218_2},
+{&thread_219_2},
+{&thread_220_2},
+{&thread_221_2},
+{&thread_222_2},
+{&thread_223_2},
+{&thread_224_2},
+{&thread_225_2},
+{&thread_226_2},
+{&thread_227_2},
+{&thread_228_2},
+{&thread_229_2},
+{&thread_230_2},
+{&thread_231_2},
+{&thread_232_2},
+{&thread_233_2},
+{&thread_234_2},
+{&thread_235_2},
+{&thread_236_2},
+{&thread_237_2},
+{&thread_238_2},
+{&thread_239_2},
+{&thread_240_2},
+{&thread_241_2},
+{&thread_242_2},
+{&thread_243_2},
+{&thread_244_2},
+{&thread_245_2},
+{&thread_246_2},
+{&thread_247_2},
+{&thread_248_2},
+{&thread_249_2},
+{&thread_250_2},
+{&thread_251_2},
+{&thread_252_2},
+{&thread_253_2},
+{&thread_254_2},
+{&thread_255_2},
+
+{&thread_0_3},
+{&thread_1_3},
+{&thread_2_3},
+{&thread_3_3},
+{&thread_4_3},
+{&thread_5_3},
+{&thread_6_3},
+{&thread_7_3},
+{&thread_8_3},
+{&thread_9_3},
+{&thread_10_3},
+{&thread_11_3},
+{&thread_12_3},
+{&thread_13_3},
+{&thread_14_3},
+{&thread_15_3},
+{&thread_16_3},
+{&thread_17_3},
+{&thread_18_3},
+{&thread_19_3},
+{&thread_20_3},
+{&thread_21_3},
+{&thread_22_3},
+{&thread_23_3},
+{&thread_24_3},
+{&thread_25_3},
+{&thread_26_3},
+{&thread_27_3},
+{&thread_28_3},
+{&thread_29_3},
+{&thread_30_3},
+{&thread_31_3},
+{&thread_32_3},
+{&thread_33_3},
+{&thread_34_3},
+{&thread_35_3},
+{&thread_36_3},
+{&thread_37_3},
+{&thread_38_3},
+{&thread_39_3},
+{&thread_40_3},
+{&thread_41_3},
+{&thread_42_3},
+{&thread_43_3},
+{&thread_44_3},
+{&thread_45_3},
+{&thread_46_3},
+{&thread_47_3},
+{&thread_48_3},
+{&thread_49_3},
+{&thread_50_3},
+{&thread_51_3},
+{&thread_52_3},
+{&thread_53_3},
+{&thread_54_3},
+{&thread_55_3},
+{&thread_56_3},
+{&thread_57_3},
+{&thread_58_3},
+{&thread_59_3},
+{&thread_60_3},
+{&thread_61_3},
+{&thread_62_3},
+{&thread_63_3},
+{&thread_64_3},
+{&thread_65_3},
+{&thread_66_3},
+{&thread_67_3},
+{&thread_68_3},
+{&thread_69_3},
+{&thread_70_3},
+{&thread_71_3},
+{&thread_72_3},
+{&thread_73_3},
+{&thread_74_3},
+{&thread_75_3},
+{&thread_76_3},
+{&thread_77_3},
+{&thread_78_3},
+{&thread_79_3},
+{&thread_80_3},
+{&thread_81_3},
+{&thread_82_3},
+{&thread_83_3},
+{&thread_84_3},
+{&thread_85_3},
+{&thread_86_3},
+{&thread_87_3},
+{&thread_88_3},
+{&thread_89_3},
+{&thread_90_3},
+{&thread_91_3},
+{&thread_92_3},
+{&thread_93_3},
+{&thread_94_3},
+{&thread_95_3},
+{&thread_96_3},
+{&thread_97_3},
+{&thread_98_3},
+{&thread_99_3},
+{&thread_100_3},
+{&thread_101_3},
+{&thread_102_3},
+{&thread_103_3},
+{&thread_104_3},
+{&thread_105_3},
+{&thread_106_3},
+{&thread_107_3},
+{&thread_108_3},
+{&thread_109_3},
+{&thread_110_3},
+{&thread_111_3},
+{&thread_112_3},
+{&thread_113_3},
+{&thread_114_3},
+{&thread_115_3},
+{&thread_116_3},
+{&thread_117_3},
+{&thread_118_3},
+{&thread_119_3},
+{&thread_120_3},
+{&thread_121_3},
+{&thread_122_3},
+{&thread_123_3},
+{&thread_124_3},
+{&thread_125_3},
+{&thread_126_3},
+{&thread_127_3},
+{&thread_128_3},
+{&thread_129_3},
+{&thread_130_3},
+{&thread_131_3},
+{&thread_132_3},
+{&thread_133_3},
+{&thread_134_3},
+{&thread_135_3},
+{&thread_136_3},
+{&thread_137_3},
+{&thread_138_3},
+{&thread_139_3},
+{&thread_140_3},
+{&thread_141_3},
+{&thread_142_3},
+{&thread_143_3},
+{&thread_144_3},
+{&thread_145_3},
+{&thread_146_3},
+{&thread_147_3},
+{&thread_148_3},
+{&thread_149_3},
+{&thread_150_3},
+{&thread_151_3},
+{&thread_152_3},
+{&thread_153_3},
+{&thread_154_3},
+{&thread_155_3},
+{&thread_156_3},
+{&thread_157_3},
+{&thread_158_3},
+{&thread_159_3},
+{&thread_160_3},
+{&thread_161_3},
+{&thread_162_3},
+{&thread_163_3},
+{&thread_164_3},
+{&thread_165_3},
+{&thread_166_3},
+{&thread_167_3},
+{&thread_168_3},
+{&thread_169_3},
+{&thread_170_3},
+{&thread_171_3},
+{&thread_172_3},
+{&thread_173_3},
+{&thread_174_3},
+{&thread_175_3},
+{&thread_176_3},
+{&thread_177_3},
+{&thread_178_3},
+{&thread_179_3},
+{&thread_180_3},
+{&thread_181_3},
+{&thread_182_3},
+{&thread_183_3},
+{&thread_184_3},
+{&thread_185_3},
+{&thread_186_3},
+{&thread_187_3},
+{&thread_188_3},
+{&thread_189_3},
+{&thread_190_3},
+{&thread_191_3},
+{&thread_192_3},
+{&thread_193_3},
+{&thread_194_3},
+{&thread_195_3},
+{&thread_196_3},
+{&thread_197_3},
+{&thread_198_3},
+{&thread_199_3},
+{&thread_200_3},
+{&thread_201_3},
+{&thread_202_3},
+{&thread_203_3},
+{&thread_204_3},
+{&thread_205_3},
+{&thread_206_3},
+{&thread_207_3},
+{&thread_208_3},
+{&thread_209_3},
+{&thread_210_3},
+{&thread_211_3},
+{&thread_212_3},
+{&thread_213_3},
+{&thread_214_3},
+{&thread_215_3},
+{&thread_216_3},
+{&thread_217_3},
+{&thread_218_3},
+{&thread_219_3},
+{&thread_220_3},
+{&thread_221_3},
+{&thread_222_3},
+{&thread_223_3},
+{&thread_224_3},
+{&thread_225_3},
+{&thread_226_3},
+{&thread_227_3},
+{&thread_228_3},
+{&thread_229_3},
+{&thread_230_3},
+{&thread_231_3},
+{&thread_232_3},
+{&thread_233_3},
+{&thread_234_3},
+{&thread_235_3},
+{&thread_236_3},
+{&thread_237_3},
+{&thread_238_3},
+{&thread_239_3},
+{&thread_240_3},
+{&thread_241_3},
+{&thread_242_3},
+{&thread_243_3},
+{&thread_244_3},
+{&thread_245_3},
+{&thread_246_3},
+{&thread_247_3},
+{&thread_248_3},
+{&thread_249_3},
+{&thread_250_3},
+{&thread_251_3},
+{&thread_252_3},
+{&thread_253_3},
+{&thread_254_3},
+{&thread_255_3}
+};
+
+/* Define the test array. This used to store the randomized test. */
+
+static TX_THREAD *_smp_randomized_test_array[TX_THREAD_SMP_MAX_CORES*2];
+
+
+/* Define thread entry prototype. Since it won't be used it can be the same. */
+
+static void control_thread_entry(ULONG thread_input);
+static void thread_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+
+static UINT pass;
+static UINT start_pass;
+static UINT end_pass;
+static UINT mapping_error;
+
+
+/* Create a test control thread. */
+
+static TX_THREAD control_thread;
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_smp_random_resume_suspend_exclusion_test(void *first_unused_memory)
+#endif
+{
+
+CHAR *pointer;
+UINT status;
+
+ /* Put first available memory address into a character pointer. */
+ pointer = (CHAR *) first_unused_memory;
+
+ /* Create a control thread to run the test. */
+ status = tx_thread_create(&control_thread, "control thread", control_thread_entry, 0,
+ pointer, 1024,
+ 0, 0, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Random Suspensions/Resumptions/Exclusions Test.......... ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+static void control_thread_entry(ULONG thread_input)
+{
+
+UINT i, j;
+UINT priority;
+UINT source_index;
+UINT successful_tests = 0;
+UINT test_errors = 0;
+TX_THREAD *thread_ptr;
+TX_THREAD *current_thread;
+UINT original_priority;
+ULONG exclusions;
+UINT status;
+
+
+ /* Clear mapping error flag. */
+ mapping_error = TX_FALSE;
+
+ /* Pickup the current thread pointer. */
+ current_thread = tx_thread_identify();
+
+ /* Loop to create all the threads. */
+ i = 0;
+ priority = 0;
+ status = TX_SUCCESS;
+ while (i < 1024)
+ {
+
+ /* Create each thread. */
+ status += tx_thread_create(_smp_randomized_source_array[i], "test thread", thread_entry, i,
+// (void *) pointer, 512,
+ malloc(1024), 1024,
+ priority, priority, TX_NO_TIME_SLICE, TX_DONT_START);
+// pointer = pointer + 512;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Random Suspensions/Resumptions/Exclusions Test.......... ERROR #2\n");
+ test_control_return(1);
+ break;
+ }
+
+ /* Move to next entry/priority. */
+ i++;
+ priority++;
+
+ /* Should priority be reset? */
+ if (priority >= TX_MAX_PRIORITIES)
+ {
+
+ /* Yes, reset the priority. */
+ priority = 0;
+ }
+ }
+
+ /* Start random test. */
+ printf("Running SMP Random Suspensions/Resumptions/Exclusions Test.......... ");
+
+ /* Clear system counters. */
+ pass = 0;
+ start_pass = 0;
+ end_pass = start_pass + MAX_PASSES;
+ do
+ {
+
+ /* Clear the randomized test array. */
+ for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++)
+ {
+ _smp_randomized_test_array[i] = TX_NULL;
+ }
+
+ /* Build the randomized test array. */
+ for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++)
+ {
+ do
+ {
+
+ source_index = (rand())%1024;
+
+ /* Determine if this index has repeated. */
+ thread_ptr = _smp_randomized_source_array[source_index];
+
+ /* Is this thread already in the test array? */
+ j = 0;
+ while (j < TX_THREAD_SMP_MAX_CORES*2)
+ {
+
+ /* Is the entry NULL? */
+ if (_smp_randomized_test_array[j] == TX_NULL)
+ {
+ j = (TX_THREAD_SMP_MAX_CORES*2);
+ }
+
+ /* Determine if we have a duplicate. */
+ if (_smp_randomized_test_array[j] == thread_ptr)
+ thread_ptr = TX_NULL;
+
+ j++;
+ }
+
+ } while (thread_ptr == TX_NULL);
+
+ /* Clear run counter. */
+ thread_ptr -> tx_thread_run_count = 0;
+
+ /* Setup the exclusion for this thread. */
+ exclusions = (ULONG) (rand()%15);
+ tx_thread_smp_core_exclude(thread_ptr, exclusions);
+
+ /* Save the thread pointer. */
+ _smp_randomized_test_array[i] = thread_ptr;
+ }
+
+ /* Now make all the random threads ready. */
+ for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++)
+ {
+ status = tx_thread_resume(_smp_randomized_test_array[i]);
+
+ /* Check for an error. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #3\n");
+ test_control_return(1);
+ break;
+ }
+ }
+
+ /* Check the status. */
+ if (status)
+ break;
+
+ /* Move to the lowest priority. */
+ status += tx_thread_priority_change(current_thread, TX_MAX_PRIORITIES-1, &original_priority);
+ tx_thread_relinquish();
+
+ /* At this point all the threads have run, or should have. */
+
+ /* Restore priority. */
+ status += tx_thread_priority_change(current_thread, original_priority, &original_priority);
+
+ /* Was there an error? */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #4\n");
+ test_control_return(1);
+ break;
+ }
+
+ /* Determine if all the threads in the the random sample ran. */
+ for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++)
+ {
+
+ /* Pickup the thread pointer. */
+ thread_ptr = _smp_randomized_test_array[i];
+
+ /* Check to see if each thread has run. */
+ if (thread_ptr -> tx_thread_run_count == 0)
+ {
+
+ /* First, try to sleep to see if this helps! */
+ tx_thread_sleep(1);
+ }
+
+ /* Has the run count incremented? */
+ if (thread_ptr -> tx_thread_run_count == 0)
+ {
+
+ /* No, this thread didn't really run! */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ break;
+ }
+
+ /* Make sure this thread suspended. */
+ while (thread_ptr -> tx_thread_state != TX_SUSPENDED)
+ {
+
+ /* Wait for the thread to complete! */
+ tx_thread_relinquish();
+ }
+
+ /* Reset the exclusion for this thread. */
+ tx_thread_smp_core_exclude(thread_ptr, 0);
+
+ /* Check for mapping error. */
+ if (mapping_error)
+ {
+
+ /* No, this thread ran on inccorect core! */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ break;
+ }
+ }
+
+ /* Increment the pass counter. */
+ pass++;
+
+ } while (pass < end_pass);
+
+ /* Test is successful! */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_entry(ULONG id)
+{
+
+UINT core;
+ULONG core_bit_map;
+TX_THREAD *thread_ptr;
+
+ /* While forever loop! */
+ while(1)
+ {
+
+ /* Get thread. */
+ thread_ptr = _smp_randomized_source_array[id];
+
+ /* Determine if this thread is running on a valid core. */
+ core = tx_thread_smp_core_get();
+
+ /* Build a bit map for this core. */
+ core_bit_map = (((ULONG) 1) << core);
+
+ /* Is this a valid core? */
+ if (core_bit_map & thread_ptr -> tx_thread_smp_cores_excluded)
+ {
+
+ /* Invalid core, set error flag. */
+ mapping_error = TX_TRUE;
+ }
+
+ /* Suspend thread! */
+ tx_thread_suspend(thread_ptr);
+ }
+}
+
diff --git a/test/smp/regression/threadx_smp_random_resume_suspend_test.c b/test/smp/regression/threadx_smp_random_resume_suspend_test.c
new file mode 100644
index 00000000..e7a6dc2c
--- /dev/null
+++ b/test/smp/regression/threadx_smp_random_resume_suspend_test.c
@@ -0,0 +1,2329 @@
+/* Define the ThreadX SMP random resume/suspend test. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//#define MAX_PASSES 50000000
+//#define MAX_PASSES 50000
+#define MAX_PASSES 500
+
+
+/* Define the ThreadX object control blocks... Must have 256 priority levels... and assumes 4 cores. */
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD thread_4;
+static TX_THREAD thread_5;
+static TX_THREAD thread_6;
+static TX_THREAD thread_7;
+static TX_THREAD thread_8;
+static TX_THREAD thread_9;
+static TX_THREAD thread_10;
+static TX_THREAD thread_11;
+static TX_THREAD thread_12;
+static TX_THREAD thread_13;
+static TX_THREAD thread_14;
+static TX_THREAD thread_15;
+static TX_THREAD thread_16;
+static TX_THREAD thread_17;
+static TX_THREAD thread_18;
+static TX_THREAD thread_19;
+static TX_THREAD thread_20;
+static TX_THREAD thread_21;
+static TX_THREAD thread_22;
+static TX_THREAD thread_23;
+static TX_THREAD thread_24;
+static TX_THREAD thread_25;
+static TX_THREAD thread_26;
+static TX_THREAD thread_27;
+static TX_THREAD thread_28;
+static TX_THREAD thread_29;
+static TX_THREAD thread_30;
+static TX_THREAD thread_31;
+static TX_THREAD thread_32;
+static TX_THREAD thread_33;
+static TX_THREAD thread_34;
+static TX_THREAD thread_35;
+static TX_THREAD thread_36;
+static TX_THREAD thread_37;
+static TX_THREAD thread_38;
+static TX_THREAD thread_39;
+static TX_THREAD thread_40;
+static TX_THREAD thread_41;
+static TX_THREAD thread_42;
+static TX_THREAD thread_43;
+static TX_THREAD thread_44;
+static TX_THREAD thread_45;
+static TX_THREAD thread_46;
+static TX_THREAD thread_47;
+static TX_THREAD thread_48;
+static TX_THREAD thread_49;
+static TX_THREAD thread_50;
+static TX_THREAD thread_51;
+static TX_THREAD thread_52;
+static TX_THREAD thread_53;
+static TX_THREAD thread_54;
+static TX_THREAD thread_55;
+static TX_THREAD thread_56;
+static TX_THREAD thread_57;
+static TX_THREAD thread_58;
+static TX_THREAD thread_59;
+static TX_THREAD thread_60;
+static TX_THREAD thread_61;
+static TX_THREAD thread_62;
+static TX_THREAD thread_63;
+static TX_THREAD thread_64;
+static TX_THREAD thread_65;
+static TX_THREAD thread_66;
+static TX_THREAD thread_67;
+static TX_THREAD thread_68;
+static TX_THREAD thread_69;
+static TX_THREAD thread_70;
+static TX_THREAD thread_71;
+static TX_THREAD thread_72;
+static TX_THREAD thread_73;
+static TX_THREAD thread_74;
+static TX_THREAD thread_75;
+static TX_THREAD thread_76;
+static TX_THREAD thread_77;
+static TX_THREAD thread_78;
+static TX_THREAD thread_79;
+static TX_THREAD thread_80;
+static TX_THREAD thread_81;
+static TX_THREAD thread_82;
+static TX_THREAD thread_83;
+static TX_THREAD thread_84;
+static TX_THREAD thread_85;
+static TX_THREAD thread_86;
+static TX_THREAD thread_87;
+static TX_THREAD thread_88;
+static TX_THREAD thread_89;
+static TX_THREAD thread_90;
+static TX_THREAD thread_91;
+static TX_THREAD thread_92;
+static TX_THREAD thread_93;
+static TX_THREAD thread_94;
+static TX_THREAD thread_95;
+static TX_THREAD thread_96;
+static TX_THREAD thread_97;
+static TX_THREAD thread_98;
+static TX_THREAD thread_99;
+static TX_THREAD thread_100;
+static TX_THREAD thread_101;
+static TX_THREAD thread_102;
+static TX_THREAD thread_103;
+static TX_THREAD thread_104;
+static TX_THREAD thread_105;
+static TX_THREAD thread_106;
+static TX_THREAD thread_107;
+static TX_THREAD thread_108;
+static TX_THREAD thread_109;
+static TX_THREAD thread_110;
+static TX_THREAD thread_111;
+static TX_THREAD thread_112;
+static TX_THREAD thread_113;
+static TX_THREAD thread_114;
+static TX_THREAD thread_115;
+static TX_THREAD thread_116;
+static TX_THREAD thread_117;
+static TX_THREAD thread_118;
+static TX_THREAD thread_119;
+static TX_THREAD thread_120;
+static TX_THREAD thread_121;
+static TX_THREAD thread_122;
+static TX_THREAD thread_123;
+static TX_THREAD thread_124;
+static TX_THREAD thread_125;
+static TX_THREAD thread_126;
+static TX_THREAD thread_127;
+static TX_THREAD thread_128;
+static TX_THREAD thread_129;
+static TX_THREAD thread_130;
+static TX_THREAD thread_131;
+static TX_THREAD thread_132;
+static TX_THREAD thread_133;
+static TX_THREAD thread_134;
+static TX_THREAD thread_135;
+static TX_THREAD thread_136;
+static TX_THREAD thread_137;
+static TX_THREAD thread_138;
+static TX_THREAD thread_139;
+static TX_THREAD thread_140;
+static TX_THREAD thread_141;
+static TX_THREAD thread_142;
+static TX_THREAD thread_143;
+static TX_THREAD thread_144;
+static TX_THREAD thread_145;
+static TX_THREAD thread_146;
+static TX_THREAD thread_147;
+static TX_THREAD thread_148;
+static TX_THREAD thread_149;
+static TX_THREAD thread_150;
+static TX_THREAD thread_151;
+static TX_THREAD thread_152;
+static TX_THREAD thread_153;
+static TX_THREAD thread_154;
+static TX_THREAD thread_155;
+static TX_THREAD thread_156;
+static TX_THREAD thread_157;
+static TX_THREAD thread_158;
+static TX_THREAD thread_159;
+static TX_THREAD thread_160;
+static TX_THREAD thread_161;
+static TX_THREAD thread_162;
+static TX_THREAD thread_163;
+static TX_THREAD thread_164;
+static TX_THREAD thread_165;
+static TX_THREAD thread_166;
+static TX_THREAD thread_167;
+static TX_THREAD thread_168;
+static TX_THREAD thread_169;
+static TX_THREAD thread_170;
+static TX_THREAD thread_171;
+static TX_THREAD thread_172;
+static TX_THREAD thread_173;
+static TX_THREAD thread_174;
+static TX_THREAD thread_175;
+static TX_THREAD thread_176;
+static TX_THREAD thread_177;
+static TX_THREAD thread_178;
+static TX_THREAD thread_179;
+static TX_THREAD thread_180;
+static TX_THREAD thread_181;
+static TX_THREAD thread_182;
+static TX_THREAD thread_183;
+static TX_THREAD thread_184;
+static TX_THREAD thread_185;
+static TX_THREAD thread_186;
+static TX_THREAD thread_187;
+static TX_THREAD thread_188;
+static TX_THREAD thread_189;
+static TX_THREAD thread_190;
+static TX_THREAD thread_191;
+static TX_THREAD thread_192;
+static TX_THREAD thread_193;
+static TX_THREAD thread_194;
+static TX_THREAD thread_195;
+static TX_THREAD thread_196;
+static TX_THREAD thread_197;
+static TX_THREAD thread_198;
+static TX_THREAD thread_199;
+static TX_THREAD thread_200;
+static TX_THREAD thread_201;
+static TX_THREAD thread_202;
+static TX_THREAD thread_203;
+static TX_THREAD thread_204;
+static TX_THREAD thread_205;
+static TX_THREAD thread_206;
+static TX_THREAD thread_207;
+static TX_THREAD thread_208;
+static TX_THREAD thread_209;
+static TX_THREAD thread_210;
+static TX_THREAD thread_211;
+static TX_THREAD thread_212;
+static TX_THREAD thread_213;
+static TX_THREAD thread_214;
+static TX_THREAD thread_215;
+static TX_THREAD thread_216;
+static TX_THREAD thread_217;
+static TX_THREAD thread_218;
+static TX_THREAD thread_219;
+static TX_THREAD thread_220;
+static TX_THREAD thread_221;
+static TX_THREAD thread_222;
+static TX_THREAD thread_223;
+static TX_THREAD thread_224;
+static TX_THREAD thread_225;
+static TX_THREAD thread_226;
+static TX_THREAD thread_227;
+static TX_THREAD thread_228;
+static TX_THREAD thread_229;
+static TX_THREAD thread_230;
+static TX_THREAD thread_231;
+static TX_THREAD thread_232;
+static TX_THREAD thread_233;
+static TX_THREAD thread_234;
+static TX_THREAD thread_235;
+static TX_THREAD thread_236;
+static TX_THREAD thread_237;
+static TX_THREAD thread_238;
+static TX_THREAD thread_239;
+static TX_THREAD thread_240;
+static TX_THREAD thread_241;
+static TX_THREAD thread_242;
+static TX_THREAD thread_243;
+static TX_THREAD thread_244;
+static TX_THREAD thread_245;
+static TX_THREAD thread_246;
+static TX_THREAD thread_247;
+static TX_THREAD thread_248;
+static TX_THREAD thread_249;
+static TX_THREAD thread_250;
+static TX_THREAD thread_251;
+static TX_THREAD thread_252;
+static TX_THREAD thread_253;
+static TX_THREAD thread_254;
+static TX_THREAD thread_255;
+
+static TX_THREAD thread_0_1;
+static TX_THREAD thread_1_1;
+static TX_THREAD thread_2_1;
+static TX_THREAD thread_3_1;
+static TX_THREAD thread_4_1;
+static TX_THREAD thread_5_1;
+static TX_THREAD thread_6_1;
+static TX_THREAD thread_7_1;
+static TX_THREAD thread_8_1;
+static TX_THREAD thread_9_1;
+static TX_THREAD thread_10_1;
+static TX_THREAD thread_11_1;
+static TX_THREAD thread_12_1;
+static TX_THREAD thread_13_1;
+static TX_THREAD thread_14_1;
+static TX_THREAD thread_15_1;
+static TX_THREAD thread_16_1;
+static TX_THREAD thread_17_1;
+static TX_THREAD thread_18_1;
+static TX_THREAD thread_19_1;
+static TX_THREAD thread_20_1;
+static TX_THREAD thread_21_1;
+static TX_THREAD thread_22_1;
+static TX_THREAD thread_23_1;
+static TX_THREAD thread_24_1;
+static TX_THREAD thread_25_1;
+static TX_THREAD thread_26_1;
+static TX_THREAD thread_27_1;
+static TX_THREAD thread_28_1;
+static TX_THREAD thread_29_1;
+static TX_THREAD thread_30_1;
+static TX_THREAD thread_31_1;
+static TX_THREAD thread_32_1;
+static TX_THREAD thread_33_1;
+static TX_THREAD thread_34_1;
+static TX_THREAD thread_35_1;
+static TX_THREAD thread_36_1;
+static TX_THREAD thread_37_1;
+static TX_THREAD thread_38_1;
+static TX_THREAD thread_39_1;
+static TX_THREAD thread_40_1;
+static TX_THREAD thread_41_1;
+static TX_THREAD thread_42_1;
+static TX_THREAD thread_43_1;
+static TX_THREAD thread_44_1;
+static TX_THREAD thread_45_1;
+static TX_THREAD thread_46_1;
+static TX_THREAD thread_47_1;
+static TX_THREAD thread_48_1;
+static TX_THREAD thread_49_1;
+static TX_THREAD thread_50_1;
+static TX_THREAD thread_51_1;
+static TX_THREAD thread_52_1;
+static TX_THREAD thread_53_1;
+static TX_THREAD thread_54_1;
+static TX_THREAD thread_55_1;
+static TX_THREAD thread_56_1;
+static TX_THREAD thread_57_1;
+static TX_THREAD thread_58_1;
+static TX_THREAD thread_59_1;
+static TX_THREAD thread_60_1;
+static TX_THREAD thread_61_1;
+static TX_THREAD thread_62_1;
+static TX_THREAD thread_63_1;
+static TX_THREAD thread_64_1;
+static TX_THREAD thread_65_1;
+static TX_THREAD thread_66_1;
+static TX_THREAD thread_67_1;
+static TX_THREAD thread_68_1;
+static TX_THREAD thread_69_1;
+static TX_THREAD thread_70_1;
+static TX_THREAD thread_71_1;
+static TX_THREAD thread_72_1;
+static TX_THREAD thread_73_1;
+static TX_THREAD thread_74_1;
+static TX_THREAD thread_75_1;
+static TX_THREAD thread_76_1;
+static TX_THREAD thread_77_1;
+static TX_THREAD thread_78_1;
+static TX_THREAD thread_79_1;
+static TX_THREAD thread_80_1;
+static TX_THREAD thread_81_1;
+static TX_THREAD thread_82_1;
+static TX_THREAD thread_83_1;
+static TX_THREAD thread_84_1;
+static TX_THREAD thread_85_1;
+static TX_THREAD thread_86_1;
+static TX_THREAD thread_87_1;
+static TX_THREAD thread_88_1;
+static TX_THREAD thread_89_1;
+static TX_THREAD thread_90_1;
+static TX_THREAD thread_91_1;
+static TX_THREAD thread_92_1;
+static TX_THREAD thread_93_1;
+static TX_THREAD thread_94_1;
+static TX_THREAD thread_95_1;
+static TX_THREAD thread_96_1;
+static TX_THREAD thread_97_1;
+static TX_THREAD thread_98_1;
+static TX_THREAD thread_99_1;
+static TX_THREAD thread_100_1;
+static TX_THREAD thread_101_1;
+static TX_THREAD thread_102_1;
+static TX_THREAD thread_103_1;
+static TX_THREAD thread_104_1;
+static TX_THREAD thread_105_1;
+static TX_THREAD thread_106_1;
+static TX_THREAD thread_107_1;
+static TX_THREAD thread_108_1;
+static TX_THREAD thread_109_1;
+static TX_THREAD thread_110_1;
+static TX_THREAD thread_111_1;
+static TX_THREAD thread_112_1;
+static TX_THREAD thread_113_1;
+static TX_THREAD thread_114_1;
+static TX_THREAD thread_115_1;
+static TX_THREAD thread_116_1;
+static TX_THREAD thread_117_1;
+static TX_THREAD thread_118_1;
+static TX_THREAD thread_119_1;
+static TX_THREAD thread_120_1;
+static TX_THREAD thread_121_1;
+static TX_THREAD thread_122_1;
+static TX_THREAD thread_123_1;
+static TX_THREAD thread_124_1;
+static TX_THREAD thread_125_1;
+static TX_THREAD thread_126_1;
+static TX_THREAD thread_127_1;
+static TX_THREAD thread_128_1;
+static TX_THREAD thread_129_1;
+static TX_THREAD thread_130_1;
+static TX_THREAD thread_131_1;
+static TX_THREAD thread_132_1;
+static TX_THREAD thread_133_1;
+static TX_THREAD thread_134_1;
+static TX_THREAD thread_135_1;
+static TX_THREAD thread_136_1;
+static TX_THREAD thread_137_1;
+static TX_THREAD thread_138_1;
+static TX_THREAD thread_139_1;
+static TX_THREAD thread_140_1;
+static TX_THREAD thread_141_1;
+static TX_THREAD thread_142_1;
+static TX_THREAD thread_143_1;
+static TX_THREAD thread_144_1;
+static TX_THREAD thread_145_1;
+static TX_THREAD thread_146_1;
+static TX_THREAD thread_147_1;
+static TX_THREAD thread_148_1;
+static TX_THREAD thread_149_1;
+static TX_THREAD thread_150_1;
+static TX_THREAD thread_151_1;
+static TX_THREAD thread_152_1;
+static TX_THREAD thread_153_1;
+static TX_THREAD thread_154_1;
+static TX_THREAD thread_155_1;
+static TX_THREAD thread_156_1;
+static TX_THREAD thread_157_1;
+static TX_THREAD thread_158_1;
+static TX_THREAD thread_159_1;
+static TX_THREAD thread_160_1;
+static TX_THREAD thread_161_1;
+static TX_THREAD thread_162_1;
+static TX_THREAD thread_163_1;
+static TX_THREAD thread_164_1;
+static TX_THREAD thread_165_1;
+static TX_THREAD thread_166_1;
+static TX_THREAD thread_167_1;
+static TX_THREAD thread_168_1;
+static TX_THREAD thread_169_1;
+static TX_THREAD thread_170_1;
+static TX_THREAD thread_171_1;
+static TX_THREAD thread_172_1;
+static TX_THREAD thread_173_1;
+static TX_THREAD thread_174_1;
+static TX_THREAD thread_175_1;
+static TX_THREAD thread_176_1;
+static TX_THREAD thread_177_1;
+static TX_THREAD thread_178_1;
+static TX_THREAD thread_179_1;
+static TX_THREAD thread_180_1;
+static TX_THREAD thread_181_1;
+static TX_THREAD thread_182_1;
+static TX_THREAD thread_183_1;
+static TX_THREAD thread_184_1;
+static TX_THREAD thread_185_1;
+static TX_THREAD thread_186_1;
+static TX_THREAD thread_187_1;
+static TX_THREAD thread_188_1;
+static TX_THREAD thread_189_1;
+static TX_THREAD thread_190_1;
+static TX_THREAD thread_191_1;
+static TX_THREAD thread_192_1;
+static TX_THREAD thread_193_1;
+static TX_THREAD thread_194_1;
+static TX_THREAD thread_195_1;
+static TX_THREAD thread_196_1;
+static TX_THREAD thread_197_1;
+static TX_THREAD thread_198_1;
+static TX_THREAD thread_199_1;
+static TX_THREAD thread_200_1;
+static TX_THREAD thread_201_1;
+static TX_THREAD thread_202_1;
+static TX_THREAD thread_203_1;
+static TX_THREAD thread_204_1;
+static TX_THREAD thread_205_1;
+static TX_THREAD thread_206_1;
+static TX_THREAD thread_207_1;
+static TX_THREAD thread_208_1;
+static TX_THREAD thread_209_1;
+static TX_THREAD thread_210_1;
+static TX_THREAD thread_211_1;
+static TX_THREAD thread_212_1;
+static TX_THREAD thread_213_1;
+static TX_THREAD thread_214_1;
+static TX_THREAD thread_215_1;
+static TX_THREAD thread_216_1;
+static TX_THREAD thread_217_1;
+static TX_THREAD thread_218_1;
+static TX_THREAD thread_219_1;
+static TX_THREAD thread_220_1;
+static TX_THREAD thread_221_1;
+static TX_THREAD thread_222_1;
+static TX_THREAD thread_223_1;
+static TX_THREAD thread_224_1;
+static TX_THREAD thread_225_1;
+static TX_THREAD thread_226_1;
+static TX_THREAD thread_227_1;
+static TX_THREAD thread_228_1;
+static TX_THREAD thread_229_1;
+static TX_THREAD thread_230_1;
+static TX_THREAD thread_231_1;
+static TX_THREAD thread_232_1;
+static TX_THREAD thread_233_1;
+static TX_THREAD thread_234_1;
+static TX_THREAD thread_235_1;
+static TX_THREAD thread_236_1;
+static TX_THREAD thread_237_1;
+static TX_THREAD thread_238_1;
+static TX_THREAD thread_239_1;
+static TX_THREAD thread_240_1;
+static TX_THREAD thread_241_1;
+static TX_THREAD thread_242_1;
+static TX_THREAD thread_243_1;
+static TX_THREAD thread_244_1;
+static TX_THREAD thread_245_1;
+static TX_THREAD thread_246_1;
+static TX_THREAD thread_247_1;
+static TX_THREAD thread_248_1;
+static TX_THREAD thread_249_1;
+static TX_THREAD thread_250_1;
+static TX_THREAD thread_251_1;
+static TX_THREAD thread_252_1;
+static TX_THREAD thread_253_1;
+static TX_THREAD thread_254_1;
+static TX_THREAD thread_255_1;
+
+static TX_THREAD thread_0_2;
+static TX_THREAD thread_1_2;
+static TX_THREAD thread_2_2;
+static TX_THREAD thread_3_2;
+static TX_THREAD thread_4_2;
+static TX_THREAD thread_5_2;
+static TX_THREAD thread_6_2;
+static TX_THREAD thread_7_2;
+static TX_THREAD thread_8_2;
+static TX_THREAD thread_9_2;
+static TX_THREAD thread_10_2;
+static TX_THREAD thread_11_2;
+static TX_THREAD thread_12_2;
+static TX_THREAD thread_13_2;
+static TX_THREAD thread_14_2;
+static TX_THREAD thread_15_2;
+static TX_THREAD thread_16_2;
+static TX_THREAD thread_17_2;
+static TX_THREAD thread_18_2;
+static TX_THREAD thread_19_2;
+static TX_THREAD thread_20_2;
+static TX_THREAD thread_21_2;
+static TX_THREAD thread_22_2;
+static TX_THREAD thread_23_2;
+static TX_THREAD thread_24_2;
+static TX_THREAD thread_25_2;
+static TX_THREAD thread_26_2;
+static TX_THREAD thread_27_2;
+static TX_THREAD thread_28_2;
+static TX_THREAD thread_29_2;
+static TX_THREAD thread_30_2;
+static TX_THREAD thread_31_2;
+static TX_THREAD thread_32_2;
+static TX_THREAD thread_33_2;
+static TX_THREAD thread_34_2;
+static TX_THREAD thread_35_2;
+static TX_THREAD thread_36_2;
+static TX_THREAD thread_37_2;
+static TX_THREAD thread_38_2;
+static TX_THREAD thread_39_2;
+static TX_THREAD thread_40_2;
+static TX_THREAD thread_41_2;
+static TX_THREAD thread_42_2;
+static TX_THREAD thread_43_2;
+static TX_THREAD thread_44_2;
+static TX_THREAD thread_45_2;
+static TX_THREAD thread_46_2;
+static TX_THREAD thread_47_2;
+static TX_THREAD thread_48_2;
+static TX_THREAD thread_49_2;
+static TX_THREAD thread_50_2;
+static TX_THREAD thread_51_2;
+static TX_THREAD thread_52_2;
+static TX_THREAD thread_53_2;
+static TX_THREAD thread_54_2;
+static TX_THREAD thread_55_2;
+static TX_THREAD thread_56_2;
+static TX_THREAD thread_57_2;
+static TX_THREAD thread_58_2;
+static TX_THREAD thread_59_2;
+static TX_THREAD thread_60_2;
+static TX_THREAD thread_61_2;
+static TX_THREAD thread_62_2;
+static TX_THREAD thread_63_2;
+static TX_THREAD thread_64_2;
+static TX_THREAD thread_65_2;
+static TX_THREAD thread_66_2;
+static TX_THREAD thread_67_2;
+static TX_THREAD thread_68_2;
+static TX_THREAD thread_69_2;
+static TX_THREAD thread_70_2;
+static TX_THREAD thread_71_2;
+static TX_THREAD thread_72_2;
+static TX_THREAD thread_73_2;
+static TX_THREAD thread_74_2;
+static TX_THREAD thread_75_2;
+static TX_THREAD thread_76_2;
+static TX_THREAD thread_77_2;
+static TX_THREAD thread_78_2;
+static TX_THREAD thread_79_2;
+static TX_THREAD thread_80_2;
+static TX_THREAD thread_81_2;
+static TX_THREAD thread_82_2;
+static TX_THREAD thread_83_2;
+static TX_THREAD thread_84_2;
+static TX_THREAD thread_85_2;
+static TX_THREAD thread_86_2;
+static TX_THREAD thread_87_2;
+static TX_THREAD thread_88_2;
+static TX_THREAD thread_89_2;
+static TX_THREAD thread_90_2;
+static TX_THREAD thread_91_2;
+static TX_THREAD thread_92_2;
+static TX_THREAD thread_93_2;
+static TX_THREAD thread_94_2;
+static TX_THREAD thread_95_2;
+static TX_THREAD thread_96_2;
+static TX_THREAD thread_97_2;
+static TX_THREAD thread_98_2;
+static TX_THREAD thread_99_2;
+static TX_THREAD thread_100_2;
+static TX_THREAD thread_101_2;
+static TX_THREAD thread_102_2;
+static TX_THREAD thread_103_2;
+static TX_THREAD thread_104_2;
+static TX_THREAD thread_105_2;
+static TX_THREAD thread_106_2;
+static TX_THREAD thread_107_2;
+static TX_THREAD thread_108_2;
+static TX_THREAD thread_109_2;
+static TX_THREAD thread_110_2;
+static TX_THREAD thread_111_2;
+static TX_THREAD thread_112_2;
+static TX_THREAD thread_113_2;
+static TX_THREAD thread_114_2;
+static TX_THREAD thread_115_2;
+static TX_THREAD thread_116_2;
+static TX_THREAD thread_117_2;
+static TX_THREAD thread_118_2;
+static TX_THREAD thread_119_2;
+static TX_THREAD thread_120_2;
+static TX_THREAD thread_121_2;
+static TX_THREAD thread_122_2;
+static TX_THREAD thread_123_2;
+static TX_THREAD thread_124_2;
+static TX_THREAD thread_125_2;
+static TX_THREAD thread_126_2;
+static TX_THREAD thread_127_2;
+static TX_THREAD thread_128_2;
+static TX_THREAD thread_129_2;
+static TX_THREAD thread_130_2;
+static TX_THREAD thread_131_2;
+static TX_THREAD thread_132_2;
+static TX_THREAD thread_133_2;
+static TX_THREAD thread_134_2;
+static TX_THREAD thread_135_2;
+static TX_THREAD thread_136_2;
+static TX_THREAD thread_137_2;
+static TX_THREAD thread_138_2;
+static TX_THREAD thread_139_2;
+static TX_THREAD thread_140_2;
+static TX_THREAD thread_141_2;
+static TX_THREAD thread_142_2;
+static TX_THREAD thread_143_2;
+static TX_THREAD thread_144_2;
+static TX_THREAD thread_145_2;
+static TX_THREAD thread_146_2;
+static TX_THREAD thread_147_2;
+static TX_THREAD thread_148_2;
+static TX_THREAD thread_149_2;
+static TX_THREAD thread_150_2;
+static TX_THREAD thread_151_2;
+static TX_THREAD thread_152_2;
+static TX_THREAD thread_153_2;
+static TX_THREAD thread_154_2;
+static TX_THREAD thread_155_2;
+static TX_THREAD thread_156_2;
+static TX_THREAD thread_157_2;
+static TX_THREAD thread_158_2;
+static TX_THREAD thread_159_2;
+static TX_THREAD thread_160_2;
+static TX_THREAD thread_161_2;
+static TX_THREAD thread_162_2;
+static TX_THREAD thread_163_2;
+static TX_THREAD thread_164_2;
+static TX_THREAD thread_165_2;
+static TX_THREAD thread_166_2;
+static TX_THREAD thread_167_2;
+static TX_THREAD thread_168_2;
+static TX_THREAD thread_169_2;
+static TX_THREAD thread_170_2;
+static TX_THREAD thread_171_2;
+static TX_THREAD thread_172_2;
+static TX_THREAD thread_173_2;
+static TX_THREAD thread_174_2;
+static TX_THREAD thread_175_2;
+static TX_THREAD thread_176_2;
+static TX_THREAD thread_177_2;
+static TX_THREAD thread_178_2;
+static TX_THREAD thread_179_2;
+static TX_THREAD thread_180_2;
+static TX_THREAD thread_181_2;
+static TX_THREAD thread_182_2;
+static TX_THREAD thread_183_2;
+static TX_THREAD thread_184_2;
+static TX_THREAD thread_185_2;
+static TX_THREAD thread_186_2;
+static TX_THREAD thread_187_2;
+static TX_THREAD thread_188_2;
+static TX_THREAD thread_189_2;
+static TX_THREAD thread_190_2;
+static TX_THREAD thread_191_2;
+static TX_THREAD thread_192_2;
+static TX_THREAD thread_193_2;
+static TX_THREAD thread_194_2;
+static TX_THREAD thread_195_2;
+static TX_THREAD thread_196_2;
+static TX_THREAD thread_197_2;
+static TX_THREAD thread_198_2;
+static TX_THREAD thread_199_2;
+static TX_THREAD thread_200_2;
+static TX_THREAD thread_201_2;
+static TX_THREAD thread_202_2;
+static TX_THREAD thread_203_2;
+static TX_THREAD thread_204_2;
+static TX_THREAD thread_205_2;
+static TX_THREAD thread_206_2;
+static TX_THREAD thread_207_2;
+static TX_THREAD thread_208_2;
+static TX_THREAD thread_209_2;
+static TX_THREAD thread_210_2;
+static TX_THREAD thread_211_2;
+static TX_THREAD thread_212_2;
+static TX_THREAD thread_213_2;
+static TX_THREAD thread_214_2;
+static TX_THREAD thread_215_2;
+static TX_THREAD thread_216_2;
+static TX_THREAD thread_217_2;
+static TX_THREAD thread_218_2;
+static TX_THREAD thread_219_2;
+static TX_THREAD thread_220_2;
+static TX_THREAD thread_221_2;
+static TX_THREAD thread_222_2;
+static TX_THREAD thread_223_2;
+static TX_THREAD thread_224_2;
+static TX_THREAD thread_225_2;
+static TX_THREAD thread_226_2;
+static TX_THREAD thread_227_2;
+static TX_THREAD thread_228_2;
+static TX_THREAD thread_229_2;
+static TX_THREAD thread_230_2;
+static TX_THREAD thread_231_2;
+static TX_THREAD thread_232_2;
+static TX_THREAD thread_233_2;
+static TX_THREAD thread_234_2;
+static TX_THREAD thread_235_2;
+static TX_THREAD thread_236_2;
+static TX_THREAD thread_237_2;
+static TX_THREAD thread_238_2;
+static TX_THREAD thread_239_2;
+static TX_THREAD thread_240_2;
+static TX_THREAD thread_241_2;
+static TX_THREAD thread_242_2;
+static TX_THREAD thread_243_2;
+static TX_THREAD thread_244_2;
+static TX_THREAD thread_245_2;
+static TX_THREAD thread_246_2;
+static TX_THREAD thread_247_2;
+static TX_THREAD thread_248_2;
+static TX_THREAD thread_249_2;
+static TX_THREAD thread_250_2;
+static TX_THREAD thread_251_2;
+static TX_THREAD thread_252_2;
+static TX_THREAD thread_253_2;
+static TX_THREAD thread_254_2;
+static TX_THREAD thread_255_2;
+
+static TX_THREAD thread_0_3;
+static TX_THREAD thread_1_3;
+static TX_THREAD thread_2_3;
+static TX_THREAD thread_3_3;
+static TX_THREAD thread_4_3;
+static TX_THREAD thread_5_3;
+static TX_THREAD thread_6_3;
+static TX_THREAD thread_7_3;
+static TX_THREAD thread_8_3;
+static TX_THREAD thread_9_3;
+static TX_THREAD thread_10_3;
+static TX_THREAD thread_11_3;
+static TX_THREAD thread_12_3;
+static TX_THREAD thread_13_3;
+static TX_THREAD thread_14_3;
+static TX_THREAD thread_15_3;
+static TX_THREAD thread_16_3;
+static TX_THREAD thread_17_3;
+static TX_THREAD thread_18_3;
+static TX_THREAD thread_19_3;
+static TX_THREAD thread_20_3;
+static TX_THREAD thread_21_3;
+static TX_THREAD thread_22_3;
+static TX_THREAD thread_23_3;
+static TX_THREAD thread_24_3;
+static TX_THREAD thread_25_3;
+static TX_THREAD thread_26_3;
+static TX_THREAD thread_27_3;
+static TX_THREAD thread_28_3;
+static TX_THREAD thread_29_3;
+static TX_THREAD thread_30_3;
+static TX_THREAD thread_31_3;
+static TX_THREAD thread_32_3;
+static TX_THREAD thread_33_3;
+static TX_THREAD thread_34_3;
+static TX_THREAD thread_35_3;
+static TX_THREAD thread_36_3;
+static TX_THREAD thread_37_3;
+static TX_THREAD thread_38_3;
+static TX_THREAD thread_39_3;
+static TX_THREAD thread_40_3;
+static TX_THREAD thread_41_3;
+static TX_THREAD thread_42_3;
+static TX_THREAD thread_43_3;
+static TX_THREAD thread_44_3;
+static TX_THREAD thread_45_3;
+static TX_THREAD thread_46_3;
+static TX_THREAD thread_47_3;
+static TX_THREAD thread_48_3;
+static TX_THREAD thread_49_3;
+static TX_THREAD thread_50_3;
+static TX_THREAD thread_51_3;
+static TX_THREAD thread_52_3;
+static TX_THREAD thread_53_3;
+static TX_THREAD thread_54_3;
+static TX_THREAD thread_55_3;
+static TX_THREAD thread_56_3;
+static TX_THREAD thread_57_3;
+static TX_THREAD thread_58_3;
+static TX_THREAD thread_59_3;
+static TX_THREAD thread_60_3;
+static TX_THREAD thread_61_3;
+static TX_THREAD thread_62_3;
+static TX_THREAD thread_63_3;
+static TX_THREAD thread_64_3;
+static TX_THREAD thread_65_3;
+static TX_THREAD thread_66_3;
+static TX_THREAD thread_67_3;
+static TX_THREAD thread_68_3;
+static TX_THREAD thread_69_3;
+static TX_THREAD thread_70_3;
+static TX_THREAD thread_71_3;
+static TX_THREAD thread_72_3;
+static TX_THREAD thread_73_3;
+static TX_THREAD thread_74_3;
+static TX_THREAD thread_75_3;
+static TX_THREAD thread_76_3;
+static TX_THREAD thread_77_3;
+static TX_THREAD thread_78_3;
+static TX_THREAD thread_79_3;
+static TX_THREAD thread_80_3;
+static TX_THREAD thread_81_3;
+static TX_THREAD thread_82_3;
+static TX_THREAD thread_83_3;
+static TX_THREAD thread_84_3;
+static TX_THREAD thread_85_3;
+static TX_THREAD thread_86_3;
+static TX_THREAD thread_87_3;
+static TX_THREAD thread_88_3;
+static TX_THREAD thread_89_3;
+static TX_THREAD thread_90_3;
+static TX_THREAD thread_91_3;
+static TX_THREAD thread_92_3;
+static TX_THREAD thread_93_3;
+static TX_THREAD thread_94_3;
+static TX_THREAD thread_95_3;
+static TX_THREAD thread_96_3;
+static TX_THREAD thread_97_3;
+static TX_THREAD thread_98_3;
+static TX_THREAD thread_99_3;
+static TX_THREAD thread_100_3;
+static TX_THREAD thread_101_3;
+static TX_THREAD thread_102_3;
+static TX_THREAD thread_103_3;
+static TX_THREAD thread_104_3;
+static TX_THREAD thread_105_3;
+static TX_THREAD thread_106_3;
+static TX_THREAD thread_107_3;
+static TX_THREAD thread_108_3;
+static TX_THREAD thread_109_3;
+static TX_THREAD thread_110_3;
+static TX_THREAD thread_111_3;
+static TX_THREAD thread_112_3;
+static TX_THREAD thread_113_3;
+static TX_THREAD thread_114_3;
+static TX_THREAD thread_115_3;
+static TX_THREAD thread_116_3;
+static TX_THREAD thread_117_3;
+static TX_THREAD thread_118_3;
+static TX_THREAD thread_119_3;
+static TX_THREAD thread_120_3;
+static TX_THREAD thread_121_3;
+static TX_THREAD thread_122_3;
+static TX_THREAD thread_123_3;
+static TX_THREAD thread_124_3;
+static TX_THREAD thread_125_3;
+static TX_THREAD thread_126_3;
+static TX_THREAD thread_127_3;
+static TX_THREAD thread_128_3;
+static TX_THREAD thread_129_3;
+static TX_THREAD thread_130_3;
+static TX_THREAD thread_131_3;
+static TX_THREAD thread_132_3;
+static TX_THREAD thread_133_3;
+static TX_THREAD thread_134_3;
+static TX_THREAD thread_135_3;
+static TX_THREAD thread_136_3;
+static TX_THREAD thread_137_3;
+static TX_THREAD thread_138_3;
+static TX_THREAD thread_139_3;
+static TX_THREAD thread_140_3;
+static TX_THREAD thread_141_3;
+static TX_THREAD thread_142_3;
+static TX_THREAD thread_143_3;
+static TX_THREAD thread_144_3;
+static TX_THREAD thread_145_3;
+static TX_THREAD thread_146_3;
+static TX_THREAD thread_147_3;
+static TX_THREAD thread_148_3;
+static TX_THREAD thread_149_3;
+static TX_THREAD thread_150_3;
+static TX_THREAD thread_151_3;
+static TX_THREAD thread_152_3;
+static TX_THREAD thread_153_3;
+static TX_THREAD thread_154_3;
+static TX_THREAD thread_155_3;
+static TX_THREAD thread_156_3;
+static TX_THREAD thread_157_3;
+static TX_THREAD thread_158_3;
+static TX_THREAD thread_159_3;
+static TX_THREAD thread_160_3;
+static TX_THREAD thread_161_3;
+static TX_THREAD thread_162_3;
+static TX_THREAD thread_163_3;
+static TX_THREAD thread_164_3;
+static TX_THREAD thread_165_3;
+static TX_THREAD thread_166_3;
+static TX_THREAD thread_167_3;
+static TX_THREAD thread_168_3;
+static TX_THREAD thread_169_3;
+static TX_THREAD thread_170_3;
+static TX_THREAD thread_171_3;
+static TX_THREAD thread_172_3;
+static TX_THREAD thread_173_3;
+static TX_THREAD thread_174_3;
+static TX_THREAD thread_175_3;
+static TX_THREAD thread_176_3;
+static TX_THREAD thread_177_3;
+static TX_THREAD thread_178_3;
+static TX_THREAD thread_179_3;
+static TX_THREAD thread_180_3;
+static TX_THREAD thread_181_3;
+static TX_THREAD thread_182_3;
+static TX_THREAD thread_183_3;
+static TX_THREAD thread_184_3;
+static TX_THREAD thread_185_3;
+static TX_THREAD thread_186_3;
+static TX_THREAD thread_187_3;
+static TX_THREAD thread_188_3;
+static TX_THREAD thread_189_3;
+static TX_THREAD thread_190_3;
+static TX_THREAD thread_191_3;
+static TX_THREAD thread_192_3;
+static TX_THREAD thread_193_3;
+static TX_THREAD thread_194_3;
+static TX_THREAD thread_195_3;
+static TX_THREAD thread_196_3;
+static TX_THREAD thread_197_3;
+static TX_THREAD thread_198_3;
+static TX_THREAD thread_199_3;
+static TX_THREAD thread_200_3;
+static TX_THREAD thread_201_3;
+static TX_THREAD thread_202_3;
+static TX_THREAD thread_203_3;
+static TX_THREAD thread_204_3;
+static TX_THREAD thread_205_3;
+static TX_THREAD thread_206_3;
+static TX_THREAD thread_207_3;
+static TX_THREAD thread_208_3;
+static TX_THREAD thread_209_3;
+static TX_THREAD thread_210_3;
+static TX_THREAD thread_211_3;
+static TX_THREAD thread_212_3;
+static TX_THREAD thread_213_3;
+static TX_THREAD thread_214_3;
+static TX_THREAD thread_215_3;
+static TX_THREAD thread_216_3;
+static TX_THREAD thread_217_3;
+static TX_THREAD thread_218_3;
+static TX_THREAD thread_219_3;
+static TX_THREAD thread_220_3;
+static TX_THREAD thread_221_3;
+static TX_THREAD thread_222_3;
+static TX_THREAD thread_223_3;
+static TX_THREAD thread_224_3;
+static TX_THREAD thread_225_3;
+static TX_THREAD thread_226_3;
+static TX_THREAD thread_227_3;
+static TX_THREAD thread_228_3;
+static TX_THREAD thread_229_3;
+static TX_THREAD thread_230_3;
+static TX_THREAD thread_231_3;
+static TX_THREAD thread_232_3;
+static TX_THREAD thread_233_3;
+static TX_THREAD thread_234_3;
+static TX_THREAD thread_235_3;
+static TX_THREAD thread_236_3;
+static TX_THREAD thread_237_3;
+static TX_THREAD thread_238_3;
+static TX_THREAD thread_239_3;
+static TX_THREAD thread_240_3;
+static TX_THREAD thread_241_3;
+static TX_THREAD thread_242_3;
+static TX_THREAD thread_243_3;
+static TX_THREAD thread_244_3;
+static TX_THREAD thread_245_3;
+static TX_THREAD thread_246_3;
+static TX_THREAD thread_247_3;
+static TX_THREAD thread_248_3;
+static TX_THREAD thread_249_3;
+static TX_THREAD thread_250_3;
+static TX_THREAD thread_251_3;
+static TX_THREAD thread_252_3;
+static TX_THREAD thread_253_3;
+static TX_THREAD thread_254_3;
+static TX_THREAD thread_255_3;
+
+/* Define test array. */
+
+static TX_THREAD *_smp_randomized_source_array[] = {
+{&thread_0},
+{&thread_1},
+{&thread_2},
+{&thread_3},
+{&thread_4},
+{&thread_5},
+{&thread_6},
+{&thread_7},
+{&thread_8},
+{&thread_9},
+{&thread_10},
+{&thread_11},
+{&thread_12},
+{&thread_13},
+{&thread_14},
+{&thread_15},
+{&thread_16},
+{&thread_17},
+{&thread_18},
+{&thread_19},
+{&thread_20},
+{&thread_21},
+{&thread_22},
+{&thread_23},
+{&thread_24},
+{&thread_25},
+{&thread_26},
+{&thread_27},
+{&thread_28},
+{&thread_29},
+{&thread_30},
+{&thread_31},
+{&thread_32},
+{&thread_33},
+{&thread_34},
+{&thread_35},
+{&thread_36},
+{&thread_37},
+{&thread_38},
+{&thread_39},
+{&thread_40},
+{&thread_41},
+{&thread_42},
+{&thread_43},
+{&thread_44},
+{&thread_45},
+{&thread_46},
+{&thread_47},
+{&thread_48},
+{&thread_49},
+{&thread_50},
+{&thread_51},
+{&thread_52},
+{&thread_53},
+{&thread_54},
+{&thread_55},
+{&thread_56},
+{&thread_57},
+{&thread_58},
+{&thread_59},
+{&thread_60},
+{&thread_61},
+{&thread_62},
+{&thread_63},
+{&thread_64},
+{&thread_65},
+{&thread_66},
+{&thread_67},
+{&thread_68},
+{&thread_69},
+{&thread_70},
+{&thread_71},
+{&thread_72},
+{&thread_73},
+{&thread_74},
+{&thread_75},
+{&thread_76},
+{&thread_77},
+{&thread_78},
+{&thread_79},
+{&thread_80},
+{&thread_81},
+{&thread_82},
+{&thread_83},
+{&thread_84},
+{&thread_85},
+{&thread_86},
+{&thread_87},
+{&thread_88},
+{&thread_89},
+{&thread_90},
+{&thread_91},
+{&thread_92},
+{&thread_93},
+{&thread_94},
+{&thread_95},
+{&thread_96},
+{&thread_97},
+{&thread_98},
+{&thread_99},
+{&thread_100},
+{&thread_101},
+{&thread_102},
+{&thread_103},
+{&thread_104},
+{&thread_105},
+{&thread_106},
+{&thread_107},
+{&thread_108},
+{&thread_109},
+{&thread_110},
+{&thread_111},
+{&thread_112},
+{&thread_113},
+{&thread_114},
+{&thread_115},
+{&thread_116},
+{&thread_117},
+{&thread_118},
+{&thread_119},
+{&thread_120},
+{&thread_121},
+{&thread_122},
+{&thread_123},
+{&thread_124},
+{&thread_125},
+{&thread_126},
+{&thread_127},
+{&thread_128},
+{&thread_129},
+{&thread_130},
+{&thread_131},
+{&thread_132},
+{&thread_133},
+{&thread_134},
+{&thread_135},
+{&thread_136},
+{&thread_137},
+{&thread_138},
+{&thread_139},
+{&thread_140},
+{&thread_141},
+{&thread_142},
+{&thread_143},
+{&thread_144},
+{&thread_145},
+{&thread_146},
+{&thread_147},
+{&thread_148},
+{&thread_149},
+{&thread_150},
+{&thread_151},
+{&thread_152},
+{&thread_153},
+{&thread_154},
+{&thread_155},
+{&thread_156},
+{&thread_157},
+{&thread_158},
+{&thread_159},
+{&thread_160},
+{&thread_161},
+{&thread_162},
+{&thread_163},
+{&thread_164},
+{&thread_165},
+{&thread_166},
+{&thread_167},
+{&thread_168},
+{&thread_169},
+{&thread_170},
+{&thread_171},
+{&thread_172},
+{&thread_173},
+{&thread_174},
+{&thread_175},
+{&thread_176},
+{&thread_177},
+{&thread_178},
+{&thread_179},
+{&thread_180},
+{&thread_181},
+{&thread_182},
+{&thread_183},
+{&thread_184},
+{&thread_185},
+{&thread_186},
+{&thread_187},
+{&thread_188},
+{&thread_189},
+{&thread_190},
+{&thread_191},
+{&thread_192},
+{&thread_193},
+{&thread_194},
+{&thread_195},
+{&thread_196},
+{&thread_197},
+{&thread_198},
+{&thread_199},
+{&thread_200},
+{&thread_201},
+{&thread_202},
+{&thread_203},
+{&thread_204},
+{&thread_205},
+{&thread_206},
+{&thread_207},
+{&thread_208},
+{&thread_209},
+{&thread_210},
+{&thread_211},
+{&thread_212},
+{&thread_213},
+{&thread_214},
+{&thread_215},
+{&thread_216},
+{&thread_217},
+{&thread_218},
+{&thread_219},
+{&thread_220},
+{&thread_221},
+{&thread_222},
+{&thread_223},
+{&thread_224},
+{&thread_225},
+{&thread_226},
+{&thread_227},
+{&thread_228},
+{&thread_229},
+{&thread_230},
+{&thread_231},
+{&thread_232},
+{&thread_233},
+{&thread_234},
+{&thread_235},
+{&thread_236},
+{&thread_237},
+{&thread_238},
+{&thread_239},
+{&thread_240},
+{&thread_241},
+{&thread_242},
+{&thread_243},
+{&thread_244},
+{&thread_245},
+{&thread_246},
+{&thread_247},
+{&thread_248},
+{&thread_249},
+{&thread_250},
+{&thread_251},
+{&thread_252},
+{&thread_253},
+{&thread_254},
+{&thread_255},
+
+{&thread_0_1},
+{&thread_1_1},
+{&thread_2_1},
+{&thread_3_1},
+{&thread_4_1},
+{&thread_5_1},
+{&thread_6_1},
+{&thread_7_1},
+{&thread_8_1},
+{&thread_9_1},
+{&thread_10_1},
+{&thread_11_1},
+{&thread_12_1},
+{&thread_13_1},
+{&thread_14_1},
+{&thread_15_1},
+{&thread_16_1},
+{&thread_17_1},
+{&thread_18_1},
+{&thread_19_1},
+{&thread_20_1},
+{&thread_21_1},
+{&thread_22_1},
+{&thread_23_1},
+{&thread_24_1},
+{&thread_25_1},
+{&thread_26_1},
+{&thread_27_1},
+{&thread_28_1},
+{&thread_29_1},
+{&thread_30_1},
+{&thread_31_1},
+{&thread_32_1},
+{&thread_33_1},
+{&thread_34_1},
+{&thread_35_1},
+{&thread_36_1},
+{&thread_37_1},
+{&thread_38_1},
+{&thread_39_1},
+{&thread_40_1},
+{&thread_41_1},
+{&thread_42_1},
+{&thread_43_1},
+{&thread_44_1},
+{&thread_45_1},
+{&thread_46_1},
+{&thread_47_1},
+{&thread_48_1},
+{&thread_49_1},
+{&thread_50_1},
+{&thread_51_1},
+{&thread_52_1},
+{&thread_53_1},
+{&thread_54_1},
+{&thread_55_1},
+{&thread_56_1},
+{&thread_57_1},
+{&thread_58_1},
+{&thread_59_1},
+{&thread_60_1},
+{&thread_61_1},
+{&thread_62_1},
+{&thread_63_1},
+{&thread_64_1},
+{&thread_65_1},
+{&thread_66_1},
+{&thread_67_1},
+{&thread_68_1},
+{&thread_69_1},
+{&thread_70_1},
+{&thread_71_1},
+{&thread_72_1},
+{&thread_73_1},
+{&thread_74_1},
+{&thread_75_1},
+{&thread_76_1},
+{&thread_77_1},
+{&thread_78_1},
+{&thread_79_1},
+{&thread_80_1},
+{&thread_81_1},
+{&thread_82_1},
+{&thread_83_1},
+{&thread_84_1},
+{&thread_85_1},
+{&thread_86_1},
+{&thread_87_1},
+{&thread_88_1},
+{&thread_89_1},
+{&thread_90_1},
+{&thread_91_1},
+{&thread_92_1},
+{&thread_93_1},
+{&thread_94_1},
+{&thread_95_1},
+{&thread_96_1},
+{&thread_97_1},
+{&thread_98_1},
+{&thread_99_1},
+{&thread_100_1},
+{&thread_101_1},
+{&thread_102_1},
+{&thread_103_1},
+{&thread_104_1},
+{&thread_105_1},
+{&thread_106_1},
+{&thread_107_1},
+{&thread_108_1},
+{&thread_109_1},
+{&thread_110_1},
+{&thread_111_1},
+{&thread_112_1},
+{&thread_113_1},
+{&thread_114_1},
+{&thread_115_1},
+{&thread_116_1},
+{&thread_117_1},
+{&thread_118_1},
+{&thread_119_1},
+{&thread_120_1},
+{&thread_121_1},
+{&thread_122_1},
+{&thread_123_1},
+{&thread_124_1},
+{&thread_125_1},
+{&thread_126_1},
+{&thread_127_1},
+{&thread_128_1},
+{&thread_129_1},
+{&thread_130_1},
+{&thread_131_1},
+{&thread_132_1},
+{&thread_133_1},
+{&thread_134_1},
+{&thread_135_1},
+{&thread_136_1},
+{&thread_137_1},
+{&thread_138_1},
+{&thread_139_1},
+{&thread_140_1},
+{&thread_141_1},
+{&thread_142_1},
+{&thread_143_1},
+{&thread_144_1},
+{&thread_145_1},
+{&thread_146_1},
+{&thread_147_1},
+{&thread_148_1},
+{&thread_149_1},
+{&thread_150_1},
+{&thread_151_1},
+{&thread_152_1},
+{&thread_153_1},
+{&thread_154_1},
+{&thread_155_1},
+{&thread_156_1},
+{&thread_157_1},
+{&thread_158_1},
+{&thread_159_1},
+{&thread_160_1},
+{&thread_161_1},
+{&thread_162_1},
+{&thread_163_1},
+{&thread_164_1},
+{&thread_165_1},
+{&thread_166_1},
+{&thread_167_1},
+{&thread_168_1},
+{&thread_169_1},
+{&thread_170_1},
+{&thread_171_1},
+{&thread_172_1},
+{&thread_173_1},
+{&thread_174_1},
+{&thread_175_1},
+{&thread_176_1},
+{&thread_177_1},
+{&thread_178_1},
+{&thread_179_1},
+{&thread_180_1},
+{&thread_181_1},
+{&thread_182_1},
+{&thread_183_1},
+{&thread_184_1},
+{&thread_185_1},
+{&thread_186_1},
+{&thread_187_1},
+{&thread_188_1},
+{&thread_189_1},
+{&thread_190_1},
+{&thread_191_1},
+{&thread_192_1},
+{&thread_193_1},
+{&thread_194_1},
+{&thread_195_1},
+{&thread_196_1},
+{&thread_197_1},
+{&thread_198_1},
+{&thread_199_1},
+{&thread_200_1},
+{&thread_201_1},
+{&thread_202_1},
+{&thread_203_1},
+{&thread_204_1},
+{&thread_205_1},
+{&thread_206_1},
+{&thread_207_1},
+{&thread_208_1},
+{&thread_209_1},
+{&thread_210_1},
+{&thread_211_1},
+{&thread_212_1},
+{&thread_213_1},
+{&thread_214_1},
+{&thread_215_1},
+{&thread_216_1},
+{&thread_217_1},
+{&thread_218_1},
+{&thread_219_1},
+{&thread_220_1},
+{&thread_221_1},
+{&thread_222_1},
+{&thread_223_1},
+{&thread_224_1},
+{&thread_225_1},
+{&thread_226_1},
+{&thread_227_1},
+{&thread_228_1},
+{&thread_229_1},
+{&thread_230_1},
+{&thread_231_1},
+{&thread_232_1},
+{&thread_233_1},
+{&thread_234_1},
+{&thread_235_1},
+{&thread_236_1},
+{&thread_237_1},
+{&thread_238_1},
+{&thread_239_1},
+{&thread_240_1},
+{&thread_241_1},
+{&thread_242_1},
+{&thread_243_1},
+{&thread_244_1},
+{&thread_245_1},
+{&thread_246_1},
+{&thread_247_1},
+{&thread_248_1},
+{&thread_249_1},
+{&thread_250_1},
+{&thread_251_1},
+{&thread_252_1},
+{&thread_253_1},
+{&thread_254_1},
+{&thread_255_1},
+
+{&thread_0_2},
+{&thread_1_2},
+{&thread_2_2},
+{&thread_3_2},
+{&thread_4_2},
+{&thread_5_2},
+{&thread_6_2},
+{&thread_7_2},
+{&thread_8_2},
+{&thread_9_2},
+{&thread_10_2},
+{&thread_11_2},
+{&thread_12_2},
+{&thread_13_2},
+{&thread_14_2},
+{&thread_15_2},
+{&thread_16_2},
+{&thread_17_2},
+{&thread_18_2},
+{&thread_19_2},
+{&thread_20_2},
+{&thread_21_2},
+{&thread_22_2},
+{&thread_23_2},
+{&thread_24_2},
+{&thread_25_2},
+{&thread_26_2},
+{&thread_27_2},
+{&thread_28_2},
+{&thread_29_2},
+{&thread_30_2},
+{&thread_31_2},
+{&thread_32_2},
+{&thread_33_2},
+{&thread_34_2},
+{&thread_35_2},
+{&thread_36_2},
+{&thread_37_2},
+{&thread_38_2},
+{&thread_39_2},
+{&thread_40_2},
+{&thread_41_2},
+{&thread_42_2},
+{&thread_43_2},
+{&thread_44_2},
+{&thread_45_2},
+{&thread_46_2},
+{&thread_47_2},
+{&thread_48_2},
+{&thread_49_2},
+{&thread_50_2},
+{&thread_51_2},
+{&thread_52_2},
+{&thread_53_2},
+{&thread_54_2},
+{&thread_55_2},
+{&thread_56_2},
+{&thread_57_2},
+{&thread_58_2},
+{&thread_59_2},
+{&thread_60_2},
+{&thread_61_2},
+{&thread_62_2},
+{&thread_63_2},
+{&thread_64_2},
+{&thread_65_2},
+{&thread_66_2},
+{&thread_67_2},
+{&thread_68_2},
+{&thread_69_2},
+{&thread_70_2},
+{&thread_71_2},
+{&thread_72_2},
+{&thread_73_2},
+{&thread_74_2},
+{&thread_75_2},
+{&thread_76_2},
+{&thread_77_2},
+{&thread_78_2},
+{&thread_79_2},
+{&thread_80_2},
+{&thread_81_2},
+{&thread_82_2},
+{&thread_83_2},
+{&thread_84_2},
+{&thread_85_2},
+{&thread_86_2},
+{&thread_87_2},
+{&thread_88_2},
+{&thread_89_2},
+{&thread_90_2},
+{&thread_91_2},
+{&thread_92_2},
+{&thread_93_2},
+{&thread_94_2},
+{&thread_95_2},
+{&thread_96_2},
+{&thread_97_2},
+{&thread_98_2},
+{&thread_99_2},
+{&thread_100_2},
+{&thread_101_2},
+{&thread_102_2},
+{&thread_103_2},
+{&thread_104_2},
+{&thread_105_2},
+{&thread_106_2},
+{&thread_107_2},
+{&thread_108_2},
+{&thread_109_2},
+{&thread_110_2},
+{&thread_111_2},
+{&thread_112_2},
+{&thread_113_2},
+{&thread_114_2},
+{&thread_115_2},
+{&thread_116_2},
+{&thread_117_2},
+{&thread_118_2},
+{&thread_119_2},
+{&thread_120_2},
+{&thread_121_2},
+{&thread_122_2},
+{&thread_123_2},
+{&thread_124_2},
+{&thread_125_2},
+{&thread_126_2},
+{&thread_127_2},
+{&thread_128_2},
+{&thread_129_2},
+{&thread_130_2},
+{&thread_131_2},
+{&thread_132_2},
+{&thread_133_2},
+{&thread_134_2},
+{&thread_135_2},
+{&thread_136_2},
+{&thread_137_2},
+{&thread_138_2},
+{&thread_139_2},
+{&thread_140_2},
+{&thread_141_2},
+{&thread_142_2},
+{&thread_143_2},
+{&thread_144_2},
+{&thread_145_2},
+{&thread_146_2},
+{&thread_147_2},
+{&thread_148_2},
+{&thread_149_2},
+{&thread_150_2},
+{&thread_151_2},
+{&thread_152_2},
+{&thread_153_2},
+{&thread_154_2},
+{&thread_155_2},
+{&thread_156_2},
+{&thread_157_2},
+{&thread_158_2},
+{&thread_159_2},
+{&thread_160_2},
+{&thread_161_2},
+{&thread_162_2},
+{&thread_163_2},
+{&thread_164_2},
+{&thread_165_2},
+{&thread_166_2},
+{&thread_167_2},
+{&thread_168_2},
+{&thread_169_2},
+{&thread_170_2},
+{&thread_171_2},
+{&thread_172_2},
+{&thread_173_2},
+{&thread_174_2},
+{&thread_175_2},
+{&thread_176_2},
+{&thread_177_2},
+{&thread_178_2},
+{&thread_179_2},
+{&thread_180_2},
+{&thread_181_2},
+{&thread_182_2},
+{&thread_183_2},
+{&thread_184_2},
+{&thread_185_2},
+{&thread_186_2},
+{&thread_187_2},
+{&thread_188_2},
+{&thread_189_2},
+{&thread_190_2},
+{&thread_191_2},
+{&thread_192_2},
+{&thread_193_2},
+{&thread_194_2},
+{&thread_195_2},
+{&thread_196_2},
+{&thread_197_2},
+{&thread_198_2},
+{&thread_199_2},
+{&thread_200_2},
+{&thread_201_2},
+{&thread_202_2},
+{&thread_203_2},
+{&thread_204_2},
+{&thread_205_2},
+{&thread_206_2},
+{&thread_207_2},
+{&thread_208_2},
+{&thread_209_2},
+{&thread_210_2},
+{&thread_211_2},
+{&thread_212_2},
+{&thread_213_2},
+{&thread_214_2},
+{&thread_215_2},
+{&thread_216_2},
+{&thread_217_2},
+{&thread_218_2},
+{&thread_219_2},
+{&thread_220_2},
+{&thread_221_2},
+{&thread_222_2},
+{&thread_223_2},
+{&thread_224_2},
+{&thread_225_2},
+{&thread_226_2},
+{&thread_227_2},
+{&thread_228_2},
+{&thread_229_2},
+{&thread_230_2},
+{&thread_231_2},
+{&thread_232_2},
+{&thread_233_2},
+{&thread_234_2},
+{&thread_235_2},
+{&thread_236_2},
+{&thread_237_2},
+{&thread_238_2},
+{&thread_239_2},
+{&thread_240_2},
+{&thread_241_2},
+{&thread_242_2},
+{&thread_243_2},
+{&thread_244_2},
+{&thread_245_2},
+{&thread_246_2},
+{&thread_247_2},
+{&thread_248_2},
+{&thread_249_2},
+{&thread_250_2},
+{&thread_251_2},
+{&thread_252_2},
+{&thread_253_2},
+{&thread_254_2},
+{&thread_255_2},
+
+{&thread_0_3},
+{&thread_1_3},
+{&thread_2_3},
+{&thread_3_3},
+{&thread_4_3},
+{&thread_5_3},
+{&thread_6_3},
+{&thread_7_3},
+{&thread_8_3},
+{&thread_9_3},
+{&thread_10_3},
+{&thread_11_3},
+{&thread_12_3},
+{&thread_13_3},
+{&thread_14_3},
+{&thread_15_3},
+{&thread_16_3},
+{&thread_17_3},
+{&thread_18_3},
+{&thread_19_3},
+{&thread_20_3},
+{&thread_21_3},
+{&thread_22_3},
+{&thread_23_3},
+{&thread_24_3},
+{&thread_25_3},
+{&thread_26_3},
+{&thread_27_3},
+{&thread_28_3},
+{&thread_29_3},
+{&thread_30_3},
+{&thread_31_3},
+{&thread_32_3},
+{&thread_33_3},
+{&thread_34_3},
+{&thread_35_3},
+{&thread_36_3},
+{&thread_37_3},
+{&thread_38_3},
+{&thread_39_3},
+{&thread_40_3},
+{&thread_41_3},
+{&thread_42_3},
+{&thread_43_3},
+{&thread_44_3},
+{&thread_45_3},
+{&thread_46_3},
+{&thread_47_3},
+{&thread_48_3},
+{&thread_49_3},
+{&thread_50_3},
+{&thread_51_3},
+{&thread_52_3},
+{&thread_53_3},
+{&thread_54_3},
+{&thread_55_3},
+{&thread_56_3},
+{&thread_57_3},
+{&thread_58_3},
+{&thread_59_3},
+{&thread_60_3},
+{&thread_61_3},
+{&thread_62_3},
+{&thread_63_3},
+{&thread_64_3},
+{&thread_65_3},
+{&thread_66_3},
+{&thread_67_3},
+{&thread_68_3},
+{&thread_69_3},
+{&thread_70_3},
+{&thread_71_3},
+{&thread_72_3},
+{&thread_73_3},
+{&thread_74_3},
+{&thread_75_3},
+{&thread_76_3},
+{&thread_77_3},
+{&thread_78_3},
+{&thread_79_3},
+{&thread_80_3},
+{&thread_81_3},
+{&thread_82_3},
+{&thread_83_3},
+{&thread_84_3},
+{&thread_85_3},
+{&thread_86_3},
+{&thread_87_3},
+{&thread_88_3},
+{&thread_89_3},
+{&thread_90_3},
+{&thread_91_3},
+{&thread_92_3},
+{&thread_93_3},
+{&thread_94_3},
+{&thread_95_3},
+{&thread_96_3},
+{&thread_97_3},
+{&thread_98_3},
+{&thread_99_3},
+{&thread_100_3},
+{&thread_101_3},
+{&thread_102_3},
+{&thread_103_3},
+{&thread_104_3},
+{&thread_105_3},
+{&thread_106_3},
+{&thread_107_3},
+{&thread_108_3},
+{&thread_109_3},
+{&thread_110_3},
+{&thread_111_3},
+{&thread_112_3},
+{&thread_113_3},
+{&thread_114_3},
+{&thread_115_3},
+{&thread_116_3},
+{&thread_117_3},
+{&thread_118_3},
+{&thread_119_3},
+{&thread_120_3},
+{&thread_121_3},
+{&thread_122_3},
+{&thread_123_3},
+{&thread_124_3},
+{&thread_125_3},
+{&thread_126_3},
+{&thread_127_3},
+{&thread_128_3},
+{&thread_129_3},
+{&thread_130_3},
+{&thread_131_3},
+{&thread_132_3},
+{&thread_133_3},
+{&thread_134_3},
+{&thread_135_3},
+{&thread_136_3},
+{&thread_137_3},
+{&thread_138_3},
+{&thread_139_3},
+{&thread_140_3},
+{&thread_141_3},
+{&thread_142_3},
+{&thread_143_3},
+{&thread_144_3},
+{&thread_145_3},
+{&thread_146_3},
+{&thread_147_3},
+{&thread_148_3},
+{&thread_149_3},
+{&thread_150_3},
+{&thread_151_3},
+{&thread_152_3},
+{&thread_153_3},
+{&thread_154_3},
+{&thread_155_3},
+{&thread_156_3},
+{&thread_157_3},
+{&thread_158_3},
+{&thread_159_3},
+{&thread_160_3},
+{&thread_161_3},
+{&thread_162_3},
+{&thread_163_3},
+{&thread_164_3},
+{&thread_165_3},
+{&thread_166_3},
+{&thread_167_3},
+{&thread_168_3},
+{&thread_169_3},
+{&thread_170_3},
+{&thread_171_3},
+{&thread_172_3},
+{&thread_173_3},
+{&thread_174_3},
+{&thread_175_3},
+{&thread_176_3},
+{&thread_177_3},
+{&thread_178_3},
+{&thread_179_3},
+{&thread_180_3},
+{&thread_181_3},
+{&thread_182_3},
+{&thread_183_3},
+{&thread_184_3},
+{&thread_185_3},
+{&thread_186_3},
+{&thread_187_3},
+{&thread_188_3},
+{&thread_189_3},
+{&thread_190_3},
+{&thread_191_3},
+{&thread_192_3},
+{&thread_193_3},
+{&thread_194_3},
+{&thread_195_3},
+{&thread_196_3},
+{&thread_197_3},
+{&thread_198_3},
+{&thread_199_3},
+{&thread_200_3},
+{&thread_201_3},
+{&thread_202_3},
+{&thread_203_3},
+{&thread_204_3},
+{&thread_205_3},
+{&thread_206_3},
+{&thread_207_3},
+{&thread_208_3},
+{&thread_209_3},
+{&thread_210_3},
+{&thread_211_3},
+{&thread_212_3},
+{&thread_213_3},
+{&thread_214_3},
+{&thread_215_3},
+{&thread_216_3},
+{&thread_217_3},
+{&thread_218_3},
+{&thread_219_3},
+{&thread_220_3},
+{&thread_221_3},
+{&thread_222_3},
+{&thread_223_3},
+{&thread_224_3},
+{&thread_225_3},
+{&thread_226_3},
+{&thread_227_3},
+{&thread_228_3},
+{&thread_229_3},
+{&thread_230_3},
+{&thread_231_3},
+{&thread_232_3},
+{&thread_233_3},
+{&thread_234_3},
+{&thread_235_3},
+{&thread_236_3},
+{&thread_237_3},
+{&thread_238_3},
+{&thread_239_3},
+{&thread_240_3},
+{&thread_241_3},
+{&thread_242_3},
+{&thread_243_3},
+{&thread_244_3},
+{&thread_245_3},
+{&thread_246_3},
+{&thread_247_3},
+{&thread_248_3},
+{&thread_249_3},
+{&thread_250_3},
+{&thread_251_3},
+{&thread_252_3},
+{&thread_253_3},
+{&thread_254_3},
+{&thread_255_3}
+};
+
+/* Define the test array. This used to store the randomized test. */
+
+static TX_THREAD *_smp_randomized_test_array[TX_THREAD_SMP_MAX_CORES*2];
+
+
+/* Define thread entry prototype. Since it won't be used it can be the same. */
+
+static void control_thread_entry(ULONG thread_input);
+static void thread_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+
+static UINT pass;
+static UINT start_pass;
+static UINT end_pass;
+
+
+/* Create a test control thread. */
+
+static TX_THREAD control_thread;
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_smp_random_resume_suspend_test(void *first_unused_memory)
+#endif
+{
+
+CHAR *pointer;
+UINT status;
+
+ /* Put first available memory address into a character pointer. */
+ pointer = (CHAR *) first_unused_memory;
+
+ /* Create a control thread to run the test. */
+ status = tx_thread_create(&control_thread, "control thread", control_thread_entry, 0,
+ pointer, 1024,
+ 0, 0, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Random Suspensions/Resumptions Test..................... ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+static void control_thread_entry(ULONG thread_input)
+{
+
+UINT i, j;
+UINT priority;
+UINT source_index;
+UINT successful_tests = 0;
+UINT test_errors = 0;
+TX_THREAD *thread_ptr;
+TX_THREAD *current_thread;
+UINT original_priority;
+UINT status;
+
+
+ /* Pickup the current thread pointer. */
+ current_thread = tx_thread_identify();
+
+ /* Loop to create all the threads. */
+ i = 0;
+ priority = 0;
+ status = TX_SUCCESS;
+ while (i < 1024)
+ {
+
+ /* Create each thread. */
+ status += tx_thread_create(_smp_randomized_source_array[i], "test thread", thread_entry, i,
+// (void *) pointer, 512,
+ malloc(1024), 1024,
+ priority, priority, TX_NO_TIME_SLICE, TX_DONT_START);
+// pointer = pointer + 512;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Random Suspensions/Resumptions Test..................... ERROR #2\n");
+ test_control_return(1);
+ break;
+ }
+
+ /* Move to next entry/priority. */
+ i++;
+ priority++;
+
+ /* Should priority be reset? */
+ if (priority >= TX_MAX_PRIORITIES)
+ {
+
+ /* Yes, reset the priority. */
+ priority = 0;
+ }
+ }
+
+ /* Start random test. */
+ printf("Running SMP Random Suspensions/Resumptions Test..................... ");
+
+ /* Clear system counters. */
+ pass = 0;
+ start_pass = 0;
+ end_pass = start_pass + MAX_PASSES;
+ do
+ {
+
+ /* Clear the randomized test array. */
+ for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++)
+ {
+ _smp_randomized_test_array[i] = TX_NULL;
+ }
+
+ /* Build the randomized test array. */
+ for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++)
+ {
+ do
+ {
+ source_index = (rand())%1024;
+
+ /* Determine if this index has repeated. */
+ thread_ptr = _smp_randomized_source_array[source_index];
+
+ /* Is this thread already in the test array? */
+ j = 0;
+ while (j < TX_THREAD_SMP_MAX_CORES*2)
+ {
+ /* Is the entry NULL? */
+ if (_smp_randomized_test_array[j] == TX_NULL)
+ {
+ j = (TX_THREAD_SMP_MAX_CORES*2);
+ }
+
+ /* Determine if we have a duplicate. */
+ if (_smp_randomized_test_array[j] == thread_ptr)
+ thread_ptr = TX_NULL;
+
+ j++;
+ }
+
+ } while (thread_ptr == TX_NULL);
+
+ /* Clear run counter. */
+ thread_ptr -> tx_thread_run_count = 0;
+
+ /* Save the thread pointer. */
+ _smp_randomized_test_array[i] = thread_ptr;
+ }
+
+ /* Now make all the random threads ready. */
+ for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++)
+ {
+ status = tx_thread_resume(_smp_randomized_test_array[i]);
+
+ /* Check for an error. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #3\n");
+ test_control_return(1);
+ break;
+ }
+ }
+
+ /* Check the status. */
+ if (status)
+ break;
+
+ /* Move to the lowest priority. */
+ status += tx_thread_priority_change(current_thread, TX_MAX_PRIORITIES-1, &original_priority);
+ tx_thread_relinquish();
+
+ /* At this point all the threads have run, or should have. */
+
+ /* Restore priority. */
+ status += tx_thread_priority_change(current_thread, original_priority, &original_priority);
+
+ /* Was there an error? */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #4\n");
+ test_control_return(1);
+ break;
+ }
+
+ /* Determine if all the threads in the the random sample ran. */
+ for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++)
+ {
+
+ /* Pickup the thread pointer. */
+ thread_ptr = _smp_randomized_test_array[i];
+
+ /* Check to see if each thread has run. */
+ if (thread_ptr -> tx_thread_run_count == 0)
+ {
+
+ /* First, try to sleep to see if this helps! */
+ tx_thread_sleep(1);
+ }
+
+ /* Has the run count incremented? */
+ if (thread_ptr -> tx_thread_run_count == 0)
+ {
+
+ /* No, this thread didn't really run! */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ break;
+ }
+
+ /* Make sure this thread suspended. */
+ while (thread_ptr -> tx_thread_state != TX_SUSPENDED)
+ {
+ /* Wait for the thread to complete! */
+ tx_thread_relinquish();
+ }
+ }
+
+ /* Increment the pass counter. */
+ pass++;
+
+ } while (pass < end_pass);
+
+ /* Test is successful! */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_entry(ULONG id)
+{
+
+ /* While forever loop! */
+ while(1)
+ {
+
+ /* Suspend thread! */
+ tx_thread_suspend(_smp_randomized_source_array[id]);
+ }
+}
+
+
diff --git a/test/smp/regression/threadx_smp_rebalance_exclusion_test.c b/test/smp/regression/threadx_smp_rebalance_exclusion_test.c
new file mode 100644
index 00000000..9c03c8bd
--- /dev/null
+++ b/test/smp/regression/threadx_smp_rebalance_exclusion_test.c
@@ -0,0 +1,204 @@
+/* Define the ThreadX SMP rebalance exclusion test. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_31k;
+
+
+static ULONG thread_0_counter;
+static ULONG thread_1_counter;
+static ULONG thread_2_counter;
+static ULONG thread_31k_counter;
+
+
+static unsigned long error = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_31k_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_smp_rebalance_exclustion_test(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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_0, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Rebalance Exclusion Test................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_1, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Rebalance Exclusion Test................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_2, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Rebalance Exclusion Test................................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_31k, "thread 31k", thread_31k_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 15, 16, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31k, 0xE); /* Core 0 only! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Rebalance Exclusion Test................................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 0. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Rebalance Exclusion Test................................ ERROR #5\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+
+ /* Inform user. */
+ printf("Running SMP Rebalance Exclusion Test................................ ");
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_1);
+ status += tx_thread_resume(&thread_2);
+ status += tx_thread_resume(&thread_31k);
+
+ /* Suspend this thread to let the others run. */
+ tx_thread_sleep(5);
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (error) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_31k_counter != 1))
+ {
+
+ /* Execution error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ thread_1_counter++;
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ thread_2_counter++;
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+
+static void thread_31k_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* Ensure this thread is on the correct core. */
+ if (tx_thread_smp_core_get() != 0)
+ error++;
+
+ thread_31k_counter++;
+ tx_thread_suspend(&thread_31k);
+ }
+}
diff --git a/test/smp/regression/threadx_smp_relinquish_test.c b/test/smp/regression/threadx_smp_relinquish_test.c
new file mode 100644
index 00000000..d7aac1ca
--- /dev/null
+++ b/test/smp/regression/threadx_smp_relinquish_test.c
@@ -0,0 +1,365 @@
+/* Define the ThreadX SMP relinquish test. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_31a;
+static TX_THREAD thread_31b;
+static TX_THREAD thread_31c;
+static TX_THREAD thread_31d;
+static TX_THREAD thread_31e;
+static TX_THREAD thread_31f;
+static TX_THREAD thread_31g;
+static TX_THREAD thread_31h;
+
+
+static ULONG thread_31a_counter;
+static ULONG thread_31b_counter;
+static ULONG thread_31c_counter;
+static ULONG thread_31d_counter;
+static ULONG thread_31e_counter;
+static ULONG thread_31f_counter;
+static ULONG thread_31g_counter;
+static ULONG thread_31h_counter;
+
+
+static unsigned long error = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_31a_entry(ULONG thread_input);
+static void thread_31b_entry(ULONG thread_input);
+static void thread_31c_entry(ULONG thread_input);
+static void thread_31d_entry(ULONG thread_input);
+static void thread_31e_entry(ULONG thread_input);
+static void thread_31f_entry(ULONG thread_input);
+static void thread_31g_entry(ULONG thread_input);
+static void thread_31h_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_smp_relinquish_test(void *first_unused_memory)
+#endif
+{
+
+UINT status;
+CHAR *pointer;
+UINT i;
+
+
+ /* 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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Relinquish Test......................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_31a, "thread 31a", thread_31a_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31a, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Relinquish Test......................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_31b, "thread 31b", thread_31b_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31b, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Relinquish Test......................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_31c, "thread 31c", thread_31c_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31c, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Relinquish Test......................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_31d, "thread 31d", thread_31d_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31d, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Relinquish Test......................................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_31e, "thread 31e", thread_31e_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31e, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Relinquish Test......................................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_31f, "thread 31f", thread_31f_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31f, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Relinquish Test......................................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_31g, "thread 31g", thread_31g_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31g, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Relinquish Test......................................... ERROR #8\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_31h, "thread 31h", thread_31h_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31h, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Relinquish Test......................................... ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Clear all the counters. */
+ thread_31a_counter = 0;
+ thread_31b_counter = 0;
+ thread_31c_counter = 0;
+ thread_31d_counter = 0;
+ thread_31e_counter = 0;
+ thread_31f_counter = 0;
+ thread_31g_counter = 0;
+ thread_31h_counter = 0;
+
+ /* Resume thread 0. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Relinquish Test......................................... ERROR #10\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+
+ /* Inform user. */
+ printf("Running SMP Relinquish Test......................................... ");
+
+ /* Resume all the same priority threads. */
+ status = tx_thread_resume(&thread_31a);
+ status += tx_thread_resume(&thread_31b);
+ status += tx_thread_resume(&thread_31c);
+ status += tx_thread_resume(&thread_31d);
+ status += tx_thread_resume(&thread_31e);
+ status += tx_thread_resume(&thread_31f);
+ status += tx_thread_resume(&thread_31g);
+ status += tx_thread_resume(&thread_31h);
+
+ /* Now sleep for 10 ticks to let see if all the threads execute. */
+ tx_thread_sleep(10);
+
+ /* Now check and make sure all the threads ran. */
+ if ((status != TX_SUCCESS) || (thread_31a_counter == 0) || (thread_31b_counter == 0) || (thread_31c_counter == 0) || (thread_31d_counter == 0) ||
+ (thread_31e_counter == 0) || (thread_31f_counter == 0) || (thread_31g_counter == 0) || (thread_31h_counter == 0))
+ {
+
+ /* Execution error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+
+ test_control_return(0);
+}
+
+
+static void thread_31a_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+
+ thread_31a_counter++;
+ }
+}
+
+
+static void thread_31b_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+
+ thread_31b_counter++;
+ }
+}
+
+
+static void thread_31c_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+
+ thread_31c_counter++;
+ }
+}
+
+
+static void thread_31d_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+
+ thread_31d_counter++;
+ }
+}
+
+
+static void thread_31e_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+
+ thread_31e_counter++;
+ }
+}
+
+
+static void thread_31f_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+
+ thread_31f_counter++;
+ }
+}
+
+
+static void thread_31g_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+
+ thread_31g_counter++;
+ }
+}
+
+
+static void thread_31h_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+
+ thread_31h_counter++;
+ }
+}
+
diff --git a/test/smp/regression/threadx_smp_resume_suspend_accending_order_test.c b/test/smp/regression/threadx_smp_resume_suspend_accending_order_test.c
new file mode 100644
index 00000000..3a845878
--- /dev/null
+++ b/test/smp/regression/threadx_smp_resume_suspend_accending_order_test.c
@@ -0,0 +1,1428 @@
+/* Define the ThreadX SMP resume and suspend threads in accending order test. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+extern TX_THREAD *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES];
+
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD thread_4;
+static TX_THREAD thread_5;
+static TX_THREAD thread_6;
+static TX_THREAD thread_7;
+static TX_THREAD thread_8;
+static TX_THREAD thread_9;
+static TX_THREAD thread_10;
+static TX_THREAD thread_11;
+static TX_THREAD thread_12;
+static TX_THREAD thread_13;
+static TX_THREAD thread_14;
+static TX_THREAD thread_15;
+static TX_THREAD thread_16;
+static TX_THREAD thread_17;
+static TX_THREAD thread_18;
+static TX_THREAD thread_19;
+static TX_THREAD thread_20;
+static TX_THREAD thread_21;
+static TX_THREAD thread_22;
+static TX_THREAD thread_23;
+static TX_THREAD thread_24;
+static TX_THREAD thread_25;
+static TX_THREAD thread_26;
+static TX_THREAD thread_27;
+static TX_THREAD thread_28;
+static TX_THREAD thread_29;
+static TX_THREAD thread_30;
+static TX_THREAD thread_31;
+
+static ULONG thread_run_counter[32];
+
+
+static unsigned long error = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_entry(ULONG thread_input);
+static void thread_0_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void delay(UINT i)
+{
+
+ /* Wait until the thread runs! */
+ while (thread_run_counter[i] == 0)
+ {
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_smp_resume_suspend_accending_order_test(void *first_unused_memory)
+#endif
+{
+
+UINT status;
+CHAR *pointer;
+UINT i;
+
+
+ /* 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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_1, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_2, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_3, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_4, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_5, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_6, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #7\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_7, "thread 7", thread_entry, 7,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 7, 7, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_7, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #8\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_8, "thread 8", thread_entry, 8,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 8, 8, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_8, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #9\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_9, "thread 9", thread_entry, 9,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 9, 9, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_9, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #9\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_10, "thread 10", thread_entry, 10,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 10, 10, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_10, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #11\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_11, "thread 11", thread_entry, 11,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 11, 11, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_11, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_12, "thread 12", thread_entry, 12,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 12, 12, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_12, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #13\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_13, "thread 13", thread_entry, 13,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 13, 13, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_13, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_14, "thread 14", thread_entry, 14,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 14, 14, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_14, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #15\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_15, "thread 15", thread_entry, 15,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_15, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #16\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_16, "thread 16", thread_entry, 16,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_16, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #17\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_17, "thread 17", thread_entry, 17,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_17, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #18\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_18, "thread 18", thread_entry, 18,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_18, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #19\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_19, "thread 19", thread_entry, 19,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 19, 19, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_19, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #20\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_20, "thread 20", thread_entry, 20,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 20, 20, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_20, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #21\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_21, "thread 21", thread_entry, 21,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 21, 21, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_21, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #22\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_22, "thread 22", thread_entry, 22,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 22, 22, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_22, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #23\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_23, "thread 23", thread_entry, 23,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 23, 23, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_23, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #24\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_24, "thread 24", thread_entry, 24,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 24, 24, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_24, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #25\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_25, "thread 25", thread_entry, 25,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 25, 25, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_25, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #26\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_26, "thread 26", thread_entry, 26,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 26, 26, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_26, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #27\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_27, "thread 27", thread_entry, 27,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 27, 27, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_27, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #28\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_28, "thread 28", thread_entry, 28,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 28, 28, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_28, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #29\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_29, "thread 29", thread_entry, 29,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 29, 29, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_29, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #30\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_30, "thread 30", thread_entry, 30,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 30, 30, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_30, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #31\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_31, "thread 31", thread_entry, 31,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Clear the thread run count array. */
+ for (i = 0; i < 32; i++)
+ {
+ thread_run_counter[i] = 0;
+ }
+
+ /* Resume thread 0. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #33\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+
+ /* Inform user. */
+ printf("Running SMP Resume-Suspend Accending Priority Order Test............ ");
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_2);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_3);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_4);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_5);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_6);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #39\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_7);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #40\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_8);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #41\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_9);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #42\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_10);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #43\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_11);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #44\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_12);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #45\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_13);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #46\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_14);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #47\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_15);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #48\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_16);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #49\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_17);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #50\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_18);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #51\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_19);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #52\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_20);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #53\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_21);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #54\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_22);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #55\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_23);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #56\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_24);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #57\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_25);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #58\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_26);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #59\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_27);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #60\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_28);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #61\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_29);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #62\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_30);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #63\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_31);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #64\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(1);
+ status = tx_thread_suspend(&thread_1);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_4)
+ || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #65\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(2);
+ status = tx_thread_suspend(&thread_2);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_4)
+ || (_tx_thread_execute_ptr[2] != &thread_5) || (_tx_thread_execute_ptr[3] != &thread_3))
+ {
+
+ /* Execution error. */
+ printf("ERROR #66\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(3);
+ status = tx_thread_suspend(&thread_3);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_4)
+ || (_tx_thread_execute_ptr[2] != &thread_5) || (_tx_thread_execute_ptr[3] != &thread_6))
+ {
+
+ /* Execution error. */
+ printf("ERROR #67\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(4);
+ status = tx_thread_suspend(&thread_4);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_7)
+ || (_tx_thread_execute_ptr[2] != &thread_5) || (_tx_thread_execute_ptr[3] != &thread_6))
+ {
+
+ /* Execution error. */
+ printf("ERROR #68\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(5);
+ status = tx_thread_suspend(&thread_5);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_7)
+ || (_tx_thread_execute_ptr[2] != &thread_8) || (_tx_thread_execute_ptr[3] != &thread_6))
+ {
+
+ /* Execution error. */
+ printf("ERROR #69\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(6);
+ status = tx_thread_suspend(&thread_6);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_7)
+ || (_tx_thread_execute_ptr[2] != &thread_8) || (_tx_thread_execute_ptr[3] != &thread_9))
+ {
+
+ /* Execution error. */
+ printf("ERROR #70\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(7);
+ status = tx_thread_suspend(&thread_7);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_10)
+ || (_tx_thread_execute_ptr[2] != &thread_8) || (_tx_thread_execute_ptr[3] != &thread_9))
+ {
+
+ /* Execution error. */
+ printf("ERROR #71\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(8);
+ status = tx_thread_suspend(&thread_8);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_10)
+ || (_tx_thread_execute_ptr[2] != &thread_11) || (_tx_thread_execute_ptr[3] != &thread_9))
+ {
+
+ /* Execution error. */
+ printf("ERROR #72\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(9);
+ status = tx_thread_suspend(&thread_9);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_10)
+ || (_tx_thread_execute_ptr[2] != &thread_11) || (_tx_thread_execute_ptr[3] != &thread_12))
+ {
+
+ /* Execution error. */
+ printf("ERROR #73\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(10);
+ status = tx_thread_suspend(&thread_10);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_13)
+ || (_tx_thread_execute_ptr[2] != &thread_11) || (_tx_thread_execute_ptr[3] != &thread_12))
+ {
+
+ /* Execution error. */
+ printf("ERROR #74\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(11);
+ status = tx_thread_suspend(&thread_11);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_13)
+ || (_tx_thread_execute_ptr[2] != &thread_14) || (_tx_thread_execute_ptr[3] != &thread_12))
+ {
+
+ /* Execution error. */
+ printf("ERROR #75\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(12);
+ status = tx_thread_suspend(&thread_12);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_13)
+ || (_tx_thread_execute_ptr[2] != &thread_14) || (_tx_thread_execute_ptr[3] != &thread_15))
+ {
+
+ /* Execution error. */
+ printf("ERROR #76\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(13);
+ status = tx_thread_suspend(&thread_13);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16)
+ || (_tx_thread_execute_ptr[2] != &thread_14) || (_tx_thread_execute_ptr[3] != &thread_15))
+ {
+
+ /* Execution error. */
+ printf("ERROR #77\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(14);
+ status = tx_thread_suspend(&thread_14);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16)
+ || (_tx_thread_execute_ptr[2] != &thread_17) || (_tx_thread_execute_ptr[3] != &thread_15))
+ {
+
+ /* Execution error. */
+ printf("ERROR #78\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(15);
+ status = tx_thread_suspend(&thread_15);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16)
+ || (_tx_thread_execute_ptr[2] != &thread_17) || (_tx_thread_execute_ptr[3] != &thread_18))
+ {
+
+ /* Execution error. */
+ printf("ERROR #79\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(16);
+ status = tx_thread_suspend(&thread_16);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_19)
+ || (_tx_thread_execute_ptr[2] != &thread_17) || (_tx_thread_execute_ptr[3] != &thread_18))
+ {
+
+ /* Execution error. */
+ printf("ERROR #80\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(17);
+ status = tx_thread_suspend(&thread_17);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_19)
+ || (_tx_thread_execute_ptr[2] != &thread_20) || (_tx_thread_execute_ptr[3] != &thread_18))
+ {
+
+ /* Execution error. */
+ printf("ERROR #81\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(18);
+ status = tx_thread_suspend(&thread_18);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_19)
+ || (_tx_thread_execute_ptr[2] != &thread_20) || (_tx_thread_execute_ptr[3] != &thread_21))
+ {
+
+ /* Execution error. */
+ printf("ERROR #82\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(19);
+ status = tx_thread_suspend(&thread_19);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_22)
+ || (_tx_thread_execute_ptr[2] != &thread_20) || (_tx_thread_execute_ptr[3] != &thread_21))
+ {
+
+ /* Execution error. */
+ printf("ERROR #83\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(20);
+ status = tx_thread_suspend(&thread_20);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_22)
+ || (_tx_thread_execute_ptr[2] != &thread_23) || (_tx_thread_execute_ptr[3] != &thread_21))
+ {
+
+ /* Execution error. */
+ printf("ERROR #84\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(21);
+ status = tx_thread_suspend(&thread_21);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_22)
+ || (_tx_thread_execute_ptr[2] != &thread_23) || (_tx_thread_execute_ptr[3] != &thread_24))
+ {
+
+ /* Execution error. */
+ printf("ERROR #85\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(22);
+ status = tx_thread_suspend(&thread_22);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_25)
+ || (_tx_thread_execute_ptr[2] != &thread_23) || (_tx_thread_execute_ptr[3] != &thread_24))
+ {
+
+ /* Execution error. */
+ printf("ERROR #86\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(23);
+ status = tx_thread_suspend(&thread_23);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_25)
+ || (_tx_thread_execute_ptr[2] != &thread_26) || (_tx_thread_execute_ptr[3] != &thread_24))
+ {
+
+ /* Execution error. */
+ printf("ERROR #87\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(24);
+ status = tx_thread_suspend(&thread_24);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_25)
+ || (_tx_thread_execute_ptr[2] != &thread_26) || (_tx_thread_execute_ptr[3] != &thread_27))
+ {
+
+ /* Execution error. */
+ printf("ERROR #88\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(25);
+ status = tx_thread_suspend(&thread_25);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_28)
+ || (_tx_thread_execute_ptr[2] != &thread_26) || (_tx_thread_execute_ptr[3] != &thread_27))
+ {
+
+ /* Execution error. */
+ printf("ERROR #89\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(26);
+ status = tx_thread_suspend(&thread_26);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_28)
+ || (_tx_thread_execute_ptr[2] != &thread_29) || (_tx_thread_execute_ptr[3] != &thread_27))
+ {
+
+ /* Execution error. */
+ printf("ERROR #90\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(27);
+ status = tx_thread_suspend(&thread_27);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_28)
+ || (_tx_thread_execute_ptr[2] != &thread_29) || (_tx_thread_execute_ptr[3] != &thread_30))
+ {
+
+ /* Execution error. */
+ printf("ERROR #91\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(28);
+ status = tx_thread_suspend(&thread_28);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31)
+ || (_tx_thread_execute_ptr[2] != &thread_29) || (_tx_thread_execute_ptr[3] != &thread_30))
+ {
+
+ /* Execution error. */
+ printf("ERROR #92\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(29);
+ status = tx_thread_suspend(&thread_29);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != &thread_30))
+ {
+
+ /* Execution error. */
+ printf("ERROR #93\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(30);
+ status = tx_thread_suspend(&thread_30);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #94\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ delay(31);
+ status = tx_thread_suspend(&thread_31);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #95\n");
+ test_control_return(1);
+ }
+
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+
+ test_control_return(0);
+}
+
+
+static void thread_entry(ULONG thread_input)
+{
+
+ /* Increment the run counter. */
+ thread_run_counter[thread_input]++;
+
+ while(1)
+ {
+
+ tx_thread_identify();
+
+ /* Indicate the thread is running... */
+ thread_run_counter[thread_input]++;
+ }
+}
diff --git a/test/smp/regression/threadx_smp_resume_suspend_decending_order_test.c b/test/smp/regression/threadx_smp_resume_suspend_decending_order_test.c
new file mode 100644
index 00000000..6eae504e
--- /dev/null
+++ b/test/smp/regression/threadx_smp_resume_suspend_decending_order_test.c
@@ -0,0 +1,1427 @@
+/* Define the ThreadX SMP resume and suspend threads in accending order test. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+extern TX_THREAD *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES];
+
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD thread_4;
+static TX_THREAD thread_5;
+static TX_THREAD thread_6;
+static TX_THREAD thread_7;
+static TX_THREAD thread_8;
+static TX_THREAD thread_9;
+static TX_THREAD thread_10;
+static TX_THREAD thread_11;
+static TX_THREAD thread_12;
+static TX_THREAD thread_13;
+static TX_THREAD thread_14;
+static TX_THREAD thread_15;
+static TX_THREAD thread_16;
+static TX_THREAD thread_17;
+static TX_THREAD thread_18;
+static TX_THREAD thread_19;
+static TX_THREAD thread_20;
+static TX_THREAD thread_21;
+static TX_THREAD thread_22;
+static TX_THREAD thread_23;
+static TX_THREAD thread_24;
+static TX_THREAD thread_25;
+static TX_THREAD thread_26;
+static TX_THREAD thread_27;
+static TX_THREAD thread_28;
+static TX_THREAD thread_29;
+static TX_THREAD thread_30;
+static TX_THREAD thread_31;
+
+static ULONG thread_run_counter[32];
+
+
+static unsigned long error = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_entry(ULONG thread_input);
+static void thread_0_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void delay(UINT i)
+{
+
+ /* Wait until the thread runs! */
+ while (thread_run_counter[i] == 0)
+ {
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_smp_resume_suspend_decending_order_test(void *first_unused_memory)
+#endif
+{
+
+UINT status;
+CHAR *pointer;
+UINT i;
+
+
+ /* 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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_1, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_2, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_3, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_4, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_5, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_6, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #7\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_7, "thread 7", thread_entry, 7,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 7, 7, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_7, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #8\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_8, "thread 8", thread_entry, 8,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 8, 8, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_8, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #9\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_9, "thread 9", thread_entry, 9,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 9, 9, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_9, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #9\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_10, "thread 10", thread_entry, 10,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 10, 10, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_10, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #11\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_11, "thread 11", thread_entry, 11,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 11, 11, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_11, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_12, "thread 12", thread_entry, 12,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 12, 12, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_12, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #13\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_13, "thread 13", thread_entry, 13,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 13, 13, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_13, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_14, "thread 14", thread_entry, 14,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 14, 14, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_14, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #15\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_15, "thread 15", thread_entry, 15,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_15, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #16\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_16, "thread 16", thread_entry, 16,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_16, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #17\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_17, "thread 17", thread_entry, 17,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_17, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #18\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_18, "thread 18", thread_entry, 18,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_18, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #19\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_19, "thread 19", thread_entry, 19,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 19, 19, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_19, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #20\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_20, "thread 20", thread_entry, 20,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 20, 20, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_20, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #21\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_21, "thread 21", thread_entry, 21,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 21, 21, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_21, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #22\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_22, "thread 22", thread_entry, 22,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 22, 22, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_22, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #23\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_23, "thread 23", thread_entry, 23,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 23, 23, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_23, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #24\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_24, "thread 24", thread_entry, 24,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 24, 24, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_24, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #25\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_25, "thread 25", thread_entry, 25,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 25, 25, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_25, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #26\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_26, "thread 26", thread_entry, 26,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 26, 26, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_26, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #27\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_27, "thread 27", thread_entry, 27,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 27, 27, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_27, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #28\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_28, "thread 28", thread_entry, 28,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 28, 28, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_28, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #29\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_29, "thread 29", thread_entry, 29,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 29, 29, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_29, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #30\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_30, "thread 30", thread_entry, 30,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 30, 30, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_30, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #31\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_31, "thread 31", thread_entry, 31,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Clear the thread run count array. */
+ for (i = 0; i < 32; i++)
+ {
+ thread_run_counter[i] = 0;
+ }
+
+ /* Resume thread 0. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #33\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+
+ /* Inform user. */
+ printf("Running SMP Resume-Suspend Decending Priority Order Test............ ");
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_31);
+ delay(31);
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_30);
+ delay(30);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31)
+ || (_tx_thread_execute_ptr[2] != &thread_30) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_29);
+ delay(29);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31)
+ || (_tx_thread_execute_ptr[2] != &thread_30) || (_tx_thread_execute_ptr[3] != &thread_29))
+ {
+
+ /* Execution error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_28);
+ delay(28);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_28)
+ || (_tx_thread_execute_ptr[2] != &thread_30) || (_tx_thread_execute_ptr[3] != &thread_29))
+ {
+
+ /* Execution error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_27);
+ delay(27);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_28)
+ || (_tx_thread_execute_ptr[2] != &thread_27) || (_tx_thread_execute_ptr[3] != &thread_29))
+ {
+
+ /* Execution error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_26);
+ delay(26);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_28)
+ || (_tx_thread_execute_ptr[2] != &thread_27) || (_tx_thread_execute_ptr[3] != &thread_26))
+ {
+
+ /* Execution error. */
+ printf("ERROR #39\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_25);
+ delay(25);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_25)
+ || (_tx_thread_execute_ptr[2] != &thread_27) || (_tx_thread_execute_ptr[3] != &thread_26))
+ {
+
+ /* Execution error. */
+ printf("ERROR #40\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_24);
+ delay(24);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_25)
+ || (_tx_thread_execute_ptr[2] != &thread_24) || (_tx_thread_execute_ptr[3] != &thread_26))
+ {
+
+ /* Execution error. */
+ printf("ERROR #41\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_23);
+ delay(23);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_25)
+ || (_tx_thread_execute_ptr[2] != &thread_24) || (_tx_thread_execute_ptr[3] != &thread_23))
+ {
+
+ /* Execution error. */
+ printf("ERROR #42\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_22);
+ delay(22);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_22)
+ || (_tx_thread_execute_ptr[2] != &thread_24) || (_tx_thread_execute_ptr[3] != &thread_23))
+ {
+
+ /* Execution error. */
+ printf("ERROR #43\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_21);
+ delay(21);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_22)
+ || (_tx_thread_execute_ptr[2] != &thread_21) || (_tx_thread_execute_ptr[3] != &thread_23))
+ {
+
+ /* Execution error. */
+ printf("ERROR #44\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_20);
+ delay(20);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_22)
+ || (_tx_thread_execute_ptr[2] != &thread_21) || (_tx_thread_execute_ptr[3] != &thread_20))
+ {
+
+ /* Execution error. */
+ printf("ERROR #45\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_19);
+ delay(19);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_19)
+ || (_tx_thread_execute_ptr[2] != &thread_21) || (_tx_thread_execute_ptr[3] != &thread_20))
+ {
+
+ /* Execution error. */
+ printf("ERROR #46\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_18);
+ delay(18);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_19)
+ || (_tx_thread_execute_ptr[2] != &thread_18) || (_tx_thread_execute_ptr[3] != &thread_20))
+ {
+
+ /* Execution error. */
+ printf("ERROR #47\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_17);
+ delay(17);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_19)
+ || (_tx_thread_execute_ptr[2] != &thread_18) || (_tx_thread_execute_ptr[3] != &thread_17))
+ {
+
+ /* Execution error. */
+ printf("ERROR #48\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_16);
+ delay(16);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16)
+ || (_tx_thread_execute_ptr[2] != &thread_18) || (_tx_thread_execute_ptr[3] != &thread_17))
+ {
+
+ /* Execution error. */
+ printf("ERROR #49\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_15);
+ delay(15);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16)
+ || (_tx_thread_execute_ptr[2] != &thread_15) || (_tx_thread_execute_ptr[3] != &thread_17))
+ {
+
+ /* Execution error. */
+ printf("ERROR #50\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_14);
+ delay(14);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16)
+ || (_tx_thread_execute_ptr[2] != &thread_15) || (_tx_thread_execute_ptr[3] != &thread_14))
+ {
+
+ /* Execution error. */
+ printf("ERROR #51\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_13);
+ delay(13);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_13)
+ || (_tx_thread_execute_ptr[2] != &thread_15) || (_tx_thread_execute_ptr[3] != &thread_14))
+ {
+
+ /* Execution error. */
+ printf("ERROR #52\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_12);
+ delay(12);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_13)
+ || (_tx_thread_execute_ptr[2] != &thread_12) || (_tx_thread_execute_ptr[3] != &thread_14))
+ {
+
+ /* Execution error. */
+ printf("ERROR #53\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_11);
+ delay(11);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_13)
+ || (_tx_thread_execute_ptr[2] != &thread_12) || (_tx_thread_execute_ptr[3] != &thread_11))
+ {
+
+ /* Execution error. */
+ printf("ERROR #54\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_10);
+ delay(10);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_10)
+ || (_tx_thread_execute_ptr[2] != &thread_12) || (_tx_thread_execute_ptr[3] != &thread_11))
+ {
+
+ /* Execution error. */
+ printf("ERROR #55\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_9);
+ delay(9);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_10)
+ || (_tx_thread_execute_ptr[2] != &thread_9) || (_tx_thread_execute_ptr[3] != &thread_11))
+ {
+
+ /* Execution error. */
+ printf("ERROR #56\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_8);
+ delay(8);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_10)
+ || (_tx_thread_execute_ptr[2] != &thread_9) || (_tx_thread_execute_ptr[3] != &thread_8))
+ {
+
+ /* Execution error. */
+ printf("ERROR #57\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_7);
+ delay(7);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_7)
+ || (_tx_thread_execute_ptr[2] != &thread_9) || (_tx_thread_execute_ptr[3] != &thread_8))
+ {
+
+ /* Execution error. */
+ printf("ERROR #58\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_6);
+ delay(6);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_7)
+ || (_tx_thread_execute_ptr[2] != &thread_6) || (_tx_thread_execute_ptr[3] != &thread_8))
+ {
+
+ /* Execution error. */
+ printf("ERROR #59\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_5);
+ delay(5);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_7)
+ || (_tx_thread_execute_ptr[2] != &thread_6) || (_tx_thread_execute_ptr[3] != &thread_5))
+ {
+
+ /* Execution error. */
+ printf("ERROR #60\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_4);
+ delay(4);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_4)
+ || (_tx_thread_execute_ptr[2] != &thread_6) || (_tx_thread_execute_ptr[3] != &thread_5))
+ {
+
+ /* Execution error. */
+ printf("ERROR #61\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_3);
+ delay(3);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_4)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_5))
+ {
+
+ /* Execution error. */
+ printf("ERROR #62\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_2);
+ delay(2);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_4)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #63\n");
+ test_control_return(1);
+ }
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_1);
+ delay(1);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #64\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in decending priority. */
+ status = tx_thread_suspend(&thread_31);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #65\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_30);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #66\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_29);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #67\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_28);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #68\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_27);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #69\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_26);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #70\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_25);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #71\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_24);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #72\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_23);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #73\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_22);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #74\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_21);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #75\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_20);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #76\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_19);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #77\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_18);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #78\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_17);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #79\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_16);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #80\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_15);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #81\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_14);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #82\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_13);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #83\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_12);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #84\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_11);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #85\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_10);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #86\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_9);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #87\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_8);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #88\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_7);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #89\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_6);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #90\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_5);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #91\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_4);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #92\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_3);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != &thread_2))
+ {
+
+ /* Execution error. */
+ printf("ERROR #93\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_2);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #94\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread in accending priority. */
+ status = tx_thread_suspend(&thread_1);
+
+ /* Check for the correct results. */
+ if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL)
+ || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
+ {
+
+ /* Execution error. */
+ printf("ERROR #95\n");
+ test_control_return(1);
+ }
+
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+
+ test_control_return(0);
+}
+
+
+static void thread_entry(ULONG thread_input)
+{
+
+ /* Increment the run counter. */
+ thread_run_counter[thread_input]++;
+
+ while(1)
+ {
+
+ tx_thread_identify();
+
+ /* Indicate the thread is running... */
+ thread_run_counter[thread_input]++;
+ }
+}
diff --git a/test/smp/regression/threadx_smp_time_slice_test.c b/test/smp/regression/threadx_smp_time_slice_test.c
new file mode 100644
index 00000000..b58f789f
--- /dev/null
+++ b/test/smp/regression/threadx_smp_time_slice_test.c
@@ -0,0 +1,361 @@
+/* Define the ThreadX SMP time-slice test. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_31a;
+static TX_THREAD thread_31b;
+static TX_THREAD thread_31c;
+static TX_THREAD thread_31d;
+static TX_THREAD thread_31e;
+static TX_THREAD thread_31f;
+static TX_THREAD thread_31g;
+static TX_THREAD thread_31h;
+
+
+static ULONG thread_31a_counter;
+static ULONG thread_31b_counter;
+static ULONG thread_31c_counter;
+static ULONG thread_31d_counter;
+static ULONG thread_31e_counter;
+static ULONG thread_31f_counter;
+static ULONG thread_31g_counter;
+static ULONG thread_31h_counter;
+
+
+static unsigned long error = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_31a_entry(ULONG thread_input);
+static void thread_31b_entry(ULONG thread_input);
+static void thread_31c_entry(ULONG thread_input);
+static void thread_31d_entry(ULONG thread_input);
+static void thread_31e_entry(ULONG thread_input);
+static void thread_31f_entry(ULONG thread_input);
+static void thread_31g_entry(ULONG thread_input);
+static void thread_31h_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_smp_time_slice_test(void *first_unused_memory)
+#endif
+{
+
+UINT status;
+CHAR *pointer;
+UINT i;
+
+
+ /* 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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Time-Slice Test......................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_31a, "thread 31a", thread_31a_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31a, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Time-Slice Test......................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_31b, "thread 31b", thread_31b_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31b, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Time-Slice Test......................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_31c, "thread 31c", thread_31c_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31c, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Time-Slice Test......................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_31d, "thread 31d", thread_31d_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31d, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Time-Slice Test......................................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_31e, "thread 31e", thread_31e_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31e, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Time-Slice Test......................................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_31f, "thread 31f", thread_31f_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31f, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Time-Slice Test......................................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_31g, "thread 31g", thread_31g_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31g, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Time-Slice Test......................................... ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Enable preemption-threshold for this thread to hit branch in tx_thread_time_slice
+ where the expired time-slice thread is replaced by a thread with preemption-threshold
+ enabled. */
+ status = tx_thread_create(&thread_31h, "thread 31h", thread_31h_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 30, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_31h, 0); /* Any core. */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Time-Slice Test......................................... ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Clear all the counters. */
+ thread_31a_counter = 0;
+ thread_31b_counter = 0;
+ thread_31c_counter = 0;
+ thread_31d_counter = 0;
+ thread_31e_counter = 0;
+ thread_31f_counter = 0;
+ thread_31g_counter = 0;
+ thread_31h_counter = 0;
+
+ /* Resume thread 0. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Time-Slice Test......................................... ERROR #10\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+
+ /* Inform user. */
+ printf("Running SMP Time-Slice Test......................................... ");
+
+ /* Resume all the same priority threads. */
+ status = tx_thread_resume(&thread_31a);
+ status += tx_thread_resume(&thread_31b);
+ status += tx_thread_resume(&thread_31c);
+ status += tx_thread_resume(&thread_31d);
+ status += tx_thread_resume(&thread_31e);
+ status += tx_thread_resume(&thread_31f);
+ status += tx_thread_resume(&thread_31g);
+ status += tx_thread_resume(&thread_31h);
+
+ /* Now sleep for 20 ticks to let see if all the threads execute. */
+ tx_thread_sleep(20);
+
+ /* Now check and make sure all the threads ran. */
+ if ((status != TX_SUCCESS) || (thread_31a_counter == 0) || (thread_31b_counter == 0) || (thread_31c_counter == 0) || (thread_31d_counter == 0) ||
+ (thread_31e_counter == 0) || (thread_31f_counter == 0) || (thread_31g_counter == 0) || (thread_31h_counter == 0))
+ {
+
+ /* Execution error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_31a_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+ tx_thread_identify();
+ thread_31a_counter++;
+ }
+}
+
+
+static void thread_31b_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_identify();
+ thread_31b_counter++;
+ }
+}
+
+
+static void thread_31c_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_identify();
+ thread_31c_counter++;
+ }
+}
+
+
+static void thread_31d_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_identify();
+ thread_31d_counter++;
+ }
+}
+
+
+static void thread_31e_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_identify();
+ thread_31e_counter++;
+ }
+}
+
+
+static void thread_31f_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_identify();
+ thread_31f_counter++;
+ }
+}
+
+
+static void thread_31g_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_identify();
+ thread_31g_counter++;
+ }
+}
+
+
+static void thread_31h_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_identify();
+ thread_31h_counter++;
+ }
+}
+
diff --git a/test/smp/regression/threadx_smp_two_threads_one_core_test.c b/test/smp/regression/threadx_smp_two_threads_one_core_test.c
new file mode 100644
index 00000000..a6dc1c80
--- /dev/null
+++ b/test/smp/regression/threadx_smp_two_threads_one_core_test.c
@@ -0,0 +1,268 @@
+/* Define the ThreadX SMP two threads excluded to one core test. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+
+
+static ULONG thread_0_counter;
+static ULONG thread_1_counter;
+static ULONG thread_2_counter;
+
+
+static unsigned long error = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_smp_two_threads_one_core_test(void *first_unused_memory)
+#endif
+{
+
+UINT status;
+CHAR *pointer;
+ULONG exclusion_map;
+
+
+ /* 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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_0, 0x0); /* No exclusions! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Two Threads One Core Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_1, 0xD); /* Only core 1! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Two Threads One Core Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_smp_core_exclude(&thread_2, 0xD); /* Only core 1! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Two Threads One Core Test............................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 0. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running SMP Two Threads One Core Test............................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to call the core-exclusion API with a NULL pointer. */
+ status = tx_thread_smp_core_exclude(TX_NULL, 1);
+
+ /* Check status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("Running SMP Two Threads One Core Test............................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to call the core-exclusion API with a bad thread pointer. */
+ thread_3.tx_thread_id = 0;
+ status = tx_thread_smp_core_exclude(&thread_3, 1);
+
+ /* Check status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("Running SMP Two Threads One Core Test............................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Test the core exclusion get API. */
+ status = tx_thread_smp_core_exclude_get(TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("Running SMP Two Threads One Core Test............................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Test the core exclusion get API with a bad thread pointer. */
+ status = tx_thread_smp_core_exclude_get(&thread_3, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("Running SMP Two Threads One Core Test............................... ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Test the core exclusion get API with a good thread pointer, but a bad return pointer. */
+ status = tx_thread_smp_core_exclude_get(&thread_2, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("Running SMP Two Threads One Core Test............................... ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Now test the proper usage for the core exclusiong get API. */
+ status = tx_thread_smp_core_exclude_get(&thread_2, &exclusion_map);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (exclusion_map != 0xD))
+ {
+
+ printf("Running SMP Two Threads One Core Test............................... ERROR #10\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+
+ /* Inform user. */
+ printf("Running SMP Two Threads One Core Test............................... ");
+
+ /* Resume all the threads. */
+ status = tx_thread_resume(&thread_1);
+ status += tx_thread_resume(&thread_2);
+
+ /* Suspend this thread to let the others run. */
+ tx_thread_sleep(10);
+
+ /* Determine if the test was successful or there was an error. */
+ if ((status != TX_SUCCESS) || (error) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1))
+ {
+
+ /* Execution error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+ /* Ensure this thread is on the correct core. */
+ if (tx_thread_smp_core_get() != 1)
+ error++;
+
+ thread_1_counter++;
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+TX_INTERRUPT_SAVE_AREA
+
+
+ while(1)
+ {
+
+ /* Ensure this thread is on the correct core. */
+ if (tx_thread_smp_core_get() != 1)
+ error++;
+
+ thread_2_counter++;
+
+
+ /* Disable interrupts. */
+ TX_DISABLE
+
+ /* Increment the preempt disable flag. */
+ _tx_thread_preempt_disable++;
+
+ /* Now call the exclude routine to exclude core 1 - move the thread. */
+ if (tx_thread_smp_core_exclude(&thread_2, 0x2))
+ error++;
+
+ /* Decrement the preempt disable flag. */
+ _tx_thread_preempt_disable--;
+
+ /* Restore interrupts. */
+ TX_RESTORE
+
+ /* Suspend thread. */
+ tx_thread_suspend(&thread_2);
+ }
+}
diff --git a/test/smp/regression/threadx_thread_basic_execution_test.c b/test/smp/regression/threadx_thread_basic_execution_test.c
new file mode 100644
index 00000000..02e18d24
--- /dev/null
+++ b/test/smp/regression/threadx_thread_basic_execution_test.c
@@ -0,0 +1,863 @@
+/* This test is designed to see if one thread can be created and executed.
+ It thread_0_entry is hit, then the thread was successfully scheduled.
+ On success, thread_0_counter gets incremented. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_block_pool.h"
+#include "tx_byte_pool.h"
+#include "tx_event_flags.h"
+#include "tx_mutex.h"
+#include "tx_queue.h"
+#include "tx_semaphore.h"
+#include "tx_thread.h"
+
+
+typedef struct THREAD_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_THREAD thread_block;
+ ULONG first_middle;
+ ULONG second_middle;
+ ULONG stack[2048/sizeof(ULONG)];
+ ULONG next_to_last;
+ ULONG last;
+
+} THREAD_MEMORY_TEST;
+
+static THREAD_MEMORY_TEST thread_memory;
+
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD test_thread;
+
+static TX_TIMER timer_0;
+
+
+static UCHAR not_used_stack[TEST_STACK_SIZE_PRINTF];
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+
+/* Define task prototypes. */
+
+static void thread_0_entry(ULONG task_input);
+
+UINT _txe_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr,
+ VOID (*entry_function)(ULONG), ULONG entry_input,
+ VOID *stack_start, ULONG stack_size,
+ UINT priority, UINT preempt_threshold,
+ ULONG time_slice, UINT auto_start, UINT thread_control_block_size);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+CHAR *pointer;
+
+ /* Attempt to create a thread from a timer. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt a thread reset from a timer. */
+ status = tx_thread_reset(&thread_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+CHAR *pointer;
+UINT status;
+UINT old_value;
+ULONG old_time_slice;
+
+
+ /* Call tx_thread_relinquish from ISR to make sure the error checking discards the call. */
+ tx_thread_relinquish();
+
+ /* Attempt to create a thread from a timer. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a thread from an ISR. */
+ status = tx_thread_delete(&thread_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to change preemption from an ISR. */
+ status = tx_thread_preemption_change(&thread_0, 1, &old_value);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to change priority from an ISR. */
+ status = tx_thread_priority_change(&thread_0, 1, &old_value);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt a thread reset from an ISR. */
+ status = tx_thread_reset(&thread_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt a thread terminate from an ISR. */
+ status = tx_thread_terminate(&thread_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt a thread time slice change from an ISR. */
+ status = tx_thread_time_slice_change(&thread_0, 1, &old_time_slice);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+
+ /* Test thread sleep call from ISR. */
+ status = tx_thread_sleep(11);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+}
+
+#if 0
+static void test_thread_entry(ULONG thread_input)
+{
+ /* Do nothing here! */
+}
+#endif
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_basic_execution_application_define(void *first_unused_memory)
+#endif
+{
+
+INT status;
+CHAR *pointer;
+TX_THREAD fake_thread;
+
+
+ /* Setup a pointer. */
+ pointer = (CHAR *) first_unused_memory;
+
+ /* Adjust it forward just to make sure there is some space for the test below. */
+ pointer = pointer + 200;
+
+ /* 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, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Basic Execution Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Now setup a fake thread to generate the other NULL pointer test in the cleanup routines. */
+ fake_thread.tx_thread_suspend_control_block = TX_NULL;
+ _tx_semaphore_cleanup(&fake_thread, 0);
+ _tx_queue_cleanup(&fake_thread, 0);
+ _tx_mutex_cleanup(&fake_thread, 0);
+ _tx_event_flags_cleanup(&fake_thread, 0);
+ _tx_byte_pool_cleanup(&fake_thread, 0);
+ _tx_block_pool_cleanup(&fake_thread, 0);
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+UINT status;
+CHAR *pointer;
+UINT old_value;
+ULONG old_time_slice;
+#endif
+
+VOID (*temp_mutex_release)(TX_THREAD *thread_ptr);
+
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Inform user of success getting to this test. */
+ printf("Running Thread Basic Execution Test................................. ");
+
+ /* Setup test thread to make sure _tx_thread_wait_abort can handle a NULL cleanup. */
+ test_thread.tx_thread_state = TX_IO_DRIVER;
+ test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ test_thread.tx_thread_suspending = TX_TRUE;
+ test_thread.tx_thread_delayed_suspend = TX_TRUE;
+ if(_tx_thread_wait_abort(&test_thread) != TX_WAIT_ABORT_ERROR)
+ {
+ printf("ERROR #XX\n");
+ test_control_return(1);
+ }
+
+ /* Setup test thread to make sure _tx_thread_timeout can handle a NULL cleanup. */
+ test_thread.tx_thread_state = TX_IO_DRIVER;
+ test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ test_thread.tx_thread_suspending = TX_TRUE;
+ test_thread.tx_thread_delayed_suspend = TX_TRUE;
+ _tx_thread_timeout((ULONG) &test_thread);
+
+ /* Setup test thread to make sure _tx_thread_terminate can handle a NULL mutex release function pointer. */
+ temp_mutex_release = _tx_thread_mutex_release;
+ _tx_thread_mutex_release = TX_NULL;
+ test_thread.tx_thread_state = TX_TERMINATED;
+ test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ test_thread.tx_thread_suspending = TX_TRUE;
+ test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ test_thread.tx_thread_delayed_suspend = TX_TRUE;
+ status = _tx_thread_terminate(&test_thread);
+ _tx_thread_mutex_release = temp_mutex_release; /* Recover Mutex release pointer. */
+
+ /* Perform thread memory test. */
+ thread_memory.first = 0x11223344;
+ thread_memory.second = 0x55667788;
+ thread_memory.first_middle = 0x21314151;
+ thread_memory.second_middle= 0x61718191;
+ thread_memory.next_to_last = 0x99aabbcc;
+ thread_memory.last = 0xddeeff00;
+
+ /* Create the thread. */
+ status += tx_thread_create(&thread_memory.thread_block, "thread memory", thread_0_entry, 1,
+ &thread_memory.stack[0], (2048*sizeof(ULONG))/sizeof(ULONG),
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ tx_thread_delete(&thread_memory.thread_block);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (thread_memory.first != 0x11223344) ||
+ (thread_memory.second != 0x55667788) ||
+ (thread_memory.first_middle != 0x21314151) ||
+ (thread_memory.second_middle != 0x61718191) ||
+ (thread_memory.next_to_last != 0x99aabbcc) ||
+ (thread_memory.last != 0xddeeff00))
+ {
+
+ /* Memory overwrite error. */
+ printf("ERROR #2\n");
+ test_control_return(1);
+ }
+
+
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to create a thread with a null pointer. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(TX_NULL, "thread 0", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with a bad control block size. */
+ pointer = (CHAR *) not_used_stack;
+ status = _txe_thread_create(&thread_3, "thread 3", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START, (sizeof(TX_THREAD)+1));
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with a NULL entry function. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_3, "thread 3", TX_NULL, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread that has already been created. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with an overlapping stack. */
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ thread_0.tx_thread_stack_ptr, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with another variation of an overlapping stack. */
+ pointer = thread_0.tx_thread_stack_start;
+ pointer = pointer - 20;
+ status = tx_thread_create(&thread_1, "thread 1", TX_NULL, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread an extra small stack. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ pointer, 1,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with an invalid thread priority. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5000, 5000, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_PRIORITY_ERROR)
+ {
+
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with an invalid preemption-threshold. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 17, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_THRESH_ERROR)
+ {
+
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with an invalid auto start. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, 3456);
+
+ /* Check for status. */
+ if (status != TX_START_ERROR)
+ {
+
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-thread. */
+ status = tx_thread_delete(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_delete(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to register a entry/exit callback on a non-thread. */
+ status = tx_thread_entry_exit_notify(TX_NULL, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to register a entry/exit callback on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_entry_exit_notify(&thread_2, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get info on a non-thread. */
+ status = tx_thread_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get info on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_info_get(&thread_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change preemption of a non-thread. */
+ status = tx_thread_preemption_change(TX_NULL, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change preemption of a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_preemption_change(&thread_2, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change preemption with a NULL return value. */
+ status = tx_thread_preemption_change(&thread_0, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change preemption with a bad threshold value. */
+ status = tx_thread_preemption_change(&thread_0, 17, &old_value);
+
+ /* Check for status. */
+ if (status != TX_THRESH_ERROR)
+ {
+
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+
+ /* Attempt to change priority of a non-thread. */
+ status = tx_thread_priority_change(TX_NULL, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change priority of a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_priority_change(&thread_2, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change priority with a NULL return value. */
+ status = tx_thread_priority_change(&thread_0, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change priority with a bad priority value. */
+ status = tx_thread_priority_change(&thread_0, 2046, &old_value);
+
+ /* Check for status. */
+ if (status != TX_PRIORITY_ERROR)
+ {
+
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread reset for a non-thread. */
+ status = tx_thread_reset(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread reset from same thread. */
+ status = tx_thread_reset(&thread_0);
+
+ /* Check for status. */
+ if (status != TX_NOT_DONE)
+ {
+
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread reset for a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_reset(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread resume with a NULL pointer. */
+ status = tx_thread_resume(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread resume on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_resume(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread suspend with a NULL pointer. */
+ status = tx_thread_suspend(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread suspend on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_suspend(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread termiante with a NULL pointer. */
+ status = tx_thread_terminate(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread terminate on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_terminate(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread time-slice chagne with a NULL pointer. */
+ status = tx_thread_time_slice_change(TX_NULL, 1, &old_time_slice);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread time-slice change on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_time_slice_change(&thread_2, 1, &old_time_slice);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread time-slice change with a null return pointer. */
+ status = tx_thread_time_slice_change(&thread_0, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread wait abort with a NULL pointer. */
+ status = tx_thread_wait_abort(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #39\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread wait abort on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_wait_abort(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #40\n");
+ test_control_return(1);
+ }
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #41\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Check status. */
+ if (error)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #42\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+
+}
diff --git a/test/smp/regression/threadx_thread_basic_time_slice_test.c b/test/smp/regression/threadx_thread_basic_time_slice_test.c
new file mode 100644
index 00000000..9a4f4373
--- /dev/null
+++ b/test/smp/regression/threadx_thread_basic_time_slice_test.c
@@ -0,0 +1,117 @@
+/* This test is designed to see if a thread can be created with a time-slice.
+ No time-slice occurs, only the processing to check for time-slicing. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_thread_basic_time_slice_application_define(void *first_unused_memory)
+#endif
+{
+
+UINT status;
+UCHAR *memory;
+
+
+ memory = (UCHAR *) 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,
+ memory, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 1, TX_AUTO_START);
+ memory = memory + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ memory, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 1, TX_DONT_START);
+ status += tx_thread_smp_core_exclude(&thread_1, 0xF);
+ status += tx_thread_resume(&thread_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Basic Time-Slice Test................................ ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ULONG target_time;
+
+
+ /* Inform user. */
+ printf("Running Thread Basic Time-Slice Test................................ ");
+
+ /* Calculate the target running time. */
+ target_time = tx_time_get() + 20;
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Determine if we are done. */
+ if (tx_time_get() >= target_time)
+ {
+
+ /* Determine if thread 1 executed. */
+ if (thread_1_counter != 0)
+ {
+
+ /* Error, thread 1 has all cores excluded so it should never run. */
+ printf("ERROR #2\n");
+ test_control_return(0);
+ }
+ else
+ {
+
+ /* Successful Time-slice test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ }
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Loop forever. */
+ while(1)
+ {
+
+ /* Increment counter. */
+ thread_1_counter++;
+ }
+}
diff --git a/test/smp/regression/threadx_thread_completed_test.c b/test/smp/regression/threadx_thread_completed_test.c
new file mode 100644
index 00000000..068058d0
--- /dev/null
+++ b/test/smp/regression/threadx_thread_completed_test.c
@@ -0,0 +1,258 @@
+/* This test is designed to see if one thread can be created, executed, and
+ return to the thread shell function. The thread shell function places
+ the thread in a finished state. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+
+static unsigned long thread_0_counter = 0;
+static unsigned long thread_0_enter = 0;
+static unsigned long thread_0_exit = 0;
+static unsigned long thread_1_counter = 0;
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD *saved_ptr;
+static ULONG saved_count;
+
+/* Define task prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void entry_exit_notify(TX_THREAD *thread_ptr, UINT type)
+{
+
+ /* Check for the appropriate thread. */
+ if (thread_ptr != &thread_0)
+ return;
+
+ /* Check for type. */
+ if (type == TX_THREAD_ENTRY)
+ thread_0_enter++;
+ else if (type == TX_THREAD_EXIT)
+ thread_0_exit++;
+}
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_completed_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Setup the notify call to test that logic. */
+ status += tx_thread_entry_exit_notify(&thread_0, entry_exit_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Completed Test....................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Thread Completed Test....................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Completed Test....................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Completed Test....................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Move the created pointer to thread 1 to test the delete path fully. */
+ saved_ptr = _tx_thread_created_ptr;
+ _tx_thread_created_ptr = &thread_0;
+}
+
+
+
+/* Define the test thread. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Fall through to the return in order to place the thread in a finished
+ state. */
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Thread Completed Test....................................... ");
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Attempt to delete thread 2, which is in the wrong stat for deleting. */
+ status = tx_thread_delete(&thread_2);
+
+ /* Check for the proper status. */
+ if (status != TX_DELETE_ERROR)
+ {
+
+ /* Thread delete error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to suspend thread 0, which is in a completed state. */
+ status = tx_thread_suspend(&thread_0);
+
+ /* Check for the correct status. */
+ if (status != TX_SUSPEND_ERROR)
+ {
+
+ /* Thread suspend error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete thread 0. */
+ status = tx_thread_delete(&thread_0);
+
+ /* Check for the proper status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread delete error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Sleep to let thread 2 run. */
+ tx_thread_sleep(2);
+
+ /* Save the created count. */
+ saved_count = _tx_thread_created_count;
+
+ /* Now setup things so we can fake a delete of one thread. */
+ _tx_thread_created_ptr = &thread_2;
+ thread_2.tx_thread_created_next = &thread_2;
+ thread_2.tx_thread_created_previous = &thread_2;
+ _tx_thread_created_count = 1;
+
+ /* Attempt to delete thread 2. */
+ status = tx_thread_delete(&thread_2);
+
+ /* Check for the proper status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread delete error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* if still okay, restore the saved thread pointer. */
+ if (saved_ptr -> tx_thread_id == TX_THREAD_ID)
+ {
+ /* Restore. */
+ _tx_thread_created_ptr = saved_ptr;
+
+ /* Setup the link pointers again. */
+ saved_ptr -> tx_thread_created_previous = &thread_1;
+ thread_1.tx_thread_created_next = saved_ptr;
+
+ /* Setup the created count. */
+ _tx_thread_created_count = saved_count - 1;
+ }
+
+ /* Determine if the first Thread has run and if it's current state is
+ finished. */
+ if ((thread_0.tx_thread_state == TX_COMPLETED) && (thread_0_counter == 1) &&
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+ (thread_0_enter == 1) && (thread_0_exit == 1))
+#else
+ (thread_0_enter == 0) && (thread_0_exit == 0))
+#endif
+ {
+
+ /* Successful thread finish test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ else
+ {
+
+ /* Thread Finish error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Fall through to the return in order to place the thread in a finished
+ state. */
+}
diff --git a/test/smp/regression/threadx_thread_create_preemption_threshold_test.c b/test/smp/regression/threadx_thread_create_preemption_threshold_test.c
new file mode 100644
index 00000000..ad0d1d4e
--- /dev/null
+++ b/test/smp/regression/threadx_thread_create_preemption_threshold_test.c
@@ -0,0 +1,140 @@
+/* This test is designed to test for preemption-threshold use during thread creation during initialization. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_thread_create_preemption_threshold_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_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 0, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Create Preemption-Threshold from Init Test........... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 0, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Create Preemption-Threshold from Init Test........... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 0, 100, TX_DONT_START);
+ status += tx_thread_resume(&thread_0);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Create Preemption-Threshold from Init Test........... ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ /* Inform user. */
+ printf("Running Thread Create Preemption-Threshold from Init Test........... ");
+
+ /* If either of the other threads have run, an error is present. */
+ if ((thread_1_counter) || (thread_2_counter))
+ {
+
+ /* Test error! */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for two ticks (one is insufficient to guarantee the other
+ tasks will run, if this executes too close to the tick interrupt. */
+ tx_thread_sleep(2);
+
+
+ /* Now, both threads should have run. */
+ if ((thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Test error! */
+ printf("ERROR #5\n");
+ test_control_return(2);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Increment this thread's counter. */
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+}
+
diff --git a/test/smp/regression/threadx_thread_delayed_suspension_test.c b/test/smp/regression/threadx_thread_delayed_suspension_test.c
new file mode 100644
index 00000000..6d6d27d0
--- /dev/null
+++ b/test/smp/regression/threadx_thread_delayed_suspension_test.c
@@ -0,0 +1,390 @@
+/* This test checks out the delayed suspension clear from tx_thread_resume. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_timer.h"
+
+
+#define DEMO_STACK_SIZE TEST_STACK_SIZE_PRINTF
+
+
+/* Define the ThreadX object control blocks... */
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+#if defined(TX_WIN32_MEMORY_SIZE) || defined(TX_LINUX_MEMORY_SIZE)
+/* Use larger array size when running on Win32 test platform because of greater speed. */
+#define ARRAY_SIZE 100
+#else
+#define ARRAY_SIZE 10
+#endif
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+static void thread_2_entry(ULONG thread_input);
+
+static UINT delayed_suspend_set;
+
+static ULONG thread_2_counter;
+static ULONG thread_2_counter_capture;
+
+static ULONG min_loop_count;
+static ULONG max_loop_count;
+static ULONG loop_count;
+static volatile ULONG count;
+static volatile ULONG destination = 0;
+static ULONG start_time;
+static ULONG lower_bound;
+static ULONG upper_bound;
+static ULONG current_itterations;
+#ifdef DEBUG_1
+static ULONG last_loop_count;
+#endif
+static TX_THREAD thread_2;
+static TX_SEMAPHORE semaphore_1;
+
+static ULONG array_delay[ARRAY_SIZE];
+
+static ULONG delay_function(void)
+{
+
+ULONG accumulator;
+ULONG i;
+
+ for (i = 0; i < ARRAY_SIZE; i++)
+ array_delay[i] = i;
+
+ for (i = 0; i < ARRAY_SIZE-4; i++)
+ {
+ array_delay[i] = (array_delay[i+1] * array_delay[i+2]) * (array_delay[i+3] * array_delay[i+4]);
+ }
+
+ accumulator = 0;
+ for (i = 0; i < ARRAY_SIZE; i++)
+ accumulator = accumulator + array_delay[i];
+
+ return(accumulator);
+}
+
+
+static void test_isr(void)
+{
+ULONG i;
+
+ /* Determine if we are in calibration mode. */
+ if (loop_count != 0xFFFFFFFF)
+ {
+ if (loop_count < min_loop_count)
+ min_loop_count = loop_count;
+ if (loop_count > max_loop_count)
+ max_loop_count = loop_count;
+
+ lower_bound = loop_count - 1;
+ upper_bound = loop_count + 1;
+ if (lower_bound < min_loop_count)
+ lower_bound = min_loop_count;
+ if (upper_bound > max_loop_count)
+ lower_bound = max_loop_count;
+
+ if ((current_itterations < lower_bound) || (current_itterations > upper_bound))
+ current_itterations = lower_bound;
+
+#ifdef DEBUG_1
+ /* Last loop count. */
+ last_loop_count = loop_count;
+#endif
+
+ /* Reset the loop count to all ones! */
+ loop_count = 0xFFFFFFFF;
+ }
+ count++;
+ for (i = 0; i < (count%32); i++)
+ destination++;
+
+ /* Check to see if the interrupt occurred in the middle of the suspension. */
+ if ((thread_2.tx_thread_suspending) && (delayed_suspend_set == 0))
+ {
+
+ /* Yes, we have taken the interrupt in the middle of a thread suspension. */
+
+ /* Indicate we have got the condition. */
+ delayed_suspend_set = 1;
+
+ /* Capture the current thread 2 counter. */
+ thread_2_counter_capture = thread_2_counter;
+
+ /* Now attempt to set the delayed suspension. */
+ tx_thread_suspend(&thread_2);
+
+ /* Check for the delayed suspension flag being set. */
+ if (thread_2.tx_thread_delayed_suspend != 1)
+ {
+
+ /* Error! Setup the counters to indicate an error. */
+ thread_2_counter = 0xEEEEEEEE;
+ thread_2_counter_capture = 0xFFFFFFFF;
+ }
+
+ /* Now, abort the suspension for thread 2... the thread should switch to a pure suspended state. */
+ tx_thread_wait_abort(&thread_2);
+
+ /* Check for the proper state. */
+ if (thread_2.tx_thread_state != TX_SUSPENDED)
+ {
+
+ /* Error! Setup the counters to indicate an error. */
+ thread_2_counter = 0xEEEEEEEE;
+ thread_2_counter_capture = 0xFFFFFFFF;
+ }
+ }
+
+}
+#endif
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_delayed_suspension_application_define(void *first_unused_memory)
+#endif
+{
+
+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. */
+
+ /* Create the main thread. */
+ tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
+ pointer, DEMO_STACK_SIZE,
+ 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Create threads 1 and 2. */
+ tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, DEMO_STACK_SIZE,
+ 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Create the semaphore. */
+ tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, DEMO_STACK_SIZE,
+ 1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ tx_semaphore_create(&semaphore_1, "semaphore 1", 0);
+
+ thread_2_counter = 0;
+ thread_2_counter_capture = 0;
+ min_loop_count = 0xFFFFFFFF;
+ max_loop_count = 0;
+ loop_count = 0xFFFFFFFF;
+#ifdef DEBUG_1
+ last_loop_count = 0;
+#endif
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Thread Delayed Suspension Clearing Test..................... ");
+
+ /* Relinquish to the other thread. */
+ tx_thread_relinquish();
+
+ /* At this point thread 1 has suspended on the semaphore. */
+
+ /* Suspend the already suspended thread. */
+ tx_thread_suspend(&thread_1);
+
+ /* Set the semaphore, which should make it go into a suspend state. */
+ tx_semaphore_put(&semaphore_0);
+
+ /* Resume the other thread so it runs again. */
+ tx_thread_resume(&thread_1);
+
+ /* Relinquish so it can run again. */
+ tx_thread_relinquish();
+
+ /* Suspend the already suspended thread. */
+ tx_thread_suspend(&thread_1);
+
+ /* Now, clear the delayed suspension. */
+ status = tx_thread_resume(&thread_1);
+
+ if (status != TX_SUSPEND_LIFTED)
+ {
+
+ /* Delayed suspension error. */
+ printf("ERROR #1\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Setup the test ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Resume the test thread. */
+ tx_thread_resume(&thread_2);
+
+ /* Wait until we see the delayed suspension set flag. */
+ while(delayed_suspend_set == 0)
+ {
+
+ /* Abort the suspension for thread 2. */
+ tx_thread_wait_abort(&thread_2);
+
+ /* Just relinquish. */
+ tx_thread_relinquish();
+ }
+
+ /* Relinquish one more time to make sure thread 2 could run if it is ready. */
+ tx_thread_relinquish();
+
+ /* At this point, check for an error. */
+ if (thread_2_counter != thread_2_counter_capture)
+ {
+
+ /* Delayed suspension error... thread kept running! */
+ printf("ERROR #2\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* This thread simply gets the semaphore... */
+ while(1)
+ {
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Check completion status. */
+ if (status != TX_SUCCESS)
+ break;
+ }
+}
+
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ULONG i;
+
+ /* Callibrate the loop count from thread sleep. */
+ for (i = 0; i < 10; i++)
+ {
+
+ /* Sleep to get a fresh time. */
+ tx_thread_sleep(1);
+
+ start_time = _tx_timer_system_clock;
+ do
+ {
+
+ /* Call delay function. */
+ delay_function();
+ loop_count++;
+ } while (start_time == _tx_timer_system_clock);
+
+ /* Wait to reset the loop count. */
+ tx_thread_sleep(1);
+ }
+
+ /* Setup the lower and upper bounds. */
+ lower_bound = min_loop_count;
+ if (lower_bound > 5)
+ lower_bound = lower_bound - 5;
+ upper_bound = max_loop_count + 5;
+
+ current_itterations = lower_bound;
+
+ /* This thread simply suspends over and over... */
+ while(1)
+ {
+
+ /* Sleep to get a fresh starting time. */
+ tx_thread_sleep(1);
+
+ loop_count = 0;
+ start_time = _tx_timer_system_clock;
+ do
+ {
+ /* Call delay function. */
+ delay_function();
+ loop_count++;
+ } while (loop_count < current_itterations);
+
+ /* Suspend this thread. */
+ tx_semaphore_get(&semaphore_1, TX_WAIT_FOREVER);
+
+ /* Adjust the current itterations. */
+ current_itterations++;
+ if (current_itterations > upper_bound)
+ {
+ if (lower_bound > min_loop_count)
+ lower_bound--;
+ if (upper_bound < max_loop_count)
+ upper_bound++;
+ current_itterations = lower_bound;
+ }
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
+#endif
diff --git a/test/smp/regression/threadx_thread_information_test.c b/test/smp/regression/threadx_thread_information_test.c
new file mode 100644
index 00000000..b72a2363
--- /dev/null
+++ b/test/smp/regression/threadx_thread_information_test.c
@@ -0,0 +1,474 @@
+/* This test is for the thread information services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+/* Define task prototypes. */
+
+static void thread_0_entry(ULONG task_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_thread_information_application_define(void *first_unused_memory)
+#endif
+{
+
+INT status;
+
+ /* 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,
+ first_unused_memory, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Information Test..................................... ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *name;
+UINT state;
+ULONG run_count;
+UINT priority;
+UINT preemption_threshold;
+ULONG time_slice;
+TX_THREAD *next_thread;
+TX_THREAD *suspended_thread;
+ULONG resumptions;
+ULONG suspensions;
+ULONG solicited_preemptions;
+ULONG interrupt_preemptions;
+ULONG priority_inversions;
+ULONG time_slices;
+ULONG relinquishes;
+ULONG timeouts;
+ULONG wait_aborts;
+TX_THREAD *last_preempted_by;
+ULONG non_idle_returns;
+ULONG idle_returns;
+
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Inform user of success getting to this test. */
+ printf("Running Thread Information Test..................................... ");
+
+ /* Get information about this thread. */
+ status = tx_thread_info_get(&thread_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_thread_info_get(&thread_0, &name, &state, &run_count, &priority, &preemption_threshold, &time_slice, &next_thread, &suspended_thread);
+
+ /* Check for error status. */
+ if ((status != TX_SUCCESS) || (state != TX_READY) || (run_count != thread_0.tx_thread_run_count) || (priority != 16) || (preemption_threshold != 16) ||
+ (time_slice != 0) || (next_thread != thread_0.tx_thread_created_next) || (suspended_thread != thread_0.tx_thread_suspended_next))
+ {
+
+ /* Thread error. */
+ printf("ERROR #2\n");
+ test_control_return(1);
+ }
+
+
+#ifdef TX_THREAD_ENABLE_PERFORMANCE_INFO
+
+ /* Get the performance information about a NULL thread pointer. */
+ status = _tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Thread error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(&thread_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_thread_performance_info_get(&thread_0, &resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check for error. */
+ if ((status != TX_SUCCESS) || (resumptions != thread_0.tx_thread_performance_resume_count) || (suspensions != thread_0.tx_thread_performance_suspend_count) ||
+ (solicited_preemptions != thread_0.tx_thread_performance_solicited_preemption_count) || (interrupt_preemptions != thread_0.tx_thread_performance_interrupt_preemption_count) ||
+ (priority_inversions != thread_0.tx_thread_performance_priority_inversion_count) || (time_slices != thread_0.tx_thread_performance_time_slice_count) ||
+ (relinquishes != thread_0.tx_thread_performance_relinquish_count) || (timeouts != thread_0.tx_thread_performance_timeout_count) || (wait_aborts != thread_0.tx_thread_performance_wait_abort_count) ||
+ (last_preempted_by != thread_0.tx_thread_performance_last_preempting_thread))
+ {
+
+ /* Thread error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_thread_performance_system_info_get(&resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check for error. */
+ if ((status != TX_SUCCESS) || (resumptions != _tx_thread_performance_resume_count) || (suspensions != _tx_thread_performance_suspend_count) ||
+ (solicited_preemptions != _tx_thread_performance_solicited_preemption_count) || (interrupt_preemptions != _tx_thread_performance_interrupt_preemption_count) ||
+ (priority_inversions != _tx_thread_performance_priority_inversion_count) || (time_slices != _tx_thread_performance_time_slice_count) ||
+ (relinquishes != _tx_thread_performance_relinquish_count) || (timeouts != _tx_thread_performance_timeout_count) || (wait_aborts != _tx_thread_performance_wait_abort_count) ||
+ (non_idle_returns != _tx_thread_performance_non_idle_return_count) || (idle_returns != _tx_thread_performance_idle_return_count))
+ {
+
+ /* Thread error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Success! */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+#else
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(&thread_0, &resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, &resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, TX_NULL, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(&resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, TX_NULL, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, TX_NULL, TX_NULL, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Success! */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+
+#endif
+
+}
diff --git a/test/smp/regression/threadx_thread_multi_level_preemption_threshold_test.c b/test/smp/regression/threadx_thread_multi_level_preemption_threshold_test.c
new file mode 100644
index 00000000..034d4f56
--- /dev/null
+++ b/test/smp/regression/threadx_thread_multi_level_preemption_threshold_test.c
@@ -0,0 +1,982 @@
+/* This test is designed to test multi-level preemption threshold. The protection placed
+ by a thread must be preserved after higher-priority thread preemption that is above the threshold. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_2a_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static unsigned long thread_1_counter = 0;
+
+static unsigned long thread_2_counter = 0;
+
+static unsigned long thread_2a_counter = 0;
+static TX_THREAD thread_2a;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+#endif
+
+static TX_THREAD thread_0;
+
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+/* Define new preemption-threshold threads for complete bit map checking. */
+
+static TX_THREAD thread_1_0;
+static TX_THREAD thread_2_1;
+static TX_THREAD thread_3_2;
+static TX_THREAD thread_4_3;
+static TX_THREAD thread_6_5;
+static TX_THREAD thread_8_7;
+static TX_THREAD thread_10_9;
+static TX_THREAD thread_12_11;
+static TX_THREAD thread_14_13;
+static TX_THREAD thread_16_15;
+static TX_THREAD thread_18_17;
+static TX_THREAD thread_20_19;
+static TX_THREAD thread_22_21;
+static TX_THREAD thread_24_23;
+static TX_THREAD thread_26_25;
+static TX_THREAD thread_28_27;
+static TX_THREAD thread_30_29;
+
+
+/* Define timer for preemption of priority 1 test. */
+
+static TX_TIMER timer_0;
+
+
+/* Define counters. */
+
+static unsigned long timer_0_counter = 0;
+static unsigned long thread_1_0_counter = 0;
+static unsigned long thread_2_1_counter = 0;
+static unsigned long thread_3_2_counter = 0;
+static unsigned long thread_4_3_counter = 0;
+static unsigned long thread_6_5_counter = 0;
+static unsigned long thread_8_7_counter = 0;
+static unsigned long thread_10_9_counter = 0;
+static unsigned long thread_12_11_counter = 0;
+static unsigned long thread_14_13_counter = 0;
+static unsigned long thread_16_15_counter = 0;
+static unsigned long thread_18_17_counter = 0;
+static unsigned long thread_20_19_counter = 0;
+static unsigned long thread_22_21_counter = 0;
+static unsigned long thread_24_23_counter = 0;
+static unsigned long thread_26_25_counter = 0;
+static unsigned long thread_28_27_counter = 0;
+static unsigned long thread_30_29_counter = 0;
+
+
+/* Define new preemption-threshold test thread entry points. */
+
+static void thread_1_0_entry(ULONG thread_input);
+static void thread_2_1_entry(ULONG thread_input);
+static void thread_3_2_entry(ULONG thread_input);
+static void thread_4_3_entry(ULONG thread_input);
+static void thread_6_5_entry(ULONG thread_input);
+static void thread_8_7_entry(ULONG thread_input);
+static void thread_10_9_entry(ULONG thread_input);
+static void thread_12_11_entry(ULONG thread_input);
+static void thread_14_13_entry(ULONG thread_input);
+static void thread_16_15_entry(ULONG thread_input);
+static void thread_18_17_entry(ULONG thread_input);
+static void thread_20_19_entry(ULONG thread_input);
+static void thread_22_21_entry(ULONG thread_input);
+static void thread_24_23_entry(ULONG thread_input);
+static void thread_26_25_entry(ULONG thread_input);
+static void thread_28_27_entry(ULONG thread_input);
+static void thread_30_29_entry(ULONG thread_input);
+
+/* Define timer 1 entry. */
+
+static void timer_0_entry(ULONG id);
+
+
+#endif
+
+
+/* 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_thread_multi_level_preemption_threshold_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,
+ (TX_MAX_PRIORITIES-1), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ (TX_MAX_PRIORITIES/2), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 10, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2a, "thread 2a", thread_2a_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 11, 11, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 9, 9, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Create new cascading preemption-threshold test threads. */
+
+ status = tx_thread_create(&thread_30_29, "thread 30-29", thread_30_29_entry, 30,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 30, 29, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #7\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_28_27, "thread 28-27", thread_28_27_entry, 28,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 28, 27, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #8\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_26_25, "thread 26-25", thread_26_25_entry, 26,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 26, 25, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #9\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_24_23, "thread 24-23", thread_24_23_entry, 24,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 24, 23, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_22_21, "thread 22-21", thread_22_21_entry, 22,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 22, 21, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #11\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_20_19, "thread 20-19", thread_20_19_entry, 20,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 20,19, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_18_17, "thread 18-17", thread_18_17_entry, 18,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 17, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #13\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_16_15, "thread 16-15", thread_16_15_entry, 16,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_14_13, "thread 14-13", thread_14_13_entry, 14,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 14, 13, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #15\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_12_11, "thread 12-11", thread_12_11_entry, 12,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 12, 11, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #16\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_10_9, "thread 10-9", thread_10_9_entry, 10,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 10, 9, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #17\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_8_7, "thread 8-7", thread_8_7_entry, 8,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 8, 7, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #18\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6_5, "thread 6-5", thread_6_5_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 5, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #19\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4_3, "thread 4-3", thread_4_3_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 3, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #20\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3_2, "thread 3-2", thread_3_2_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #21\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2_1, "thread 2-1", thread_2_1_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 1, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #22\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1_0, "thread 1-0", thread_1_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #23\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 0, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #24\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+UINT status;
+UINT old_preempt;
+#endif
+
+
+ /* Inform user. */
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ");
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */
+
+ /* Wakeup Thread 1. It has a higher-priority but should be blocked by
+ preemption threshold. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Check status and make sure the other run counters are proper. */
+ if ((status != TX_SUCCESS) || (thread_1_counter) || (thread_2_counter) ||
+ (thread_3_counter) || (thread_4_counter))
+ {
+
+ /* Thread Preempt Threshold error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 2 which will preempt this thread. */
+ status = tx_thread_resume(&thread_2);
+
+ /* Check for good status and proper run counters. All other threads except for
+ thread 1 should have executed. */
+ if ((status != TX_SUCCESS) || (thread_1_counter) || (thread_2_counter != 1) ||
+ (thread_3_counter != 1) || (thread_4_counter != 1))
+ {
+
+ /* Thread Preempt Threshold error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Set preemption threshold low enough to allow thread 1 to execute. */
+ status = tx_thread_preemption_change(&thread_0, ((TX_MAX_PRIORITIES/2)+1), &old_preempt);
+
+ /* Check for good status and proper run counters. All other threads except for
+ thread 1 should have executed. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1) ||
+ (thread_3_counter != 1) || (thread_4_counter != 1) ||
+ (_tx_thread_preempt_disable))
+ {
+
+ /* Thread Preempt Threshold error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Set preemption threshold to keep new test threads from running. */
+ status = tx_thread_preemption_change(&thread_0, 17, &old_preempt);
+
+ /* Now wakup the lowest priority preemption-threshold thread. */
+ status += tx_thread_resume(&thread_30_29);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread Preempt Threshold error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Now, self suspend. */
+ status = tx_thread_suspend(&thread_0);
+
+ /* Check to make sure all the preemption-threshold threads ran. */
+ if ((thread_1_0_counter != 1) ||
+ (thread_2_1_counter != 1) ||
+ (thread_3_2_counter != 1) ||
+ (thread_4_3_counter != 1) ||
+ (thread_6_5_counter != 1) ||
+ (thread_8_7_counter != 1) ||
+ (thread_10_9_counter != 1) ||
+ (thread_12_11_counter != 1) ||
+ (thread_14_13_counter != 1) ||
+ (thread_16_15_counter != 1) ||
+ (thread_18_17_counter != 1) ||
+ (thread_20_19_counter != 1) ||
+ (thread_22_21_counter != 1) ||
+ (thread_24_23_counter != 1) ||
+ (thread_26_25_counter != 1) ||
+ (thread_28_27_counter != 1) ||
+ (thread_30_29_counter != 1))
+ {
+
+ /* Thread Preempt Threshold error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Successful Thread Suspend non-current thread test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Resume thread 3 which will not preempt because of thread 2's preemption
+ threshold. */
+ status = tx_thread_resume(&thread_3);
+
+ /* Resume thread 2a which will not preempt this thread because it is at
+ the same priority. */
+ status += tx_thread_resume(&thread_2a);
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_3_counter) ||
+ (thread_4_counter))
+ return;
+
+ /* Resume thread 4 which will preempt. We should get back here before thread
+ three runs because of preemption threshold. */
+ status = tx_thread_resume(&thread_4);
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_3_counter) ||
+ (thread_4_counter != 1))
+ return;
+
+ /* Relinquish to the other thread at this priority level. This should
+ clear the preemption threshold condition and allow thread 3 to run. */
+ tx_thread_relinquish();
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_2a_counter != 1) ||
+ (thread_3_counter != 1) || (thread_4_counter != 1))
+ return;
+
+ /* If all is okay, increment thread 2's counter. */
+ thread_2_counter++;
+}
+
+
+static void thread_2a_entry(ULONG thread_input)
+{
+
+ if (thread_3_counter == 1)
+ thread_2a_counter++;
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+ thread_3_counter++;
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+ thread_4_counter++;
+}
+
+
+
+static void timer_0_entry(ULONG id)
+{
+
+ /* Pretend like a preemption occurred on a thread priority of 1 with preemption-threshold set to 0. */
+ _tx_thread_preempted_maps[0] = _tx_thread_preempted_maps[0] | 2;
+
+ /* Set the thread's preemption threshold as well. */
+ thread_1_0.tx_thread_preempt_threshold = 0;
+
+ /* Increment timer 0 counter. */
+ timer_0_counter++;
+}
+
+
+static void thread_1_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Activate the timer to force a priority 0 thread to interrupt. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Loop to wait until timer 0 runs. */
+ while (timer_0_counter == 0)
+ {
+ }
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_1_0_counter++;
+ }
+}
+
+
+static void thread_2_1_entry(ULONG thread_input)
+{
+
+ /* Increment this thread's counter. */
+ thread_2_1_counter++;
+}
+
+
+static void thread_3_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_1_0);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_3_2_counter++;
+ }
+}
+
+
+static void thread_4_3_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_2_1);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_4_3_counter++;
+ }
+}
+
+
+static void thread_6_5_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_4_3);
+
+ /* In this particular case, we have two different preemptions to make
+ sure we exercise all the code. */
+
+ /* Now resume next highest priority thread. */
+ status = tx_thread_resume(&thread_3_2);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_6_5_counter++;
+ }
+}
+
+
+static void thread_8_7_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_6_5);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_8_7_counter++;
+ }
+}
+
+
+static void thread_10_9_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_8_7);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_10_9_counter++;
+ }
+}
+
+static void thread_12_11_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_10_9);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_12_11_counter++;
+ }
+}
+
+
+static void thread_14_13_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_12_11);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_14_13_counter++;
+ }
+}
+
+
+static void thread_16_15_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_14_13);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_16_15_counter++;
+ }
+}
+
+
+static void thread_18_17_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_16_15);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_18_17_counter++;
+ }
+}
+
+
+static void thread_20_19_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_18_17);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_20_19_counter++;
+ }
+}
+
+
+static void thread_22_21_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_20_19);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_22_21_counter++;
+ }
+}
+
+
+static void thread_24_23_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_22_21);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_24_23_counter++;
+ }
+}
+
+static void thread_26_25_entry(ULONG thread_input)\
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_24_23);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_26_25_counter++;
+ }
+}
+
+static void thread_28_27_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_26_25);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_28_27_counter++;
+ }
+}
+
+static void thread_30_29_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_28_27);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_30_29_counter++;
+ }
+
+ /* Resume thread_0. */
+ tx_thread_resume(&thread_0);
+}
+
+
+#endif
diff --git a/test/smp/regression/threadx_thread_multiple_non_current_test.c b/test/smp/regression/threadx_thread_multiple_non_current_test.c
new file mode 100644
index 00000000..51212b3b
--- /dev/null
+++ b/test/smp/regression/threadx_thread_multiple_non_current_test.c
@@ -0,0 +1,222 @@
+/* This test is designed to see if multiple non-current threads can be suspended.
+ The order the suspension and resumption occurs makes sure everything is working
+ right. Thread execution should remain predictable even after suspension and
+ resumption of threads within a priority group. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_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_thread_multiple_non_current_suspension_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Non-Current Suspend Test............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Non-Current Suspend Test............................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Non-Current Suspend Test............................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Non-Current Suspend Test............................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Non-Current Suspend Test............................. ERROR #5\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Thread Non-Current Suspend Test............................. ");
+
+ /* Wakeup all other threads at same priority. */
+ status = tx_thread_resume(&thread_1);
+ status += tx_thread_resume(&thread_2);
+
+ /* Check for good status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Wakeup thread with preempt. */
+ status = tx_thread_resume(&thread_3);
+
+ /* Check for good status and proper counters. */
+ if ((status != TX_SUCCESS) || (thread_3_counter != 1) || (thread_1_counter) ||
+ (thread_2_counter) || (thread_4_counter))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread 1. */
+ status = tx_thread_suspend(&thread_1);
+
+ /* Resume thread 4. */
+ status += tx_thread_resume(&thread_4);
+
+ /* Check for good status and proper counters. */
+ if ((status != TX_SUCCESS) || (thread_3_counter != 1) || (thread_1_counter) ||
+ (thread_2_counter) || (thread_4_counter))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to thread 2 and 4 before we get back. */
+ tx_thread_relinquish();
+
+ /* Check for good status and proper counters. */
+ if ((status != TX_SUCCESS) || (thread_3_counter != 1) || (thread_1_counter) ||
+ (thread_2_counter != 1) || (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Successful Thread Suspend non-current thread test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ thread_1_counter++;
+}
+
+static void thread_2_entry(ULONG thread_input)
+{
+ if (thread_4_counter == 0)
+ thread_2_counter++;
+}
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+ thread_3_counter++;
+}
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+ if (thread_2_counter == 1)
+ thread_4_counter++;
+}
+
diff --git a/test/smp/regression/threadx_thread_multiple_sleep_test.c b/test/smp/regression/threadx_thread_multiple_sleep_test.c
new file mode 100644
index 00000000..9a876295
--- /dev/null
+++ b/test/smp/regression/threadx_thread_multiple_sleep_test.c
@@ -0,0 +1,184 @@
+/* This test is designed to test multiple threads sleeping for 33 ticks. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+//static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_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_thread_multiple_sleep_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(33);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(33);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 0 counter. */
+ thread_2_counter++;
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(33);
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+
+ /* Inform user. */
+ printf("Running Thread Multiple Thread Sleep for 33 Test.................... ");
+
+ /* Clear the tick count. */
+ tx_time_set(0);
+
+ /* Sleep for 100 ticks (+1 in case tick before threads 0,1,2 have run). */
+ tx_thread_sleep(101);
+
+ /* Determine if the sleep was accurate. */
+ if ((thread_0_counter == 4) && (thread_1_counter == 4) &&
+ (thread_2_counter == 4))
+ {
+
+ /* Successful Multiple Sleep test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ else
+ {
+
+ /* Thread Multiple Sleep error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+}
+
diff --git a/test/smp/regression/threadx_thread_multiple_suspension_test.c b/test/smp/regression/threadx_thread_multiple_suspension_test.c
new file mode 100644
index 00000000..0e4e5c06
--- /dev/null
+++ b/test/smp/regression/threadx_thread_multiple_suspension_test.c
@@ -0,0 +1,432 @@
+/* This test is designed to see if multiple threads can be created and suspend.
+ The order the suspension and resumption occurs makes sure everything is working
+ right. All the counters should increment at the same rate. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_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_thread_multiple_suspension_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. */
+
+ /* Create thread 0. */
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 13, 13, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 1. */
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ (TX_MAX_PRIORITIES/2), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 2. */
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ (TX_MAX_PRIORITIES/2), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 3. */
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ (TX_MAX_PRIORITIES/2), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 4. */
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 5. Make this thread non-preemptable for the range of priorities here... */
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ (TX_MAX_PRIORITIES-1), 13, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #6\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Suspend this thread... */
+ tx_thread_suspend(&thread_0);
+
+ /* Resume thread 5... */
+ tx_thread_resume(&thread_5);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 2 counter. */
+ thread_2_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 3 counter. */
+ thread_3_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_3);
+ }
+}
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 4 counter. */
+ thread_4_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_4);
+ }
+}
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ");
+
+ /* Determine if all the other threads are in a suspended state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Resume all of the threads. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_1);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_READY) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_2);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_READY) ||
+ (thread_2.tx_thread_state != TX_READY) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_3);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_READY) ||
+ (thread_2.tx_thread_state != TX_READY) || (thread_3.tx_thread_state != TX_READY) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_4);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_READY) ||
+ (thread_2.tx_thread_state != TX_READY) || (thread_3.tx_thread_state != TX_READY) ||
+ (thread_4.tx_thread_state != TX_READY) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow other threads to run. */
+ tx_thread_relinquish();
+
+ /* Determine if all the other threads are in a suspended state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run twice. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2) || (thread_3_counter != 2) ||
+ (thread_4_counter != 2))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Suspend a thread that is already suspended. */
+ status = tx_thread_suspend(&thread_4);
+
+ /* Check for error condition. */
+ if (status != TX_SUCCESS)
+ {
+ /* Thread Suspend error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Increment thread 5 counter. */
+ thread_5_counter++;
+
+ /* Successful Thread Suspend test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
diff --git a/test/smp/regression/threadx_thread_multiple_time_slice_test.c b/test/smp/regression/threadx_thread_multiple_time_slice_test.c
new file mode 100644
index 00000000..6e1f61fd
--- /dev/null
+++ b/test/smp/regression/threadx_thread_multiple_time_slice_test.c
@@ -0,0 +1,269 @@
+/* This test is designed to see if two threads can be created and execute with a time-slice.
+ Thread 7 should run twice as long because it has more of a time-slice. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static volatile unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static volatile unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static volatile unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+static volatile unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+static volatile unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+#endif
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+#endif
+
+
+/* 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_thread_multiple_time_slice_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, 2, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 4, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create control thread. */
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+ /* Create threads with preemption-threshold and time-slice, such and make sure time-slice is defeated by
+ preemption-threshold. */
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 17, 2, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 4, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #5\n");
+ test_control_return(1);
+ }
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Call thread identify for Win32 test case. */
+ tx_thread_identify();
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Call thread identify for Win32 test case. */
+ tx_thread_identify();
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+unsigned long counter_sum;
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+UINT status;
+#endif
+
+
+ /* Inform user. */
+ printf("Running Thread Multiple Thread Time-Slice Test...................... ");
+
+ /* Sleep for some multiple of 6. */
+ tx_thread_sleep(48);
+
+ /* Increment thread 2 counter. */
+ thread_2_counter++;
+
+ /* Compute the delta. Should be twice as much, but some test environments (Windows/Linux) are
+ not as good in terms of real time processing. */
+ counter_sum = thread_0_counter;
+ counter_sum = counter_sum + (thread_0_counter/4);
+ if (thread_1_counter <= counter_sum)
+ {
+
+ /* Thread Time-slice error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+#ifdef TX_DISABLE_PREEMPTION_THRESHOLD
+ else
+ {
+ /* Successful Thread Time-slice test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+#else
+ /* Now suspend threads 0 and 1 so we can let 3 and 4 run. */
+ status = tx_thread_suspend(&thread_0);
+ status += tx_thread_suspend(&thread_1);
+
+ /* Check status. */
+ if (status)
+ {
+ /* Thread Time-slice error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Now sleep and see if thread 4 ever runs. */
+ tx_thread_sleep(4);
+
+ /* Determine if thread 3 ran and thread 4 didn't. */
+ if ((thread_3_counter) && (thread_4_counter == 0))
+ {
+ /* Successful Thread Time-slice test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ else
+ {
+
+ /* Thread Time-slice error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+#endif
+}
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+/* Define the test threads. */
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 3 counter. */
+ thread_3_counter++;
+
+ /* Call thread identify for Win32 test case. */
+ tx_thread_identify();
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* We should never get here! */
+
+ /* Increment thread 4 counter. */
+ thread_4_counter++;
+
+ /* Call thread identify for Win32 test case. */
+ tx_thread_identify();
+ }
+}
+#endif
+
diff --git a/test/smp/regression/threadx_thread_preemptable_suspension_test.c b/test/smp/regression/threadx_thread_preemptable_suspension_test.c
new file mode 100644
index 00000000..b1c1bc52
--- /dev/null
+++ b/test/smp/regression/threadx_thread_preemptable_suspension_test.c
@@ -0,0 +1,416 @@
+/* This test is designed to see if multiple threads can be created and suspended.
+ The order the suspension and resumption occurs makes sure everything is working right.
+ All the counters should increment at the same rate. This test differs from test 4 in
+ that thread 5 is preemptable. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_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_thread_preemptable_suspension_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. */
+
+ /* Create thread 0. */
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 13, 13, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 1. */
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 2. */
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 3. */
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 4. */
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 5. Make this thread fully preemptable... */
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #6\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Suspend this thread... */
+ tx_thread_suspend(&thread_0);
+
+ /* Resume thread 5... */
+ tx_thread_resume(&thread_5);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 2 counter. */
+ thread_2_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 3 counter. */
+ thread_3_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_3);
+ }
+}
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 4 counter. */
+ thread_4_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_4);
+ }
+}
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ");
+
+ /* Determine if all the other threads are in a suspended state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Resume all of the threads. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run the proper amount. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_1);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run the proper amount. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_2);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has the proper amount. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_3);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run the proper amount. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2) || (thread_3_counter != 2) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_4);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2) || (thread_3_counter != 2) ||
+ (thread_4_counter != 2))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish - this should not do anything! */
+ tx_thread_relinquish();
+
+ /* Determine if all the other threads are in a suspended state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run twice. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2) || (thread_3_counter != 2) ||
+ (thread_4_counter != 2))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 5 counter. */
+ thread_5_counter++;
+
+ /* Successful Thread Suspend test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
diff --git a/test/smp/regression/threadx_thread_preemption_change_test.c b/test/smp/regression/threadx_thread_preemption_change_test.c
new file mode 100644
index 00000000..a16b2633
--- /dev/null
+++ b/test/smp/regression/threadx_thread_preemption_change_test.c
@@ -0,0 +1,379 @@
+/* This test is designed to test the change preemption service call. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_initialize.h"
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+static unsigned long thread_0_counter = 0;
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_MUTEX mutex_0;
+#endif
+
+static TX_THREAD thread_0;
+
+
+/* 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_thread_preemption_change_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, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Preemption Change Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Preemption Change Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 14, 14, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Preemption Change Test............................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Preemption Change Test............................... ERROR #4\n");
+ test_control_return(1);
+ }
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+UINT old_threshold;
+UINT status;
+UINT i;
+#endif
+
+
+ /* Inform user. */
+ printf("Running Thread Preemption Change Test............................... ");
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Resume thread 1, which has a higher priority. Preemption is disabled
+ though so thread 1 should not run yet. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_2_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Change the preemption-threshold such that thread 1 doesn't run yet... just for code coverage. */
+ status = tx_thread_preemption_change(&thread_0, 15, &old_threshold);
+
+ /* Change the preemption threshold. This should cause thread 1 to execute! */
+ status += tx_thread_preemption_change(&thread_0, 16, &old_threshold);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) ||
+ (old_threshold != 15))
+ {
+
+ /* Thread error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Change the preemption threshold of another thread. */
+ status = tx_thread_preemption_change(&thread_2, 11, &old_threshold);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) ||
+ (old_threshold != 14))
+ {
+
+ /* Thread error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Change the preemption threshold back to 15. */
+ status = tx_thread_preemption_change(&thread_0, 15, &old_threshold);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) ||
+ (old_threshold != 16))
+ {
+
+ /* Thread error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 2. This should preempt because it is priority 14 and the
+ current preemption threshold is 15. */
+ status = tx_thread_resume(&thread_2);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* At this point, we are going to loop through preemption changes that result in
+ preemption. */
+ for (i = 0; i < (TX_THREAD_EXECUTE_LOG_SIZE*3); i++)
+ {
+
+ /* Change the preemption threshold back to 14. */
+ status = tx_thread_preemption_change(&thread_0, 14, &old_threshold);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 2 again. */
+ status = tx_thread_resume(&thread_2);
+
+ /* Check status an thread 2 run counter. */
+ if ((status != TX_SUCCESS) && (thread_2_counter != (i+1)))
+ {
+
+ /* Thread error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Change the preemption threshold back to 15 to allow thread 2 to run. */
+ status = tx_thread_preemption_change(&thread_0, 15, &old_threshold);
+
+ /* Check status an thread 2 run counter. */
+ if ((status != TX_SUCCESS) && (thread_2_counter != (i+2)))
+ {
+
+ /* Thread error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+ }
+
+ /* Change the priority of threads 0 and 1. */
+ status = tx_thread_priority_change(&thread_0, 7, &old_threshold);
+ status += tx_thread_priority_change(&thread_1, 5, &old_threshold);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Change the preemption-threshold of this thread. */
+ status = tx_thread_preemption_change(&thread_0, 0, &old_threshold);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (old_threshold != 7))
+ {
+
+ /* Thread error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Get the mutex that has priority inheritance. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 1 so that it can suspend on the mutex and automatically raise its priority. */
+ tx_thread_resume(&thread_1);
+
+ /* Self suspend so that thread 1 and run. */
+ tx_thread_suspend(&thread_0);
+
+ /* Restore the preemption-threshold of this thread. */
+ status = tx_thread_preemption_change(&thread_0, old_threshold, &old_threshold);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (old_threshold != 0) || (thread_0.tx_thread_priority != 5) || (thread_0.tx_thread_preempt_threshold != 5))
+ {
+
+ /* Thread error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Ensure thread 0's entries in these lists were removed. */
+ if (_tx_thread_preempted_maps[0] != 0 ||
+ _tx_thread_preemption_threshold_list[5] != TX_NULL)
+ {
+
+ /* Thread error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Let thread 1 run again so it can release the mutex and undo the priority inheritance. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 7) || (thread_0.tx_thread_preempt_threshold != 7))
+ {
+
+ /* Thread error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Test direct call to the thread preemption change routine with a threshold greater than the current priority. */
+ status = _tx_thread_preemption_change(&thread_0, 8, &old_threshold);
+
+ /* Check status. */
+ if (status != TX_THRESH_ERROR)
+ {
+
+ /* Thread error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+
+}
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT old_threshold;
+
+ /* Hit branch in _tx_thread_preemption_change where preemption-threshold is being disabled
+ but the thread doesn't have preemption-threshold. */
+ tx_thread_preemption_change(&thread_1, 15, &old_threshold);
+
+ /* Self suspend after initial run. */
+ tx_thread_suspend(&thread_1);
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_1);
+
+ /* Resume thread 0. */
+ tx_thread_resume(&thread_0);
+
+ /* Get the mutex, which will cause suspension. */
+ tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ tx_mutex_put(&mutex_0);
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* Increment thread counter. */
+ thread_2_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_2);
+ }
+}
+#endif
diff --git a/test/smp/regression/threadx_thread_priority_change.c b/test/smp/regression/threadx_thread_priority_change.c
new file mode 100644
index 00000000..af65c5e0
--- /dev/null
+++ b/test/smp/regression/threadx_thread_priority_change.c
@@ -0,0 +1,544 @@
+/* This test is designed to test the change priority service call. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_THREAD thread_3;
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_4;
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_5;
+static unsigned long thread_5_counter = 0;
+extern UINT priority_change_extension_selection;
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+
+
+
+extern unsigned long _tx_thread_priority_map;
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+/* Prototype for internal function. */
+VOID _tx_thread_smp_simple_priority_change(TX_THREAD *thread_ptr,UINT new_priority);
+
+
+/* This test routine is used to get a thread of a non ready state. */
+void suspend_thread(void)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+TX_THREAD *thread_ptr;
+
+
+ /* Setup the thread pointer. */
+ thread_ptr = &thread_0;
+
+ /* Disable interrupts. */
+ TX_DISABLE
+
+ /* Set the state to suspended. */
+ thread_ptr -> tx_thread_state = TX_SUSPENDED;
+
+#ifdef TX_NOT_INTERRUPTABLE
+
+ /* Call actual non-interruptable thread suspension routine. */
+ _tx_thread_system_ni_suspend(thread_ptr, ((ULONG) 0));
+
+ /* Restore interrupts. */
+ TX_RESTORE
+#else
+
+ /* Set the suspending flag. */
+ thread_ptr -> tx_thread_suspending = TX_TRUE;
+
+ /* Setup for no timeout period. */
+ thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks = ((ULONG) 0);
+
+ /* Temporarily disable preemption. */
+ _tx_thread_preempt_disable++;
+
+ /* Restore interrupts. */
+ TX_RESTORE
+
+ /* Call actual thread suspension routine. */
+ _tx_thread_system_suspend(thread_ptr);
+#endif
+}
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+UINT saved_preempt_disable;
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Determine if we have the interrupt condition we are looking for. */
+ if ((thread_3.tx_thread_priority == 6) &&
+ (thread_3.tx_thread_state == TX_READY) &&
+ (_tx_thread_priority_list[6] != &thread_3) &&
+ (thread_3_counter > 100))
+ {
+
+ /* Save the preempt disable flag. */
+ saved_preempt_disable = _tx_thread_preempt_disable;
+
+ /* Clear the preempt disable flag to ensure the API works correctly. */
+ _tx_thread_preempt_disable = 0;
+
+ /* Suspend the thread to generate the condition. */
+ tx_thread_suspend(&thread_3);
+
+ /* Restore the preempt disable flag. */
+ _tx_thread_preempt_disable = saved_preempt_disable;
+
+ /* Done trying to generate this test condition. */
+ test_isr_dispatch = TX_NULL;
+ }
+#else
+
+ /* Can't get the interrupt inside the code wit TX_NOT_INTERRUPTABLE defined, so simply stop after thread_3_counter > 100. */
+ if (thread_3_counter > 100)
+ {
+
+ /* Done trying to generate this test condition. */
+ test_isr_dispatch = TX_NULL;
+ }
+#endif
+}
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_priority_change_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Priority Change Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 22, 22, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Priority Change Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 30, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Priority Change Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+//ULONG current_time;
+UINT old_threshold;
+UINT old_priority;
+UINT status;
+TX_THREAD *temp_thread;
+
+
+ /* Inform user. */
+ printf("Running Thread Priority Change Test................................. ");
+
+ /* Resume thread 3. */
+ tx_thread_resume(&thread_3);
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Change priority to 22, to match that of the next highest priority ready thread.
+ This is to test the update of the priority list when a thread is moved to a
+ priority with already ready threads. */
+ status = tx_thread_priority_change(&thread_0, 22, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 16) || (thread_1_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Restore original priority. */
+ tx_thread_priority_change(&thread_0, old_priority, &old_priority);
+
+ /* See if we can change priority of this thread. */
+ status = tx_thread_priority_change(&thread_0, 7, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 16) || (thread_1_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* See if we can change priority of another ready thread. */
+ status = tx_thread_priority_change(&thread_1, 21, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 22) || (thread_1_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* See if we can cause preemption by lowering this thread's priority. */
+ status = tx_thread_priority_change(&thread_0, 22, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 7) || (thread_1_counter != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Thread 1 should have run already... Raise this threads priority
+ back up. */
+ status = tx_thread_priority_change(&thread_0, 8, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 22) || (thread_1_counter != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* See if we can change the priority of a suspended thread. */
+ status = tx_thread_priority_change(&thread_1, 19, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 21) || (thread_1_counter != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Resume the suspended thread so it is in a ready condition. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Should not have run yet. Raise its priority to 8 still should not run yet! */
+ status = tx_thread_priority_change(&thread_1, 8, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 19) || (thread_1_counter != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Raise its priority to 7, now it should run. */
+ status = tx_thread_priority_change(&thread_1, 7, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 8) || (thread_1_counter != 2) || (thread_2_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Now thread 1 should be suspended. Let's change thread 0's priority and make sure thread 2 doesn't run yet! */
+ status = tx_thread_priority_change(&thread_0, 7, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 8) || (thread_1_counter != 2) || (thread_2_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Now resume thread 1, it won't run because it's priority is less than this thread. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Change the priority of thread 1 - the non executing thread to test that path. */
+ status += tx_thread_priority_change(&thread_1, 23, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 7) || (thread_1_counter != 2) || (thread_2_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+ /* Now setup the preemption-threshold for thread 1. */
+ status = tx_thread_preemption_change(&thread_1, 14, &old_threshold);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_threshold != 23) || (thread_1_counter != 2) || (thread_2_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Resume a higher priority preemption-threshold thread. */
+ status = tx_thread_resume(&thread_5);
+
+ /* Now lower this thread's priority. */
+ status += tx_thread_priority_change(&thread_0, 15, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 7) || (thread_1_counter != 2) || (thread_2_counter != 0) || (thread_5_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Change to a higher priority. */
+ tx_thread_priority_change(&thread_0, 7, &old_priority);
+
+ /* Disable interrupts. */
+ TX_DISABLE
+
+ /* Simulate a call from inside of mutex put, but doing it here makes life easier. */
+ _tx_thread_preempt_disable++;
+
+ /* Suspend thread 0. */
+ suspend_thread();
+
+ /* Resume thread 0. */
+ tx_thread_resume(&thread_0);
+
+ /* Change priority to get avoid the reset of the priority list. */
+ tx_thread_priority_change(&thread_0, 16, &old_priority);
+
+ /* Move the priority back so we have some room to test. */
+ tx_thread_priority_change(&thread_0, 7, &old_priority);
+
+ /* Now create the invalid core index situation. */
+ priority_change_extension_selection = 1;
+ tx_thread_priority_change(&thread_0, 8, &old_priority);
+ thread_0.tx_thread_smp_core_mapped = 0;
+
+ /* Now fiddle with the original priority to satisfy that branch. */
+ priority_change_extension_selection = 2;
+ tx_thread_priority_change(&thread_0, 9, &old_priority);
+ _tx_thread_execute_ptr[0] = &thread_0;
+
+ /* Create the condition where original pt thread is same as the current thread. */
+ temp_thread = _tx_thread_preemption__threshold_scheduled;
+ priority_change_extension_selection = 3;
+ tx_thread_priority_change(&thread_0, 15, &old_priority);
+ _tx_thread_preemption__threshold_scheduled = temp_thread;
+
+ /* Move the thread back to a higher priority. */
+ tx_thread_priority_change(&thread_0, 7, &old_priority);
+
+ /* Create the condition where the new thread is NULL. */
+ temp_thread = _tx_thread_preemption__threshold_scheduled;
+ priority_change_extension_selection = 4;
+ tx_thread_priority_change(&thread_0, 15, &old_priority);
+ _tx_thread_preemption__threshold_scheduled = temp_thread;
+
+ /* Decrement the preempt disable count. */
+ _tx_thread_preempt_disable--;
+
+ /* Restore interrupts. */
+ TX_RESTORE
+
+ /* Hit branch in _tx_thread_smp_simple_priority_change such that the
+ new priority is less than the inheritance priority. */
+ thread_0.tx_thread_inherit_priority = 0;
+ _tx_thread_smp_simple_priority_change(&thread_0, 16);
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Suspend self and wait for upper thread to resume. */
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* This thread should never run! */
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT old_priority;
+UINT loop;
+
+
+ /* Resume threads 4. */
+ tx_thread_resume(&thread_4);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ loop = rand() % 100;
+ while (loop--)
+ {
+ thread_3_counter++;
+ }
+
+ /* Raise priority of thread 3 for code coverage. */
+ tx_thread_priority_change(&thread_3, 6, &old_priority);
+ tx_thread_priority_change(&thread_3, 5, &old_priority);
+
+ /* Check to see if thread 4 has run... it should not have executed
+ yet. If it does, set the thread_1_counter to indicate an error! */
+ if (thread_4_counter)
+ thread_1_counter++;
+
+ } while (test_isr_dispatch);
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+ thread_4_counter++;
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+ thread_5_counter++;
+}
+
+
diff --git a/test/smp/regression/threadx_thread_relinquish_test.c b/test/smp/regression/threadx_thread_relinquish_test.c
new file mode 100644
index 00000000..2a48717b
--- /dev/null
+++ b/test/smp/regression/threadx_thread_relinquish_test.c
@@ -0,0 +1,459 @@
+/* This test is designed to see if multiple threads can be created and relinquish control between them. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static unsigned long thread_7_counter = 0;
+static TX_THREAD thread_7;
+
+static unsigned long thread_8_counter = 0;
+static TX_THREAD thread_8;
+
+static unsigned long thread_9_counter = 0;
+static TX_THREAD thread_9;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+static void thread_7_entry(ULONG thread_input);
+static void thread_8_entry(ULONG thread_input);
+static void thread_9_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_thread_relinquish_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. */
+
+ /* Create thread 0. */
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 1. */
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 2. */
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 3. */
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 4. */
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 5. */
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 15, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 6. */
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 7. */
+ status = tx_thread_create(&thread_7, "thread 7", thread_7_entry, 7,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 8. */
+ status = tx_thread_create(&thread_8, "thread 8", thread_8_entry, 8,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 9. */
+ status = tx_thread_create(&thread_9, "thread 9", thread_9_entry, 9,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 31, 31, 1, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #10\n");
+ test_control_return(1);
+ }
+}
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ /* Check for correct input value and execution of other threads. */
+ if ((thread_input != 0) || (thread_1_counter) || (thread_2_counter) ||
+ (thread_3_counter))
+ return;
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Relinquish to other thread(s). */
+ tx_thread_relinquish();
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Check for correct input value and execution of other threads. */
+ if ((thread_input != 1) || (thread_0_counter != 1) || (thread_2_counter) ||
+ (thread_3_counter))
+ return;
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Relinquish to other thread(s). */
+ tx_thread_relinquish();
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Check for correct input value and execution of other threads. */
+ if ((thread_input != 2) || (thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_3_counter))
+ return;
+
+ /* Increment thread 2 counter. */
+ thread_2_counter++;
+
+ /* Relinquish to other thread(s). */
+ tx_thread_relinquish();
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+UINT old_threshold;
+UINT old_priority;
+
+
+ /* Inform user. */
+ printf("Running Thread Relinquish Test...................................... ");
+
+ /* Check for correct input value and execution of other threads. */
+ if ((thread_input != 3) || (thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_0.tx_thread_state != TX_READY) ||
+ (thread_1.tx_thread_state != TX_READY) || (thread_2.tx_thread_state != TX_READY))
+ {
+
+ /* Thread Relinquish error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 3 counter. */
+ thread_3_counter++;
+
+ /* Immediate response relinquish. */
+ tx_thread_relinquish();
+
+ /* All other threads should be completed now. */
+ if ((thread_0.tx_thread_state != TX_COMPLETED) || (thread_1.tx_thread_state != TX_COMPLETED) ||
+ (thread_2.tx_thread_state != TX_COMPLETED))
+ {
+
+ /* Thread Relinquish error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Execute immediate response relinquish. */
+ tx_thread_relinquish();
+
+ /* Move to the lowest default priority. */
+ status = tx_thread_priority_change(&thread_3, 31, &old_priority);
+
+ /* Temporarily make enable preemption-threshold with this thread. */
+ status += tx_thread_preemption_change(&thread_3, 3, &old_threshold);
+
+ /* Execute immediate response, bypassing the error checking. */
+ _tx_thread_preemption__threshold_scheduled = TX_NULL;
+ _tx_thread_relinquish();
+
+ /* Restore the preemtion-threshold and priority. */
+ status += tx_thread_preemption_change(&thread_3, old_threshold, &old_threshold);
+
+ /* Enable all cores for all threads. */
+ status += tx_thread_smp_core_exclude(&thread_4, 0);
+ status += tx_thread_smp_core_exclude(&thread_5, 0);
+ status += tx_thread_smp_core_exclude(&thread_6, 0);
+ status += tx_thread_smp_core_exclude(&thread_7, 0);
+ status += tx_thread_smp_core_exclude(&thread_8, 0);
+ status += tx_thread_smp_core_exclude(&thread_9, 0);
+
+ /* Now lets resume threads 4 through 9. Thread 5 has preemption-threshold set which will excercise
+ the preemption-threshold logic. */
+ status += tx_thread_resume(&thread_4);
+ status += tx_thread_resume(&thread_5);
+ status += tx_thread_resume(&thread_6);
+ status += tx_thread_resume(&thread_7);
+ status += tx_thread_resume(&thread_8);
+ status += tx_thread_resume(&thread_9);
+
+ /* Now relinquish to let these other threads run. */
+ tx_thread_relinquish();
+
+ /* Sleep for 20 ticks to test the paths. */
+ tx_thread_sleep(20);
+
+ /* Now see if the results are as expected. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread Relinquish error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Successful thread relinquish test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+ /* Loop to test relinquish. */
+ while(1)
+ {
+
+ /* Increment thread 2 counter. */
+ thread_4_counter++;
+
+ /* Relinquish to other thread(s). */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+
+ /* Loop to test relinquish. */
+ while(1)
+ {
+
+ /* Increment thread 2 counter. */
+ thread_5_counter++;
+
+ /* Relinquish to other thread(s). */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+
+ /* Loop to test relinquish. */
+ while(1)
+ {
+
+ /* Increment thread 2 counter. */
+ thread_6_counter++;
+
+ /* Relinquish to other thread(s). */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void thread_7_entry(ULONG thread_input)
+{
+
+
+ /* Loop to test relinquish. */
+ while(1)
+ {
+
+ /* Increment thread 2 counter. */
+ thread_7_counter++;
+
+ /* Relinquish to other thread(s). */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void thread_8_entry(ULONG thread_input)
+{
+
+
+ /* Loop to test relinquish. */
+ while(1)
+ {
+
+ /* Increment thread 2 counter. */
+ thread_8_counter++;
+
+ /* Relinquish to other thread(s). */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void thread_9_entry(ULONG thread_input)
+{
+
+
+ /* Loop to test relinquish. */
+ while(1)
+ {
+
+ /* Increment thread 2 counter. */
+ thread_9_counter++;
+
+ /* Relinquish to other thread(s). */
+ tx_thread_relinquish();
+ }
+}
+
+
diff --git a/test/smp/regression/threadx_thread_reset_test.c b/test/smp/regression/threadx_thread_reset_test.c
new file mode 100644
index 00000000..ff3531a5
--- /dev/null
+++ b/test/smp/regression/threadx_thread_reset_test.c
@@ -0,0 +1,248 @@
+/* This test is designed to test the tx_thread_reset function. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+
+static unsigned long thread_0_counter = 0;
+static unsigned long thread_0_enter = 0;
+static unsigned long thread_0_exit = 0;
+static unsigned long thread_1_counter = 0;
+static unsigned long thread_2_counter = 0;
+
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+
+
+/* Define task prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void entry_exit_notify(TX_THREAD *thread_ptr, UINT type)
+{
+
+ /* Check for the appropriate thread. */
+ if (thread_ptr != &thread_0)
+ return;
+
+ /* Check for type. */
+ if (type == TX_THREAD_ENTRY)
+ thread_0_enter++;
+ else if (type == TX_THREAD_EXIT)
+ thread_0_exit++;
+}
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_reset_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Setup the notify call to test that logic. */
+ status += tx_thread_entry_exit_notify(&thread_0, entry_exit_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Reset Test........................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Thread Reset Test........................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+#endif
+
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Reset Test........................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Reset Test........................................... ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test thread. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Fall through to the return in order to place the thread in a finished
+ state. */
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Thread Reset Test........................................... ");
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Attempt to delete thread 2, which is in the wrong stat for deleting. */
+ status = tx_thread_delete(&thread_2);
+
+ /* Check for the proper status. */
+ if (status != TX_DELETE_ERROR)
+ {
+
+ /* Thread delete error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Determine if the first Thread has run and if it's current state is
+ finished. */
+ if ((thread_0.tx_thread_state != TX_COMPLETED) || (thread_0_counter != 1) ||
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+ (thread_0_enter != 1) || (thread_0_exit != 1) || (thread_2_counter != 0))
+#else
+ (thread_0_enter != 0) || (thread_0_exit != 0) || (thread_2_counter != 0))
+#endif
+ {
+
+ /* Thread reset error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Call thread reset on thread 2, which should result in an error. */
+ status = tx_thread_reset(&thread_2);
+
+ /* Check for proper status. */
+ if (status != TX_NOT_DONE)
+ {
+
+ /* Thread reset error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Now call the thread reset function on thread 0. */
+ status = tx_thread_reset(&thread_0);
+
+ /* Determine if the first Thread has been reset but not executed. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_0_counter != 1) ||
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+ (thread_0_enter != 1) || (thread_0_exit != 1) || (thread_2_counter != 0))
+#else
+ (thread_0_enter != 0) || (thread_0_exit != 0) || (thread_2_counter != 0))
+#endif
+ {
+
+ /* Thread reset error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Terminate thread 0. */
+ status = tx_thread_terminate(&thread_0);
+ status += tx_thread_reset(&thread_0);
+
+
+ /* Now resume thread 0 to let it run. */
+ status += tx_thread_resume(&thread_0);
+
+ /* Determine if the first Thread has run and if it's current state is
+ finished. */
+ if ((thread_0.tx_thread_state != TX_COMPLETED) || (thread_0_counter != 2) ||
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+ (thread_0_enter != 2) || (thread_0_exit != 3) || (thread_2_counter != 0))
+#else
+ (thread_0_enter != 0) || (thread_0_exit != 0) || (thread_2_counter != 0))
+#endif
+ {
+
+ /* Thread reset error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+
+ /* Successful thread finish test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Increment thread 2 counter. */
+ thread_2_counter++;
+
+ /* Fall through to the return in order to place the thread in a finished
+ state. */
+}
diff --git a/test/smp/regression/threadx_thread_simple_sleep_non_clear_test.c b/test/smp/regression/threadx_thread_simple_sleep_non_clear_test.c
new file mode 100644
index 00000000..5713e41d
--- /dev/null
+++ b/test/smp/regression/threadx_thread_simple_sleep_non_clear_test.c
@@ -0,0 +1,90 @@
+/* This test is designed to test a simple sleep for 18 ticks, with something in the
+ remaining field of the thread control block. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+
+/* 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_thread_simple_sleep_non_clear_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;
+
+ /* Place a 1 in the thread control block to simulate a control block created in
+ random memory. */
+ thread_0.tx_thread_timer.tx_timer_internal_re_initialize_ticks = 1;
+
+ /* 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, 3, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Sleep with non-zero TX_THREAD........................ ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+
+ /* Inform user. */
+ printf("Running Thread Sleep with non-zero TX_THREAD........................ ");
+
+ /* Clear the tick count. */
+ tx_time_set(0);
+
+ /* Sleep for 18 ticks. */
+ tx_thread_sleep(9);
+ tx_thread_sleep(9);
+
+ /* Determine if the sleep was accurate. */
+ if ((tx_time_get() == 18) ||
+ (tx_time_get() == 19))
+ {
+
+ /* Successful Simple Sleep test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ else
+ {
+
+ /* Thread Simple Sleep error. */
+ printf("ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
diff --git a/test/smp/regression/threadx_thread_simple_sleep_test.c b/test/smp/regression/threadx_thread_simple_sleep_test.c
new file mode 100644
index 00000000..b87bd82d
--- /dev/null
+++ b/test/smp/regression/threadx_thread_simple_sleep_test.c
@@ -0,0 +1,85 @@
+/* This test is designed to test a simple sleep for 18 ticks. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+
+/* 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_thread_simple_sleep_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, 3, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Simple Sleep for 18 Ticks Test....................... ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+
+ /* Inform user. */
+ printf("Running Thread Simple Sleep for 18 Ticks Test....................... ");
+
+ /* Clear the tick count. */
+ tx_time_set(0);
+
+ /* Sleep for 18 ticks. */
+ tx_thread_sleep(18);
+
+ /* Determine if the sleep was accurate. */
+ if ((tx_time_get() == 18) ||
+ (tx_time_get() == 19))
+ {
+
+ /* Successful Simple Sleep test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ else
+ {
+
+ /* Thread Simple Sleep error. */
+ printf("ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
diff --git a/test/smp/regression/threadx_thread_simple_suspend_test.c b/test/smp/regression/threadx_thread_simple_suspend_test.c
new file mode 100644
index 00000000..52215a75
--- /dev/null
+++ b/test/smp/regression/threadx_thread_simple_suspend_test.c
@@ -0,0 +1,116 @@
+/* This test is designed to see if a thread can successfully suspend itself in a single
+ thread system. This also tests a thread created that is not automatically enabled. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static TX_THREAD thread_1;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_thread_simple_supsend_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Simple Suspend Test.................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Simple Suspend Test.................................. ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test thread. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Resume the test control thread. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Suspend the running thread. */
+ tx_thread_suspend(&thread_0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Inform user. */
+ printf("Running Thread Simple Suspend Test.................................. ");
+
+ /* The other thread should be in a suspended state now. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_0_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful Thread Suspend test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
diff --git a/test/smp/regression/threadx_thread_sleep_for_100ticks_test.c b/test/smp/regression/threadx_thread_sleep_for_100ticks_test.c
new file mode 100644
index 00000000..69eadbc6
--- /dev/null
+++ b/test/smp/regression/threadx_thread_sleep_for_100ticks_test.c
@@ -0,0 +1,435 @@
+/* This test is designed to test a simple sleep for 100 ticks. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_timer.h"
+
+//#define DEBUG
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+
+static TX_THREAD thread_0;
+
+static int error = 0;
+
+static int isr_count = 0;
+
+#ifdef TEST_INTERRUPT_CONDITION
+#ifndef TX_NOT_INTERRUPTABLE
+
+#if defined(TX_WIN32_MEMORY_SIZE) || defined(TX_LINUX_MEMORY_SIZE)
+/* Use larger array size when running on Win32 test platform because of greater speed. */
+#define ARRAY_SIZE 100
+#else
+#define ARRAY_SIZE 10
+#endif
+
+
+static UINT isr_test_suspend_interrupt = TX_TRUE;
+static UINT isr_test_suspend_interrupted_condition = TX_FALSE;
+static ULONG min_loop_count;
+static ULONG max_loop_count;
+static TX_SEMAPHORE test_semaphore;
+static ULONG loop_count;
+static volatile ULONG count;
+static volatile ULONG destination = 0;
+static ULONG array_delay[ARRAY_SIZE];
+static ULONG start_time;
+static ULONG lower_bound;
+static ULONG upper_bound;
+static ULONG current_itterations;
+#ifdef DEBUG_1
+static ULONG last_loop_count;
+#endif
+static ULONG delay_function(void)
+{
+
+ULONG accumulator;
+ULONG i;
+
+ for (i = 0; i < ARRAY_SIZE; i++)
+ array_delay[i] = i;
+
+ for (i = 0; i < ARRAY_SIZE-4; i++)
+ {
+ array_delay[i] = (array_delay[i+1] * array_delay[i+2]) * (array_delay[i+3] * array_delay[i+4]);
+ }
+
+ accumulator = 0;
+ for (i = 0; i < ARRAY_SIZE; i++)
+ accumulator = accumulator + array_delay[i];
+
+ return(accumulator);
+}
+
+#endif
+#endif
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+UINT status;
+
+#ifdef TEST_INTERRUPT_CONDITION
+#ifndef TX_NOT_INTERRUPTABLE
+ULONG i;
+
+ /* Determine if we are in calibration mode. */
+ if ((loop_count) && (loop_count != 0xFFFFFFFF))
+ {
+ if (loop_count < min_loop_count)
+ min_loop_count = loop_count;
+ if (loop_count > max_loop_count)
+ max_loop_count = loop_count;
+
+ lower_bound = loop_count - 1;
+ upper_bound = loop_count + 1;
+ if (lower_bound < min_loop_count)
+ lower_bound = min_loop_count;
+ if (upper_bound > max_loop_count)
+ lower_bound = max_loop_count;
+
+ if ((current_itterations < lower_bound) || (current_itterations > upper_bound))
+ current_itterations = lower_bound;
+
+#ifdef DEBUG_1
+ /* Last loop count. */
+ last_loop_count = loop_count;
+#endif
+
+ /* Reset the loop count to all ones! */
+ loop_count = 0xFFFFFFFF;
+ }
+ count++;
+ for (i = 0; i < (count%32); i++)
+ destination++;
+
+ /* Determine if the ISR is in the mode to wakeup the thread suspending with a timeout. */
+ if (isr_test_suspend_interrupt)
+ {
+
+ /* Determine if the thread is suspended on the semaphore... */
+ if (thread_0.tx_thread_state == TX_SEMAPHORE_SUSP)
+ {
+
+ /* Determine if the test condition is present... */
+ if ((_tx_thread_preempt_disable) &&
+ (thread_0.tx_thread_timer.tx_timer_internal_list_head == TX_NULL))
+ {
+
+ /* Set the flag showing the condition is present. */
+ isr_test_suspend_interrupted_condition = TX_TRUE;
+
+ /* All done with the test. */
+ isr_test_suspend_interrupt = TX_FALSE;
+ }
+
+ /* Post to the semaphore to wakeup the thread. */
+ tx_semaphore_put(&test_semaphore);
+ }
+
+ return;
+ }
+#endif
+#endif
+
+ /* Increment the ISR count. */
+ isr_count++;
+
+ /* Call sleep from ISR to check for error! */
+ status = tx_thread_sleep(100);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+
+ error = 1;
+ }
+
+ /* End the ISR. */
+ test_isr_dispatch = TX_NULL;
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_sleep_for_100ticks_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, 3, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Sleep for 100 Ticks Test............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+#ifdef TEST_INTERRUPT_CONDITION
+#ifndef TX_NOT_INTERRUPTABLE
+
+ status = tx_semaphore_create(&test_semaphore, "test semaphore", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Sleep for 100 Ticks Test............................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ min_loop_count = 0xFFFFFFFF;
+ max_loop_count = 0;
+ loop_count = 0xFFFFFFFF;
+ current_itterations = 0;
+#ifdef DEBUG_1
+ last_loop_count = 0x0;
+#endif
+#endif
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+#ifdef TEST_INTERRUPT_CONDITION
+#ifndef TX_NOT_INTERRUPTABLE
+ULONG i;
+volatile ULONG value = 0;
+#endif
+#endif
+
+ /* Inform user. */
+ printf("Running Thread Sleep for 100 Ticks Test............................. ");
+
+ /* Call sleep with an expiration of 0 and test error code. */
+ status = tx_thread_sleep(0);
+
+ /* Check error code. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread Simple Sleep error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+#ifdef TEST_INTERRUPT_CONDITION
+#ifndef TX_NOT_INTERRUPTABLE
+
+
+ isr_test_suspend_interrupt = TX_TRUE;
+ isr_test_suspend_interrupted_condition = TX_FALSE;
+#endif
+#endif
+
+ /* Setup the test ISR. */
+ test_isr_dispatch = test_isr;
+
+#ifdef TEST_INTERRUPT_CONDITION
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Callibrate the loop count from thread sleep. */
+ for (i = 0; i < 180; i++)
+ {
+
+ /* Sleep to get a fresh time. */
+ tx_thread_sleep(1);
+
+ /* Set the loop count to 0 and start counting.... */
+ loop_count = 0;
+ start_time = _tx_timer_system_clock;
+ do
+ {
+
+ /* Call delay function. */
+ delay_function();
+ loop_count++;
+ } while (start_time == _tx_timer_system_clock);
+
+ /* Wait to reset the loop count. */
+ tx_thread_sleep(1);
+ }
+
+#if 1
+ /* Setup the lower and upper bounds. */
+ lower_bound = min_loop_count;
+ if (lower_bound > 5)
+ lower_bound = lower_bound - 5;
+ upper_bound = max_loop_count + 5;
+#else
+ /* Setup the lower and upper bounds. */
+ lower_bound = min_loop_count;
+ upper_bound = max_loop_count;
+#endif
+
+ current_itterations = lower_bound;
+#ifdef DEBUG
+ i = 0;
+#endif
+ while (isr_test_suspend_interrupted_condition != TX_TRUE)
+ {
+
+ /* Sleep to get a frest timer slot. */
+ tx_thread_sleep(1);
+
+ /* Loop to delay to next interrupt. */
+ loop_count = 0;
+ start_time = _tx_timer_system_clock;
+ do
+ {
+ /* Call delay function. */
+ delay_function();
+ loop_count++;
+ } while (loop_count < current_itterations);
+
+ /* Check for a timer interrupt... if so, just skip the semaphore get. */
+ if (start_time != _tx_timer_system_clock)
+ continue;
+
+ /* Suspend on the semaphore for 20 ticks... */
+ tx_semaphore_get(&test_semaphore, 20);
+
+ /* Adjust the current itterations. */
+ current_itterations++;
+ if (current_itterations > upper_bound)
+ {
+ if (lower_bound > min_loop_count)
+ lower_bound--;
+ if (upper_bound < max_loop_count)
+ upper_bound++;
+ current_itterations = lower_bound;
+ }
+
+ /* Set the tick count simply to use value. */
+ tx_time_set(value);
+#ifdef DEBUG
+ /* Debug block. */
+ i++;
+ if ((i % 180) == 0)
+ {
+ printf("*** update ***\n");
+ if (loop_count == 0xFFFFFFFF)
+ printf("loop count: NA\n");
+ else
+ printf("loop count: %lu\n", loop_count);
+ printf("current: %lu\n", current_itterations);
+ printf("last loop count: %lu\n", last_loop_count);
+ printf("minimum: %lu\n", min_loop_count);
+ printf("maximum: %lu\n", max_loop_count);
+ printf("lower bound: %lu\n", lower_bound);
+ printf("upper bound: %lu\n", upper_bound);
+ printf("count: %lu\n", i);
+ }
+#endif
+ }
+
+#ifdef DEBUG
+ /* Debug block */
+ printf("*** final ***\n");
+ if (loop_count == 0xFFFFFFFF)
+ printf("loop count: NA\n");
+ else
+ printf("loop count: %lu\n", loop_count);
+ printf("current: %lu\n", current_itterations);
+ printf("last loop count: %lu\n", last_loop_count);
+ printf("minimum: %lu\n", min_loop_count);
+ printf("maximum: %lu\n", max_loop_count);
+ printf("lower bound: %lu\n", lower_bound);
+ printf("upper bound: %lu\n", upper_bound);
+ printf("count: %lu\n", i);
+#endif
+
+ /* Clear the tick count. */
+ tx_time_set(0);
+
+ /* Sleep for 100 ticks. */
+ tx_thread_sleep(100);
+
+ /* Check for error. */
+ if (tx_time_get() < 100)
+ {
+
+ /* Thread Simple Sleep error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+#endif
+#endif
+
+ /* Clear the tick count. */
+ tx_time_set(0);
+
+
+ /* Sleep for 100 ticks. */
+ status = tx_thread_sleep(100);
+
+ /* Determine if the sleep was accurate. */
+ if ((status != TX_SUCCESS) || (tx_time_get() < 100) ||
+ (tx_time_get() > 101))
+ {
+
+ /* Thread Simple Sleep error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Check to make sure the ISR happened and the proper return value was present. */
+ if ((isr_count == 0) || (error))
+ {
+
+ /* Thread Simple Sleep error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful Simple Sleep test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
diff --git a/test/smp/regression/threadx_thread_sleep_terminate_test.c b/test/smp/regression/threadx_thread_sleep_terminate_test.c
new file mode 100644
index 00000000..871fc6e2
--- /dev/null
+++ b/test/smp/regression/threadx_thread_sleep_terminate_test.c
@@ -0,0 +1,187 @@
+/* This test is designed to test thread termination of a thread in a sleep condition. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static unsigned long thread_1_enter = 0;
+static unsigned long thread_1_exit = 0;
+static TX_THREAD thread_1;
+
+extern UINT _tx_thread_preempt_disable;
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+
+static void entry_exit_notify(TX_THREAD *thread_ptr, UINT type)
+{
+
+ /* Check for the appropriate thread. */
+ if (thread_ptr != &thread_1)
+ return;
+
+ /* Check for type. */
+ if (type == TX_THREAD_ENTRY)
+ thread_1_enter++;
+ else if (type == TX_THREAD_EXIT)
+ thread_1_exit++;
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_sleep_terminate_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend Terminate Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend Terminate Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Setup the notify call to test that logic. */
+ status += tx_thread_entry_exit_notify(&thread_1, entry_exit_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend Terminate Test............................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Thread Suspend Terminate Test............................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Thread Suspend Terminate Test............................... ");
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Sleep to allow lower-priority thread 1 to run. */
+ tx_thread_sleep(5);
+
+ /* Now terminate thread 1. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (_tx_thread_preempt_disable))
+ {
+
+ /* Terminate error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Now try to suspend a terminated thread. */
+ status = tx_thread_suspend(&thread_1);
+
+ /* Check status. */
+ if (status != TX_SUSPEND_ERROR)
+ {
+
+ /* Suspend error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Suspend thread 1. */
+ status = tx_thread_sleep(100);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+ thread_1_counter = 0; /* Make an error! */
+ return;
+ }
+ }
+}
+
+
diff --git a/test/smp/regression/threadx_thread_stack_checking_test.c b/test/smp/regression/threadx_thread_stack_checking_test.c
new file mode 100644
index 00000000..3ffe3841
--- /dev/null
+++ b/test/smp/regression/threadx_thread_stack_checking_test.c
@@ -0,0 +1,224 @@
+/* This test is for the thread stack checking services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Prototype for direct call. */
+
+VOID _tx_thread_stack_analyze(TX_THREAD *thread_ptr);
+
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static CHAR *thread_2_stack_start;
+static UINT stack_error = 0;
+
+
+/* Define task prototypes. */
+
+static void thread_0_entry(ULONG task_input);
+static void thread_1_entry(ULONG task_input);
+static void thread_2_entry(ULONG task_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the stack checking error handler. */
+
+void stack_error_handler(TX_THREAD *thread_ptr)
+{
+
+ /* Check for the right thread. */
+ if (thread_ptr == &thread_2)
+ stack_error = 1;
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_stack_checking_application_define(void *first_unused_memory)
+#endif
+{
+
+INT status;
+CHAR *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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Stack Checking Test.................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Stack Checking Test.................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, TX_NO_TIME_SLICE, TX_DONT_START);
+ thread_2_stack_start = pointer;
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Stack Checking Test.................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Register the stack checking handler. */
+ status = tx_thread_stack_error_notify(stack_error_handler);
+
+#ifdef TX_ENABLE_STACK_CHECKING
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+#else
+ if (status != TX_FEATURE_NOT_ENABLED)
+#endif
+
+ {
+
+ printf("Running Thread Stack Checking Test.................................. ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Inform user of success getting to this test. */
+ printf("Running Thread Stack Checking Test.................................. ");
+
+ /* Resume thread 1 to get the stack checking to take place. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Suspend to allow thread 1 to run. */
+ tx_thread_suspend(&thread_0);
+
+ /* Terminate thread 1. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check error code. */
+#ifdef TX_ENABLE_STACK_CHECKING
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) || (stack_error != 1))
+#else
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) || (stack_error != 0))
+#endif
+ {
+
+ /* Thread error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Success! */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+TX_THREAD fake_thread;
+
+ /* Call stack analyze with a NULL pointer. */
+ _tx_thread_stack_analyze(TX_NULL);
+
+ /* Call the stack analyze with a fake stack just to test that path. */
+ fake_thread.tx_thread_id = 0;
+ _tx_thread_stack_analyze(&fake_thread);
+
+ /* Call the stack analyze with a NULL stack pointer. */
+ fake_thread.tx_thread_id = ((ULONG) 0x54485244);
+ fake_thread.tx_thread_stack_start = TX_NULL;
+ _tx_thread_stack_analyze(&fake_thread);
+
+ /* Call the stack analyze with a NULL highest stack pointer. */
+ fake_thread.tx_thread_id = ((ULONG) 0x54485244);
+ fake_thread.tx_thread_stack_start = (void *) 0x1000;
+ fake_thread.tx_thread_stack_highest_ptr = TX_NULL;
+ _tx_thread_stack_analyze(&fake_thread);
+
+ /* Clear the pattern in thread 2's stack. */
+ TX_MEMSET(thread_2_stack_start, (CHAR) 0x11, TEST_STACK_SIZE_PRINTF);
+
+ /* Resume thread 2, which should cause the stack error to occur. */
+ tx_thread_resume(&thread_2);
+
+ /* Suspend thread 2. */
+ tx_thread_suspend(&thread_2);
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Now, deregister the stack error handler and get into a spin condition. We will then
+ want to terminate thread 1 from thread 0 when it awakes! */
+ tx_thread_stack_error_notify(TX_NULL);
+
+ /* Now resume thread 2 again to cause the stack error! */
+ tx_thread_resume(&thread_2);
+
+ /* Now suspend thread 2 again. */
+ tx_thread_suspend(&thread_2);
+
+ /* Resume thread 0. */
+ tx_thread_resume(&thread_0);
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Increment thread 1 counter. */
+ thread_2_counter++;
+}
diff --git a/test/smp/regression/threadx_thread_terminate_delete_test.c b/test/smp/regression/threadx_thread_terminate_delete_test.c
new file mode 100644
index 00000000..dbe919f3
--- /dev/null
+++ b/test/smp/regression/threadx_thread_terminate_delete_test.c
@@ -0,0 +1,341 @@
+/* This test is designed to test thread terminate (self, and other), thread delete,
+ and thread identify services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static unsigned long thread_1_enter = 0;
+static unsigned long thread_1_exit = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_THREAD thread_3;
+static unsigned long thread_3_enter = 0;
+static unsigned long thread_3_exit = 0;
+
+
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void entry_exit_notify(TX_THREAD *thread_ptr, UINT type)
+{
+
+ /* Check for the appropriate thread. */
+ if (thread_ptr != &thread_1)
+ return;
+
+ /* Check for type. */
+ if (type == TX_THREAD_ENTRY)
+ thread_1_enter++;
+ else if (type == TX_THREAD_EXIT)
+ thread_1_exit++;
+}
+
+
+static void entry_exit_notify3(TX_THREAD *thread_ptr, UINT type)
+{
+
+ /* Check for the appropriate thread. */
+ if (thread_ptr != &thread_3)
+ return;
+
+ /* Check for type. */
+ if (type == TX_THREAD_ENTRY)
+ thread_3_enter++;
+ else if (type == TX_THREAD_EXIT)
+ thread_3_exit++;
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_terminate_delete_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Setup the notify call to test that logic. */
+ status = tx_thread_entry_exit_notify(&thread_1, entry_exit_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+
+#endif
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 12, 12, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Setup the notify call to test that logic. */
+ status = tx_thread_entry_exit_notify(&thread_3, entry_exit_notify3);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #7\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #8\n");
+ test_control_return(1);
+ }
+
+#endif
+
+
+ /* Create a semaphore for thread 3 to suspend on. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #9\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Thread Terminate and Delete Test............................ ");
+
+ /* Let other threads execute. */
+ tx_thread_relinquish();
+
+ /* Make sure thread 1 is terminated and thread 2 is suspended. */
+ if ((thread_1.tx_thread_state != TX_TERMINATED) ||
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+ (thread_1_enter != 1) || (thread_1_exit != 1) ||
+#else
+ (thread_1_enter != 0) || (thread_1_exit != 0) ||
+#endif
+ (thread_2.tx_thread_state != TX_SUSPENDED))
+ {
+
+ /* Thread error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* At this point, terminate thread 2 which should be in a suspended state
+ right now. */
+ status = tx_thread_terminate(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Delete thread 1 (thread 1 alread terminated) and 2. */
+ status = tx_thread_delete(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_delete(&thread_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* At this point, terminate thread 3 which should be in a suspended state
+ on the semaphore right now. */
+ status = tx_thread_terminate(&thread_3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Delete thread 3. */
+ status = tx_thread_delete(&thread_3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Test identity. */
+ if (tx_thread_identify() != &thread_1)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Terminate self. */
+ tx_thread_terminate(&thread_1);
+}
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Test identity. */
+ if (tx_thread_identify() != &thread_2)
+ return;
+
+ /* Increment thread counter. */
+ thread_2_counter++;
+
+ /* Suspend thread. */
+ tx_thread_suspend(&thread_2);
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+ /* Get the semaphore with wait forever! */
+ tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Increment thread counter. */
+ thread_2_counter++;
+}
+
diff --git a/test/smp/regression/threadx_thread_time_slice_change_test.c b/test/smp/regression/threadx_thread_time_slice_change_test.c
new file mode 100644
index 00000000..8ee7df3b
--- /dev/null
+++ b/test/smp/regression/threadx_thread_time_slice_change_test.c
@@ -0,0 +1,149 @@
+/* This test is designed to test the change time-slice service call. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+extern unsigned long _tx_timer_time_slice;
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_thread_time_slice_change_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 Thread Time-Slice Change Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 22, 22, 200, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Time-Slice Change Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG old_time_slice = 0;
+
+
+ /* Inform user. */
+ printf("Running Thread Time-Slice Change Test............................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Change the time-slice of other thread. */
+ status = tx_thread_time_slice_change(&thread_1, 33, &old_time_slice);
+
+ /* Check status and the time sice of specified thread. */
+ if ((status != TX_SUCCESS) || (old_time_slice != 200) || (thread_1.tx_thread_new_time_slice != 33))
+ {
+
+ /* Thread error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Sleep to get a fresh timer. */
+ tx_thread_sleep(1);
+
+ /* Change the time-slice of this thread. */
+ status = tx_thread_time_slice_change(&thread_0, 66, &old_time_slice);
+
+ /* Check status and the time sice of specified thread. */
+ if ((status != TX_SUCCESS) || (old_time_slice != 100) || (thread_0.tx_thread_new_time_slice != 66) ||
+ (_tx_timer_time_slice != 66))
+ {
+
+ /* Thread error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Change the time-slice of this thread. */
+ status = tx_thread_time_slice_change(&thread_1, 2, &old_time_slice);
+
+ /* Sleep for 8 ticks just to allow thread 1 to run and time-slice with no other thread ready. */
+ tx_thread_sleep(8);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* Identify. */
+ tx_thread_identify();
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
diff --git a/test/smp/regression/threadx_thread_wait_abort_and_isr_test.c b/test/smp/regression/threadx_thread_wait_abort_and_isr_test.c
new file mode 100644
index 00000000..073151ac
--- /dev/null
+++ b/test/smp/regression/threadx_thread_wait_abort_and_isr_test.c
@@ -0,0 +1,272 @@
+/* This test is designed to test for simultaneous thread suspension lifting AND thread wait abort calls. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_timer.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+
+static unsigned long semaphore_put_counter = 0;
+static unsigned long condition_count = 0;
+
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void timer_0_entry(ULONG timer_input);
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void isr_entry(void)
+{
+
+UINT status;
+static volatile UINT miss_count = 0;
+
+
+ /* Attempt to sleep from a timer in order to test the error logic. */
+ status = tx_thread_sleep(1);
+
+ /* Check for proper error status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Blow up the test to force an error. */
+ condition_count = 10000000;
+ semaphore_put_counter = 0xFFFF0000;
+ }
+
+ /* Determine if the interrupt occurred when the preempt disable flag was set. */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* Yes this is the condition we are looking for, increment the test condition counter. */
+ condition_count++;
+ }
+
+ /*
+ It is possible for this test to get into a resonance condition in which
+ the ISR never occurs while preemption is disabled (especially if the
+ ISR is installed in the periodic timer interrupt handler, which is
+ conveniently available). Detect this condition and break out of it by
+ perturbing the duration of this ISR a pseudo-random amount of time.
+ */
+ else if (++miss_count > 100)
+ for (miss_count = _tx_timer_system_clock % 100; miss_count != 0; --miss_count);
+
+ /* Put the semaphore to wakeup thread 0. */
+ status = tx_semaphore_put(&semaphore_0);
+
+ /* Increment the semaphore counter. */
+ if (status == TX_SUCCESS)
+ semaphore_put_counter++;
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_wait_abort_and_isr_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Wait Abort and ISR Resume Test....................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Wait Abort and ISR Resume Test....................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create semaphore - consumer producer semaphore. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Wait Abort and ISR Resume Test....................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a timer to ensure a context save is called for every interrupt. */
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Wait Abort and ISR Resume Test....................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Clear the condition count variable. */
+ condition_count = 0;
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Setup ISR for this test. */
+ test_isr_dispatch = isr_entry;
+
+ /* Inform user. */
+ printf("Running Thread Wait Abort and ISR Resume Test....................... ");
+
+ /* Loop to exploit the probability window inside tx_thread_wait_abort. */
+ while (condition_count < 20)
+ {
+
+ /* Suspend on the semaphore that is going to be set via the ISR. */
+ status = tx_semaphore_get(&semaphore_0, (thread_0_counter % 5) + 1);
+
+ /* Determine if we have an unexpected result. */
+ if ((status != TX_SUCCESS) && (status != TX_WAIT_ABORTED))
+ {
+
+ /* Test error! */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Check for the preempt disable flag being set. */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* Test error! */
+ printf("ERROR #6\n");
+ test_control_return(2);
+ }
+
+ /* Determine if we really got the semaphore. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment the thread count. */
+ thread_0_counter++;
+
+#ifdef TX_NOT_INTERRUPTABLE
+
+ /* Determine if we have a non-interruptable build of ThreadX. If so, just
+ get out of this loop after 100 passes. */
+
+ if (thread_0_counter >= 100)
+ break;
+#endif
+
+ }
+ }
+
+ /* Clear ISR dispatch. */
+ test_isr_dispatch = TX_NULL;
+
+#ifdef TX_NOT_INTERRUPTABLE
+ /* At this point, check to see if we got all the semaphores! */
+ if ((thread_0_counter != (semaphore_put_counter - semaphore_0.tx_semaphore_count)) ||
+ (condition_count != 0))
+#else
+ /* At this point, check to see if we got all the semaphores! */
+ if (thread_0_counter != (semaphore_put_counter - semaphore_0.tx_semaphore_count))
+#endif
+ {
+
+ /* Test error! */
+ printf("ERROR #7\n");
+ test_control_return(3);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Abort the suspension on the semaphore in thread 0. */
+ tx_thread_wait_abort(&thread_0);
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Let thread 0 run again! */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void timer_0_entry(ULONG input)
+{
+ timer_0_counter++;
+}
+
diff --git a/test/smp/regression/threadx_thread_wait_abort_test.c b/test/smp/regression/threadx_thread_wait_abort_test.c
new file mode 100644
index 00000000..a2e8e42d
--- /dev/null
+++ b/test/smp/regression/threadx_thread_wait_abort_test.c
@@ -0,0 +1,138 @@
+/* This test is designed to test thread wait abort. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_thread_wait_abort_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Wait Abort Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Wait Abort Test...................................... ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Thread Wait Abort Test...................................... ");
+
+ /* Let other thread run. */
+ tx_thread_resume(&thread_1);
+
+ /* Make sure thread 1 is sleeping. */
+ if (thread_1.tx_thread_state != TX_SLEEP)
+ {
+
+ /* Thread error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* At this point, call tx_thread_wait_abort to abort the sleep in thread1. */
+ status = tx_thread_wait_abort(&thread_1);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_SUSPENDED))
+ {
+
+ /* Thread error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Sleep for a long long time. */
+ status = tx_thread_sleep(1000000000);
+
+ /* Check for the proper status. */
+ if (status != TX_WAIT_ABORTED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Suspend self. */
+ tx_thread_suspend(&thread_1);
+}
+
diff --git a/test/smp/regression/threadx_time_get_set_test.c b/test/smp/regression/threadx_time_get_set_test.c
new file mode 100644
index 00000000..486294e9
--- /dev/null
+++ b/test/smp/regression/threadx_time_get_set_test.c
@@ -0,0 +1,109 @@
+/* This test is designed to test simple tx_time_get and set services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_timer.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_time_get_set_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Time Simple Get/Set Test.................................... ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ULONG current_time;
+
+
+ /* Inform user. */
+ printf("Running Time Simple Get/Set Test.................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Sleep for 1 tick to get a fresh timer. */
+ tx_thread_sleep(1);
+
+ /* Set time to 0. */
+ tx_time_set(0);
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(35);
+
+ /* Pickup the current time. */
+ /* Call internal function to cover this function. */
+ current_time = _tx_time_get();
+
+ /* Check Current time. It should be 35. */
+ if (current_time != 35)
+ {
+
+ /* System time error. */
+ printf("ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Set the new time. */
+ tx_time_set(7);
+
+ /* Check the new time. */
+ if (tx_time_get() != 7)
+ {
+
+ /* System time error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful time test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
diff --git a/test/smp/regression/threadx_timer_activate_deactivate_test.c b/test/smp/regression/threadx_timer_activate_deactivate_test.c
new file mode 100644
index 00000000..a238ea33
--- /dev/null
+++ b/test/smp/regression/threadx_timer_activate_deactivate_test.c
@@ -0,0 +1,268 @@
+/* This test is designed to test application timer activation/deactivation services
+ from threads and the activation routines. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_timer.h"
+
+
+static TX_THREAD thread_0;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+static TX_TIMER_INTERNAL test_timer;
+static TX_TIMER_INTERNAL *list_head;
+static TX_TIMER test_app_timer;
+
+static TX_TIMER timer_2;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_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_timer_activate_deactivate_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Activate/Deactivate Test.............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 13, 23, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Activate/Deactivate Test.............................. ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
+VOID _tx_timer_system_activate(TX_TIMER_INTERNAL *timer_ptr);
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+TX_TIMER_INTERNAL **current_list_head;
+
+
+ /* Inform user. */
+ printf("Running Timer Activate/Deactivate Test.............................. ");
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+
+ /* Call the timer thread entry function with an invalid value to make sure the code simply returns. */
+ _tx_timer_thread_entry(0);
+#endif
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+
+ tx_thread_resume(&_tx_timer_thread);
+#endif
+
+ /* Call the internal timer activate function with 0 remaining time. */
+ test_timer.tx_timer_internal_remaining_ticks = 0;
+ _tx_timer_system_activate(&test_timer);
+
+ /* Call the internal timer activate function with an existing head pointer. */
+ test_timer.tx_timer_internal_remaining_ticks = 1;
+ list_head = TX_NULL;
+ test_timer.tx_timer_internal_list_head = &list_head;
+ _tx_timer_system_activate(&test_timer);
+
+ /* Call the internal timer deactivate function to ensure the list head is not updated unless valid. */
+ list_head = TX_NULL;
+ test_timer.tx_timer_internal_list_head = &list_head;
+ test_timer.tx_timer_internal_active_next = &test_timer;
+ _tx_timer_system_deactivate(&test_timer);
+
+ /* Call timer info get with a timer setup to exercise a path not possible, in order to exercise all
+ conditionals. */
+ test_app_timer.tx_timer_internal.tx_timer_internal_list_head = (_tx_timer_list_end + 1);
+ status = _tx_timer_info_get(&test_app_timer, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Deactivate and activate the timer. */
+ test_app_timer.tx_timer_internal.tx_timer_internal_active_next = &test_app_timer.tx_timer_internal;
+ status += _tx_timer_deactivate(&test_app_timer);
+
+ /* Change timer with a non-NULL list head, to cause processing to be skipped. */
+ test_app_timer.tx_timer_internal.tx_timer_internal_list_head = (_tx_timer_list_end + 1);
+ status += _tx_timer_change(&test_app_timer, 0, 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to activate the same timer again. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_ACTIVATE_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for a 14 ticks. */
+ tx_thread_sleep(14);
+
+ /* At this point the initial expiration of the timer should have
+ happened. */
+ if (timer_0_counter != 1)
+ {
+
+ /* Application timer activate/deactivate error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for the reschedule time to make sure the timer doesn't hit
+ again! */
+ tx_thread_sleep(24);
+
+ /* At this point the timer counter should still be 1. */
+ if (timer_0_counter != 1)
+ {
+
+ /* Application timer activate/deactivate error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Clear timer 0's counter. */
+ timer_0_counter = 0;
+
+ /* Activate the timer. This should use the reschedule time. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Test timer that is in the process of expiration - on temporary "expired" list. */
+ TX_MEMSET(&timer_2, 0, (sizeof(TX_TIMER)));
+
+ /* Setup fake timer and test for reactivate condition - current timer. */
+ timer_2.tx_timer_id = TX_TIMER_ID;
+ timer_2.tx_timer_internal.tx_timer_internal_list_head = (TX_TIMER_INTERNAL **) &current_list_head;
+ current_list_head = (struct TX_TIMER_INTERNAL_STRUCT **) &(timer_2.tx_timer_internal);
+ timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = TX_TIMER_ENTRIES*2;
+ timer_2.tx_timer_internal.tx_timer_internal_active_next = &(timer_2.tx_timer_internal);
+ status = tx_timer_deactivate(&timer_2);
+
+ /* Check for error. */
+ if ((status != TX_SUCCESS) || (timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks != TX_TIMER_ENTRIES))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8a\n");
+ test_control_return(1);
+ }
+
+
+ /* Sleep for twice the expiration time to make sure the timer
+ doesn't automatically reschedule. */
+ tx_thread_sleep(47);
+
+ /* Check for an error. */
+
+ /* At this point the timer counter should still be 1. */
+ if (timer_0_counter != 1)
+ {
+
+ /* Application timer activate/deactivate error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Application Timer test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+UINT status;
+
+
+ /* Attempt to sleep from a timer in order to test the error logic. */
+ status = tx_thread_sleep(1);
+
+ /* Check for proper error status. */
+ if (status == TX_CALLER_ERROR)
+ {
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+
+ /* Deactivate the timer from the expiration routine. */
+ tx_timer_deactivate(&timer_0);
+ }
+}
+
+
diff --git a/test/smp/regression/threadx_timer_deactivate_accuracy_test.c b/test/smp/regression/threadx_timer_deactivate_accuracy_test.c
new file mode 100644
index 00000000..6af4bde4
--- /dev/null
+++ b/test/smp/regression/threadx_timer_deactivate_accuracy_test.c
@@ -0,0 +1,286 @@
+/* This test is designed to test application timer activation/deactivation services
+ from threads... Make sure the remaining ticks are being saved/restored properly. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long expected_time;
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_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_timer_deactivate_accuracy_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Activation/Deactivation Accuracy Test................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 29, 31, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Activation/Deactivation Accuracy Test................. ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Timer Activation/Deactivation Accuracy Test................. ");
+
+ /* Sleep so we have to handle the wrap condition. */
+ tx_thread_sleep(10);
+
+ /* Activate the timer. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(2);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(3);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(4);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(5);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(6);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(7);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) || (timer_0_counter))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(2);
+
+ /* At this point the timer should have ran! */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) || (timer_0_counter != 1))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful Re-activate test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+}
+
diff --git a/test/smp/regression/threadx_timer_information_test.c b/test/smp/regression/threadx_timer_information_test.c
new file mode 100644
index 00000000..4dbc3c9b
--- /dev/null
+++ b/test/smp/regression/threadx_timer_information_test.c
@@ -0,0 +1,538 @@
+/* This test is designed to test timer information services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_timer.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+static unsigned long timer_1_counter = 0;
+static TX_TIMER timer_1;
+
+
+static TX_TIMER timer_2;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_input);
+static void timer_1_expiration(ULONG timer_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_timer_information_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Information Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Information Test...................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234,
+ 1000, 1000, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Information Test...................................... ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+UINT interrupt_status;
+CHAR *name;
+UINT active;
+ULONG remaining_ticks;
+ULONG reschedule_ticks;
+TX_TIMER *next_timer;
+ULONG activates;
+ULONG reactivates;
+ULONG deactivates;
+ULONG expirations;
+ULONG expiration_adjusts;
+TX_TIMER_INTERNAL **list_head;
+
+
+ /* Inform user. */
+ printf("Running Timer Information Test...................................... ");
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(19);
+
+ /* Check for an error. */
+ if (timer_0_counter != 2)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Deactivate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Sleep again. */
+ tx_thread_sleep(19);
+
+ /* Check for an error. */
+ if (timer_0_counter != 2)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Modify the timer. */
+ status = tx_timer_change(&timer_0, 100, 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Clear the system time. */
+ tx_time_set(0);
+
+ /* Activate the timer. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for 120. */
+ tx_thread_sleep(120);
+
+ /* Check the counters to make sure everything is where it should be. */
+ if ((timer_0_counter != 23) || (tx_time_get() != 120))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Get the timer information. */
+ status = tx_timer_info_get(&timer_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &next_timer);
+ status += tx_timer_info_get(&timer_0, &name, &active, &remaining_ticks, &reschedule_ticks, &next_timer);
+
+ /* Check for successful completion. */
+ if ((status != TX_SUCCESS) || (active != TX_TRUE) || (remaining_ticks != 1) || (reschedule_ticks != 1) || (next_timer != &timer_1))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Now, deactivate timer 0 to get another path through the info get service. */
+ status = tx_timer_deactivate(&timer_0);
+ status += tx_timer_info_get(&timer_0, &name, &active, &remaining_ticks, &reschedule_ticks, &next_timer);
+
+ /* Check for successful completion. */
+ if ((status != TX_SUCCESS) || (active != TX_FALSE) || (remaining_ticks != 1) || (reschedule_ticks != 1) || (next_timer != &timer_1))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Change timer 0 to a large value and get the information again. */
+ status = tx_timer_change(&timer_0, 100, 200);
+ status += tx_timer_activate(&timer_0);
+
+ status += tx_timer_info_get(&timer_0, &name, &active, &remaining_ticks, &reschedule_ticks, &next_timer);
+
+ /* Check for successful completion. */
+ if ((status != TX_SUCCESS) || (active != TX_TRUE) || (remaining_ticks != 100) || (reschedule_ticks != 200) || (next_timer != &timer_1))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+#ifdef TX_TIMER_ENABLE_PERFORMANCE_INFO
+
+ /* Check for NULL pointer. */
+ status = _tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(&timer_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_timer_performance_info_get(&timer_0, &activates, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for successful completion. */
+ if ((status != TX_SUCCESS) || (activates != timer_0.tx_timer_performance_activate_count) || (reactivates != timer_0.tx_timer_performance_reactivate_count) ||
+ (deactivates != timer_0.tx_timer_performance_deactivate_count) || (expirations != timer_0.tx_timer_performance_expiration_count) || (expiration_adjusts != timer_0.tx_timer_performance__expiration_adjust_count))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_timer_performance_system_info_get(&activates, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for successful completion. */
+ if ((status != TX_SUCCESS) || (activates != _tx_timer_performance_activate_count) || (reactivates != _tx_timer_performance_reactivate_count) ||
+ (deactivates != _tx_timer_performance_deactivate_count) || (expirations != _tx_timer_performance_expiration_count) || (expiration_adjusts != _tx_timer_performance__expiration_adjust_count))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(&timer_0, &activates, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(TX_NULL, &activates, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(TX_NULL, TX_NULL, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(&activates, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(TX_NULL, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Test timer that is in the process of expiration - on temporary "expired" list. */
+ TX_MEMSET(&timer_2, 0, (sizeof(TX_TIMER)));
+
+ /* Setup fake timer and test for no-reactivate condition. */
+ timer_2.tx_timer_id = TX_TIMER_ID;
+ timer_2.tx_timer_internal.tx_timer_internal_list_head = (TX_TIMER_INTERNAL **) &list_head;
+ list_head = (struct TX_TIMER_INTERNAL_STRUCT **) &(timer_2.tx_timer_internal);
+ timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = 10;
+ status = tx_timer_info_get(&timer_2, TX_NULL, TX_NULL, &remaining_ticks, &reschedule_ticks, TX_NULL);
+
+ /* Check for error. */
+ if ((status != TX_SUCCESS) || (remaining_ticks != 0) || (reschedule_ticks != 0))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #28a\n");
+ test_control_return(1);
+ }
+
+ /* Setup fake timer and test for reactivate condition - on temporary "expired" list. */
+ timer_2.tx_timer_id = TX_TIMER_ID;
+ timer_2.tx_timer_internal.tx_timer_internal_list_head = (TX_TIMER_INTERNAL **) &list_head;
+ list_head = (struct TX_TIMER_INTERNAL_STRUCT **) &(timer_2.tx_timer_internal);
+ timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = TX_TIMER_ENTRIES * 2;
+ status = tx_timer_info_get(&timer_2, TX_NULL, TX_NULL, &remaining_ticks, &reschedule_ticks, TX_NULL);
+
+ /* Check for error. */
+ if ((status != TX_SUCCESS) || (remaining_ticks != TX_TIMER_ENTRIES) || (reschedule_ticks != 0))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #28a\n");
+ test_control_return(1);
+ }
+
+
+ /* Lockout interrupts. */
+ interrupt_status = tx_interrupt_control(TX_INT_DISABLE);
+
+ /* Setup fake timer and test for reactivate condition - current timer. */
+ timer_2.tx_timer_id = TX_TIMER_ID;
+ timer_2.tx_timer_internal.tx_timer_internal_list_head = (TX_TIMER_INTERNAL **) &list_head;
+ list_head = (struct TX_TIMER_INTERNAL_STRUCT **) &(timer_2.tx_timer_internal);
+ timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = 13;
+ _tx_timer_expired_timer_ptr = &timer_2.tx_timer_internal;
+ status = tx_timer_info_get(&timer_2, TX_NULL, TX_NULL, &remaining_ticks, &reschedule_ticks, TX_NULL);
+ _tx_timer_expired_timer_ptr = TX_NULL;
+
+ /* Restore interrupts. */
+ tx_interrupt_control(interrupt_status);
+
+ /* Check for error. */
+ if ((status != TX_SUCCESS) || (remaining_ticks != 0) || (reschedule_ticks != 0))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #28b\n");
+ test_control_return(1);
+ }
+
+
+ /* Delete the timer... that are currently active and on the same expiration
+ list! */
+ status = tx_timer_deactivate(&timer_0);
+ status += tx_timer_deactivate(&timer_1);
+ status += tx_timer_change(&timer_0, 100, 200);
+ status += tx_timer_change(&timer_1, 100, 200);
+ status += tx_timer_activate(&timer_0);
+ status += tx_timer_activate(&timer_1);
+ status += tx_timer_delete(&timer_0);
+ status += tx_timer_delete(&timer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful Multiple Sleep test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+}
+
+
+static void timer_1_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_1_counter++;
+}
diff --git a/test/smp/regression/threadx_timer_large_timer_accuracy_test.c b/test/smp/regression/threadx_timer_large_timer_accuracy_test.c
new file mode 100644
index 00000000..dde97fe4
--- /dev/null
+++ b/test/smp/regression/threadx_timer_large_timer_accuracy_test.c
@@ -0,0 +1,286 @@
+/* This test is designed to test application timer activation/deactivation services
+ from threads... To make sure large timer expirations are being saved/restored properly. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long expected_time;
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_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_timer_large_timer_accuracy_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Large Timer Activate Accuracy Test.................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 100, 31, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Large Timer Activate Accuracy Test.................... ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Timer Large Timer Activate Accuracy Test.................... ");
+
+ /* Sleep so we have to handle the wrap condition. */
+ tx_thread_sleep(10);
+
+ /* Activate the timer. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(20);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(35);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(2);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(1);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(2);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(5);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) || (timer_0_counter))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(35);
+
+ /* At this point the timer should have ran! */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) || (timer_0_counter != 1))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful Re-activate test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+}
+
diff --git a/test/smp/regression/threadx_timer_multiple_accuracy_test.c b/test/smp/regression/threadx_timer_multiple_accuracy_test.c
new file mode 100644
index 00000000..a7be91e2
--- /dev/null
+++ b/test/smp/regression/threadx_timer_multiple_accuracy_test.c
@@ -0,0 +1,186 @@
+/* This test is designed to test the accuracy of three free running timers. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+static unsigned long timer_1_counter = 0;
+static TX_TIMER timer_1;
+static unsigned long timer_2_counter = 0;
+static TX_TIMER timer_2;
+
+
+/* Define prototypes. */
+static void thread_0_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_input);
+static void timer_1_expiration(ULONG timer_input);
+static void timer_2_expiration(ULONG timer_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_timer_multiple_accuracy_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Accuracy Test.......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 1, 1, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Accuracy Test.......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234,
+ 2, 2, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Accuracy Test.......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_2, "timer 2", timer_2_expiration, 0x1234,
+ 3, 3, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Accuracy Test.......................... ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Timer Multiple Timer Accuracy Test.......................... ");
+
+ /* Sleep to get a fresh timer. */
+ tx_thread_sleep(1);
+
+ /* Activate all the timers. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for a some ticks. */
+ tx_thread_sleep(300);
+
+ /* Insure that each timer ran twice. */
+ if ((timer_0_counter != 300) || (timer_1_counter != 150) ||
+ (timer_2_counter != 100))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful timer test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+}
+
+static void timer_1_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_1_counter++;
+}
+
+static void timer_2_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_2_counter++;
+}
+
diff --git a/test/smp/regression/threadx_timer_multiple_test.c b/test/smp/regression/threadx_timer_multiple_test.c
new file mode 100644
index 00000000..3f02d5a7
--- /dev/null
+++ b/test/smp/regression/threadx_timer_multiple_test.c
@@ -0,0 +1,349 @@
+/* This test is designed to test a simple application timer services,
+ including create, activate, deactivate, change, and delete with multiple timers. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+static unsigned long timer_1_counter = 0;
+static TX_TIMER timer_1;
+static unsigned long timer_2_counter = 0;
+static TX_TIMER timer_2;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_input);
+static void timer_1_expiration(ULONG timer_input);
+static void timer_2_expiration(ULONG timer_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_timer_multiple_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Test................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 100, 200, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Test................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234,
+ 100, 200, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Test................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_2, "timer 2", timer_2_expiration, 0x1234,
+ 100, 200, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Test................................... ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Timer Multiple Timer Test................................... ");
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(301);
+
+ /* Insure that each timer ran twice. */
+ if ((timer_0_counter != 2) || (timer_1_counter != 2) ||
+ (timer_2_counter != 2))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Deactivate the timers. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_deactivate(&timer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_deactivate(&timer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Sleep again. */
+ tx_thread_sleep(100);
+
+ /* Insure that each timer haven't run again. */
+ if ((timer_0_counter != 2) || (timer_1_counter != 2) ||
+ (timer_2_counter != 2))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Modify the timer. */
+ status = tx_timer_change(&timer_0, 100, 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_change(&timer_1, 100, 2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_change(&timer_2, 100, 3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Activate the timer. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for 200. */
+ tx_thread_sleep(200);
+
+ /* Insure that each timer haven't run again. */
+ if ((timer_0_counter != 103) || (timer_1_counter != 53) ||
+ (timer_2_counter != 36))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Deactivate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_deactivate(&timer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_deactivate(&timer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Delete the timer. */
+ status = tx_timer_delete(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_delete(&timer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_delete(&timer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Successful Multiple timer test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+}
+
+static void timer_1_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_1_counter++;
+}
+
+static void timer_2_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_2_counter++;
+}
+
diff --git a/test/smp/regression/threadx_timer_simple_test.c b/test/smp/regression/threadx_timer_simple_test.c
new file mode 100644
index 00000000..ec3ff235
--- /dev/null
+++ b/test/smp/regression/threadx_timer_simple_test.c
@@ -0,0 +1,830 @@
+/* This test is designed to test a simple application timer services, including create,
+ activate, deactivate, change, and delete. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_timer.h"
+
+typedef struct TIMER_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_TIMER timer;
+ ULONG next_to_last;
+ ULONG last;
+
+} TIMER_MEMORY_TEST;
+
+static TIMER_MEMORY_TEST timer_memory;
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define external reference to status from timer create during initialization. */
+
+extern UINT test_timer_create_init;
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+static unsigned long timer_1_counter = 0;
+static TX_TIMER timer_1;
+
+static TX_TIMER timer_2;
+static TX_TIMER timer_3;
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_input);
+static void timer_1_expiration(ULONG timer_input);
+
+UINT _txe_timer_create(TX_TIMER *timer_ptr, CHAR *name_ptr,
+ VOID (*expiration_function)(ULONG), ULONG expiration_input,
+ ULONG initial_ticks, ULONG reschedule_ticks, UINT auto_activate, UINT timer_control_block_size);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+
+
+ /* Determine if the timer was able to be created durning initialization. */
+ if (test_timer_create_init != TX_SUCCESS)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a timer from a timer. */
+ status = tx_timer_delete(&timer_0);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a timer from a timer. */
+ status = tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+ /* Just to test another path, set this timer expired variable. */
+ if (timer_executed == 0)
+ _tx_timer_expired = 1;
+#endif
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+
+ /* Attempt to delete a timer from an ISR. */
+ status = tx_timer_delete(&timer_0);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a timer from an ISR. */
+ status = tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_timer_simple_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 3, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Simple Test........................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Simple Test........................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234,
+ 1000, 1000, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Simple Test........................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+
+ /* Call the timer thread entry function with a bad ID to test another path. */
+ _tx_timer_thread_entry(0);
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT tx_interrupt_save;
+UINT status;
+ULONG exclusion_map;
+
+
+ /* Inform user. */
+ printf("Running Timer Simple Test........................................... ");
+
+ /* Perform timer memory test. */
+ timer_memory.first = 0x11223344;
+ timer_memory.second = 0x55667788;
+ timer_memory.next_to_last = 0x99aabbcc;
+ timer_memory.last = 0xddeeff00;
+
+ /* Create the timer. */
+ status = tx_timer_create(&timer_memory.timer, "timer memory", timer_0_expiration, 0x1234,
+ 1000000, 100000, TX_NO_ACTIVATE);
+ tx_timer_delete(&timer_memory.timer);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (timer_memory.first != 0x11223344) ||
+ (timer_memory.second != 0x55667788) ||
+ (timer_memory.next_to_last != 0x99aabbcc) ||
+ (timer_memory.last != 0xddeeff00))
+ {
+
+ /* Memory overwrite error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to activate a non-timer. */
+ status = tx_timer_activate(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to activate a non-created timer. */
+ timer_2.tx_timer_id = 0;
+ status = tx_timer_activate(&timer_2);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to activate a timer with a 0 expiration. */
+ timer_2.tx_timer_id = ((ULONG) 0x4154494D);
+ timer_2.tx_timer_internal.tx_timer_internal_list_head = TX_NULL;
+ timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = 0;
+ status = tx_timer_activate(&timer_2);
+
+ /* Check status. */
+ if (status != TX_ACTIVATE_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+
+ /* Attempt to activate a timer with a wait forever expiration. */
+ timer_2.tx_timer_id = ((ULONG) 0x4154494D);
+ timer_2.tx_timer_internal.tx_timer_internal_list_head = TX_NULL;
+ timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = TX_WAIT_FOREVER;
+ status = tx_timer_activate(&timer_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ timer_2.tx_timer_id = 0;
+
+ /* Attempt to deactivate a non-timer. */
+ status = tx_timer_deactivate(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to deactivate a non-created timer. */
+ timer_2.tx_timer_id = 0;
+ status = tx_timer_deactivate(&timer_2);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change a non-timer. */
+ status = tx_timer_change(TX_NULL, 1, 1);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change a non-created timer. */
+ timer_2.tx_timer_id = 0;
+ status = tx_timer_change(&timer_2, 1, 1);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change a timer with a 0 initial ticks. */
+ status = tx_timer_change(&timer_0, 0, 1);
+
+ /* Check status. */
+ if (status != TX_TICK_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-time. */
+ status = tx_timer_delete(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-created time. */
+ timer_2.tx_timer_id = 0;
+ status = tx_timer_delete(&timer_2);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get info from a non-timer. */
+ status = tx_timer_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get info from a non-created timer. */
+ timer_2.tx_timer_id = 0;
+ status = tx_timer_info_get(&timer_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a timer with a NULL pointer. */
+ status = tx_timer_create(TX_NULL, "timer 0", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a timer with a bad control block size. */
+ status = _txe_timer_create(&timer_3, "timer 3", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE, (sizeof(TX_TIMER)+1));
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a timer that has already been created. */
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a timer with an invalid number of initial ticks. */
+ status = tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234,
+ 0, 18, TX_AUTO_ACTIVATE);
+
+ /* Check status. */
+ if (status != TX_TICK_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a timer with an invalid activation. */
+ status = tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE+3999);
+
+ /* Check status. */
+ if (status != TX_ACTIVATE_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(19);
+
+ /* Check for an error. */
+ if (timer_0_counter != 2)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Deactivate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Sleep again. */
+ tx_thread_sleep(19);
+
+ /* Check for an error. */
+ if (timer_0_counter != 2)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Modify the timer. */
+ status = tx_timer_change(&timer_0, 100, 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Clear the system time. */
+ tx_time_set(0);
+
+ /* Activate the timer. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for 120. */
+ tx_thread_sleep(120);
+
+ /* Check the counters to make sure everything is where it should be. */
+ if ((timer_0_counter != 23) || (tx_time_get() != 120))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Delete the timer... that are currently active and on the same expiration
+ list! */
+ status = tx_timer_deactivate(&timer_0);
+ status += tx_timer_deactivate(&timer_1);
+ status += tx_timer_change(&timer_0, 100, 100);
+ status += tx_timer_change(&timer_1, 100, 100);
+ status += tx_timer_activate(&timer_0);
+ status += tx_timer_activate(&timer_1);
+ status += tx_timer_delete(&timer_0);
+ status += tx_timer_delete(&timer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Resume thread 1 to take an interrupt on top of it. */
+ tx_thread_resume(&thread_1);
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Deactivate and delete timer 0. */
+ status = tx_timer_deactivate(&timer_0);
+ status += tx_timer_delete(&timer_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Check for ISR errors. */
+ if (error)
+ {
+
+ /* Thread error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Test the SMP timer exclusion get routines with bad values. */
+ status = tx_timer_smp_core_exclude_get(TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_smp_core_exclude_get(&timer_0, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Test the SMP timer exclusion set routines with bad values. */
+ status = tx_timer_smp_core_exclude(TX_NULL, 0);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_smp_core_exclude(&timer_0, 0);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+ /* Create two timers and exclude them from core 0. */
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 10, 10, TX_NO_ACTIVATE);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234,
+ 10, 10, TX_NO_ACTIVATE);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+
+ /* Now test the exclusion get with a valid timer, but with a NULL destination. */
+ status = tx_timer_smp_core_exclude_get(&timer_0, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #39\n");
+ test_control_return(1);
+ }
+
+ /* Now exclude the processing of each timer from executing on core 0. */
+ status = tx_timer_smp_core_exclude(&timer_0, 0x1);
+ status += tx_timer_smp_core_exclude(&timer_1, 0x1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #40\n");
+ test_control_return(1);
+ }
+
+ /* Now test the exclusion get with a valid timer. */
+ status = tx_timer_smp_core_exclude_get(&timer_0, &exclusion_map);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (exclusion_map != 0x1))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #41\n");
+ test_control_return(1);
+ }
+
+ /* Clear the timer counters. */
+ timer_0_counter = 0;
+ timer_1_counter = 0;
+
+ /* Sleep for one tick to get a new timer period. */
+ tx_thread_sleep(1);
+
+ /* Now activate both timers and immediately deactivate timer 1 so we test the system deactivate path. */
+ status += tx_timer_activate(&timer_0);
+ status = tx_timer_activate(&timer_1);
+ tx_interrupt_save = _tx_thread_smp_protect();
+ _tx_timer_system_deactivate(&timer_1.tx_timer_internal);
+ _tx_thread_smp_unprotect(tx_interrupt_save);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #42\n");
+ test_control_return(1);
+ }
+
+ /* Now sleep for 20 ticks to ensure the timer works when excluded from core 0. */
+ tx_thread_sleep(20);
+
+ /* Deactivate timer 0. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Delete both timers. */
+ status += tx_timer_delete(&timer_0);
+ status += tx_timer_delete(&timer_1);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (timer_0_counter == 0) || (timer_1_counter != 0))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #43\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful simple timer test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+ }
+}
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+}
+
+
+static void timer_1_expiration(ULONG timer_input)
+{
+
+ /* Process timer expiration. */
+ timer_1_counter++;
+}
diff --git a/test/smp/regression/threadx_trace_basic_test.c b/test/smp/regression/threadx_trace_basic_test.c
new file mode 100644
index 00000000..c6bc9be4
--- /dev/null
+++ b/test/smp/regression/threadx_trace_basic_test.c
@@ -0,0 +1,824 @@
+/* This test is designed to test trace functionality in ThreadX. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+#define TX_SOURCE_CODE
+#include "tx_trace.h"
+
+//#define FILE_DUMP
+
+#ifdef __linux__
+#define TX_WIN32_MEMORY_SIZE TX_LINUX_MEMORY_SIZE
+#define _tx_win32_critical_section _tx_linux_mutex
+#define tx_win32_critical_section_nested_count tx_linux_mutex_nested_count
+#endif /* __linux__ */
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+extern UINT _tx_trace_interrupt_control(UINT new_posture);
+extern VOID _tx_trace_object_register(UCHAR object_type, VOID *object_ptr, CHAR *object_name, ULONG parameter_1, ULONG parameter_2);
+extern VOID _tx_trace_object_unregister(VOID *object_ptr);
+
+static unsigned long thread_0_counter = 0;
+static unsigned long thread_1_counter = 0;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+
+static TX_TIMER timer_0;
+
+static TX_BLOCK_POOL block_pool_0;
+static TX_BYTE_POOL byte_pool_0;
+static TX_EVENT_FLAGS_GROUP group_0;
+static TX_MUTEX mutex_0;
+static TX_QUEUE queue_0;
+static TX_SEMAPHORE semaphore_0;
+
+/* Define a bunch of semaphores for loading up the trace buffer. */
+
+static TX_SEMAPHORE semaphore_1;
+static TX_SEMAPHORE semaphore_2;
+static TX_SEMAPHORE semaphore_3;
+static TX_SEMAPHORE semaphore_4;
+static TX_SEMAPHORE semaphore_5;
+static TX_SEMAPHORE semaphore_6;
+static TX_SEMAPHORE semaphore_7;
+static TX_SEMAPHORE semaphore_8;
+static TX_SEMAPHORE semaphore_9;
+static TX_SEMAPHORE semaphore_10;
+static TX_SEMAPHORE semaphore_11;
+static TX_SEMAPHORE semaphore_12;
+static TX_SEMAPHORE semaphore_13;
+static TX_SEMAPHORE semaphore_14;
+static TX_SEMAPHORE semaphore_15;
+static TX_SEMAPHORE semaphore_16;
+
+
+static unsigned long error = 0;
+static unsigned long full_buffer = 0;
+static void *save_pointer;
+
+#if TX_WIN32_MEMORY_SIZE
+
+static FILE *trace_dump_file;
+static CHAR trace_dump_file_name[]= "tracedump000.trx";
+
+#endif
+
+
+/* Define task prototypes. */
+
+static void thread_0_entry(ULONG task_input);
+static void thread_1_entry(ULONG task_input);
+static void thread_2_entry(ULONG task_input);
+
+
+/* Define the trace buffer. */
+UCHAR trace_buffer[16384];
+
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+UINT _tx_thread_interrupt_control(UINT new_posture);
+
+
+void trace_dump(void)
+{
+
+#if FILE_DUMP
+
+/* Win32 automatic dump! */
+UINT old_interrupt;
+
+
+ /* Disable interrupts. */
+ old_interrupt = _tx_thread_smp_protect();
+
+ /* If win32, we can actually dump the file! */
+ trace_dump_file = fopen(trace_dump_file_name, "wb+");
+
+ fwrite(trace_buffer, 1, sizeof(trace_buffer), trace_dump_file);
+
+ fclose(trace_dump_file);
+
+ /* Restore interrupts. */
+ _tx_thread_smp_unprotect(old_interrupt);
+
+ /* Prepare for next file dump. */
+ trace_dump_file_name[11]++;
+ if (trace_dump_file_name[11] > '9')
+ {
+ trace_dump_file_name[11] = '0';
+ trace_dump_file_name[10]++;
+
+ if (trace_dump_file_name[10] > '9')
+ {
+ trace_dump_file_name[10] = '0';
+ trace_dump_file_name[9]++;
+
+ if (trace_dump_file_name[9] > '9')
+ trace_dump_file_name[9] = '0';
+ }
+ }
+
+#endif
+
+}
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+ /* Resume thread 1. */
+ tx_thread_resume(&thread_1);
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ if ((_tx_thread_smp_protection.tx_thread_smp_protect_in_force != 1) ||
+ (_tx_win32_critical_section.tx_win32_critical_section_nested_count > 1))
+ {
+
+ /* Make ISR entry event. */
+ tx_trace_isr_enter_insert(2);
+ }
+ else
+ {
+
+ /* Make ISR entry event. */
+ tx_trace_isr_enter_insert(1);
+ }
+
+ /* Resume thread 2. */
+ tx_thread_resume(&thread_2);
+
+ /* Make ISR entry event. */
+ tx_trace_isr_exit_insert(1);
+
+ /* Make ISR entry event. */
+ tx_trace_isr_enter_insert(0);
+
+ /* Make ISR entry event. */
+ tx_trace_isr_exit_insert(0);
+
+}
+
+
+/* Define the trace buffer full notify function. */
+
+static VOID trace_buffer_full(void *ptr)
+{
+
+ /* Dump trace file! */
+ trace_dump();
+
+ full_buffer++;
+}
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_trace_basic_application_define(void *first_unused_memory)
+#endif
+{
+
+INT status;
+CHAR *pointer;
+
+
+ /* Setup a pointer. */
+ pointer = (CHAR *) first_unused_memory;
+
+ /* Adjust it forward just to make sure there is some space for the test below. */
+ pointer = pointer + 200;
+
+ /* Create a bunch of objects before being enabled. */
+
+ /* Create a timer for the test. */
+ save_pointer = (void *) pointer;
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 2, 2, TX_AUTO_ACTIVATE);
+ tx_block_pool_create(&block_pool_0, "block pool 0", 20, pointer, 100);
+ pointer = pointer + 100;
+ tx_byte_pool_create(&byte_pool_0, "byte pool 0", pointer, 1000);
+ pointer = pointer + 1000;
+ tx_event_flags_create(&group_0, "event flags group 0");
+ tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+ tx_queue_create(&queue_0, "queue 0", 16, pointer, 400);
+ pointer = pointer + 400;
+ tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
+
+ /* Enable event tracing. */
+ _tx_trace_initialize();
+ status = tx_trace_enable(trace_buffer, sizeof(trace_buffer), 16);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Trace Basic Test............................................ ERROR #1\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Trace Basic Test............................................ ERROR #2\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* 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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Trace Basic Test............................................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Trace Basic Test............................................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 14, 14, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Trace Basic Test............................................ ERROR #5\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+UINT old_interrupt;
+CHAR *pointer;
+TX_INTERRUPT_SAVE_AREA
+ULONG object;
+
+ /* Coverage for build without TraceX enabled. */
+ tx_interrupt_save = _tx_trace_interrupt_control(TX_INT_DISABLE);
+ _tx_trace_interrupt_control(tx_interrupt_save);
+#ifndef TX_ENABLE_EVENT_TRACE
+ _tx_trace_object_register(0, TX_NULL, TX_NULL, 0, 0);
+ _tx_trace_object_register(1, TX_NULL, TX_NULL, 0, 0);
+ _tx_trace_object_register(1, &object, TX_NULL, 0, 0);
+ _tx_trace_object_register(1, &object, "fake name", 0, 0);
+ _tx_trace_object_register(1, &object, "fake name", 1, 0);
+#endif
+ _tx_trace_object_register(1, &object, "fake name", 1, 1);
+ _tx_trace_object_unregister(TX_NULL);
+ _tx_trace_object_unregister(&object);
+
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Inform user of success getting to this test. */
+ printf("Running Trace Basic Test............................................ ");
+
+ /* Delete the additional objects. */
+ tx_timer_delete(&timer_0);
+ tx_block_pool_delete(&block_pool_0);
+ tx_byte_pool_delete(&byte_pool_0);
+ tx_event_flags_delete(&group_0);
+ tx_mutex_delete(&mutex_0);
+ tx_queue_delete(&queue_0);
+ tx_semaphore_delete(&semaphore_0);
+
+ /* Create all the semaphores. */
+ tx_semaphore_create(&semaphore_1, "semaphore 1", 1);
+ tx_semaphore_create(&semaphore_2, "semaphore 2", 1);
+ tx_semaphore_create(&semaphore_3, "semaphore 3", 1);
+ tx_semaphore_create(&semaphore_4, "semaphore 4", 1);
+ tx_semaphore_create(&semaphore_5, "semaphore 5", 1);
+ tx_semaphore_create(&semaphore_6, "semaphore 6", 1);
+ tx_semaphore_create(&semaphore_7, "semaphore 7", 1);
+ tx_semaphore_create(&semaphore_8, "semaphore 8", 1);
+ tx_semaphore_create(&semaphore_9, "semaphore 9", 1);
+ tx_semaphore_create(&semaphore_10, "semaphore 10", 1);
+ tx_semaphore_create(&semaphore_11, "semaphore 11", 1);
+ tx_semaphore_create(&semaphore_12, "semaphore 12", 1);
+ tx_semaphore_create(&semaphore_13, "semaphore 13", 1);
+ tx_semaphore_create(&semaphore_14, "semaphore 14", 1);
+ tx_semaphore_create(&semaphore_15, "semaphore 15", 1);
+ tx_semaphore_create(&semaphore_16, "semaphore 16", 1);
+
+ /* Delete them all. */
+ tx_semaphore_delete(&semaphore_1);
+ tx_semaphore_delete(&semaphore_2);
+ tx_semaphore_delete(&semaphore_3);
+ tx_semaphore_delete(&semaphore_4);
+ tx_semaphore_delete(&semaphore_5);
+ tx_semaphore_delete(&semaphore_6);
+ tx_semaphore_delete(&semaphore_7);
+ tx_semaphore_delete(&semaphore_8);
+ tx_semaphore_delete(&semaphore_9);
+ tx_semaphore_delete(&semaphore_10);
+ tx_semaphore_delete(&semaphore_11);
+ tx_semaphore_delete(&semaphore_12);
+ tx_semaphore_delete(&semaphore_13);
+ tx_semaphore_delete(&semaphore_14);
+ tx_semaphore_delete(&semaphore_15);
+ tx_semaphore_delete(&semaphore_16);
+
+ /* Create one over again. */
+ tx_semaphore_create(&semaphore_1, "semaphore 1", 1);
+
+ /* Now, create them all again. */
+ pointer = (CHAR *) save_pointer;
+ tx_block_pool_create(&block_pool_0, "block pool 0", 20, pointer, 100);
+ pointer = pointer + 100;
+ tx_byte_pool_create(&byte_pool_0, "byte pool 0", pointer, 1000);
+ pointer = pointer + 1000;
+ tx_event_flags_create(&group_0, "event flags group 0");
+ tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+ tx_queue_create(&queue_0, "queue 0", 16, pointer, 400);
+ pointer = pointer + 400;
+ tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
+
+ /* Attempt to enable event tracing again. */
+ status = tx_trace_enable(trace_buffer, sizeof(trace_buffer), 8);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_NOT_DONE)
+ {
+
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to enable event tracing again. */
+ status = tx_trace_enable(TX_NULL, 0, 8);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to enable event tracing again. */
+ status = tx_trace_enable(TX_NULL, 1, 0);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to enable event tracing again. */
+ status = tx_trace_enable(TX_NULL, 1, 8);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Filter all events. */
+ status = tx_trace_event_filter(TX_TRACE_ALL_EVENTS);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Trace error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Filter all events. */
+ status = tx_trace_event_filter(0);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Unfilter all events. */
+ status = tx_trace_event_unfilter(TX_TRACE_ALL_EVENTS);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Trace error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Unfilter all events. */
+ status = tx_trace_event_unfilter(0);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Register the trace buffer full notification routine. */
+ status = tx_trace_buffer_full_notify(trace_buffer_full);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Trace error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Check the NULL path with trace disabled. */
+ status = tx_trace_buffer_full_notify(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 2, 2, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ while (full_buffer < 40)
+ {
+
+if ((_tx_thread_smp_protection.tx_thread_smp_protect_in_force != 0) ||
+ (_tx_win32_critical_section.tx_win32_critical_section_nested_count != 0))
+ test_isr_dispatch = test_isr;
+
+ if (full_buffer < 20)
+ {
+
+ /* Disable interrupts. */
+ old_interrupt = tx_interrupt_control(TX_INT_DISABLE);
+
+if ((_tx_thread_smp_protection.tx_thread_smp_protect_in_force != 0) ||
+ (_tx_win32_critical_section.tx_win32_critical_section_nested_count != 1))
+ test_isr_dispatch = test_isr;
+
+ /* Restore interrupts. */
+ tx_interrupt_control(old_interrupt);
+
+if ((_tx_thread_smp_protection.tx_thread_smp_protect_in_force != 0) ||
+ (_tx_win32_critical_section.tx_win32_critical_section_nested_count != 0))
+ test_isr_dispatch = test_isr;
+ }
+
+ /* Insert user event. */
+ status = tx_trace_user_event_insert(1027, 1, 2, 3, 4);
+
+if ((_tx_thread_smp_protection.tx_thread_smp_protect_in_force != 0) ||
+ (_tx_win32_critical_section.tx_win32_critical_section_nested_count != 0))
+ test_isr_dispatch = test_isr;
+
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Trace error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Insert user event. */
+ status = tx_trace_user_event_insert(0, 1, 2, 3, 4);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Insert user event. */
+ status = tx_trace_user_event_insert(0, 0, 2, 3, 4);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Insert user event. */
+ status = tx_trace_user_event_insert(0, 0, 0, 3, 4);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Insert user event. */
+ status = tx_trace_user_event_insert(0, 0, 0, 0, 4);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Insert user event. */
+ status = tx_trace_user_event_insert(0, 0, 0, 0, 0);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ break;
+#endif
+ }
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Disable the trace buffer. */
+ status = tx_trace_disable();
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Trace error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Attempt to disable again, just to get the TX_NOT_DONE error code. */
+ status = tx_trace_disable();
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_NOT_DONE)
+ {
+
+ /* Trace error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Attempt to enable event tracing with a bogus size. */
+ status = tx_trace_enable(trace_buffer, 1, 8);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Trace error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+#endif
+
+
+ /* Attempt to make an user event when tracing is not enabled. */
+ status = tx_trace_user_event_insert(1027, 1, 2, 3, 4);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_NOT_DONE)
+ {
+
+ /* Trace error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+#endif
+
+
+ /* Check status. */
+ if (error)
+ {
+
+ /* Trace error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG task_input)
+{
+
+ while(1)
+ {
+
+ thread_1_counter++;
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+
+static void thread_2_entry(ULONG task_input)
+{
+
+ while(1)
+ {
+
+ thread_2_counter++;
+ tx_thread_suspend(&thread_2);
+ }
+}
diff --git a/test/tx/cmake/CMakeLists.txt b/test/tx/cmake/CMakeLists.txt
new file mode 100644
index 00000000..02e2a41b
--- /dev/null
+++ b/test/tx/cmake/CMakeLists.txt
@@ -0,0 +1,73 @@
+cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
+cmake_policy(SET CMP0054 NEW)
+cmake_policy(SET CMP0057 NEW)
+
+project(threadx_test LANGUAGES C)
+
+# Set build configurations
+set(BUILD_CONFIGURATIONS default_build_coverage disable_notify_callbacks_build
+ stack_checking_build trace_build)
+set(CMAKE_CONFIGURATION_TYPES
+ ${BUILD_CONFIGURATIONS}
+ CACHE STRING "list of supported configuration types" FORCE)
+set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
+ ${CMAKE_CONFIGURATION_TYPES})
+list(GET CMAKE_CONFIGURATION_TYPES 0 BUILD_TYPE)
+if((NOT CMAKE_BUILD_TYPE) OR (NOT ("${CMAKE_BUILD_TYPE}" IN_LIST
+ CMAKE_CONFIGURATION_TYPES)))
+ set(CMAKE_BUILD_TYPE
+ "${BUILD_TYPE}"
+ CACHE STRING "Build Type of the project" FORCE)
+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(trace_build -DTX_ENABLE_EVENT_TRACE)
+
+add_compile_options(
+ -m32
+ -std=c99
+ -ggdb
+ -g3
+ -gdwarf-2
+ -fdiagnostics-color
+ -Werror
+ -DTX_REGRESSION_TEST
+ -DTEST_STACK_SIZE_PRINTF=4096
+ ${${CMAKE_BUILD_TYPE}})
+add_link_options(-m32)
+
+enable_testing()
+
+add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../../.. threadx)
+add_subdirectory(regression)
+add_subdirectory(samples)
+
+# Coverage
+if(CMAKE_BUILD_TYPE MATCHES ".*_coverage")
+ target_compile_options(threadx PRIVATE -fprofile-arcs -ftest-coverage)
+ target_link_options(threadx PRIVATE -fprofile-arcs -ftest-coverage)
+endif()
+
+target_compile_options(
+ threadx
+ PRIVATE -Werror
+ -Wall
+ -Wextra
+ -pedantic
+ -fmessage-length=0
+ -fsigned-char
+ -ffunction-sections
+ -fdata-sections
+ -Wunused
+ -Wuninitialized
+ -Wmissing-declarations
+ -Wconversion
+ -Wpointer-arith
+ # -Wshadow
+ -Wlogical-op
+ -Waggregate-return
+ -Wfloat-equal)
diff --git a/test/tx/cmake/coverage.sh b/test/tx/cmake/coverage.sh
new file mode 100755
index 00000000..ae2c7a4b
--- /dev/null
+++ b/test/tx/cmake/coverage.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+set -e
+
+cd $(dirname $0)
+mkdir -p coverage_report/$1
+gcovr --object-directory=build/$1/threadx/CMakeFiles/threadx.dir/common/src -r build/$1 -f ../../../common/src --xml-pretty --output coverage_report/$1.xml
+gcovr --object-directory=build/$1/threadx/CMakeFiles/threadx.dir/common/src -r build/$1 -f ../../../common/src --html --html-details --output coverage_report/$1/index.html
diff --git a/test/tx/cmake/regression/CMakeLists.txt b/test/tx/cmake/regression/CMakeLists.txt
new file mode 100644
index 00000000..160f9e29
--- /dev/null
+++ b/test/tx/cmake/regression/CMakeLists.txt
@@ -0,0 +1,121 @@
+cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
+cmake_policy(SET CMP0057 NEW)
+
+project(regression_test LANGUAGES C)
+
+set(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../regression)
+
+set(regression_test_cases
+ ${SOURCE_DIR}/threadx_block_memory_basic_test.c
+ ${SOURCE_DIR}/threadx_block_memory_error_detection_test.c
+ ${SOURCE_DIR}/threadx_block_memory_information_test.c
+ ${SOURCE_DIR}/threadx_block_memory_prioritize_test.c
+ ${SOURCE_DIR}/threadx_block_memory_suspension_test.c
+ ${SOURCE_DIR}/threadx_block_memory_suspension_timeout_test.c
+ ${SOURCE_DIR}/threadx_block_memory_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_basic_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_information_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_prioritize_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_suspension_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_suspension_timeout_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_thread_contention_test.c
+ ${SOURCE_DIR}/threadx_byte_memory_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_event_flag_basic_test.c
+ ${SOURCE_DIR}/threadx_event_flag_information_test.c
+ ${SOURCE_DIR}/threadx_event_flag_isr_set_clear_test.c
+ ${SOURCE_DIR}/threadx_event_flag_isr_wait_abort_test.c
+ ${SOURCE_DIR}/threadx_event_flag_single_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_event_flag_suspension_consume_test.c
+ ${SOURCE_DIR}/threadx_event_flag_suspension_different_bits_consume_test.c
+ ${SOURCE_DIR}/threadx_event_flag_suspension_different_bits_test.c
+ ${SOURCE_DIR}/threadx_event_flag_suspension_test.c
+ ${SOURCE_DIR}/threadx_event_flag_suspension_timeout_test.c
+ ${SOURCE_DIR}/threadx_event_flag_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_interrupt_control_test.c
+ ${SOURCE_DIR}/threadx_mutex_basic_test.c
+ ${SOURCE_DIR}/threadx_mutex_delete_test.c
+ ${SOURCE_DIR}/threadx_mutex_information_test.c
+ ${SOURCE_DIR}/threadx_mutex_nested_priority_inheritance_test.c
+ ${SOURCE_DIR}/threadx_mutex_no_preemption_test.c
+ ${SOURCE_DIR}/threadx_mutex_preemption_test.c
+ ${SOURCE_DIR}/threadx_mutex_priority_inheritance_test.c
+ ${SOURCE_DIR}/threadx_mutex_proritize_test.c
+ ${SOURCE_DIR}/threadx_mutex_suspension_timeout_test.c
+ ${SOURCE_DIR}/threadx_mutex_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_queue_basic_eight_word_test.c
+ ${SOURCE_DIR}/threadx_queue_basic_four_word_test.c
+ ${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_empty_suspension_test.c
+ ${SOURCE_DIR}/threadx_queue_flush_no_suspension_test.c
+ ${SOURCE_DIR}/threadx_queue_flush_test.c
+ ${SOURCE_DIR}/threadx_queue_front_send_test.c
+ ${SOURCE_DIR}/threadx_queue_full_suspension_test.c
+ ${SOURCE_DIR}/threadx_queue_information_test.c
+ ${SOURCE_DIR}/threadx_queue_prioritize.c
+ ${SOURCE_DIR}/threadx_queue_suspension_timeout_test.c
+ ${SOURCE_DIR}/threadx_queue_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_semaphore_basic_test.c
+ ${SOURCE_DIR}/threadx_semaphore_ceiling_put_test.c
+ ${SOURCE_DIR}/threadx_semaphore_delete_test.c
+ ${SOURCE_DIR}/threadx_semaphore_information_test.c
+ ${SOURCE_DIR}/threadx_semaphore_non_preemption_test.c
+ ${SOURCE_DIR}/threadx_semaphore_preemption_test.c
+ ${SOURCE_DIR}/threadx_semaphore_prioritize.c
+ ${SOURCE_DIR}/threadx_semaphore_thread_terminate_test.c
+ ${SOURCE_DIR}/threadx_semaphore_timeout_test.c
+ ${SOURCE_DIR}/threadx_thread_basic_execution_test.c
+ ${SOURCE_DIR}/threadx_thread_basic_time_slice_test.c
+ ${SOURCE_DIR}/threadx_thread_completed_test.c
+ ${SOURCE_DIR}/threadx_thread_create_preemption_threshold_test.c
+ ${SOURCE_DIR}/threadx_thread_delayed_suspension_test.c
+ ${SOURCE_DIR}/threadx_thread_information_test.c
+ ${SOURCE_DIR}/threadx_thread_multi_level_preemption_threshold_test.c
+ ${SOURCE_DIR}/threadx_thread_multiple_non_current_test.c
+ ${SOURCE_DIR}/threadx_thread_multiple_sleep_test.c
+ ${SOURCE_DIR}/threadx_thread_multiple_suspension_test.c
+ ${SOURCE_DIR}/threadx_thread_multiple_time_slice_test.c
+ ${SOURCE_DIR}/threadx_thread_preemptable_suspension_test.c
+ ${SOURCE_DIR}/threadx_thread_preemption_change_test.c
+ ${SOURCE_DIR}/threadx_thread_priority_change.c
+ ${SOURCE_DIR}/threadx_thread_relinquish_test.c
+ ${SOURCE_DIR}/threadx_thread_reset_test.c
+ ${SOURCE_DIR}/threadx_thread_simple_sleep_non_clear_test.c
+ ${SOURCE_DIR}/threadx_thread_simple_sleep_test.c
+ ${SOURCE_DIR}/threadx_thread_simple_suspend_test.c
+ ${SOURCE_DIR}/threadx_thread_sleep_for_100ticks_test.c
+ ${SOURCE_DIR}/threadx_thread_sleep_terminate_test.c
+ ${SOURCE_DIR}/threadx_thread_stack_checking_test.c
+ ${SOURCE_DIR}/threadx_thread_terminate_delete_test.c
+ ${SOURCE_DIR}/threadx_thread_time_slice_change_test.c
+ ${SOURCE_DIR}/threadx_thread_wait_abort_and_isr_test.c
+ ${SOURCE_DIR}/threadx_thread_wait_abort_test.c
+ ${SOURCE_DIR}/threadx_time_get_set_test.c
+ ${SOURCE_DIR}/threadx_timer_activate_deactivate_test.c
+ ${SOURCE_DIR}/threadx_timer_deactivate_accuracy_test.c
+ ${SOURCE_DIR}/threadx_timer_information_test.c
+ ${SOURCE_DIR}/threadx_timer_large_timer_accuracy_test.c
+ ${SOURCE_DIR}/threadx_timer_multiple_accuracy_test.c
+ ${SOURCE_DIR}/threadx_timer_multiple_test.c
+ ${SOURCE_DIR}/threadx_timer_simple_test.c
+ ${SOURCE_DIR}/threadx_trace_basic_test.c
+ ${SOURCE_DIR}/threadx_initialize_kernel_setup_test.c)
+
+add_custom_command(
+ OUTPUT ${SOURCE_DIR}/tx_initialize_low_level.c
+ COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/generate_test_file.sh
+ COMMENT "Generating tx_initialize_low_level.c for test")
+
+add_library(test_utility ${SOURCE_DIR}/tx_initialize_low_level.c
+ ${SOURCE_DIR}/testcontrol.c)
+target_link_libraries(test_utility PUBLIC azrtos::threadx)
+target_compile_definitions(test_utility PUBLIC CTEST BATCH_TEST
+ TEST_STACK_SIZE_PRINTF=4096)
+
+foreach(test_case ${regression_test_cases})
+ get_filename_component(test_name ${test_case} NAME_WE)
+ add_executable(${test_name} ${test_case})
+ target_link_libraries(${test_name} PRIVATE test_utility)
+ add_test(${CMAKE_BUILD_TYPE}::${test_name} ${test_name})
+endforeach()
diff --git a/test/tx/cmake/regression/generate_test_file.sh b/test/tx/cmake/regression/generate_test_file.sh
new file mode 100755
index 00000000..ac0a70fa
--- /dev/null
+++ b/test/tx/cmake/regression/generate_test_file.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+dst=$(dirname $0)/../../regression/tx_initialize_low_level.c
+src=$(dirname $0)/../../../../ports/linux/gnu/src/tx_initialize_low_level.c
+
+line=`sed -n '/_tx_linux_timer_interrupt/=' $src | tail -n 1`
+sed "${line}iVOID test_interrupt_dispatch(VOID);" $src > tmp1
+line=`sed -n '/_tx_timer_interrupt/=' $src | tail -n 1`
+sed "${line}itest_interrupt_dispatch();" tmp1 > $dst
+rm tmp1 \ No newline at end of file
diff --git a/test/tx/cmake/run.sh b/test/tx/cmake/run.sh
new file mode 120000
index 00000000..429ff2bd
--- /dev/null
+++ b/test/tx/cmake/run.sh
@@ -0,0 +1 @@
+../../../scripts/cmake_bootstrap.sh \ No newline at end of file
diff --git a/test/tx/cmake/samples/CMakeLists.txt b/test/tx/cmake/samples/CMakeLists.txt
new file mode 100644
index 00000000..2915ed22
--- /dev/null
+++ b/test/tx/cmake/samples/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
+cmake_policy(SET CMP0057 NEW)
+
+project(samples LANGUAGES C)
+
+set(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../../ports/linux/gnu/example_build)
+
+set(sample_files
+ ${SOURCE_DIR}/sample_threadx.c)
+
+foreach(sample_file ${sample_files})
+ get_filename_component(sample_file_name ${sample_file} NAME_WE)
+ add_executable(${sample_file_name} ${sample_file} ${CMAKE_CURRENT_LIST_DIR}/fake.c)
+ target_link_libraries(${sample_file_name} PRIVATE azrtos::threadx)
+endforeach()
diff --git a/test/tx/cmake/samples/fake.c b/test/tx/cmake/samples/fake.c
new file mode 100644
index 00000000..199f257e
--- /dev/null
+++ b/test/tx/cmake/samples/fake.c
@@ -0,0 +1,20 @@
+#include "tx_api.h"
+
+typedef unsigned int TEST_FLAG;
+TEST_FLAG threadx_byte_allocate_loop_test;
+TEST_FLAG threadx_byte_release_loop_test;
+TEST_FLAG threadx_mutex_suspension_put_test;
+TEST_FLAG threadx_mutex_suspension_priority_test;
+#ifndef TX_TIMER_PROCESS_IN_ISR
+TEST_FLAG threadx_delete_timer_thread;
+#endif
+
+void abort_and_resume_byte_allocating_thread(void){}
+void abort_all_threads_suspended_on_mutex(void){}
+void suspend_lowest_priority(void){}
+#ifndef TX_TIMER_PROCESS_IN_ISR
+void delete_timer_thread(void){}
+#endif
+TEST_FLAG test_stack_analyze_flag;
+TEST_FLAG test_initialize_flag;
+TEST_FLAG test_forced_mutex_timeout; \ No newline at end of file
diff --git a/test/tx/regression/testcontrol.c b/test/tx/regression/testcontrol.c
new file mode 100644
index 00000000..ff257ca1
--- /dev/null
+++ b/test/tx/regression/testcontrol.c
@@ -0,0 +1,1411 @@
+/* This is the test control routine of the ThreadX kernel. All tests are dispatched from this routine. */
+
+#include "tx_api.h"
+#include <stdio.h>
+#include "tx_initialize.h"
+#include "tx_timer.h"
+#include "tx_thread.h"
+#include "tx_semaphore.h"
+#include "tx_queue.h"
+#include "tx_mutex.h"
+#include "tx_block_pool.h"
+#include "tx_byte_pool.h"
+#include "tx_event_flags.h"
+
+/* Version check. */
+#ifndef EL_PRODUCT_THREADX
+#error "EL_PRODUCT_THREADX is not defined."
+#endif
+
+#if defined(EXPECTED_MAJOR_VERSION) && ( !defined(THREADX_MAJOR_VERSION) || THREADX_MAJOR_VERSION != EXPECTED_MAJOR_VERSION)
+#error "THREADX_MAJOR_VERSION"
+#endif /* Check THREADX_MAJOR_VERSION */
+
+#if defined(EXPECTED_MINOR_VERSION) && ( !defined(THREADX_MINOR_VERSION) || THREADX_MINOR_VERSION != EXPECTED_MINOR_VERSION)
+#error "THREADX_MINOR_VERSION"
+#endif /* Check THREADX_MINOR_VERSION */
+
+
+#define TEST_STACK_SIZE 6144
+
+
+/* Define the test control ThreadX objects... */
+
+TX_THREAD test_control_thread;
+TX_THREAD test_thread;
+TX_THREAD test_thread1;
+TX_THREAD test_thread2;
+TX_THREAD test_thread3;
+ULONG test_thread3_stack[256];
+TX_QUEUE test_queue;
+ULONG test_thread2_stack[256];
+TX_TIMER test_timer;
+TX_MUTEX init_mutex;
+TX_MUTEX init_mutex_inherit;
+TX_MUTEX cleanup_mutex;
+TX_EVENT_FLAGS_GROUP cleanup_event_flags;
+TX_BLOCK_POOL cleanup_block_pool;
+TX_BYTE_POOL cleanup_byte_pool;
+TX_QUEUE cleanup_queue;
+TX_SEMAPHORE cleanup_semaphore;
+TX_SEMAPHORE init_semaphore;
+ULONG init_queue_area[20];
+TX_QUEUE init_queue;
+TX_BYTE_POOL init_byte_pool;
+ULONG init_byte_pool_area[50];
+TX_BLOCK_POOL init_block_pool;
+ULONG init_block_pool_area[50];
+TX_EVENT_FLAGS_GROUP init_event_flags;
+TX_TIMER init_timer;
+TX_THREAD init_test_thread;
+TX_THREAD second_test_thread;
+#ifndef TX_TIMER_PROCESS_IN_ISR
+TEST_FLAG threadx_delete_timer_thread;
+#endif
+TX_TIMER_INTERNAL **_timer_list_start_backup;
+TEST_FLAG test_stack_analyze_flag;
+TEST_FLAG test_initialize_flag;
+TX_BLOCK_POOL fake_block_pool;
+TX_BYTE_POOL fake_byte_pool;
+TX_EVENT_FLAGS_GROUP fake_event_flags;
+TX_MUTEX fake_mutex;
+TX_QUEUE fake_queue;
+TX_SEMAPHORE fake_semaphore;
+
+TEST_FLAG test_forced_mutex_timeout;
+TEST_FLAG threadx_mutex_suspension_put_test;
+TEST_FLAG threadx_mutex_suspension_priority_test;
+TEST_FLAG threadx_byte_allocate_loop_test;
+TEST_FLAG threadx_byte_release_loop_test;
+
+
+/* Define the test control global variables. */
+
+ULONG test_control_return_status;
+ULONG test_control_successful_tests;
+ULONG test_control_failed_tests;
+ULONG test_control_system_errors;
+
+UINT test_mutex_from_init;
+UINT test_semaphore_from_init;
+UINT test_queue_from_init;
+UINT test_event_flags_from_init;
+UINT test_byte_pool_create_init;
+UINT test_block_pool_create_init;
+UINT test_timer_create_init;
+
+
+/* Remember the start of free memory. */
+
+UCHAR *test_free_memory_ptr;
+
+
+/* Define the function pointer for ISR dispatch. */
+
+VOID (*test_isr_dispatch)(void);
+
+
+UCHAR test_control_memory[0x60000];
+UCHAR tests_memory[0x60000];
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+extern volatile ULONG _tx_thread_system_state;
+
+
+/* Define test entry pointer type. */
+
+typedef struct TEST_ENTRY_STRUCT
+{
+
+VOID (*test_entry)(void *);
+} TEST_ENTRY;
+
+
+/* Define the prototypes for the test entry points. */
+
+void threadx_block_memory_basic_application_define(void *);
+void threadx_block_memory_error_detection_application_define(void *);
+void threadx_block_memory_suspension_application_define(void *);
+void threadx_block_memory_suspension_timeout_application_define(void *);
+void threadx_block_memory_thread_terminate_application_define(void *);
+void threadx_block_memory_prioritize_application_define(void *);
+void threadx_block_memory_information_application_define(void *);
+
+void threadx_byte_memory_basic_application_define(void *);
+void threadx_byte_memory_thread_contention_application_define(void *);
+void threadx_byte_memory_suspension_application_define(void *);
+void threadx_byte_memory_suspension_timeout_application_define(void *);
+void threadx_byte_memory_thread_terminate_application_define(void *);
+void threadx_byte_memory_prioritize_application_define(void *);
+void threadx_byte_memory_information_application_define(void *);
+
+void threadx_event_flag_basic_application_define(void *);
+void threadx_event_flag_suspension_application_define(void *);
+void threadx_event_flag_suspension_consume_application_define(void *);
+void threadx_event_flag_suspension_different_bits_application_define(void *);
+void threadx_event_flag_suspension_different_bits_consume_application_define(void *);
+void threadx_event_flag_suspension_timeout_application_define(void *);
+void threadx_event_flag_thread_terminate_application_define(void *);
+void threadx_event_flag_single_thread_terminate_application_define(void *);
+void threadx_event_flag_isr_set_clear_application_define(void *);
+void threadx_event_flag_isr_wait_abort_application_define(void *);
+void threadx_event_flag_information_application_define(void *);
+
+void threadx_interrupt_control_application_define(void *);
+
+void threadx_mutex_basic_application_define(void *);
+void threadx_mutex_delete_application_define(void *);
+void threadx_mutex_preemption_application_define(void *);
+void threadx_mutext_no_preemption_application_define(void *);
+void threadx_mutex_suspension_timeout_application_define(void *);
+void threadx_mutex_thread_terminate_application_define(void *);
+void threadx_mutex_priority_inheritance_application_define(void *);
+void threadx_mutex_nested_priority_inheritance_application_define(void *);
+void threadx_mutex_prioritize_application_define(void *);
+void threadx_mutex_information_application_define(void *);
+
+void threadx_queue_basic_application_define(void *);
+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_empty_suspension_application_define(void *);
+void threadx_queue_full_suspension_application_define(void *);
+void threadx_queue_suspension_timeout_application_define(void *);
+void threadx_queue_thread_terminate_application_define(void *);
+void threadx_queue_flush_application_define(void *);
+void threadx_queue_flush_no_suspension_application_define(void *);
+void threadx_queue_front_send_application_define(void *);
+void threadx_queue_prioritize_application_define(void *);
+void threadx_queue_information_application_define(void *);
+
+void threadx_semaphore_basic_application_define(void *);
+void threadx_semaphore_delete_application_define(void *);
+void threadx_semaphore_preemption_application_define(void *);
+void threadx_semaphore_non_preemption_application_define(void *);
+void threadx_semaphore_timeout_application_define(void *);
+void threadx_semaphore_thread_terminate_application_define(void *);
+void threadx_semaphore_prioritize_application_define(void *);
+void threadx_semaphore_ceiling_put_application_define(void *);
+void threadx_semaphore_information_application_define(void *);
+
+void threadx_thread_basic_execution_application_define(void *);
+void threadx_thread_completed_application_define(void *);
+void threadx_thread_relinquish_application_define(void *);
+void threadx_thread_simple_supsend_application_define(void *);
+void threadx_thread_multiple_suspension_application_define(void *);
+void threadx_thread_multiple_non_current_suspension_application_define(void *);
+void threadx_thread_multi_level_preemption_threshold_application_define(void *);
+void threadx_thread_preemptable_suspension_application_define(void *);
+void threadx_thread_basic_time_slice_application_define(void *);
+void threadx_thread_multiple_time_slice_application_define(void *);
+void threadx_thread_simple_sleep_application_define(void *);
+void threadx_thread_simple_sleep_non_clear_application_define(void *);
+void threadx_thread_sleep_for_100ticks_application_define(void *);
+void threadx_thread_multiple_sleep_application_define(void *);
+void threadx_thread_terminate_delete_application_define(void *);
+void threadx_thread_preemption_change_application_define(void *);
+void threadx_thread_priority_change_application_define(void *);
+void threadx_thread_time_slice_change_application_define(void *);
+void threadx_thread_sleep_terminate_application_define(void *);
+void threadx_thread_delayed_suspension_application_define(void *);
+void threadx_thread_wait_abort_application_define(void *);
+void threadx_thread_wait_abort_and_isr_application_define(void *);
+void threadx_thread_create_preemption_threshold_application_define(void *);
+void threadx_thread_information_application_define(void *);
+void threadx_thread_reset_application_define(void *);
+void threadx_thread_stack_checking_application_define(void *);
+
+void threadx_time_get_set_application_define(void *);
+
+void threadx_timer_simple_application_define(void *);
+void threadx_timer_activate_deactivate_application_define(void *);
+void threadx_timer_deactivate_accuracy_application_define(void *);
+void threadx_timer_large_timer_accuracy_application_define(void *);
+void threadx_timer_multiple_application_define(void *);
+void threadx_timer_multiple_accuracy_application_define(void *);
+void threadx_timer_information_application_define(void *);
+
+void threadx_trace_basic_application_define(void *);
+void test_application_define(void *first_unused_memory);
+
+
+
+/* Define the array of test entry points. */
+
+TEST_ENTRY test_control_tests[] =
+{
+#if CTEST
+ test_application_define,
+#else
+
+ threadx_block_memory_basic_application_define,
+ threadx_block_memory_error_detection_application_define,
+ threadx_block_memory_prioritize_application_define,
+ threadx_block_memory_suspension_application_define,
+ threadx_block_memory_suspension_timeout_application_define,
+ threadx_block_memory_thread_terminate_application_define,
+ threadx_block_memory_information_application_define,
+
+ threadx_byte_memory_basic_application_define,
+ threadx_byte_memory_suspension_application_define,
+ threadx_byte_memory_suspension_timeout_application_define,
+ threadx_byte_memory_thread_terminate_application_define,
+ threadx_byte_memory_prioritize_application_define,
+ threadx_byte_memory_thread_contention_application_define,
+ threadx_byte_memory_information_application_define,
+
+ threadx_event_flag_basic_application_define,
+ threadx_event_flag_suspension_application_define,
+ threadx_event_flag_suspension_consume_application_define,
+ threadx_event_flag_suspension_different_bits_application_define,
+ threadx_event_flag_suspension_different_bits_consume_application_define,
+ threadx_event_flag_suspension_timeout_application_define,
+ threadx_event_flag_thread_terminate_application_define,
+ threadx_event_flag_single_thread_terminate_application_define,
+ threadx_event_flag_isr_set_clear_application_define,
+ threadx_event_flag_isr_wait_abort_application_define,
+ threadx_event_flag_information_application_define,
+
+ threadx_interrupt_control_application_define,
+
+ threadx_mutex_basic_application_define,
+ threadx_mutex_delete_application_define,
+ threadx_mutex_preemption_application_define,
+ threadx_mutext_no_preemption_application_define,
+ threadx_mutex_suspension_timeout_application_define,
+ threadx_mutex_thread_terminate_application_define,
+ threadx_mutex_priority_inheritance_application_define,
+ threadx_mutex_prioritize_application_define,
+ threadx_mutex_nested_priority_inheritance_application_define,
+ threadx_mutex_information_application_define,
+
+ threadx_queue_basic_application_define,
+ threadx_queue_basic_two_word_application_define,
+ threadx_queue_basic_four_word_application_define,
+ threadx_queue_basic_eight_word_application_define,
+ threadx_queue_basic_sixteen_word_application_define,
+ threadx_queue_empty_suspension_application_define,
+ threadx_queue_full_suspension_application_define,
+ threadx_queue_suspension_timeout_application_define,
+ threadx_queue_thread_terminate_application_define,
+ threadx_queue_flush_application_define,
+ threadx_queue_flush_no_suspension_application_define,
+ threadx_queue_front_send_application_define,
+ threadx_queue_prioritize_application_define,
+ threadx_queue_information_application_define,
+
+ threadx_semaphore_basic_application_define,
+ threadx_semaphore_delete_application_define,
+ threadx_semaphore_preemption_application_define,
+ threadx_semaphore_non_preemption_application_define,
+ threadx_semaphore_timeout_application_define,
+ threadx_semaphore_thread_terminate_application_define,
+ threadx_semaphore_prioritize_application_define,
+ threadx_semaphore_ceiling_put_application_define,
+ threadx_semaphore_information_application_define,
+
+ threadx_thread_basic_execution_application_define,
+ threadx_thread_completed_application_define,
+ threadx_thread_relinquish_application_define,
+ threadx_thread_simple_supsend_application_define,
+ threadx_thread_multiple_suspension_application_define,
+ threadx_thread_multiple_non_current_suspension_application_define,
+ threadx_thread_multi_level_preemption_threshold_application_define,
+ threadx_thread_preemptable_suspension_application_define,
+ threadx_thread_basic_time_slice_application_define,
+ threadx_thread_multiple_time_slice_application_define,
+ threadx_thread_simple_sleep_application_define,
+ threadx_thread_simple_sleep_non_clear_application_define,
+ threadx_thread_sleep_for_100ticks_application_define,
+ threadx_thread_multiple_sleep_application_define,
+ threadx_thread_terminate_delete_application_define,
+
+ threadx_thread_priority_change_application_define,
+
+ threadx_thread_time_slice_change_application_define,
+ threadx_thread_sleep_terminate_application_define,
+ threadx_thread_delayed_suspension_application_define,
+ threadx_thread_wait_abort_application_define,
+ threadx_thread_wait_abort_and_isr_application_define,
+ threadx_thread_create_preemption_threshold_application_define,
+ threadx_thread_preemption_change_application_define,
+ threadx_thread_information_application_define,
+ threadx_thread_reset_application_define,
+ threadx_thread_stack_checking_application_define,
+
+ threadx_time_get_set_application_define,
+
+ threadx_timer_simple_application_define,
+ threadx_timer_activate_deactivate_application_define,
+ threadx_timer_deactivate_accuracy_application_define,
+ threadx_timer_large_timer_accuracy_application_define,
+ threadx_timer_multiple_application_define,
+ threadx_timer_multiple_accuracy_application_define,
+ threadx_timer_information_application_define,
+
+ threadx_trace_basic_application_define,
+#endif
+
+ TX_NULL,
+};
+
+/* Define thread prototypes. */
+
+void test_control_thread_entry(ULONG thread_input);
+void test_thread_entry(ULONG thread_input);
+void test_thread_entry1(ULONG thread_input);
+void test_control_return(UINT status);
+void test_control_cleanup(void);
+void test_exit_notify(TX_THREAD *thread_ptr, UINT type);
+
+
+/* Define necessary exernal references. */
+
+#ifdef __ghs
+extern TX_MUTEX __ghLockMutex;
+#endif
+
+extern TX_TIMER *_tx_timer_created_ptr;
+extern ULONG _tx_timer_created_count;
+#ifndef TX_TIMER_PROCESS_IN_ISR
+extern TX_THREAD _tx_timer_thread;
+#endif
+extern TX_THREAD *_tx_thread_created_ptr;
+extern ULONG _tx_thread_created_count;
+extern TX_SEMAPHORE *_tx_semaphore_created_ptr;
+extern ULONG _tx_semaphore_created_count;
+extern TX_QUEUE *_tx_queue_created_ptr;
+extern ULONG _tx_queue_created_count;
+extern TX_MUTEX *_tx_mutex_created_ptr;
+extern ULONG _tx_mutex_created_count;
+extern TX_EVENT_FLAGS_GROUP *_tx_event_flags_created_ptr;
+extern ULONG _tx_event_flags_created_count;
+extern TX_BYTE_POOL *_tx_byte_pool_created_ptr;
+extern ULONG _tx_byte_pool_created_count;
+extern TX_BLOCK_POOL *_tx_block_pool_created_ptr;
+extern ULONG _tx_block_pool_created_count;
+
+#ifdef EXTERNAL_EXIT
+void external_exit(UINT code);
+#endif
+
+
+/* Define the interrupt processing dispatcher. The individual tests will set this up when they desire
+ asynchrouns processing for testing purposes. */
+
+void test_interrupt_dispatch(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Test calling tx_thread_relinquish from ISR to see if the error checking throws it out. */
+ tx_thread_relinquish();
+#endif
+
+ /* Check for something to run... */
+ if (test_isr_dispatch)
+ {
+
+ (test_isr_dispatch)();
+ }
+}
+
+
+/* Define init timer entry. */
+
+static void init_timer_entry(ULONG timer_input)
+{
+
+}
+
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+
+/* Define the deletion of the system timer thread. */
+
+void delete_timer_thread(void)
+{
+
+ _tx_thread_terminate(&_tx_timer_thread);
+ _tx_thread_delete(&_tx_timer_thread);
+}
+
+#endif
+
+
+/* Define main entry point. */
+#ifndef EXTERNAL_MAIN
+void main()
+{
+
+#ifndef TX_MISRA_ENABLE
+#ifndef TX_MANUAL_TEST
+
+ /* Test the pre-initialize path through _tx_initialize_kernel_enter. */
+ _tx_thread_system_state = TX_INITIALIZE_ALMOST_DONE;
+ test_initialize_flag = 1;
+
+ /* Call the internal kernel enter function to exercise two paths. */
+ _tx_initialize_kernel_enter();
+ _tx_thread_system_state = 0;
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+ threadx_delete_timer_thread = 1;
+#endif
+#endif
+#endif
+
+ /* Enter the ThreadX kernel. */
+ tx_kernel_enter();
+}
+#endif
+
+
+/* Define what the initial system looks like. */
+
+void tx_application_define(void *first_unused_memory)
+{
+
+UCHAR *pointer;
+VOID (*temp_mutex_release)(TX_THREAD *thread_ptr);
+TX_THREAD *temp_thread;
+UINT old_preemption;
+UINT status;
+ULONG flags;
+ULONG temp;
+UINT i, j;
+
+
+ /* Initialize the test error/success counters. */
+ test_control_successful_tests = 0;
+ test_control_failed_tests = 0;
+ test_control_system_errors = 0;
+
+ /* Setup a pointer to the first unused memory. */
+ pointer = (UCHAR *) &test_control_memory[0]; //first_unused_memory;
+
+ /* Create the test control thread. */
+ tx_thread_create(&test_control_thread, "test control thread", test_control_thread_entry, 0,
+ pointer, TEST_STACK_SIZE,
+ 17, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE;
+
+ /* Create the test thread. */
+ tx_thread_create(&test_thread, "test thread", test_thread_entry, 0,
+ pointer, TEST_STACK_SIZE,
+ 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE;
+
+ /* Create the second test thread. */
+ tx_thread_create(&test_thread1, "test thread 1", test_thread_entry1, 0,
+ pointer, TEST_STACK_SIZE,
+ 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE;
+
+ /* Suspend the test thread temporarily. */
+ tx_thread_suspend(&test_thread);
+
+ /* Resume the test thread again to exercise the resume code fully. */
+ tx_thread_resume(&test_thread);
+
+ /* Timer change just to exercise the code... an error from initialization! */
+ test_timer.tx_timer_id = TX_TIMER_ID;
+ tx_timer_change(&test_timer, 1, 1);
+
+ /* Test mutex created and used in initialization. */
+ test_mutex_from_init = tx_mutex_create(&init_mutex, "init mutex", TX_INHERIT);
+ test_mutex_from_init += tx_mutex_get(&init_mutex, TX_NO_WAIT);
+ test_mutex_from_init += tx_mutex_get(&init_mutex, TX_NO_WAIT);
+ test_mutex_from_init += tx_mutex_put(&init_mutex);
+ test_mutex_from_init += tx_mutex_put(&init_mutex);
+ test_mutex_from_init = tx_mutex_create(&init_mutex_inherit, "init mutex", TX_INHERIT);
+ test_mutex_from_init += tx_mutex_get(&init_mutex_inherit, TX_NO_WAIT);
+ test_mutex_from_init += tx_mutex_get(&init_mutex_inherit, TX_NO_WAIT);
+ test_mutex_from_init += tx_mutex_put(&init_mutex_inherit);
+ test_mutex_from_init += tx_mutex_put(&init_mutex_inherit);
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Test timer create from initialization. */
+ test_block_pool_create_init = tx_block_pool_create(&init_block_pool, "init block pool", 10, init_block_pool_area, sizeof(init_block_pool_area));
+
+ /* Test byte pool create from initialization. */
+ test_byte_pool_create_init = tx_byte_pool_create(&init_byte_pool, "init byte pool", init_byte_pool_area, sizeof(init_byte_pool_area));
+ test_byte_pool_create_init += tx_byte_allocate(&init_byte_pool, (VOID **) &pointer, 20, TX_NO_WAIT);
+ test_byte_pool_create_init += tx_byte_release(pointer);
+
+ /* Test event flag create from initialization. */
+ test_event_flags_from_init = tx_event_flags_create(&init_event_flags, "init events");
+
+ /* Test queue create from initialization. */
+ test_queue_from_init = tx_queue_create(&init_queue, "init queue", TX_1_ULONG, init_queue_area, sizeof(init_queue_area));
+
+ /* Test semaphore create from initialization. */
+ test_semaphore_from_init = tx_semaphore_create(&init_semaphore, "init semaphore", 0);
+
+ /* Test timer creat from initialization. */
+ test_timer_create_init = tx_timer_create(&init_timer, "init timer", init_timer_entry, 0x5678,
+ 100, 200, TX_AUTO_ACTIVATE);
+
+ /* Test calling tx_thread_relinquish to see if the error checking throws it out. */
+ tx_thread_relinquish();
+#endif
+
+ /* Remember the free memory pointer. */
+ test_free_memory_ptr = &tests_memory[0]; //pointer;
+
+ /* Clear the ISR dispatch. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Ensure that _tx_thread_time_slice can handle NULL thread, note that current thread pointer is NULL at this point. */
+ _tx_thread_time_slice();
+
+ /* Test to make sure _tx_thread_time_slice can handle a none-ready thread. */
+ init_test_thread.tx_thread_state = TX_IO_DRIVER;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_TRUE;
+ _tx_thread_current_ptr = &init_test_thread;
+ _tx_thread_time_slice();
+
+ /* Test to make sure _tx_thread_time_slice can handle preemption-threshold set. */
+ init_test_thread.tx_thread_state = TX_READY;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_priority = 10;
+ init_test_thread.tx_thread_preempt_threshold = 9;
+ init_test_thread.tx_thread_ready_next = &init_test_thread;
+ init_test_thread.tx_thread_ready_previous = &init_test_thread;
+ _tx_thread_time_slice();
+ _tx_thread_current_ptr = TX_NULL;
+
+ /* Test to make sure _tx_thread_shell_entry can handle a NULL mutex release function pointer. */
+ temp_mutex_release = _tx_thread_mutex_release;
+ temp_thread = _tx_thread_execute_ptr;
+ _tx_thread_mutex_release = TX_NULL;
+ init_test_thread.tx_thread_state = TX_READY;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_FALSE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+ _tx_thread_current_ptr = &init_test_thread;
+ _tx_thread_execute_ptr = &init_test_thread;
+ _tx_thread_entry_exit_notify(&init_test_thread, test_exit_notify);
+ _tx_thread_shell_entry();
+ _tx_thread_current_ptr = TX_NULL;
+ _tx_thread_execute_ptr = temp_thread;
+ _tx_thread_mutex_release = temp_mutex_release; /* Recover Mutex release pointer. */
+
+ /* Test _tx_thread_system_suspend when not current, preemption is needed but disabled. */
+ temp_thread = _tx_thread_execute_ptr;
+ init_test_thread.tx_thread_state = TX_READY;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_FALSE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+ _tx_thread_execute_ptr = &init_test_thread;
+#ifndef TX_NOT_INTERRUPTABLE
+ _tx_thread_preempt_disable++;
+#endif
+ _tx_thread_system_suspend(&init_test_thread);
+ _tx_thread_execute_ptr = temp_thread;
+
+ /* Test _tx_thread_system_resume when not current, suspending and in a COMPLETED state. */
+ temp_thread = _tx_thread_execute_ptr;
+ init_test_thread.tx_thread_state = TX_COMPLETED;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_TRUE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+ _tx_thread_preempt_disable++;
+ _tx_thread_execute_ptr = &init_test_thread;
+ _tx_thread_system_resume(&init_test_thread);
+ _tx_thread_execute_ptr = temp_thread;
+
+
+ /* Test _tx_thread_system_resume when not current, not suspending and already in a TX_READY state. */
+ temp_thread = _tx_thread_execute_ptr;
+ init_test_thread.tx_thread_state = TX_READY;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_FALSE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+ _tx_thread_preempt_disable++;
+ _tx_thread_execute_ptr = &init_test_thread;
+ _tx_thread_system_resume(&init_test_thread);
+ _tx_thread_execute_ptr = temp_thread;
+
+ /* Test _tx_thread_system_resume when not current, suspending and in a TERMINATED state. */
+ temp_thread = _tx_thread_execute_ptr;
+ init_test_thread.tx_thread_state = TX_TERMINATED;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_TRUE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+ _tx_thread_preempt_disable++;
+ _tx_thread_execute_ptr = &init_test_thread;
+ _tx_thread_system_resume(&init_test_thread);
+ _tx_thread_execute_ptr = temp_thread;
+
+ /* Test tx_thread_resume to test the saved_thread_ptr being NULL. */
+ temp_thread = _tx_thread_execute_ptr;
+ _tx_thread_execute_ptr = TX_NULL;
+ tx_thread_resume(&test_thread1);
+ tx_thread_suspend(&test_thread1);
+ _tx_thread_execute_ptr = temp_thread;
+
+ /* Test preemption change when the new priority is the same as the threshold. */
+ init_test_thread.tx_thread_state = TX_SUSPENDED;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_FALSE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_user_priority = 10;
+ init_test_thread.tx_thread_user_preempt_threshold = 10;
+ init_test_thread.tx_thread_priority = 10;
+ init_test_thread.tx_thread_preempt_threshold = 10;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+ _tx_thread_preemption_change(&init_test_thread, 10, &old_preemption);
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Test semaphore cleanup with an invalid semaphore ID. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_semaphore;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup);
+ cleanup_semaphore.tx_semaphore_id = 0;
+ cleanup_semaphore.tx_semaphore_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_semaphore_cleanup(&init_test_thread, 0);
+
+ /* Test semaphore cleanup with an invalid suspension sequence. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_semaphore;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup);
+ cleanup_semaphore.tx_semaphore_id = 0;
+ cleanup_semaphore.tx_semaphore_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_semaphore_cleanup(&init_test_thread, 1);
+
+ /* Test semaphore cleanup with a NULL semaphore pointer. */
+ init_test_thread.tx_thread_suspend_control_block = TX_NULL;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup);
+ cleanup_semaphore.tx_semaphore_id = TX_SEMAPHORE_ID;
+ cleanup_semaphore.tx_semaphore_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_semaphore_cleanup(&init_test_thread, 0);
+
+ /* Test semaphore cleanup with an valid semaphore ID but a suspension count of 0. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_semaphore;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup);
+ cleanup_semaphore.tx_semaphore_id = TX_SEMAPHORE_ID;
+ cleanup_semaphore.tx_semaphore_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_semaphore_cleanup(&init_test_thread, 0);
+
+ /* Test queue cleanup with a NULL cleanup pointer. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ cleanup_queue.tx_queue_id = 0;
+ cleanup_queue.tx_queue_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_queue_cleanup(&init_test_thread, 0);
+
+ /* Test queue cleanup with a NULL queue pointer. */
+ init_test_thread.tx_thread_suspend_control_block = TX_NULL;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup);
+ cleanup_queue.tx_queue_id = 0;
+ cleanup_queue.tx_queue_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_queue_cleanup(&init_test_thread, 0);
+
+ /* Test queue cleanup with an invalid queue ID. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup);
+ cleanup_queue.tx_queue_id = 0;
+ cleanup_queue.tx_queue_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_queue_cleanup(&init_test_thread, 0);
+
+ /* Test queue cleanup with an invalid suspension sequence. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup);
+ cleanup_queue.tx_queue_id = 0;
+ cleanup_queue.tx_queue_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_queue_cleanup(&init_test_thread, 1);
+
+ /* Test queue cleanup with an valid queue ID but a suspension count of 0. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup);
+ cleanup_queue.tx_queue_id = TX_QUEUE_ID;
+ cleanup_queue.tx_queue_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_queue_cleanup(&init_test_thread, 0);
+
+ /* Test mutex cleanup with a NULL cleanup pointer. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ cleanup_mutex.tx_mutex_id = 0;
+ cleanup_mutex.tx_mutex_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_mutex_cleanup(&init_test_thread, 0);
+
+ /* Test mutex cleanup with a NULL mutex pointer. */
+ init_test_thread.tx_thread_suspend_control_block = TX_NULL;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup);
+ cleanup_mutex.tx_mutex_id = 0;
+ cleanup_mutex.tx_mutex_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_mutex_cleanup(&init_test_thread, 0);
+
+ /* Test mutex cleanup with an invalid mutex ID. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup);
+ cleanup_mutex.tx_mutex_id = 0;
+ cleanup_mutex.tx_mutex_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_mutex_cleanup(&init_test_thread, 0);
+
+ /* Test mutex cleanup with an invalid suspension sequence. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup);
+ cleanup_mutex.tx_mutex_id = 0;
+ cleanup_mutex.tx_mutex_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_mutex_cleanup(&init_test_thread, 1);
+
+ /* Test mutex cleanup with an valid mutex ID but a suspension count of 0. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup);
+ cleanup_mutex.tx_mutex_id = TX_MUTEX_ID;
+ cleanup_mutex.tx_mutex_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_mutex_cleanup(&init_test_thread, 0);
+
+ /* Test event flag cleanup with a NULL cleanup pointer. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ cleanup_event_flags.tx_event_flags_group_id = 0;
+ cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_event_flags_cleanup(&init_test_thread, 0);
+
+ /* Test event flag cleanup with a NULL event flag pointer. */
+ init_test_thread.tx_thread_suspend_control_block = TX_NULL;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
+ cleanup_event_flags.tx_event_flags_group_id = 0;
+ cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_event_flags_cleanup(&init_test_thread, 0);
+
+ /* Test event flag cleanup with an invalid ID. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
+ cleanup_event_flags.tx_event_flags_group_id = 0;
+ cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_event_flags_cleanup(&init_test_thread, 0);
+
+ /* Test event flag cleanup with an invalid suspension sequence. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
+ cleanup_event_flags.tx_event_flags_group_id = 0;
+ cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_event_flags_cleanup(&init_test_thread, 1);
+
+ /* Test event flag cleanup with an valid ID but a suspension count of 0. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
+ cleanup_event_flags.tx_event_flags_group_id = TX_EVENT_FLAGS_ID;
+ cleanup_event_flags.tx_event_flags_group_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_event_flags_cleanup(&init_test_thread, 0);
+
+ /* Test block pool cleanup with a NULL cleanup pointer. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ cleanup_block_pool.tx_block_pool_id = 0;
+ cleanup_block_pool.tx_block_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_block_pool_cleanup(&init_test_thread, 0);
+
+ /* Test block pool cleanup with a NULL block pool pointer. */
+ init_test_thread.tx_thread_suspend_control_block = TX_NULL;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
+ cleanup_block_pool.tx_block_pool_id = 0;
+ cleanup_block_pool.tx_block_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_block_pool_cleanup(&init_test_thread, 0);
+
+ /* Test block pool cleanup with an invalid ID. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
+ cleanup_block_pool.tx_block_pool_id = 0;
+ cleanup_block_pool.tx_block_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_block_pool_cleanup(&init_test_thread, 0);
+
+ /* Test block pool cleanup with an invalid suspension sequence. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
+ cleanup_block_pool.tx_block_pool_id = 0;
+ cleanup_block_pool.tx_block_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_block_pool_cleanup(&init_test_thread, 1);
+
+ /* Test block pool cleanup with an valid ID but a suspension count of 0. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
+ cleanup_block_pool.tx_block_pool_id = TX_BLOCK_POOL_ID;
+ cleanup_block_pool.tx_block_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_block_pool_cleanup(&init_test_thread, 0);
+
+ /* Test byte pool cleanup with a NULL cleanup pointer. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ cleanup_byte_pool.tx_byte_pool_id = 0;
+ cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_byte_pool_cleanup(&init_test_thread, 0);
+
+ /* Test byte pool cleanup with a NULL byte pool pointer. */
+ init_test_thread.tx_thread_suspend_control_block = TX_NULL;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
+ cleanup_byte_pool.tx_byte_pool_id = 0;
+ cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_byte_pool_cleanup(&init_test_thread, 0);
+
+ /* Test byte pool cleanup with an invalid ID. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
+ cleanup_byte_pool.tx_byte_pool_id = 0;
+ cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_byte_pool_cleanup(&init_test_thread, 0);
+
+ /* Test byte pool cleanup with an invalid suspension sequence. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
+ cleanup_byte_pool.tx_byte_pool_id = 0;
+ cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_byte_pool_cleanup(&init_test_thread, 1);
+
+ /* Test byte pool cleanup with an valid ID but a suspension count of 0. */
+ init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool;
+ init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
+ cleanup_byte_pool.tx_byte_pool_id = TX_BYTE_POOL_ID;
+ cleanup_byte_pool.tx_byte_pool_suspended_count = 0;
+ init_test_thread.tx_thread_suspension_sequence = 0;
+ _tx_byte_pool_cleanup(&init_test_thread, 0);
+#endif
+
+#ifndef TX_ENABLE_EVENT_TRACE
+
+ /* Call ISR trace events when trace is not enabled. */
+
+ /* Call trace ISR enter event insert. */
+ tx_trace_isr_enter_insert(1);
+
+ /* Call trace ISR exit event insert. */
+ tx_trace_isr_exit_insert(1);
+
+#endif
+
+ /* Test the list start path in timer info get and timer deactivate. */
+ test_timer.tx_timer_id = 0;
+ _tx_timer_create(&test_timer, "init timer", init_timer_entry, 0x5678, 100, 200, TX_AUTO_ACTIVATE);
+ _timer_list_start_backup = _tx_timer_list_start;
+ _tx_timer_list_start = _tx_timer_list_end;
+ _tx_timer_info_get(&test_timer, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ _tx_timer_deactivate(&test_timer);
+ _tx_timer_list_start = _timer_list_start_backup;
+ _tx_timer_deactivate(&test_timer);
+ _tx_timer_delete(&test_timer);
+
+ /* Test the stack analyze function with a dummy thread. */
+
+ /* Clear the test stack analyze flag. */
+ test_stack_analyze_flag = 0;
+
+ /* Make a fake thread with a fake stack. */
+ test_thread2.tx_thread_id = TX_THREAD_ID;
+ for (i = 0; i < (sizeof(test_thread2_stack)/sizeof(ULONG)); i++)
+ {
+ /* Set the fake thread stack to the fill pattern. */
+ test_thread2_stack[i] = TX_STACK_FILL;
+ }
+
+ /* Setup index to last point. */
+ i = (sizeof(test_thread2_stack)/sizeof(ULONG)) - 1;
+
+ /* Setup the stack start and end pointers. */
+ test_thread2.tx_thread_stack_start = &(test_thread2_stack[0]);
+ test_thread2.tx_thread_stack_end = &(test_thread2_stack[i]);
+ test_thread2.tx_thread_stack_size = sizeof(test_thread2_stack);
+ test_thread2.tx_thread_stack_highest_ptr = test_thread2.tx_thread_stack_end;
+ test_thread2.tx_thread_stack_ptr = test_thread2.tx_thread_stack_start;
+
+ /* Fill 20 words of stack. */
+ for (j = 0; j < 20; j++)
+ {
+ /* Fill the stack with 0s. */
+ test_thread2_stack[i--] = 0;
+ }
+
+ /* Call the analyze stack function. */
+ _tx_thread_stack_analyze(&test_thread2);
+
+ /* Call it again for no change coverage. */
+ _tx_thread_stack_analyze(&test_thread2);
+
+ /* Fill 99 words of stack. */
+ for (j = 0; j < 99; j++)
+ {
+ /* Fill the stack with 1s. */
+ test_thread2_stack[i--] = 1;
+ }
+
+ /* Call the analyze stack function. */
+ _tx_thread_stack_analyze(&test_thread2);
+
+ /* Call it again for no change coverage. */
+ _tx_thread_stack_analyze(&test_thread2);
+
+#ifndef TX_MANUAL_TEST
+
+ /* Now set the flag to 1 to cause the thread ID to be cleared. */
+ test_stack_analyze_flag = 1;
+
+ /* Call stack analyze with an ID that is cleared in the middle. */
+ _tx_thread_stack_analyze(&test_thread2);
+
+ /* Restore the ID. */
+ test_thread2.tx_thread_id = TX_THREAD_ID;
+
+ /* Now set the flag to 2 to cause the stack ptr to be equal to the start of the stack. */
+ test_stack_analyze_flag = 2;
+
+ /* Call stack analyze with an ID that is cleared in the middle. */
+ _tx_thread_stack_analyze(&test_thread2);
+ test_thread2.tx_thread_stack_highest_ptr = test_thread2.tx_thread_stack_end;
+
+ /* Now set the flag to 3 to cause the stack pointer to not have the fill pattern. */
+ test_stack_analyze_flag = 3;
+
+ /* Call stack analyze with an ID that is cleared in the middle. */
+ _tx_thread_stack_analyze(&test_thread2);
+#endif
+
+ /* Test error condition on _tx_queue_flush. */
+ test_queue.tx_queue_enqueued = 1;
+ test_queue.tx_queue_suspended_count = 1;
+ test_queue.tx_queue_suspension_list = TX_NULL;
+
+ /* Call _tx_queue_flush to test the thread NULL check. */
+ _tx_queue_flush(&test_queue);
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Make sure the suspension cancelled path is exercised in tx_thread_system_resume... This normally happens,
+ however, sometimes on less real-time platforms the timing is not guaranteed. */
+
+ /* Increment the preempt disable flag. */
+ _tx_thread_preempt_disable++;
+
+ /* Build a thread control block with fake info. */
+ test_thread3.tx_thread_suspending = TX_TRUE;
+ test_thread3.tx_thread_state = TX_SUSPENDED;
+ test_thread3.tx_thread_delayed_suspend = TX_FALSE;
+ test_thread3.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ test_thread3.tx_thread_stack_start = (VOID *) &test_thread2_stack[0];
+ test_thread3.tx_thread_stack_end = (VOID *) &test_thread2_stack[255];
+ test_thread3.tx_thread_stack_ptr = (VOID *) &test_thread2_stack[255];
+
+ /* Call the system resume function directly to insure the suspension cancel works properly. */
+ _tx_thread_system_resume(&test_thread3);
+#endif
+
+ /* Test preempt-disable safeguard. */
+
+ /* Increment the preempt disable flag. */
+ _tx_thread_preempt_disable++;
+
+ /* Test block pool suspenson safeguard. */
+ fake_block_pool.tx_block_pool_available = 0;
+ status = _tx_block_allocate(&fake_block_pool, (VOID **) &pointer, TX_WAIT_FOREVER);
+ if (status != TX_NO_MEMORY)
+ test_control_system_errors++;
+
+ /* Test byte pool suspension safeguard. */
+ fake_byte_pool.tx_byte_pool_fragments = 2;
+ fake_byte_pool.tx_byte_pool_available = 0;
+ status = _tx_byte_allocate(&fake_byte_pool, (VOID **) &pointer, 1000, TX_WAIT_FOREVER);
+ if (status != TX_NO_MEMORY)
+ test_control_system_errors++;
+
+ /* Test event flags suspension safeguard. */
+ fake_event_flags.tx_event_flags_group_current = 0;
+ status = _tx_event_flags_get(&fake_event_flags, 1, TX_AND, &flags, TX_WAIT_FOREVER);
+ if (status != TX_NO_EVENTS)
+ test_control_system_errors++;
+
+ /* Test mutex suspension safeguard. */
+ fake_mutex.tx_mutex_ownership_count = 1;
+ fake_mutex.tx_mutex_inherit = 0;
+ fake_mutex.tx_mutex_owner = &init_test_thread;
+ status = _tx_mutex_get(&fake_mutex, TX_WAIT_FOREVER);
+ if (status != TX_NOT_AVAILABLE)
+ test_control_system_errors++;
+
+ /* Test queue front send suspension safeguard. */
+ fake_queue.tx_queue_available_storage = 0;
+ status = _tx_queue_front_send(&fake_queue, (VOID *) pointer, TX_WAIT_FOREVER);
+ if (status != TX_QUEUE_FULL)
+ test_control_system_errors++;
+
+ /* Test queue receive suspension safeguard. */
+ fake_queue.tx_queue_enqueued = 0;
+ status = _tx_queue_receive(&fake_queue, (VOID **) &pointer, TX_WAIT_FOREVER);
+ if (status != TX_QUEUE_EMPTY)
+ test_control_system_errors++;
+
+ /* Test queue send suspension safeguard. */
+ fake_queue.tx_queue_available_storage = 0;
+ status = _tx_queue_send(&fake_queue, (VOID *) pointer, TX_WAIT_FOREVER);
+ if (status != TX_QUEUE_FULL)
+ test_control_system_errors++;
+
+ /* Test semaphore suspension safeguard. */
+ fake_semaphore.tx_semaphore_count = 0;
+ status = _tx_semaphore_get(&fake_semaphore, TX_WAIT_FOREVER);
+ if (status != TX_NO_INSTANCE)
+ test_control_system_errors++;
+
+ /* Test thread sleep suspension safeguard. */
+ _tx_thread_current_ptr = &init_test_thread;
+ temp = _tx_thread_system_state;
+ _tx_thread_system_state = 0;
+ status = _tx_thread_sleep(10);
+ if (status != TX_CALLER_ERROR)
+ test_control_system_errors++;
+
+ /* Test thread suspend suspension safeguard. */
+ init_test_thread.tx_thread_state = TX_READY;
+ status = _tx_thread_suspend(&init_test_thread);
+ if (status != TX_SUSPEND_ERROR)
+ test_control_system_errors++;
+ _tx_thread_system_state = temp;
+ _tx_thread_current_ptr = TX_NULL;
+
+
+ /* Decrement the preempt disable flag. */
+ _tx_thread_preempt_disable--;
+}
+
+
+
+/* Define the test control thread. This thread is responsible for dispatching all of the
+ tests in the ThreadX test suite. */
+
+void test_control_thread_entry(ULONG thread_input)
+{
+
+UINT i;
+
+ /* Raise the priority of the control thread to 0. */
+ tx_thread_priority_change(&test_control_thread, 0, &i);
+#ifdef CTEST
+ test_control_cleanup();
+#endif
+
+ /* Print out banner. */
+ printf("********************** ThreadX Validation/Regression Test Suite *********************************\n\n");
+
+ /* Print version id. */
+ printf("Version: %s\n\n", _tx_version_id);
+
+ /* Print out the tests... */
+ printf("Running validation/regression test:\n\n");
+
+ /* Loop to process all tests... */
+ i = 0;
+ while (test_control_tests[i].test_entry != TX_NULL)
+ {
+
+ /* Clear the ISR dispatch. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Dispatch the test. */
+ (test_control_tests[i++].test_entry)(test_free_memory_ptr);
+
+ /* Clear the ISR dispatch. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Suspend control test to allow test to run. */
+ tx_thread_suspend(&test_control_thread);
+
+ /* Test finished, cleanup in preparation for the next test. */
+ test_control_cleanup();
+ }
+
+ /* Finished with all tests, print results and return! */
+ printf("**** Testing Complete ****\n");
+ printf("**** Test Summary: Tests Passed: %lu Tests Failed: %lu System Errors: %lu\n", test_control_successful_tests, test_control_failed_tests, test_control_system_errors);
+#ifndef EXTERNAL_EXIT
+ exit(test_control_failed_tests + test_control_system_errors);
+#else
+ external_exit(test_control_failed_tests + test_control_system_errors);
+#endif
+}
+
+
+void test_control_return(UINT status)
+{
+
+UINT old_posture = TX_INT_ENABLE;
+
+
+ /* Save the status in a global. */
+ test_control_return_status = status;
+
+ /* Ensure interrupts are enabled. */
+ old_posture = tx_interrupt_control(TX_INT_ENABLE);
+
+ /* Determine if it was successful or not. */
+ if (status)
+ test_control_failed_tests++;
+ else
+ test_control_successful_tests++;
+
+ /* Now check for system errors. */
+
+ /* Is preempt disable flag set? */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* System error - preempt disable should never be set inside of a thread! */
+ printf(" ***** SYSTEM ERROR ***** _tx_thread_preempt_disable is non-zero!\n");
+ test_control_system_errors++;
+ }
+
+ /* Is system state set? */
+ if (_tx_thread_system_state)
+ {
+
+ /* System error - system state should never be set inside of a thread! */
+ printf(" ***** SYSTEM ERROR ***** _tx_thread_system_state is non-zero!\n");
+ test_control_system_errors++;
+ }
+
+ /* Are interrupts disabled? */
+ if (old_posture == TX_INT_DISABLE)
+ {
+
+ /* System error - interrupts should alwasy be enabled in our test threads! */
+ printf(" ***** SYSTEM ERROR ***** test returned with interrupts disabled!\n");
+ test_control_system_errors++;
+ }
+
+ /* Resume the control thread to fully exit the test. */
+ tx_thread_resume(&test_control_thread);
+}
+
+
+void test_control_cleanup(void)
+{
+
+TX_MUTEX *mutex_ptr;
+TX_THREAD *thread_ptr;
+
+
+ /* Delete all queues. */
+ while(_tx_queue_created_ptr)
+ {
+
+ /* Delete queue. */
+ tx_queue_delete(_tx_queue_created_ptr);
+ }
+
+ /* Delete all semaphores. */
+ while(_tx_semaphore_created_ptr)
+ {
+
+ /* Delete semaphore. */
+ tx_semaphore_delete(_tx_semaphore_created_ptr);
+ }
+
+ /* Delete all event flag groups. */
+ while(_tx_event_flags_created_ptr)
+ {
+
+ /* Delete event flag group. */
+ tx_event_flags_delete(_tx_event_flags_created_ptr);
+ }
+
+ /* Delete all byte pools. */
+ while(_tx_byte_pool_created_ptr)
+ {
+
+ /* Delete byte pool. */
+ tx_byte_pool_delete(_tx_byte_pool_created_ptr);
+ }
+
+ /* Delete all block pools. */
+ while(_tx_block_pool_created_ptr)
+ {
+
+ /* Delete block pool. */
+ tx_block_pool_delete(_tx_block_pool_created_ptr);
+ }
+
+ /* Delete all timers. */
+ while(_tx_timer_created_ptr)
+ {
+
+ /* Deactivate timer. */
+ tx_timer_deactivate(_tx_timer_created_ptr);
+
+ /* Delete timer. */
+ tx_timer_delete(_tx_timer_created_ptr);
+ }
+
+ /* Delete all mutexes (except for system mutex). */
+ while(_tx_mutex_created_ptr)
+ {
+
+ /* Setup working mutex pointer. */
+ mutex_ptr = _tx_mutex_created_ptr;
+
+#ifdef __ghs
+
+ /* Determine if the mutex is the GHS system mutex. If so, don't delete! */
+ if (mutex_ptr == &__ghLockMutex)
+ {
+
+ /* Move to next mutex. */
+ mutex_ptr = mutex_ptr -> tx_mutex_created_next;
+ }
+
+ /* Determine if there are no more mutexes to delete. */
+ if (_tx_mutex_created_count == 1)
+ break;
+#endif
+
+ /* Delete mutex. */
+ tx_mutex_delete(mutex_ptr);
+ }
+
+ /* Delete all threads, except for timer thread, and test control thread. */
+ while (_tx_thread_created_ptr)
+ {
+
+ /* Setup working pointer. */
+ thread_ptr = _tx_thread_created_ptr;
+
+
+#ifdef TX_TIMER_PROCESS_IN_ISR
+
+ /* Determine if there are more threads to delete. */
+ if (_tx_thread_created_count == 1)
+ break;
+
+ /* Determine if this thread is the test control thread. */
+ if (thread_ptr == &test_control_thread)
+ {
+
+ /* Move to the next thread pointer. */
+ thread_ptr = thread_ptr -> tx_thread_created_next;
+ }
+#else
+
+ /* Determine if there are more threads to delete. */
+ if (_tx_thread_created_count == 2)
+ break;
+
+ /* Move to the thread not protected. */
+ while ((thread_ptr == &_tx_timer_thread) || (thread_ptr == &test_control_thread))
+ {
+
+ /* Yes, move to the next thread. */
+ thread_ptr = thread_ptr -> tx_thread_created_next;
+ }
+#endif
+
+ /* First terminate the thread to ensure it is ready for deletion. */
+ tx_thread_terminate(thread_ptr);
+
+ /* Delete the thread. */
+ tx_thread_delete(thread_ptr);
+ }
+
+ /* At this point, only the test control thread and the system timer thread and/or mutex should still be
+ in the system. */
+}
+
+void test_thread_entry(ULONG thread_input)
+{
+
+ /* Resume the next test thread. */
+ tx_thread_resume(&test_thread1);
+
+ /* Suspend this thread but with preemption disabled, so we will actually return. */
+ _tx_thread_preempt_disable++;
+ tx_thread_suspend(&test_thread);
+
+ /* Now perform a fake thread resume to cause preemption and exercise the path in _tx_thread_system_resume that returns to the scheduler. */
+ init_test_thread.tx_thread_state = TX_TERMINATED;
+ init_test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ init_test_thread.tx_thread_new_time_slice = 0;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_suspending = TX_TRUE;
+ init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ init_test_thread.tx_thread_entry = test_thread_entry1;
+ _tx_thread_system_resume(&init_test_thread);
+
+ /* We should not get back here! */
+}
+
+
+void test_thread_entry1(ULONG thread_input)
+{
+
+ /* Do nothing, just return! */
+}
+
+
+void test_exit_notify(TX_THREAD *thread_ptr, UINT type)
+{
+
+ /* Clear the suspending flag to short-circuit the suspension. */
+ thread_ptr -> tx_thread_suspending = TX_FALSE;
+}
+
+
+__attribute__((weak)) void abort_all_threads_suspended_on_mutex(void)
+{
+}
+
+__attribute__((weak)) void suspend_lowest_priority(void)
+{
+}
+
+__attribute__((weak)) void abort_and_resume_byte_allocating_thread(void)
+{
+}
diff --git a/test/tx/regression/threadx_block_memory_basic_test.c b/test/tx/regression/threadx_block_memory_basic_test.c
new file mode 100644
index 00000000..5f2afa01
--- /dev/null
+++ b/test/tx/regression/threadx_block_memory_basic_test.c
@@ -0,0 +1,568 @@
+/* This test is designed to test simple memory block pool creation, deletion, and
+ allocates and releases. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+typedef struct BLOCK_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_BLOCK_POOL pool;
+ ULONG first_middle;
+ ULONG second_middle;
+ ULONG pool_area[2048/sizeof(ULONG)];
+ ULONG next_to_last;
+ ULONG last;
+
+} BLOCK_MEMORY_TEST;
+
+static BLOCK_MEMORY_TEST block_memory;
+
+
+/* Define external reference for status of block pool create from initialization. */
+
+extern UINT test_block_pool_create_init;
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+
+
+static TX_BLOCK_POOL pool_0;
+static TX_BLOCK_POOL pool_1;
+static TX_BLOCK_POOL pool_2;
+static TX_BLOCK_POOL pool_3;
+
+static TX_TIMER timer_0;
+
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Prototype direct call to block pool core service. */
+
+UINT _tx_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size,
+ VOID *pool_start, ULONG pool_size);
+
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Determine if calling block pool create from initialization was successful. */
+ if (test_block_pool_create_init != TX_SUCCESS)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a block pool from a timer. */
+ pointer = (CHAR *) 0x30000;
+ status = tx_block_pool_create(&pool_3, "pool 3", 100, pointer, 320);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a block pool. */
+ status = tx_block_pool_delete(&pool_0);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ timer_executed = 1;
+
+ /* Attempt to allocate a block with suspension from a timer. */
+ status = tx_block_allocate(&pool_0, (void **) &pointer, 10);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+CHAR *pointer;
+UINT status;
+
+
+ /* Attempt to Allocate block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a block pool from an ISR. */
+ status = tx_block_pool_create(&pool_3, "pool 3", 100, (void *) 0x100000, 320);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a pool from an ISR. */
+ status = tx_block_pool_delete(&pool_0);
+
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_block_memory_basic_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Basic Functionality Test....................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Basic Functionality Test....................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create block pools 0 and 1. */
+ status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
+ pointer = pointer + 320;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Basic Functionality Test....................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_block_pool_create(&pool_1, "pool 1", 100, pointer, 320);
+ pointer = pointer + 320;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Basic Functionality Test....................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Check the no-blocks path. */
+ status = _tx_block_pool_create(&pool_2, "pool 2", 100, pointer, 50);
+ pointer = pointer + 320;
+
+ /* Check status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ printf("Running Block Memory Basic Functionality Test....................... ERROR #5\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+CHAR *pointer_2;
+CHAR *pointer_3;
+CHAR *pointer_4;
+INT i;
+unsigned long fake_block[20];
+
+
+ /* Inform user. */
+ printf("Running Block Memory Basic Functionality Test....................... ");
+
+ /* Perform block memory test. */
+ block_memory.first = 0x11223344;
+ block_memory.second = 0x55667788;
+ block_memory.first_middle = 0x21314151;
+ block_memory.second_middle= 0x61718191;
+ block_memory.next_to_last = 0x99aabbcc;
+ block_memory.last = 0xddeeff00;
+
+ /* Create the block pool. */
+ status = tx_block_pool_create(&block_memory.pool, "pool memory", 16, &block_memory.pool_area[0], (2048*sizeof(ULONG))/sizeof(ULONG));
+ tx_block_pool_delete(&block_memory.pool);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (block_memory.first != 0x11223344) ||
+ (block_memory.second != 0x55667788) ||
+ (block_memory.first_middle != 0x21314151) ||
+ (block_memory.second_middle != 0x61718191) ||
+ (block_memory.next_to_last != 0x99aabbcc) ||
+ (block_memory.last != 0xddeeff00))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Try to release a non-block. */
+ fake_block[0] = 0;
+ fake_block[1] = 0;
+ status = tx_block_release(&fake_block[2]);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Try to release a block that points to a non-pool. */
+ fake_block[0] = 0;
+ fake_block[1] = (unsigned long) &fake_block[0];
+ status = tx_block_release(&fake_block[2]);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Allocate first block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Allocate second block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+
+ /* Allocate third block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Attempt to allocate fourth block from the pool. This should fail because
+ there should be no more blocks in the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Block memory error. */
+ printf("ERROR ##12\n");
+ test_control_return(1);
+ }
+
+ /* Set the memory of all of the allocated blocks. */
+ for (i =0; i < 100; i++)
+ {
+ pointer_1[i] = (CHAR) 0xFF;
+ pointer_2[i] = (CHAR) 0xFF;
+ pointer_3[i] = (CHAR) 0xFF;
+ }
+
+ /* Now release each of the blocks. */
+ status = tx_block_release(pointer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Release the second block. */
+ status = tx_block_release(pointer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Release the third block. */
+ status = tx_block_release(pointer_3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Allocate each block again to make sure everything still
+ works. The block addresses should come out in reverse
+ order, because a released block is placed at the head of
+ the list. */
+
+ /* Allocate first block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Allocate second block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+
+ /* Allocate third block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Attempt to allocate fourth block from the pool. This should fail because
+ there should be no more blocks in the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Now resume the background thread. */
+ tx_thread_resume(&thread_1);
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete both block pools. */
+ status = tx_block_pool_delete(&pool_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ status = tx_block_pool_delete(&pool_1);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (error))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+ }
+}
diff --git a/test/tx/regression/threadx_block_memory_error_detection_test.c b/test/tx/regression/threadx_block_memory_error_detection_test.c
new file mode 100644
index 00000000..de28012f
--- /dev/null
+++ b/test/tx/regression/threadx_block_memory_error_detection_test.c
@@ -0,0 +1,387 @@
+/* This test is designed to test error detection for simple memory block operations. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+
+static TX_BLOCK_POOL pool_0;
+static TX_BLOCK_POOL pool_1;
+static TX_BLOCK_POOL pool_2;
+static CHAR *pointer;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+UINT _txe_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size,
+ VOID *pool_start, ULONG pool_size, UINT pool_control_block_size);
+
+
+/* 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_block_memory_error_detection_application_define(void *first_unused_memory)
+#endif
+{
+
+INT status;
+
+ /* 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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Create block pool 0. */
+ status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
+ pointer = pointer + 320;
+
+#ifndef TX_DISABLE_ERROR_CHECKING /* skip this test and pretend it passed */
+
+ /* Create block pool again to get pool_ptr error. */
+ status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
+ if (status != TX_POOL_ERROR)
+ return;
+
+ /* Create block pool with NULL pointer. */
+ status = tx_block_pool_create(TX_NULL, "pool 0", 100, pointer, 320);
+ if (status != TX_POOL_ERROR)
+ {
+
+ printf("Running Block Memory Error Detection Test........................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create block pool pointer if NULL start. */
+ status = tx_block_pool_create(&pool_1, "pool 0", 100, NULL, 320);
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("Running Block Memory Error Detection Test........................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create block pool pointer with invalid size. */
+ status = tx_block_pool_create(&pool_1, "pool 0", 100, pointer, 100);
+ if (status != TX_SIZE_ERROR)
+ {
+
+ printf("Running Block Memory Error Detection Test........................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Attempt of allocate block with NULL dest. */
+ status = tx_block_allocate(&pool_0, (VOID **) TX_NULL, TX_NO_WAIT);
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("Running Block Memory Error Detection Test........................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Delete null pointer. */
+ status = tx_block_pool_delete(TX_NULL);
+ if (status != TX_POOL_ERROR)
+ {
+
+ printf("Running Block Memory Error Detection Test........................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+#endif /* TX_DISABLE_ERROR_CHECKING */
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+UINT status;
+CHAR *pointer_1;
+CHAR *pointer_2;
+CHAR *pointer_3;
+CHAR *pointer_4;
+INT i;
+#endif
+
+ /* Inform user. */
+ printf("Running Block Memory Error Detection Test........................... ");
+
+#ifndef TX_DISABLE_ERROR_CHECKING /* skip this test and pretend it passed */
+
+ status = tx_block_pool_create(&pool_1, "pool 1", 100, pointer, 320);
+ pointer = pointer + 320;
+
+ /* Attempt to create a pool with an invalid size. */
+ status = _txe_block_pool_create(&pool_2, "pool 2", 100, pointer, 320, 777777);
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Error! */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Allocate with a NULL destination pointer. */
+ status = tx_block_allocate(&pool_0, (VOID **) TX_NULL, TX_NO_WAIT);
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Error! */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Allocate with a NULL pool pointer. */
+ status = tx_block_allocate(TX_NULL, (VOID **) TX_NULL, TX_NO_WAIT);
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Error! */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Allocate with bad pool pointer. */
+ pool_2.tx_block_pool_id = 0;
+ status = tx_block_allocate(&pool_2, (VOID **) TX_NULL, TX_NO_WAIT);
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Error! */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Release bad pool ptr. */
+ status = tx_block_release(TX_NULL);
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Error! */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Allocate first block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Allocate second block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+
+ /* Allocate third block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Attempt to allocate fourth block from the pool. This should fail because
+ there should be no more blocks in the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Error! */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Set the memory of all of the allocated blocks. */
+ for (i =0; i < 100; i++)
+ {
+ pointer_1[i] = (CHAR) 0xFF;
+ pointer_2[i] = (CHAR) 0xFF;
+ pointer_3[i] = (CHAR) 0xFF;
+ }
+
+ /* Now release each of the blocks. */
+ status = tx_block_release(pointer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Release the second block. */
+ status = tx_block_release(pointer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Release the third block. */
+ status = tx_block_release(pointer_3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Allocate each block again to make sure everything still
+ works. The block addresses should come out in reverse
+ order, because a released block is placed at the head of
+ the list. */
+
+ /* Allocate first block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Allocate second block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+
+ /* Allocate third block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Attempt to allocate fourth block from the pool. This should fail because
+ there should be no more blocks in the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Error! */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Delete both block pools. */
+ status = tx_block_pool_delete(&pool_0);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ status = tx_block_pool_delete(&pool_1);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Error! */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete again. */
+ status = tx_block_pool_delete(&pool_1);
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Error! */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ thread_0_counter++;
+
+#endif /* TX_DISABLE_ERROR_CHECKING */
+
+ /* All is good! */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
diff --git a/test/tx/regression/threadx_block_memory_information_test.c b/test/tx/regression/threadx_block_memory_information_test.c
new file mode 100644
index 00000000..d6416bc2
--- /dev/null
+++ b/test/tx/regression/threadx_block_memory_information_test.c
@@ -0,0 +1,713 @@
+/* This test is designed to test block memory information services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_block_pool.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static TX_BLOCK_POOL block_pool_0;
+static TX_BLOCK_POOL block_pool_2;
+#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
+static TX_BLOCK_POOL block_pool_1;
+#endif
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+/* Direct core function to bypass the error checking shell. */
+UINT _tx_block_pool_info_get(TX_BLOCK_POOL *pool_ptr, CHAR **name, ULONG *available_blocks,
+ ULONG *total_blocks, TX_THREAD **first_suspended,
+ ULONG *suspended_count, TX_BLOCK_POOL **next_pool);
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_block_memory_information_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create the block_pool with one block. */
+ status = tx_block_pool_create(&block_pool_0, "block_pool 0", 30, pointer, 40);
+ pointer = pointer + 40;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Information Test............................... ERROR #8\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+CHAR *name;
+ULONG available;
+ULONG total_blocks;
+TX_THREAD *first_suspended;
+ULONG suspended_count;
+TX_BLOCK_POOL *next_pool;
+ULONG allocates;
+ULONG releases;
+ULONG suspensions;
+ULONG timeouts;
+
+
+ /* Inform user. */
+ printf("Running Block Memory Information Test............................... ");
+
+ /* Allocate the one block. */
+ tx_block_allocate(&block_pool_0, &pointer, TX_NO_WAIT);
+
+ /* Nothing to do here, but check prioritization with no suspended threads. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check for an error condition. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Get both threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 and 2 are suspended on the block_pool. */
+ if ((thread_1.tx_thread_state != TX_BLOCK_MEMORY) || (thread_2.tx_thread_state != TX_BLOCK_MEMORY) ||
+ (block_pool_0.tx_block_pool_suspension_list != &thread_1))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_2))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check status and make sure thread 3 is at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_3))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Now determine if thread 4 is at the front of the list... It should be! */
+ if (block_pool_0.tx_block_pool_suspension_list != &thread_4)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Test the NULL pointer on the info get call. */
+ status = tx_block_pool_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for the proper error code. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Test the non-thread pointer on the info get call. */
+ block_pool_2.tx_block_pool_id = 0;
+ status = tx_block_pool_info_get(&block_pool_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for the proper error code. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Now use the information services in order to test them. */
+ status = tx_block_pool_info_get(&block_pool_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_block_pool_info_get(&block_pool_0, &name, &available, &total_blocks, &first_suspended, &suspended_count, &next_pool);
+
+ /* Check for an error condition. */
+ if ((status) || (available != block_pool_0.tx_block_pool_available) || (total_blocks != block_pool_0.tx_block_pool_total) ||
+ (first_suspended != &thread_4) || (suspended_count != block_pool_0.tx_block_pool_suspended_count) || (next_pool != &block_pool_0))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
+
+ /* Call the core block pool info get function with a NULL pointer. */
+ status = _tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for the proper error code. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Call the core block pool info get function with a non-initialized pool. */
+ status = _tx_block_pool_performance_info_get(&block_pool_1, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for the proper error code. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Now get the pool performance information. */
+ status = tx_block_pool_performance_info_get(&block_pool_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_block_pool_performance_info_get(&block_pool_0, &allocates, &releases, &suspensions, &timeouts);
+
+ /* Check for an error condition. */
+ if ((status) || (allocates != block_pool_0.tx_block_pool_performance_allocate_count) ||
+ (releases != block_pool_0.tx_block_pool_performance_release_count) ||
+ (suspensions != block_pool_0.tx_block_pool_performance_suspension_count) ||
+ (timeouts != block_pool_0.tx_block_pool_performance_timeout_count))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system pool performance information. */
+ status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_block_pool_performance_system_info_get(&allocates, &releases, &suspensions, &timeouts);
+
+ /* Check for an error condition. */
+ if ((status) || (allocates != _tx_block_pool_performance_allocate_count) || (releases != _tx_block_pool_performance_release_count) ||
+ (suspensions != _tx_block_pool_performance_suspension_count) || (timeouts != _tx_block_pool_performance_timeout_count))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+#else
+
+ /* Call the block pool performance info get function. */
+ status = tx_block_pool_performance_info_get(&block_pool_0, &allocates, &releases, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Call the block pool performance info get function. */
+ status = tx_block_pool_performance_info_get(TX_NULL, &allocates, &releases, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Call the block pool performance info get function. */
+ status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, &releases, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Call the block pool performance info get function. */
+ status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Call the block pool performance info get function. */
+ status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Call the block pool performance info get function. */
+ status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system pool performance information. */
+ status = tx_block_pool_performance_system_info_get(&allocates, &releases, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system pool performance information. */
+ status = tx_block_pool_performance_system_info_get(TX_NULL, &releases, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system pool performance information. */
+ status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system pool performance information. */
+ status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system pool performance information. */
+ status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for the proper error code. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+#endif
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+VOID *pointer;
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+ }
+}
+
diff --git a/test/tx/regression/threadx_block_memory_prioritize_test.c b/test/tx/regression/threadx_block_memory_prioritize_test.c
new file mode 100644
index 00000000..274daa01
--- /dev/null
+++ b/test/tx/regression/threadx_block_memory_prioritize_test.c
@@ -0,0 +1,500 @@
+/* This test is designed to test block memory pool prioritize. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static TX_BLOCK_POOL block_pool_0;
+static TX_BLOCK_POOL block_pool_1;
+
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Determine if thread 3 is at the front of the suspension list. */
+ if (block_pool_0.tx_block_pool_suspension_list == &thread_3)
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+ }
+ else
+ {
+
+ /* Abort the wait of thread 5. */
+ tx_thread_wait_abort(&thread_5);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_block_memory_prioritize_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create the block_pool with one block. */
+ status = tx_block_pool_create(&block_pool_0, "block_pool 0", 30, pointer, 40);
+ pointer = pointer + 40;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Prioritize Test................................ ERROR #8\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Inform user. */
+ printf("Running Block Memory Prioritize Test................................ ");
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to prioritize with a NULL pointer. */
+ status = tx_block_pool_prioritize(TX_NULL);
+
+ /* Check for an error condition. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to prioritize with a bad pool pointer. */
+ block_pool_1.tx_block_pool_id = 0;
+ status = tx_block_pool_prioritize(&block_pool_1);
+
+ /* Check for an error condition. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Allocate the one block. */
+ tx_block_allocate(&block_pool_0, &pointer, TX_NO_WAIT);
+
+ /* Nothing to do here, but check prioritization with no suspended threads. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check for an error condition. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Get both threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 and 2 are suspended on the block_pool. */
+ if ((thread_1.tx_thread_state != TX_BLOCK_MEMORY) || (thread_2.tx_thread_state != TX_BLOCK_MEMORY) ||
+ (block_pool_0.tx_block_pool_suspension_list != &thread_1))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check status and make sure thread 2 is at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_2))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Call block pool prioritize again to test the don't-do-anything path in tx_block_pool_prioritize. */
+ status += tx_block_pool_prioritize(&block_pool_0);
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check status and make sure thread 3 is at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_3))
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_block_pool_prioritize(&block_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Now determine if thread 4 is at the front of the list... It should be! */
+ if (block_pool_0.tx_block_pool_suspension_list != &thread_4)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+VOID *pointer;
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get block from pool. */
+ status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+ }
+}
diff --git a/test/tx/regression/threadx_block_memory_suspension_test.c b/test/tx/regression/threadx_block_memory_suspension_test.c
new file mode 100644
index 00000000..6f2d635c
--- /dev/null
+++ b/test/tx/regression/threadx_block_memory_suspension_test.c
@@ -0,0 +1,311 @@
+/* This test is designed to test suspension on memory block pools. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_BLOCK_POOL pool_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_block_memory_suspension_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Test................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Test................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Test................................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create block pool. */
+ status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
+ pointer = pointer + 320;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Test................................ ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+CHAR *pointer_2;
+CHAR *pointer_3;
+
+
+ /* Inform user. */
+ printf("Running Block Memory Suspension Test................................ ");
+
+ /* Increment the run counter. */
+ thread_0_counter++;
+
+ /* Allocate all blocks from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+
+ /* Get the last block. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Let the other thread suspend on the pool. */
+ tx_thread_relinquish();
+
+ /* Now release the block to lift the suspension on the other thread. */
+ status = tx_block_release(pointer_3);
+
+ /* Check status and run counter. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Let the other thread run again. */
+ tx_thread_relinquish();
+
+ /* Check the run counter of the other thread. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* At this point the other thread has run and there is one block free. */
+
+ /* Get the last block again. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Resume the second thread. */
+ tx_thread_resume(&thread_2);
+
+ /* Let both threads suspend on the block pool via relinquish. */
+ tx_thread_relinquish();
+
+ /* Now release the block. */
+ status = tx_block_release(pointer_3);
+
+ /* Check status and run counter. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Let thread 1 release the block. */
+ tx_thread_relinquish();
+
+ /* Let thread 2 get the block and release the block. */
+ tx_thread_relinquish();
+
+ /* Check status and run counter. */
+ if ((thread_1_counter != 3) || (thread_2_counter != 1))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+ else
+ {
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+
+
+ /* Attempt to get a block from the pool. */
+ while(1)
+ {
+
+ /* Allocate a block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_WAIT_FOREVER);
+
+ /* Determine if the allocate was successful. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Release the block. */
+ tx_block_release(pointer_1);
+
+ /* Switch back to other thread. */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+
+
+ /* Attempt to get a block from the pool. */
+ while(1)
+ {
+
+ /* Allocate a block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_WAIT_FOREVER);
+
+ /* Determine if the allocate was successful. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Release the block. */
+ tx_block_release(pointer_1);
+
+ /* Switch back to other thread. */
+ tx_thread_relinquish();
+ }
+}
+
+
diff --git a/test/tx/regression/threadx_block_memory_suspension_timeout_test.c b/test/tx/regression/threadx_block_memory_suspension_timeout_test.c
new file mode 100644
index 00000000..f290f01a
--- /dev/null
+++ b/test/tx/regression/threadx_block_memory_suspension_timeout_test.c
@@ -0,0 +1,212 @@
+/* This test is designed to test timeouts on suspension on memory block pools. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_BLOCK_POOL pool_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_block_memory_suspension_timeout_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Timeout Test........................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Timeout Test........................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Timeout Test........................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create block pool. */
+ status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
+ pointer = pointer + 320;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Suspension Timeout Test........................ ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+CHAR *pointer_2;
+CHAR *pointer_3;
+
+
+ /* Inform user. */
+ printf("Running Block Memory Suspension Timeout Test........................ ");
+
+ /* Allocate all blocks from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+ status += tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+ status += tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+ /* Sleep for 64 ticks to allow the other thread 6 timeouts on the block
+ pool. */
+ tx_thread_sleep(64);
+
+ /* Incrment the run counter. */
+ thread_0_counter++;
+
+ /* Check the counter of the other thread. */
+ if ((thread_1_counter != 6) || (thread_2_counter != 3))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+
+
+ /* Attempt to get a block from the pool. */
+ while(1)
+ {
+
+ /* Allocate a block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, 10);
+
+ /* Determine if the allocate was successful. */
+ if (status != TX_NO_MEMORY)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+
+
+ /* Delay so we get some single suspension timeouts as well. */
+ tx_thread_sleep(32);
+
+ /* Attempt to get a block from the pool. */
+ while(1)
+ {
+
+ /* Allocate a block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, 10);
+
+ /* Determine if the allocate was successful. */
+ if (status != TX_NO_MEMORY)
+ return;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
diff --git a/test/tx/regression/threadx_block_memory_thread_terminate_test.c b/test/tx/regression/threadx_block_memory_thread_terminate_test.c
new file mode 100644
index 00000000..c9221af9
--- /dev/null
+++ b/test/tx/regression/threadx_block_memory_thread_terminate_test.c
@@ -0,0 +1,185 @@
+/* This test is designed to test thread termination on a thread suspended on a block
+ memory pool. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+
+static TX_BLOCK_POOL pool_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_block_memory_thread_terminate_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Thread Terminate Test.......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Thread Terminate Test.......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create block pool. */
+ status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
+ pointer = pointer + 320;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Block Memory Thread Terminate Test.......................... ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+CHAR *pointer_2;
+CHAR *pointer_3;
+
+
+ /* Inform user. */
+ printf("Running Block Memory Thread Terminate Test.......................... ");
+
+ /* Allocate all blocks from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
+ status += tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
+ status += tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
+
+ /* Increment the run counter. */
+ thread_0_counter++;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block memory error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+ TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
+ TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
+
+
+ /* Let other thread suspend on block pool. */
+ tx_thread_relinquish();
+
+ /* Terminate the other thread. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_TERMINATED) ||
+ (thread_1_counter != 0))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Release all the blocks. */
+ status = tx_block_release(pointer_1);
+ status += tx_block_release(pointer_2);
+ status += tx_block_release(pointer_3);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_TERMINATED) ||
+ (thread_1_counter != 0))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+
+
+ /* Attempt to get a block from the pool. */
+ while(1)
+ {
+
+ /* Allocate a block from the pool. */
+ status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, 10);
+
+ /* Determine if the allocate was successful. */
+ if (status != TX_NO_MEMORY)
+ return;
+
+ /* Set all the memory of the blocks. */
+ TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
diff --git a/test/tx/regression/threadx_byte_memory_basic_test.c b/test/tx/regression/threadx_byte_memory_basic_test.c
new file mode 100644
index 00000000..9fffc840
--- /dev/null
+++ b/test/tx/regression/threadx_byte_memory_basic_test.c
@@ -0,0 +1,1064 @@
+/* This test is designed to test simple memory byte pool creation, deletion, and
+ allocates and releases. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+typedef struct BYTE_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_BYTE_POOL pool;
+ ULONG first_middle;
+ ULONG second_middle;
+ ULONG pool_area[2048/sizeof(ULONG)];
+ ULONG next_to_last;
+ ULONG last;
+
+} BYTE_MEMORY_TEST;
+
+static BYTE_MEMORY_TEST byte_memory;
+
+
+/* Define external reference to byte pool creation status. */
+
+extern UINT test_byte_pool_create_init;
+
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+UINT _txe_byte_pool_create(TX_BYTE_POOL *pool_ptr, CHAR *name_ptr, VOID *pool_start,
+ ULONG pool_size, UINT pool_control_block_size);
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+
+static TX_BYTE_POOL pool_0;
+static TX_BYTE_POOL pool_1;
+static TX_BYTE_POOL pool_2;
+static TX_BYTE_POOL pool_3;
+
+static TX_BYTE_POOL pool_4;
+static UCHAR *search_ptr_1;
+static UCHAR *block_0;
+static UCHAR *block_1;
+static UCHAR *block_2;
+static UCHAR *block_3;
+static UCHAR *block_4;
+static CHAR *pool_4_memory;
+static TX_TIMER timer_0;
+
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+UINT _tx_byte_release(VOID *memory_ptr);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Determine if calling byte pool create from initialization was successful. */
+ if (test_byte_pool_create_init != TX_SUCCESS)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a byte pool from a timer. */
+ pointer = (CHAR *) 0x30000;
+ status = tx_byte_pool_create(&pool_2, "pool 2", pointer, 108);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a byte pool with an invalid size. */
+ status = _txe_byte_pool_create(&pool_3, "pool 3", pointer,
+ 108, (sizeof(TX_BYTE_POOL)+1));
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Try to delete a byte pool from a timer. */
+ status = tx_byte_pool_delete(&pool_0);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to release byte memory from timer. */
+ pointer = (CHAR *) 0x30000;
+ status = tx_byte_release(pointer);
+
+ /* Check for error status! */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+CHAR *pointer;
+UINT status;
+
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 24, 100);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+
+ /* Attempt to create a byte pool from an ISR. */
+ status = tx_byte_pool_create(&pool_2, "pool 0", (void *) 0x100000, 108);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to deleate a pool from an ISR. */
+ status = tx_byte_pool_delete(&pool_0);
+
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to release byte memory from ISR. */
+ pointer = (CHAR *) 0x30000;
+ status = tx_byte_release(pointer);
+
+ /* Check for error status! */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_byte_memory_basic_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Basic Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create byte pools 0 and 1. */
+ status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
+ pointer = pointer + 108;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Basic Test...................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_byte_pool_create(&pool_1, "pool 1", pointer, 200);
+ pointer = pointer + 200;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Basic Test...................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Test for search pointer issue on wrapped seach with prior block to search pointer merged. */
+ status = tx_byte_pool_create(&pool_4, "pool 4", pointer, 300);
+ pool_4_memory = pointer;
+ pointer = pointer + 300;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Basic Test...................................... ERROR #3a\n");
+ test_control_return(1);
+ }
+
+ /* Allocate first block. */
+ status += tx_byte_allocate(&pool_4, (VOID **) &block_0, 80, TX_NO_WAIT);
+
+ /* Save next search pointer. */
+ search_ptr_1 = pool_4.tx_byte_pool_search;
+
+ /* Clear the allocatged memory. */
+ TX_MEMSET(block_0, 0, 80);
+
+ /* Allocate another block. */
+ status += tx_byte_allocate(&pool_4, (VOID **) &block_1, 80, TX_NO_WAIT);
+
+ /* Clear the allocated block. */
+ TX_MEMSET(block_1, 0, 80);
+
+ /* Allocate the third and final block. */
+ status += tx_byte_allocate(&pool_4, (VOID **) &block_2, 80, TX_NO_WAIT);
+
+ /* Clear the allocated block. */
+ TX_MEMSET(block_2, 0, 80);
+
+ /* Release the first block. */
+ status += tx_byte_release(block_0);
+
+ /* Release the second block. */
+ status += tx_byte_release(block_1);
+
+ /* Manually move the search pointer to create the case where the search wraps and a merge happens on the search pointer
+ necessitating its update. */
+ pool_4.tx_byte_pool_search = search_ptr_1; /* Point to the middle block. */
+
+ /* Allocate a larger block that will wrap the search and require moving as well as an update of the search pointer. */
+ status += tx_byte_allocate(&pool_4, (VOID **) &block_3, 120, TX_NO_WAIT);
+
+ /* Clear the newly allocated block. */
+ TX_MEMSET(block_3, 0, 120);
+
+ /* At this point, verify the search pointer was properly updated in the previous allocation. */
+ status += tx_byte_allocate(&pool_4, (VOID **) &block_4, 40, TX_NO_WAIT); /* Should fail since search pointer is now invalid! */
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Basic Test...................................... ERROR #3b\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer_1;
+CHAR *pointer_2;
+CHAR *pointer_3;
+CHAR *pointer_4;
+INT i;
+ULONG array[20];
+UCHAR *save_search;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Basic Test...................................... ");
+
+ /* Perform byte memory test. */
+ byte_memory.first = 0x11223344;
+ byte_memory.second = 0x55667788;
+ byte_memory.first_middle = 0x21314151;
+ byte_memory.second_middle= 0x61718191;
+ byte_memory.next_to_last = 0x99aabbcc;
+ byte_memory.last = 0xddeeff00;
+
+ /* Create the byte pool. */
+ status = tx_byte_pool_create(&byte_memory.pool, "pool memory", &byte_memory.pool_area[0], (2048*sizeof(ULONG))/sizeof(ULONG));
+ tx_byte_pool_delete(&byte_memory.pool);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (byte_memory.first != 0x11223344) ||
+ (byte_memory.second != 0x55667788) ||
+ (byte_memory.first_middle != 0x21314151) ||
+ (byte_memory.second_middle != 0x61718191) ||
+ (byte_memory.next_to_last != 0x99aabbcc) ||
+ (byte_memory.last != 0xddeeff00))
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Increment the run counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Try to create a NULL pool. */
+ pointer_1 = (CHAR *) 0x30000;
+ status = tx_byte_pool_create(TX_NULL, "pool 0", pointer_1, 108);
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Try to create the same pool. */
+ status = tx_byte_pool_create(&pool_0, "pool 0", pointer_1, 108);
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Try to create a pool with a NULL start address. */
+ status = tx_byte_pool_create(&pool_2, "pool 2", TX_NULL, 108);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Try to create a pool with a a bad size. */
+ status = tx_byte_pool_create(&pool_2, "pool 2", pointer_1, 1);
+
+ /* Check status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Try to delete a byte pool with a NULL pointer. */
+ status = tx_byte_pool_delete(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Try to delete a byte pool that hasn't been created. */
+ pool_2.tx_byte_pool_id = 0;
+ status = tx_byte_pool_delete(&pool_2);
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Test NULL pool pointer. */
+ status = tx_byte_allocate(TX_NULL, (VOID **) &pointer_1, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Test non-created pool pointer. */
+ pool_2.tx_byte_pool_id = 0;
+ status = tx_byte_allocate(&pool_2, (VOID **) &pointer_1, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Test NULL memory pointer. */
+ status = tx_byte_allocate(&pool_0, (VOID **) TX_NULL, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Test extreme size. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 240000, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Test size of 0. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Test NULL pointer release. */
+ status = tx_byte_release(TX_NULL);
+
+ /* Check for error status! */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_2, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to allocate fourth area from the pool. This should fail because
+ there should be not enough bytes in the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_4, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Set the memory of all of the allocated memory. */
+ for (i =0; i < 24; i++)
+ {
+ pointer_1[i] = (CHAR) 0xFF;
+ pointer_2[i] = (CHAR) 0xFF;
+ pointer_3[i] = (CHAR) 0xFF;
+ }
+
+ /* Test the byte release with a bad block pointer. */
+ status = _tx_byte_release(TX_NULL);
+
+ /* Check for error status! */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Test another bad block release... no pool pointer! */
+ array[0] = 0;
+ array[1] = 0;
+ array[2] = 0;
+ status = _tx_byte_release(&array[2]);
+
+ /* Check for error status! */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Test another bad block release.... pool pointer is not a valid pool! */
+ array[0] = 0;
+ array[1] = (ULONG) &array[3];
+ array[2] = 0;
+ array[3] = 0;
+ status = _tx_byte_release(&array[2]);
+
+ /* Check for error status! */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Now release each of the blocks. */
+ status = tx_byte_release(pointer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Now release the same block again. */
+ status = tx_byte_release(pointer_1);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Release the second memory area. */
+ status = tx_byte_release(pointer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Release the third memory area. */
+ status = tx_byte_release(pointer_3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Allocate each block again to make sure everything still
+ works. */
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Allocate second memory area from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_2, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Allocate third memory area from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to allocate fourth memory area from the pool. This should fail because
+ there should be not enough bytes in the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_4, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Now release each of the blocks. */
+ status = tx_byte_release(pointer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Release the second memory area. */
+ status = tx_byte_release(pointer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Release the third memory area. */
+ status = tx_byte_release(pointer_3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Now allocate a block that should cause all of the blocks to merge
+ together. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 88, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to allocate fourth memory area from the pool. This should fail because
+ there should be not enough bytes in the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_4, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+ /* Release the block. */
+ status = tx_byte_release(pointer_3);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+ /* Now ensure the search pointer update in the byte search algorithm is updated. */
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ /* Allocate second memory area from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_2, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+
+ /* Allocate third memory area from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #39\n");
+ test_control_return(1);
+ }
+
+ /* Release the middle block. */
+ status = tx_byte_release(pointer_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #40\n");
+ test_control_return(1);
+ }
+
+ /* Move the search pointer to the third block to exercise that code in the byte search algorithm. */
+ pool_0.tx_byte_pool_search = (UCHAR *) pointer_3-8;
+
+ /* Now allocate the block again. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_2, 24, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #41\n");
+ test_control_return(1);
+ }
+
+ /* Now release the blocks are test the merge with the update of the search pointer. */
+ status = tx_byte_release(pointer_3);
+ status += tx_byte_release(pointer_2);
+ status += tx_byte_release(pointer_1);
+
+ /* Move the search pointer to the third block to exercise that code in the byte search algorithm. */
+ pool_0.tx_byte_pool_search = (UCHAR *) pointer_3-8;
+
+ /* Allocate a large block to force the search pointer update. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 88, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #42\n");
+ test_control_return(1);
+ }
+
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #43\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete both byte pools. */
+ status = tx_byte_pool_delete(&pool_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #44\n");
+ test_control_return(1);
+ }
+
+ status = tx_byte_pool_delete(&pool_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #45\n");
+ test_control_return(1);
+ }
+
+ /* Delete pool 4. */
+ status = tx_byte_pool_delete(&pool_4);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #46\n");
+ test_control_return(1);
+ }
+
+ /* Create pool 4. */
+ status = tx_byte_pool_create(&pool_4, "pool 4", pool_4_memory, 300);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #47\n");
+ test_control_return(1);
+ }
+
+ /* Allocate three blocks... */
+ status = tx_byte_allocate(&pool_4, (VOID **) &pointer_1, 84, TX_NO_WAIT);
+ status += tx_byte_allocate(&pool_4, (VOID **) &pointer_2, 84, TX_NO_WAIT);
+ status += tx_byte_allocate(&pool_4, (VOID **) &pointer_3, 84, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #48\n");
+ test_control_return(1);
+ }
+
+ /* At this point, there should be three allocated blocks and the reserved block at the end. */
+
+ /* Now release all the blocks in reverse order. This should leave the search pointer at the last block. */
+ status = tx_byte_release(pointer_3);
+ save_search = pool_4.tx_byte_pool_search;
+ status += tx_byte_release(pointer_2);
+ status += tx_byte_release(pointer_1);
+
+ /* Move the search pointer back to the last block. */
+ pool_4.tx_byte_pool_search = save_search;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #49\n");
+ test_control_return(1);
+ }
+
+ /* Now attempt to allocate a block that requires a merge, which should exercise the branch in byte search that does not
+ result in a search pointer change. */
+ status = tx_byte_allocate(&pool_4, (VOID **) &pointer_1, 168, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #50\n");
+ test_control_return(1);
+ }
+
+ /* Release the last block. */
+ status = tx_byte_release(pointer_1);
+
+ /* Allocate all the blocks. */
+ status = tx_byte_allocate(&pool_4, (VOID **) &pointer_1, 84, TX_NO_WAIT);
+ status += tx_byte_allocate(&pool_4, (VOID **) &pointer_2, 84, TX_NO_WAIT);
+ status += tx_byte_allocate(&pool_4, (VOID **) &pointer_3, 84, TX_NO_WAIT);
+
+ /* Release all of the blocks in order. */
+ status += tx_byte_release(pointer_1);
+ status += tx_byte_release(pointer_2);
+ status += tx_byte_release(pointer_3);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #50\n");
+ test_control_return(1);
+ }
+
+ /* Now setup a special test to exercise the examine blocks equal to 0 path in the byte pool search. */
+ pool_4.tx_byte_pool_search = save_search;
+ pool_4.tx_byte_pool_fragments = (UINT) (-1);
+
+ /* Call byte allocate to execise the examine blocks equal to 0 path on non-merge block condition. */
+ status = tx_byte_allocate(&pool_4, (VOID **) &pointer_1, 168, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #51\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
diff --git a/test/tx/regression/threadx_byte_memory_information_test.c b/test/tx/regression/threadx_byte_memory_information_test.c
new file mode 100644
index 00000000..2d1c20bc
--- /dev/null
+++ b/test/tx/regression/threadx_byte_memory_information_test.c
@@ -0,0 +1,784 @@
+/* This test is designed to test byte memory information. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_byte_pool.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static TX_BYTE_POOL byte_pool_0;
+#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
+static TX_BYTE_POOL byte_pool_1;
+#endif
+static TX_BYTE_POOL byte_pool_2;
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+UINT _tx_byte_pool_performance_info_get(TX_BYTE_POOL *pool_ptr, ULONG *allocates, ULONG *releases,
+ ULONG *fragments_searched, ULONG *merges, ULONG *splits, ULONG *suspensions, ULONG *timeouts);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_byte_memory_information_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create the byte_pool with one byte. */
+ status = tx_byte_pool_create(&byte_pool_0, "byte_pool 0", pointer, 100);
+ pointer = pointer + 100;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Information Test................................ ERROR #8\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+CHAR *name;
+ULONG available;
+ULONG fragments;
+TX_THREAD *first_suspended;
+ULONG suspended_count;
+TX_BYTE_POOL *next_pool;
+ULONG allocates;
+ULONG releases;
+ULONG fragments_searched;
+ULONG merges;
+ULONG splits;
+ULONG suspensions;
+ULONG timeouts;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Information Test................................ ");
+
+ /* Allocate the one byte. */
+ tx_byte_allocate(&byte_pool_0, &pointer, 80, TX_NO_WAIT);
+
+ /* Nothing to do here, but check prioritization with no suspended threads. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 and 2 are suspended on the byte_pool. */
+ if ((thread_1.tx_thread_state != TX_BYTE_MEMORY) || (thread_2.tx_thread_state != TX_BYTE_MEMORY) ||
+ (byte_pool_0.tx_byte_pool_suspension_list != &thread_1))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the byte pool suspension list. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 2 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_2))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the byte pool suspension list. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 3 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_3))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the byte pool suspension list. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Check status and make sure thread 3 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_4))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Call byte pool info with a NULL pointer. */
+ status = tx_byte_pool_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Call byte pool info with an non-created pool pointer. */
+ byte_pool_2.tx_byte_pool_id = 0;
+ status = tx_byte_pool_info_get(&byte_pool_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Get the byte pool information. */
+ status = tx_byte_pool_info_get(&byte_pool_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_byte_pool_info_get(&byte_pool_0, &name, &available, &fragments, &first_suspended, &suspended_count, &next_pool);
+
+ /* Check the status. */
+ if ((status != TX_SUCCESS) || (available != byte_pool_0.tx_byte_pool_available) || (fragments != byte_pool_0.tx_byte_pool_fragments) ||
+ (first_suspended != &thread_4) || (suspended_count != byte_pool_0.tx_byte_pool_suspended_count) || (next_pool != &byte_pool_0))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+
+#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(&byte_pool_1, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(&byte_pool_0, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if ((status != TX_SUCCESS) || (allocates != byte_pool_0.tx_byte_pool_performance_allocate_count) || (releases != byte_pool_0.tx_byte_pool_performance_release_count) ||
+ (fragments_searched != byte_pool_0.tx_byte_pool_performance_search_count) || (merges != byte_pool_0.tx_byte_pool_performance_merge_count) ||
+ (splits != byte_pool_0.tx_byte_pool_performance_split_count) || (suspensions != byte_pool_0.tx_byte_pool_performance_suspension_count) ||
+ (timeouts != byte_pool_0.tx_byte_pool_performance_timeout_count))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(&allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if ((status != TX_SUCCESS) || (allocates != _tx_byte_pool_performance_allocate_count) || (releases != _tx_byte_pool_performance_release_count) ||
+ (fragments_searched != _tx_byte_pool_performance_search_count) || (merges != _tx_byte_pool_performance_merge_count) ||
+ (splits != _tx_byte_pool_performance_split_count) || (suspensions != _tx_byte_pool_performance_suspension_count) ||
+ (timeouts != _tx_byte_pool_performance_timeout_count))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+#else
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(&byte_pool_0, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool performance information. */
+ status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(&allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &merges, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &splits, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ /* Get the byte pool system performance information. */
+ status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+#endif
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+VOID *pointer;
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+ }
+}
diff --git a/test/tx/regression/threadx_byte_memory_prioritize_test.c b/test/tx/regression/threadx_byte_memory_prioritize_test.c
new file mode 100644
index 00000000..f06d5cd3
--- /dev/null
+++ b/test/tx/regression/threadx_byte_memory_prioritize_test.c
@@ -0,0 +1,498 @@
+/* This test is designed to test byte memory prioritize. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static TX_BYTE_POOL byte_pool_0;
+static TX_BYTE_POOL byte_pool_1;
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Determine if thread 3 is at the front of the suspension list. */
+ if (byte_pool_0.tx_byte_pool_suspension_list == &thread_3)
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+ }
+ else
+ {
+
+ /* Abort the wait of thread 5. */
+ tx_thread_wait_abort(&thread_5);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_byte_memory_prioritize_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create the byte_pool with one byte. */
+ status = tx_byte_pool_create(&byte_pool_0, "byte_pool 0", pointer, 100);
+ pointer = pointer + 100;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Prioritize Test................................. ERROR #8\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Prioritize Test................................. ");
+
+ /* Allocate the one byte. */
+ tx_byte_allocate(&byte_pool_0, &pointer, 80, TX_NO_WAIT);
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Call byte pool prioritize with a NULL pointer. */
+ status = tx_byte_pool_prioritize(TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Call byte pool info with an non-created pool pointer. */
+ byte_pool_1.tx_byte_pool_id = 0;
+ status = tx_byte_pool_prioritize(&byte_pool_1);
+
+ /* Check for error. */
+ if (status != TX_POOL_ERROR)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Nothing to do here, but check prioritization with no suspended threads. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 and 2 are suspended on the byte_pool. */
+ if ((thread_1.tx_thread_state != TX_BYTE_MEMORY) || (thread_2.tx_thread_state != TX_BYTE_MEMORY) ||
+ (byte_pool_0.tx_byte_pool_suspension_list != &thread_1))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the byte pool suspension list. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 2 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_2))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Call byte pool prioritize again to test the don't-do-anything path in tx_byte_pool_prioritize. */
+ status += tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the byte pool suspension list. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 3 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_3))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the byte pool suspension list. */
+ status = tx_byte_pool_prioritize(&byte_pool_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Check status and make sure thread 3 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_4))
+ {
+
+ /* Byte Pool error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+VOID *pointer;
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+UINT status;
+VOID *pointer;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get byte from pool. */
+ status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+ }
+}
+
diff --git a/test/tx/regression/threadx_byte_memory_suspension_test.c b/test/tx/regression/threadx_byte_memory_suspension_test.c
new file mode 100644
index 00000000..069410c5
--- /dev/null
+++ b/test/tx/regression/threadx_byte_memory_suspension_test.c
@@ -0,0 +1,391 @@
+/* This test is designed to test suspension on a memory byte pool. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+
+static TX_BYTE_POOL pool_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+
+
+
+#ifndef TX_MANUAL_TEST
+
+/* Define test flags for automated test. */
+
+extern TEST_FLAG threadx_byte_allocate_loop_test;
+extern TEST_FLAG threadx_byte_release_loop_test;
+
+#endif
+
+
+void abort_and_resume_byte_allocating_thread(void)
+{
+
+UCHAR *search_ptr;
+
+ /* Adjust the search pointer to avoid the search pointer change for this test. */
+ search_ptr = pool_0.tx_byte_pool_search;
+ while (search_ptr >= pool_0.tx_byte_pool_search)
+
+ {
+ search_ptr = *((UCHAR **) ((VOID *) search_ptr));
+ }
+ pool_0.tx_byte_pool_search = search_ptr;
+
+ tx_thread_wait_abort(&thread_3);
+ tx_thread_resume(&thread_3);
+}
+
+
+/* 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_byte_memory_suspension_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create byte pool 0. */
+ status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
+ pointer = pointer + 108;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Test................................. ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Suspension Test................................. ");
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Allocate memory from the pool. Only one block of this size will fit. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Let other thread suspend on byte pool. */
+ tx_thread_relinquish();
+
+ /* Now release the blocks. */
+ status = tx_byte_release(pointer);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) && (thread_1_counter == 0))
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Let other thread run again. */
+ tx_thread_relinquish();
+
+ /* Check to make sure thread 1 has now run. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Now allocate the memory again. Only one block of this size will fit. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Resume the second thread. */
+ tx_thread_resume(&thread_2);
+
+ /* Now relinquish to let both thread 1 and 2 suspend. */
+ tx_thread_relinquish();
+
+ /* At this point both threads should be suspended on the byte pool. */
+
+ /* Release the memory again. */
+ status = tx_byte_release(pointer);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Now relinquish to get the other threads to run once. */
+ tx_thread_relinquish();
+ tx_thread_relinquish();
+
+ /* At this point both threads 1 and 2 are suspended on the byte pool again. */
+ if ((thread_1_counter != 3) && (thread_2_counter != 1))
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Now allocate the memory again. Only one block of this size will fit. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #10a\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 3 to get it suspended on the the pool. */
+ tx_thread_resume(&thread_3);
+
+#ifdef TX_MANUAL_TEST
+
+ /* Set BP hear. Now release the memory and step into the code. After byte search issue IRQ2 mannually, which will
+ make thread 3 abort the first request and make another request of a different size. This is the path we are trying
+ to generate in the test. */
+ status = tx_byte_release(pointer);
+#else
+
+ /* Set the flag that will make thread 3 abort the first request and make another request of a different size. This tests the memory size change path
+ in the byte release loop logic. */
+ threadx_byte_release_loop_test = 1;
+ status = tx_byte_release(pointer);
+
+#endif
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #10b\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+ while(1)
+ {
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Now release each of the blocks. */
+ status = tx_byte_release(pointer);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Let thread 0 run again. */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+ while(1)
+ {
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Now release each of the blocks. */
+ status = tx_byte_release(pointer);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Let thread 0 run again. */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+ while (1)
+ {
+
+ /* Allocate memory from the pool. */
+ tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
+
+#ifdef TX_MANUAL_TEST
+
+ /* Set BP here and manually clear the owner after one failed byte search just to test the loop
+ construct in tx_byte_allocate.c. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 90, TX_WAIT_FOREVER);
+#else
+
+ /* Set the flag that clears the pool owner after one failed byte search to test the loop
+ construct processing in tx_byte_allocate.c. */
+ threadx_byte_allocate_loop_test = 1;
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 90, TX_WAIT_FOREVER);
+#endif
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+
+ /* Now release the block. */
+ status = tx_byte_release(pointer);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* suspend this thread. */
+ tx_thread_suspend(&thread_3);
+ }
+}
diff --git a/test/tx/regression/threadx_byte_memory_suspension_timeout_test.c b/test/tx/regression/threadx_byte_memory_suspension_timeout_test.c
new file mode 100644
index 00000000..ed122dab
--- /dev/null
+++ b/test/tx/regression/threadx_byte_memory_suspension_timeout_test.c
@@ -0,0 +1,196 @@
+/* This test is designed to test suspension timeout on a memory byte pool. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_BYTE_POOL pool_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_byte_memory_suspension_timeout_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Timeout Test......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Timeout Test......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Timeout Test......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create byte pool 0. */
+ status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
+ pointer = pointer + 108;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Suspension Timeout Test......................... ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Suspension Timeout Test......................... ");
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Allocate memory from the pool. Only one block of this size will fit. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0))
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Sleep to allow the other thread to suspend and timeout on the memory
+ pool once. */
+ tx_thread_sleep(64);
+
+ /* Check the counter of the other thread. */
+ if ((thread_1_counter != 6) || (thread_2_counter != 3))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+ while(1)
+ {
+
+ /* Allocate memory from the pool - with timeout. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, 10);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Delay so we get some single suspension timeouts as well. */
+ tx_thread_sleep(32);
+
+ while(1)
+ {
+
+ /* Allocate memory from the pool - with timeout. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, 10);
+
+ /* Check status. */
+ if (status != TX_NO_MEMORY)
+ return;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
diff --git a/test/tx/regression/threadx_byte_memory_thread_contention_test.c b/test/tx/regression/threadx_byte_memory_thread_contention_test.c
new file mode 100644
index 00000000..a3e689c8
--- /dev/null
+++ b/test/tx/regression/threadx_byte_memory_thread_contention_test.c
@@ -0,0 +1,255 @@
+/* This test is designed to test contention of two threads on a single
+ memory byte pool. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static unsigned long initial_pool_size;
+
+
+static TX_BYTE_POOL pool_0;
+
+
+static int test_done;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_byte_memory_thread_contention_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,
+ 17, 17, 1, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Contention Test.......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 1, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Contention Test.......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 1, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Contention Test.......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create byte pool 0. */
+ status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
+ pointer = pointer + 108;
+
+ /* Save off the intial pool size. */
+ initial_pool_size = pool_0.tx_byte_pool_available;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Contention Test.......................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Set the test done flag to false. */
+ test_done = TX_FALSE;
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Thread Contention Test.......................... ");
+
+ /* Set time to 0. */
+ tx_time_set(0);
+
+ while(1)
+ {
+
+ /* Allocate memory from the pool. This size will cause merge activity
+ because the search pointer will sit in this large block about half
+ the time. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Fill the memory. */
+ TX_MEMSET(pointer, (CHAR) 0xEF, 60);
+
+ /* Now release the block. */
+ status = tx_byte_release(pointer);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Check the time. */
+ if (tx_time_get() > 128)
+ break;
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+ }
+
+ /* Set the done flag. */
+ test_done = TX_TRUE;
+
+ /* Sleep to let the other threads finish up! */
+ tx_thread_sleep(2);
+
+ /* Determine if we all all the original memory and that thread 1
+ is in the proper place. */
+ if (pool_0.tx_byte_pool_available != initial_pool_size)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ while(test_done == TX_FALSE)
+ {
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 30, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Fill the memory. */
+ TX_MEMSET(pointer, (CHAR) 0xEF, 30);
+
+ /* Now release the block. */
+ status = tx_byte_release(pointer);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ while(test_done == TX_FALSE)
+ {
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 12, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Fill the memory. */
+ TX_MEMSET(pointer, (CHAR) 0xEF, 12);
+
+ /* Now release the block. */
+ status = tx_byte_release(pointer);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
diff --git a/test/tx/regression/threadx_byte_memory_thread_terminate_test.c b/test/tx/regression/threadx_byte_memory_thread_terminate_test.c
new file mode 100644
index 00000000..29fec0c0
--- /dev/null
+++ b/test/tx/regression/threadx_byte_memory_thread_terminate_test.c
@@ -0,0 +1,177 @@
+/* This test is designed to test termination on thread suspended on memory byte pool. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+
+static TX_BYTE_POOL pool_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_byte_memory_thread_terminate_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Terminate Test........................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Terminate Test........................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create byte pools 0 and 1. */
+ status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
+ pointer = pointer + 108;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Byte Memory Thread Terminate Test........................... ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+
+ /* Inform user. */
+ printf("Running Byte Memory Thread Terminate Test........................... ");
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Allocate memory from the pool. Only one block of this size will fit. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Let other thread suspend on byte pool. */
+ tx_thread_relinquish();
+
+ /* Terminate the other thread. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Release block back. */
+ status = tx_byte_release(pointer);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Allocate memory from the pool. Only one block of this size will fit. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0))
+ {
+
+ /* Byte memory error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *pointer;
+
+ while(1)
+ {
+
+ /* Allocate memory from the pool. */
+ status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
+
+ /* Should never get here! */
+ if (status != TX_NO_MEMORY)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
diff --git a/test/tx/regression/threadx_event_flag_basic_test.c b/test/tx/regression/threadx_event_flag_basic_test.c
new file mode 100644
index 00000000..9c19f9bd
--- /dev/null
+++ b/test/tx/regression/threadx_event_flag_basic_test.c
@@ -0,0 +1,743 @@
+/* This test is designed to test simple event flag group creation, deletion, gets and
+ sets. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+typedef struct EVENT_FLAG_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_EVENT_FLAGS_GROUP event_flags;
+ ULONG next_to_last;
+ ULONG last;
+
+} EVENT_FLAG_MEMORY_TEST;
+
+static EVENT_FLAG_MEMORY_TEST event_flag_memory;
+
+
+/* Define external reference to the event flag create call from initialization. */
+
+extern UINT test_event_flags_from_init;
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_TIMER timer_0;
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+static TX_EVENT_FLAGS_GROUP group_0;
+static TX_EVENT_FLAGS_GROUP group_1;
+static TX_EVENT_FLAGS_GROUP group_2;
+static TX_EVENT_FLAGS_GROUP group_3;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+UINT _txe_event_flags_create(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name_ptr, UINT event_control_block_size);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+ULONG actual_events;
+
+
+ /* Determine if calling event flag create from initialization was successful. */
+ if (test_event_flags_from_init != TX_SUCCESS)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create an event flag group from a timer. */
+ status = tx_event_flags_create(&group_2, "group 2");
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Try to delete an event flags group from a timer. */
+ status = tx_event_flags_delete(&group_0);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Get events with suspendsion from a timer. */
+ status = tx_event_flags_get(&group_0, 0x80008000, 14, &actual_events, 100);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+ULONG actual_events;
+
+
+ /* Attempt to create an event flag group from an ISR. */
+ status = tx_event_flags_create(&group_2, "group 2");
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete an event flags group from an ISR. */
+ status = tx_event_flags_delete(&group_0);
+
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Get events with suspendsion from an ISR. */
+ status = tx_event_flags_get(&group_0, 0x80008000, 14, &actual_events, 100);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+
+ isr_executed = 1;
+#endif
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_basic_application_define(void *first_unused_memory)
+#endif
+{
+
+INT 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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0 and 1. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_event_flags_create(&group_1, "group 1");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Un-register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, TX_NULL);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #5a\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Basic Test....................................... ERROR #6a\n");
+ test_control_return(1);
+ }
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Basic Test....................................... ");
+
+ /* Perform event flag memory test. */
+ event_flag_memory.first = 0x11223344;
+ event_flag_memory.second = 0x55667788;
+ event_flag_memory.next_to_last = 0x99aabbcc;
+ event_flag_memory.last = 0xddeeff00;
+
+ /* Create the event flag group. */
+ status = tx_event_flags_create(&event_flag_memory.event_flags, "group memory");
+ tx_event_flags_delete(&event_flag_memory.event_flags);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (event_flag_memory.first != 0x11223344) ||
+ (event_flag_memory.second != 0x55667788) ||
+ (event_flag_memory.next_to_last != 0x99aabbcc) ||
+ (event_flag_memory.last != 0xddeeff00))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Event flags should be created now. */
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Try to create with a NULL pointer. */
+ status = tx_event_flags_create(TX_NULL, "group 0");
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Try to create with a bad size. */
+ status = _txe_event_flags_create(&group_3, "group 3", (sizeof(TX_EVENT_FLAGS_GROUP)+1));
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Try to create an already created group. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Delete with a NULL pointer. */
+ status = tx_event_flags_delete(TX_NULL);
+
+ /* Check the status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Delete with a non-created pointer. */
+ group_2.tx_event_flags_group_id = 0;
+ status = tx_event_flags_delete(&group_2);
+
+ /* Check the status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Get events with a null group pointer. */
+ status = tx_event_flags_get(TX_NULL, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Get events with a non-created group pointer. */
+ group_2.tx_event_flags_group_id = 0;
+ status = tx_event_flags_get(&group_2, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Get events with a null flags retun pointer. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, TX_NULL, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Get events with a bad option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, 14, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_OPTION_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Set evetns with a NULL group pointer. */
+ status = tx_event_flags_set(TX_NULL, 0x80008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Set events with a non-created group pointer. */
+ group_2.tx_event_flags_group_id = 0;
+ status = tx_event_flags_set(&group_2, 0x80008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Set events with a bad option. */
+ status = tx_event_flags_set(&group_0, 0x80008000, 14);
+
+ /* Check status. */
+ if (status != TX_OPTION_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to register the event set notify function with a NULL group pointer. */
+ status = tx_event_flags_set_notify(TX_NULL, event_set_notify);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to register the event set notify function with a non-created group pointer. */
+ group_2.tx_event_flags_group_id = 0;
+ status = tx_event_flags_set_notify(&group_2, event_set_notify);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Attempt to get events from an empty event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. OR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. AND CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Set the necessary events. */
+ status = tx_event_flags_set(&group_0, 0x80008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Just for fun, clear bit 15. */
+ status = tx_event_flags_set(&group_0, 0x80000000, TX_AND);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Set bit 15 again. */
+ status = tx_event_flags_set(&group_0, 0x00008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Now attemp to retrieve events... */
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. OR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. AND CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Put event flags back in the group. */
+
+ /* Set the necessary events. */
+ status = tx_event_flags_set(&group_0, 0x80008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x00008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Now resume thread 1. */
+ tx_thread_resume(&thread_1);
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete both event flag groups. */
+ status = tx_event_flags_delete(&group_0);
+
+ /* Check the status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ status = tx_event_flags_delete(&group_1);
+
+ /* Check the status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+ }
+}
+
diff --git a/test/tx/regression/threadx_event_flag_information_test.c b/test/tx/regression/threadx_event_flag_information_test.c
new file mode 100644
index 00000000..1f03fdf3
--- /dev/null
+++ b/test/tx/regression/threadx_event_flag_information_test.c
@@ -0,0 +1,562 @@
+/* This test is designed to test the event flag group information gathering services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_event_flags.h"
+
+
+static TX_THREAD thread_0;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+static TX_EVENT_FLAGS_GROUP group_1;
+static TX_EVENT_FLAGS_GROUP group_2;
+
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+UINT _tx_event_flags_performance_info_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG *sets, ULONG *gets,
+ ULONG *suspensions, ULONG *timeouts);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_information_application_define(void *first_unused_memory)
+#endif
+{
+
+INT 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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Information Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0 and 1. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Information Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_event_flags_create(&group_1, "group 1");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Information Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Information Test................................. ERROR #4\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Information Test................................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+CHAR *name;
+ULONG current_flags;
+TX_THREAD *first_suspended;
+ULONG suspended_count;
+TX_EVENT_FLAGS_GROUP *next_group;
+ULONG sets;
+ULONG gets;
+ULONG suspensions;
+ULONG timeouts;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Information Test................................. ");
+
+ /* Event flags should be created now. */
+
+ /* Attempt to get events from an empty event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. OR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. AND CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Set the necessary events. */
+ status = tx_event_flags_set(&group_0, 0x80008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Just for fun, clear bit 15. */
+ status = tx_event_flags_set(&group_0, 0x80000000, TX_AND);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Set bit 15 again. */
+ status = tx_event_flags_set(&group_0, 0x00008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Now attemp to retrieve events... */
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. OR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. AND CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from an empty event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Put event flags back in the group. */
+
+ /* Set the necessary events. */
+ status = tx_event_flags_set(&group_0, 0x80008000, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x00008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get events from event flag group. OR CLEAR option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Get information with a NULL pointer. */
+ status = tx_event_flags_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Get information from a non-created group. */
+ group_2.tx_event_flags_group_id = 0;
+ status = tx_event_flags_info_get(&group_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_GROUP_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Get information about the event flag group. */
+ status = tx_event_flags_info_get(&group_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_event_flags_info_get(&group_0, &name, &current_flags, &first_suspended, &suspended_count, &next_group);
+
+ /* Check the status. */
+ if ((status != TX_SUCCESS) || (current_flags != group_0.tx_event_flags_group_current) || (first_suspended != TX_NULL) || (suspended_count != 0) || (next_group != &group_1))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
+
+ /* Get performance information with NULL pointer. */
+ status = _tx_event_flags_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check the status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(&group_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_event_flags_performance_info_get(&group_0, &sets, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if ((status != TX_SUCCESS) || (sets != group_0.tx_event_flags_group_performance_set_count) || (gets != group_0.tx_event_flags_group__performance_get_count) ||
+ (suspensions != group_0.tx_event_flags_group___performance_suspension_count) || (timeouts != group_0.tx_event_flags_group____performance_timeout_count))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information on all event flags groups. */
+ status = tx_event_flags_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_event_flags_performance_system_info_get(&sets, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if ((status != TX_SUCCESS) || (sets != _tx_event_flags_performance_set_count) || (gets != _tx_event_flags_performance_get_count) ||
+ (suspensions != _tx_event_flags_performance_suspension_count) || (timeouts != _tx_event_flags_performance_timeout_count))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(&group_0, &sets, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(TX_NULL, &sets, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(TX_NULL, TX_NULL, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information on the event flag group. */
+ status = tx_event_flags_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information on all event flags groups. */
+ status = tx_event_flags_performance_system_info_get(&sets, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information on all event flags groups. */
+ status = tx_event_flags_performance_system_info_get(TX_NULL, &gets, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information on all event flags groups. */
+ status = tx_event_flags_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information on all event flags groups. */
+ status = tx_event_flags_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information on all event flags groups. */
+ status = tx_event_flags_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check the status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Delete both event flag groups. */
+ status = tx_event_flags_delete(&group_0);
+
+ /* Check the status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ status = tx_event_flags_delete(&group_1);
+
+ /* Check the status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
diff --git a/test/tx/regression/threadx_event_flag_isr_set_clear_test.c b/test/tx/regression/threadx_event_flag_isr_set_clear_test.c
new file mode 100644
index 00000000..2d2f28af
--- /dev/null
+++ b/test/tx/regression/threadx_event_flag_isr_set_clear_test.c
@@ -0,0 +1,359 @@
+/* This test is designed to test for simultaneous thread event flag set AND ISR event flag set and clear. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+static unsigned long event_flags_set_counter = 0;
+static unsigned long condition_count = 0;
+
+static TX_EVENT_FLAGS_GROUP event_flags_0;
+
+extern UINT _tx_thread_preempt_disable;
+extern UINT _tx_timer_system_clock;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void timer_0_entry(ULONG timer_input);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+static void test_isr(void)
+{
+
+UINT status;
+ULONG actual;
+static volatile UINT miss_count = 0;
+
+
+ /* Determine if the interrupt occurred when the preempt disable flag was set. */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* Yes this is the condition we are looking for, increment the test condition counter. */
+ condition_count++;
+ }
+
+ /*
+ It is possible for this test to get into a resonance condition in which
+ the ISR never occurs while preemption is disabled (especially if the
+ ISR is installed in the periodic timer interrupt handler, which is
+ conveniently available). Detect this condition and break out of it by
+ perturbing the duration of this ISR a pseudo-random amount of time.
+ */
+ else if (++miss_count > 100)
+ {
+ for (miss_count = _tx_timer_system_clock % 100; miss_count != 0; --miss_count);
+ }
+
+ if (((event_flags_0.tx_event_flags_group_current & 0x3) == 0) &&
+ (event_flags_0.tx_event_flags_group_suspended_count == 2))
+ {
+
+ /* Put the event_flags to wakeup thread 0. */
+ status = tx_event_flags_set(&event_flags_0, 0x3, TX_OR);
+
+ /* Clear the same flags immediately. */
+ status += tx_event_flags_set(&event_flags_0, 0xFFFFFFFC, TX_AND);
+
+ /* Setup some event flags just so we can clear them. */
+ status += tx_event_flags_set(&event_flags_0, 0x30000, TX_OR);
+
+ /* Clear the same flags immediately. */
+ status += tx_event_flags_set(&event_flags_0, 0xFFFEFFFF, TX_AND);
+
+ /* Clear the same flags immediately. */
+ status += tx_event_flags_set(&event_flags_0, 0xFFFDFFFC, TX_AND);
+
+ /* Check for an error. */
+ if (status)
+ return;
+
+ /* Get the events from an ISR. */
+ status = tx_event_flags_get(&event_flags_0, 0x30000, TX_OR, &actual, TX_NO_WAIT);
+
+ /* Check to make sure this results in an error. */
+ if (status != TX_NO_EVENTS)
+ return;
+
+ /* Do a set and a get consume from an ISR. */
+ status = tx_event_flags_set(&event_flags_0, 0x000000C0, TX_OR);
+
+ status += tx_event_flags_get(&event_flags_0, 0x00000080, TX_OR, &actual, TX_NO_WAIT);
+
+ status += tx_event_flags_get(&event_flags_0, 0x000000C0, TX_OR_CLEAR, &actual, TX_NO_WAIT);
+
+ /* Increment the event_flags counter. */
+ if ((status == TX_SUCCESS) && (actual == 0xC4))
+ {
+ event_flags_set_counter++;
+ }
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_isr_set_clear_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_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flags group. */
+ status = tx_event_flags_create(&event_flags_0, "event_flags 0");
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create a timer to ensure a context save is called for every interrupt. */
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&event_flags_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #6\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Set/Clear from ISR Test.......................... ");
+
+ /* Setup the test ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Loop to exploit the probability window inside tx_event_flags_set call. */
+ while (condition_count < 40)
+ {
+
+ /* Suspend on the event_flags that is going to be set via the ISR. */
+ status = tx_event_flags_get(&event_flags_0, 2, TX_OR_CLEAR, &actual, 4);
+
+ /* Determine if we have an unexpected result. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Test error! */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Check for the preempt disable flag being set. */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* Test error! */
+ printf("ERROR #9\n");
+ test_control_return(2);
+ }
+
+ /* Determine if we really got the event_flags. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment the thread count. */
+ thread_0_counter++;
+ }
+ }
+
+ /* Setup the test ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Let the other threads run once more... */
+ tx_thread_relinquish();
+
+ /* At this point, check to see if we got all the event_flagss! */
+ if ((thread_0_counter != event_flags_set_counter) ||
+ (thread_1_counter != event_flags_set_counter))
+ {
+
+ /* Test error! */
+ printf("ERROR #10\n");
+ test_control_return(3);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual;
+
+
+ /* Loop to exploit the probability window inside tx_event_flags_set call. */
+ while (1)
+ {
+
+ /* Suspend on the event_flags that is going to be set via the ISR. */
+ status = tx_event_flags_get(&event_flags_0, 1, TX_OR_CLEAR, &actual, 4);
+
+ /* Determine if we have an unexpected result. */
+ if (status != TX_SUCCESS)
+ {
+
+ break;
+ }
+
+ /* Increment this thread's counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Set event flags - not the one needed by threads 0 and 1. */
+ tx_event_flags_set(&event_flags_0, 0x4, TX_OR);
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Let thread 0 run again! */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void timer_0_entry(ULONG input)
+{
+ timer_0_counter++;
+}
+
+
diff --git a/test/tx/regression/threadx_event_flag_isr_wait_abort_test.c b/test/tx/regression/threadx_event_flag_isr_wait_abort_test.c
new file mode 100644
index 00000000..1c9bf5d2
--- /dev/null
+++ b/test/tx/regression/threadx_event_flag_isr_wait_abort_test.c
@@ -0,0 +1,331 @@
+/* This test is designed to test for wait abort from an ISR. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+static unsigned long event_flags_wait_abort_counter = 0;
+static unsigned long condition_count = 0;
+
+static TX_EVENT_FLAGS_GROUP event_flags_0;
+
+extern UINT _tx_thread_preempt_disable;
+extern UINT _tx_timer_system_clock;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void timer_0_entry(ULONG timer_input);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+static void test_isr(void)
+{
+
+UINT status;
+static volatile UINT miss_count = 0;
+
+
+ /* Determine if the interrupt occurred when the preempt disable flag was set. */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* Yes this is the condition we are looking for, increment the test condition counter. */
+ condition_count++;
+ }
+
+ /*
+ It is possible for this test to get into a resonance condition in which
+ the ISR never occurs while preemption is disabled (especially if the
+ ISR is installed in the periodic timer interrupt handler, which is
+ conveniently available). Detect this condition and break out of it by
+ perturbing the duration of this ISR a pseudo-random amount of time.
+ */
+ else if (++miss_count > 100)
+ {
+ for (miss_count = _tx_timer_system_clock % 100; miss_count != 0; --miss_count);
+ }
+
+ if (((event_flags_0.tx_event_flags_group_current & 0x3) == 0) &&
+ (event_flags_0.tx_event_flags_group_suspended_count == 2))
+ {
+
+ /* Set event flags - not the one needed by threads 0 and 1. */
+ status = tx_event_flags_set(&event_flags_0, 0x4, TX_OR);
+
+ /* Abort the threads 1 and 2. */
+ status += tx_thread_wait_abort(&thread_0);
+ status += tx_thread_wait_abort(&thread_1);
+
+ if (status == TX_SUCCESS)
+ {
+
+ event_flags_wait_abort_counter++;
+ }
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_isr_wait_abort_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flags group. */
+ status = tx_event_flags_create(&event_flags_0, "event_flags 0");
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create a timer to ensure a context save is called for every interrupt. */
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&event_flags_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #6\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Wait Abort from ISR Test......................... ");
+
+ /* Setup the test ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Loop to exploit the probability window inside tx_event_flags_set call. */
+ while (condition_count < 40)
+ {
+
+ /* Suspend on the event_flags that is going to be set via the ISR. */
+ status = tx_event_flags_get(&event_flags_0, 2, TX_OR_CLEAR, &actual, 4);
+
+ /* Determine if we have an unexpected result. */
+ if (status != TX_WAIT_ABORTED)
+ {
+
+ /* Test error! */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Check for the preempt disable flag being set. */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* Test error! */
+ printf("ERROR #9\n");
+ test_control_return(2);
+ }
+
+ /* Determine if we really got the event_flags. */
+ if (status == TX_WAIT_ABORTED)
+ {
+
+ /* Increment the thread count. */
+ thread_0_counter++;
+ }
+ }
+
+ /* Setup the test ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Let the other threads run once more... */
+ tx_thread_relinquish();
+
+ /* At this point, check to see if we got all the event_flagss! */
+ if ((thread_0_counter != event_flags_wait_abort_counter) ||
+ (thread_1_counter != event_flags_wait_abort_counter))
+ {
+
+ /* Test error! */
+ printf("ERROR #10\n");
+ test_control_return(3);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual;
+
+
+ /* Loop to exploit the probability window inside tx_event_flags_set call. */
+ while (1)
+ {
+
+ /* Suspend on the event_flags that is going to be set via the ISR. */
+ status = tx_event_flags_get(&event_flags_0, 1, TX_OR_CLEAR, &actual, 4);
+
+ /* Determine if we have an unexpected result. */
+ if (status != TX_WAIT_ABORTED)
+ {
+
+ break;
+ }
+
+ /* Increment this thread's counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Set event flags - not the one needed by threads 0 and 1. */
+ tx_event_flags_set(&event_flags_0, 0x4, TX_OR);
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Let thread 0 run again! */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void timer_0_entry(ULONG input)
+{
+ timer_0_counter++;
+}
diff --git a/test/tx/regression/threadx_event_flag_single_thread_terminate_test.c b/test/tx/regression/threadx_event_flag_single_thread_terminate_test.c
new file mode 100644
index 00000000..a5db6e41
--- /dev/null
+++ b/test/tx/regression/threadx_event_flag_single_thread_terminate_test.c
@@ -0,0 +1,331 @@
+/* This test is designed to test event flag suspension with a single suspended thread
+ being terminated at the same priority level. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+extern UINT _tx_thread_preempt_disable;
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_single_thread_terminate_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Single Thread Terminate Test..................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Single Thread Terminate Test..................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Single Thread Terminate Test..................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Single Thread Terminate Test..................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Single Thread Terminate Test..................... ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Single Thread Terminate Test..................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Single Thread Terminate Test..................... ");
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Sleep to allow lower-priority thread 1 to run. */
+ tx_thread_sleep(5);
+
+ /* Resume Thread 2. */
+ status = tx_thread_resume(&thread_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Now terminate thread 1. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Now sleep to allow Thread 2 to run. */
+ tx_thread_sleep(5);
+
+ /* Set only one of the event flags needed. */
+ status = tx_event_flags_set(&group_0, 0x00080000, TX_OR);
+
+ /* Now sleep to allow thread 2 to run. */
+ tx_thread_sleep(5);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) && (thread_2_counter != 1))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Set the other event flag needed. */
+ status = tx_event_flags_set(&group_0, 0x00800000, TX_OR);
+
+ /* Now sleep to allow thread 2 to run. */
+ tx_thread_sleep(5);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) && (thread_2_counter != 2))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* At this point, thread 2 is suspended on the flags again. Or some flags that are
+ not needed. */
+
+ /* Set an event flag that is not needed. */
+ status = tx_event_flags_set(&group_0, 0x00000001, TX_OR);
+
+ /* Now sleep to allow thread 2 to run. */
+ tx_thread_sleep(5);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) && (thread_2_counter != 2))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Set an event flag that is needed. */
+ status = tx_event_flags_set(&group_0, 0x00080001, TX_OR);
+
+ /* Now sleep to allow thread 2 to run. */
+ tx_thread_sleep(5);
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 3) ||
+ (_tx_thread_preempt_disable))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Terminate thread 2. */
+ status = tx_thread_terminate(&thread_2);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_2_counter != 3))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Self suspend thread. */
+ status = tx_thread_suspend(&thread_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+ thread_1_counter = 0; /* Make an error! */
+ return;
+ }
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x000880000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. OR option. */
+ status = tx_event_flags_get(&group_0, 0x000880000, TX_OR_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x000880000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ return;
+ }
+}
+
diff --git a/test/tx/regression/threadx_event_flag_suspension_consume_test.c b/test/tx/regression/threadx_event_flag_suspension_consume_test.c
new file mode 100644
index 00000000..b83a8123
--- /dev/null
+++ b/test/tx/regression/threadx_event_flag_suspension_consume_test.c
@@ -0,0 +1,281 @@
+/* This test is designed to test event flag suspension and resumption of two threads
+ waiting on the same event flag set with the consumption. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_suspension_consume_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #6\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Test...................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG event_flag = 1;
+int i;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Suspension/Consumption Test...................... ");
+
+ /* Set all event flags. */
+ for (i = 0; i < 32; i++)
+ {
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Set event flag. */
+ status = tx_event_flags_set(&group_0, event_flag, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Check the thread counters... */
+ if ((i < 31) && ((thread_1_counter != 1) || (thread_2_counter != 1) || (thread_3_counter != 1)))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+ if ((i == 31) && ((thread_1_counter != 2) || (thread_2_counter != 2) || (thread_3_counter != 2)))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Shift event flag up one bit. */
+ event_flag = event_flag << 1;
+
+ /* Check for 0. */
+ if (event_flag == 0)
+ event_flag = 1;
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
+ return;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
+ return;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_3_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
+ return;
+ }
+}
+
diff --git a/test/tx/regression/threadx_event_flag_suspension_different_bits_consume_test.c b/test/tx/regression/threadx_event_flag_suspension_different_bits_consume_test.c
new file mode 100644
index 00000000..fa4a985a
--- /dev/null
+++ b/test/tx/regression/threadx_event_flag_suspension_different_bits_consume_test.c
@@ -0,0 +1,224 @@
+/* This test is designed to test event flag suspension and resumption of two threads
+ waiting on different event flags with consumption. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_suspension_different_bits_consume_application_define(void *first_unused_memory)
+#endif
+{
+
+INT 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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #2\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ");
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Set event flag. */
+ status = tx_event_flags_set(&group_0, 0x80000000, TX_OR);
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2) ||
+ (thread_2_counter != 1))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Set event flag. */
+ status = tx_event_flags_set(&group_0, 0x00008000, TX_OR);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80000000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL))
+ return;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x00008000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x00008000UL))
+ return;
+ }
+}
+
diff --git a/test/tx/regression/threadx_event_flag_suspension_different_bits_test.c b/test/tx/regression/threadx_event_flag_suspension_different_bits_test.c
new file mode 100644
index 00000000..92505744
--- /dev/null
+++ b/test/tx/regression/threadx_event_flag_suspension_different_bits_test.c
@@ -0,0 +1,230 @@
+/* This test is designed to test event flag suspension and resumption of two threads
+ waiting on different event flags. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_suspension_different_bits_application_define(void *first_unused_memory)
+#endif
+{
+
+INT 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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Suspension Unique Bit Test....................... ");
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Set event flag. */
+ status = tx_event_flags_set(&group_0, 0x80000000, TX_OR);
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2) ||
+ (thread_2_counter != 1))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Set event flag. */
+ status = tx_event_flags_set(&group_0, 0x00008000, TX_OR);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80000000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL))
+ return;
+
+ /* Clear the event flags. */
+ tx_event_flags_set(&group_0, 0x7FFFFFFF, TX_AND);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x00008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x00008000UL))
+ return;
+
+ /* Clear the event flags. */
+ tx_event_flags_set(&group_0, 0xFFFF7FFF, TX_AND);
+ }
+}
+
diff --git a/test/tx/regression/threadx_event_flag_suspension_test.c b/test/tx/regression/threadx_event_flag_suspension_test.c
new file mode 100644
index 00000000..3587fadd
--- /dev/null
+++ b/test/tx/regression/threadx_event_flag_suspension_test.c
@@ -0,0 +1,349 @@
+/* This test is designed to test event flag suspension and resumption of three threads
+ waiting on the same event flag set. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_suspension_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #7\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Suspension Same Bit Test......................... ERROR #8\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG event_flag = 1;
+int i;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Suspension Same Bit Test......................... ");
+
+ /* Set all event flags. */
+ for (i = 0; i < 32; i++)
+ {
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Set event flag. */
+ status = tx_event_flags_set(&group_0, event_flag, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Check the thread counters... */
+ if ((i < 31) && ((thread_1_counter != 1) || (thread_2_counter != 1) || (thread_3_counter != 1)))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+ if ((i == 31) && ((thread_1_counter != 2) || (thread_2_counter != 2) || (thread_3_counter != 2)))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Shift event flag up one bit. */
+ event_flag = event_flag << 1;
+
+ /* Check for 0. */
+ if (event_flag == 0)
+ event_flag = 1;
+ }
+
+ /* Set the event flags to 0. */
+ status = tx_event_flags_set(&group_0, 0x0, TX_AND);
+
+ /* Resume thread 4 so it can suspend on the event flag group too. */
+ status += tx_thread_resume(&thread_4);
+
+ /* Determine if there was an error. */
+ if ((status != TX_SUCCESS) || (thread_4_counter != 1))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Now set the event flag that only thread 4 is waiting on to ensure that we are not satisfying the first thread on the list. */
+ status = tx_event_flags_set(&group_0, 0x1, TX_OR);
+
+ /* Determine if there was an error. */
+ if ((status != TX_SUCCESS) || (thread_4_counter != 2))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
+ return;
+
+ /* Clear the event flags. */
+ tx_event_flags_set(&group_0, 0, TX_AND);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
+ return;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_3_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
+ return;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_4_counter++;
+
+ /* Attempt to get events from event flag group. OR option. */
+ status = tx_event_flags_get(&group_0, 0x00000001, TX_OR_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_events != 0x1UL))
+ return;
+ }
+}
diff --git a/test/tx/regression/threadx_event_flag_suspension_timeout_test.c b/test/tx/regression/threadx_event_flag_suspension_timeout_test.c
new file mode 100644
index 00000000..2fed61c0
--- /dev/null
+++ b/test/tx/regression/threadx_event_flag_suspension_timeout_test.c
@@ -0,0 +1,266 @@
+/* This test is designed to test event flag suspension timeout processing. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_suspension_timeout_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Timeout Test.......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Timeout Test.......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Timeout Test.......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Timeout Test.......................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Suspension Timeout Test.......................... ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Suspension Timeout Test.......................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ULONG actual_events;
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Suspension Timeout Test.......................... ");
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Set event flag 0. */
+ tx_event_flags_set(&group_0, 0x00000001, TX_OR);
+
+ /* Resume thread 3. */
+ tx_thread_resume(&thread_3);
+ tx_thread_sleep(1); /* Thread 3 should now be suspended on group 0. */
+ tx_event_flags_set(&group_0, 0x00000002, TX_OR);
+
+ /* Start everything on a new timer. */
+ tx_thread_sleep(2);
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_sleep(1);
+ status = tx_event_flags_get(&group_0, 0x00000001, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check the status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #6a\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for 63 ticks. */
+ tx_thread_sleep(63);
+
+ /* Check the run counters. */
+ if ((thread_1_counter != 33) || (thread_2_counter != 13))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80000000, TX_AND_CLEAR, &actual_events, 2);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ return;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x00008000, TX_AND_CLEAR, &actual_events, 5);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ return;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_3_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x00000002, TX_AND, &actual_events, 5);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ return;
+ }
+}
diff --git a/test/tx/regression/threadx_event_flag_thread_terminate_test.c b/test/tx/regression/threadx_event_flag_thread_terminate_test.c
new file mode 100644
index 00000000..eecb76e6
--- /dev/null
+++ b/test/tx/regression/threadx_event_flag_thread_terminate_test.c
@@ -0,0 +1,234 @@
+/* This test is designed to test event flag suspension with the suspended threads
+ being terminated. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_EVENT_FLAGS_GROUP group_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
+{
+
+ /* Not necessary to do anything in this function. */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_event_flag_thread_terminate_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Thread Terminate Test............................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Thread Terminate Test............................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Thread Terminate Test............................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create event flag group 0. */
+ status = tx_event_flags_create(&group_0, "group 0");
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Thread Terminate Test............................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Register the event set notify function. */
+ status = tx_event_flags_set_notify(&group_0, event_set_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Event Flag Thread Terminate Test............................ ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Event Flag Thread Terminate Test............................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Event Flag Thread Terminate Test............................ ");
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Terminate thread 2. */
+ status = tx_thread_terminate(&thread_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Terminate thread 1. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Event flag error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Set event flags to make sure no threads are suspended. */
+ status = tx_event_flags_set(&group_0, 0xFFFFFFFF, TX_OR);
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Event flag error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x80000000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ return;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+//ULONG event_flag = 1;
+ULONG actual_events;
+
+ /* Wait for event flags. */
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_2_counter++;
+
+ /* Attempt to get events from event flag group. AND option. */
+ status = tx_event_flags_get(&group_0, 0x00008000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_NO_EVENTS)
+ return;
+ }
+}
+
diff --git a/test/tx/regression/threadx_initialize_kernel_setup_test.c b/test/tx/regression/threadx_initialize_kernel_setup_test.c
new file mode 100644
index 00000000..f248694d
--- /dev/null
+++ b/test/tx/regression/threadx_initialize_kernel_setup_test.c
@@ -0,0 +1,81 @@
+/* This test is designed to test kernel setup functionality in ThreadX. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_initialize.h"
+#include "tx_thread.h"
+
+
+TEST_FLAG test_forced_mutex_timeout;
+TEST_FLAG threadx_mutex_suspension_put_test;
+TEST_FLAG threadx_mutex_suspension_priority_test;
+TEST_FLAG threadx_byte_allocate_loop_test;
+TEST_FLAG test_initialize_flag;
+TEST_FLAG threadx_byte_release_loop_test;
+TEST_FLAG test_stack_analyze_flag;
+
+
+/* Define the test control global variables. */
+
+ULONG test_control_return_status;
+ULONG test_control_successful_tests;
+ULONG test_control_failed_tests;
+ULONG test_control_system_errors;
+
+UINT test_mutex_from_init;
+UINT test_semaphore_from_init;
+UINT test_queue_from_init;
+UINT test_event_flags_from_init;
+UINT test_byte_pool_create_init;
+UINT test_block_pool_create_init;
+UINT test_timer_create_init;
+
+
+__attribute__((weak)) void abort_all_threads_suspended_on_mutex(void)
+{
+}
+
+__attribute__((weak)) void suspend_lowest_priority(void)
+{
+}
+
+__attribute__((weak)) void abort_and_resume_byte_allocating_thread(void)
+{
+}
+
+void main()
+{
+
+ /* Setup the ThreadX kernel. */
+ _tx_initialize_kernel_setup();
+
+ if (_tx_thread_system_state == TX_INITIALIZE_ALMOST_DONE)
+ {
+ printf("Running Initialize Kernel Setup Test................................ SUCCESS!\n");
+ exit(0);
+ }
+ else
+ {
+ printf("Running Initialize Kernel Setup Test................................ ERROR!\n");
+ exit(1);
+ }
+}
+
+void test_application_define(void *first_unused_memory){}
+void tx_application_define(void *first_unused_memory){}
+
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+
+/* Define the deletion of the system timer thread. */
+
+extern TX_THREAD _tx_timer_thread;
+TEST_FLAG threadx_delete_timer_thread;
+void delete_timer_thread(void)
+{
+
+ _tx_thread_terminate(&_tx_timer_thread);
+ _tx_thread_delete(&_tx_timer_thread);
+}
+
+#endif \ No newline at end of file
diff --git a/test/tx/regression/threadx_interrupt_control_test.c b/test/tx/regression/threadx_interrupt_control_test.c
new file mode 100644
index 00000000..d58ceba3
--- /dev/null
+++ b/test/tx/regression/threadx_interrupt_control_test.c
@@ -0,0 +1,94 @@
+/* This test is designed to test the interrupt control service call avaialbe to the
+ application. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+
+/* 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_interrupt_control_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Interrupt Control Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT saved_interrupt_posture;
+
+
+ /* Inform user. */
+ printf("Running Interrupt Control Test...................................... ");
+
+ /* Lockout interrupts. */
+ saved_interrupt_posture = tx_interrupt_control(TX_INT_DISABLE);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Restore interrupts. */
+ saved_interrupt_posture = tx_interrupt_control(saved_interrupt_posture);
+
+ /* Sleep to make sure interrupts now work. */
+ tx_thread_sleep(2);
+
+ /* Check to make sure the returned interrupt type works. */
+ if (saved_interrupt_posture != TX_INT_DISABLE)
+ {
+
+ /* Interrupt control error. */
+ printf("ERROR #2\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
diff --git a/test/tx/regression/threadx_mutex_basic_test.c b/test/tx/regression/threadx_mutex_basic_test.c
new file mode 100644
index 00000000..2e784961
--- /dev/null
+++ b/test/tx/regression/threadx_mutex_basic_test.c
@@ -0,0 +1,767 @@
+/* This test is designed to test the mutex create/delete and immediate
+ return gets and puts. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_mutex.h"
+
+
+typedef struct MUTEX_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_MUTEX mutex;
+ ULONG next_to_last;
+ ULONG last;
+
+} MUTEX_MEMORY_TEST;
+
+static MUTEX_MEMORY_TEST mutex_memory;
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+static unsigned long thread_0_counter = 0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD thread_4;
+
+static TX_MUTEX mutex_0;
+static TX_MUTEX mutex_1;
+static TX_MUTEX mutex_2;
+static TX_MUTEX mutex_3;
+static TX_MUTEX mutex_4;
+static TX_MUTEX mutex_5;
+static TX_MUTEX mutex_6;
+static TX_MUTEX mutex_7;
+static TX_MUTEX mutex_8;
+
+static TX_TIMER timer_0;
+
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+
+UINT _txe_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit, UINT mutex_control_block_size);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+
+ /* Attempt to create a mutex from a timer. */
+ status = tx_mutex_create(&mutex_4, "mutex 4", TX_NO_INHERIT);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a mutex from a timer. */
+ status = tx_mutex_delete(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to get from mutex from a timer with suspension. */
+ status = tx_mutex_get(&mutex_2, 100);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+
+
+ /* Attempt to create a mutex from an ISR. */
+ status = tx_mutex_create(&mutex_4, "mutex 4", TX_NO_INHERIT);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a mutex from an ISR. */
+ status = tx_mutex_delete(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to get from mutex from an ISR with suspension. */
+ status = tx_mutex_get(&mutex_2, 100);
+
+ /* Check status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to get from mutex from an ISR without suspension. */
+ status = tx_mutex_get(&mutex_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to put a mutex from an ISR. */
+ status = tx_mutex_put(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+}
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_mutex_basic_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+
+ status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ status += tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ status += tx_thread_create(&thread_4, "thread 4", thread_4_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Basic Test............................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Basic Test............................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_1, "mutex 1", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Basic Test............................................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Basic Test............................................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Basic Test............................................ ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_8, "mutex 8", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Basic Test............................................ ERROR #5a\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Basic Test............................................ ");
+
+ /* Perform mutex memory test. */
+ mutex_memory.first = 0x11223344;
+ mutex_memory.second = 0x55667788;
+ mutex_memory.next_to_last = 0x99aabbcc;
+ mutex_memory.last = 0xddeeff00;
+
+ /* Create the semaphore. */
+ status = tx_mutex_create(&mutex_memory.mutex, "mutex memory", TX_INHERIT);
+ tx_mutex_delete(&mutex_memory.mutex);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (mutex_memory.first != 0x11223344) ||
+ (mutex_memory.second != 0x55667788) ||
+ (mutex_memory.next_to_last != 0x99aabbcc) ||
+ (mutex_memory.last != 0xddeeff00))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to create a mutex with a NULL pointer. */
+ status = tx_mutex_create(TX_NULL, "mutex 2", TX_INHERIT);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a mutex with a bad size. */
+ status = _txe_mutex_create(&mutex_5, "mutex 5", TX_INHERIT, (sizeof(TX_MUTEX)+1));
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a mutex that has already been created. */
+ status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a mutex with a bad inheritance option. */
+ status = tx_mutex_create(&mutex_4, "mutex 4", 14);
+
+ /* Check status. */
+ if (status != TX_INHERIT_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a mutex with a NULL pointer. */
+ status = tx_mutex_delete(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-created mutex. */
+ mutex_4.tx_mutex_id = 0;
+ status = tx_mutex_delete(&mutex_4);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get a mutex with a NULL pointer. */
+ status = tx_mutex_get(TX_NULL, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get a non-created mutex. */
+ mutex_4.tx_mutex_id = 0;
+ status = tx_mutex_get(&mutex_4, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to put a NULL mutex. */
+ status = tx_mutex_put(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to put a non-created mutex. */
+ mutex_4.tx_mutex_id = 0;
+ status = tx_mutex_put(&mutex_4);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Attempt to get from mutex that is available. Should be successful! */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get the same mutex again. Should be successful! */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Put the mutex. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_ownership_count != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Put the mutex again. Should be successful! */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) != (mutex_0.tx_mutex_owner != TX_NULL))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow other thread to get the mutex. */
+ tx_thread_relinquish();
+
+ /* Attempt to get the mutex. Should be unsuccessful. */
+ status = tx_mutex_get(&mutex_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NOT_AVAILABLE)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish again so that the other thread can release it. */
+ tx_thread_relinquish();
+
+ /* Delete mutex. */
+ status = tx_mutex_delete(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ status = tx_mutex_delete(&mutex_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get a priority inheritance mutex. */
+ status = tx_mutex_get(&mutex_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get another priority inheritance mutex. */
+ status = tx_mutex_get(&mutex_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Wakeup thread 2 to get the ISR to take place on top of the thread. */
+ tx_thread_resume(&thread_2);
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Block memory error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Release mutex multiple times. */
+ status = tx_mutex_put(&mutex_2);
+ status += tx_mutex_put(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_NOT_OWNED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to release a mutex that is not owned. */
+ status = _tx_mutex_put(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_NOT_OWNED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Delete mutex. */
+ status = tx_mutex_delete(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Get mutex 8. */
+ status = tx_mutex_get(&mutex_8, TX_WAIT_FOREVER);
+
+ /* Start thread 3 and 4. */
+ status += tx_thread_resume(&thread_3);
+ status += tx_thread_resume(&thread_4);
+
+ /* Sleep to let thread 3 suspend on the mutex. */
+ tx_thread_sleep(2);
+
+ /* Now, put the mutex to give it to thread 3. */
+ status += tx_mutex_put(&mutex_8);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #29a\n");
+ test_control_return(1);
+ }
+
+ status = tx_mutex_delete(&mutex_3);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Attempt to get from mutex that is available. Should be successful! */
+ status = tx_mutex_get(&mutex_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Let other thread run again. */
+ tx_thread_relinquish();
+
+ /* Release mutex! */
+ status = tx_mutex_put(&mutex_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Create and obtain a couple mutexes so the thread completion can release them. */
+ status = tx_mutex_create(&mutex_6, "mutex 6", TX_NO_INHERIT);
+ status += tx_mutex_create(&mutex_7, "mutex 7", TX_NO_INHERIT);
+ status += tx_mutex_get(&mutex_6, TX_NO_WAIT);
+ status += tx_mutex_get(&mutex_7, TX_NO_WAIT);
+ status += tx_mutex_get(&mutex_6, TX_NO_WAIT);
+ status += tx_mutex_get(&mutex_7, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_mutex_get(&mutex_8, TX_WAIT_FOREVER);
+ tx_mutex_put(&mutex_8);
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_mutex_get(&mutex_8, TX_WAIT_FOREVER);
+ tx_mutex_put(&mutex_8);
+ }
+}
diff --git a/test/tx/regression/threadx_mutex_delete_test.c b/test/tx/regression/threadx_mutex_delete_test.c
new file mode 100644
index 00000000..28676f4b
--- /dev/null
+++ b/test/tx/regression/threadx_mutex_delete_test.c
@@ -0,0 +1,194 @@
+/* This test is designed to test the mutex suspension and mutex delete with
+ suspended threads. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_MUTEX mutex_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_mutex_delete_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 Mutex Delete Test........................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Mutex Delete Test........................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_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 Mutex Delete Test........................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Delete Test........................................... ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Delete Test........................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Grab the mutex so it is owned by this thread. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to let other threads run. */
+ tx_thread_relinquish();
+
+ /* Other threads should now be suspended on the mutex. */
+
+ /* Delete the mutex to test it out! */
+ status = tx_mutex_delete(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow other threads to run again before we return. */
+ tx_thread_relinquish();
+
+ /* Now check the run counter of each thread. */
+ if ((thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_DELETED)
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_DELETED)
+ thread_2_counter++;
+}
diff --git a/test/tx/regression/threadx_mutex_information_test.c b/test/tx/regression/threadx_mutex_information_test.c
new file mode 100644
index 00000000..e95c16c6
--- /dev/null
+++ b/test/tx/regression/threadx_mutex_information_test.c
@@ -0,0 +1,592 @@
+/* This test is designed to test the mutex information services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_mutex.h"
+
+
+static unsigned long thread_0_counter = 0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+
+static TX_MUTEX mutex_0;
+static TX_MUTEX mutex_1;
+static TX_MUTEX mutex_2;
+static TX_MUTEX mutex_3;
+static TX_MUTEX mutex_4;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+UINT _tx_mutex_performance_info_get(TX_MUTEX *mutex_ptr, ULONG *puts, ULONG *gets,
+ ULONG *suspensions, ULONG *timeouts, ULONG *inversions, ULONG *inheritances);
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_mutex_information_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Information Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Information Test...................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_1, "mutex 1", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Information Test...................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Information Test...................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Information Test...................................... ERROR #5\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *name;
+ULONG count;
+TX_THREAD *owner;
+TX_THREAD *first_suspended;
+ULONG suspended_count;
+TX_MUTEX *next_mutex;
+ULONG puts;
+ULONG gets;
+ULONG suspensions;
+ULONG timeouts;
+ULONG inversions;
+ULONG inheritances;
+
+
+ /* Inform user. */
+ printf("Running Mutex Information Test...................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Attempt to get from mutex that is available. Should be successful! */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get the same mutex again. Should be successful! */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Put the mutex. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_ownership_count != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Put the mutex again. Should be successful! */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow other thread to get the mutex. */
+ tx_thread_relinquish();
+
+ /* Attempt to get the mutex. Should be unsuccessful. */
+ status = tx_mutex_get(&mutex_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NOT_AVAILABLE)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish again so that the other thread can release it. */
+ tx_thread_relinquish();
+
+ /* Delete mutex. */
+ status = tx_mutex_delete(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ status = tx_mutex_delete(&mutex_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get a priority inheritance mutex. */
+ status = tx_mutex_get(&mutex_2, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get another priority inheritance mutex. */
+ status = tx_mutex_get(&mutex_3, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to get mutex info with a NULL pointer. */
+ status = tx_mutex_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get mutex info from a non-created mutex. */
+ mutex_4.tx_mutex_id = 0;
+ status = tx_mutex_info_get(&mutex_4, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Get mutex information. */
+ status = tx_mutex_info_get(&mutex_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_mutex_info_get(&mutex_2, &name, &count, &owner, &first_suspended, &suspended_count, &next_mutex);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (count != mutex_2.tx_mutex_ownership_count) || (owner != mutex_2.tx_mutex_owner) ||
+ (first_suspended != mutex_2.tx_mutex_suspension_list) || (suspended_count != mutex_2.tx_mutex_suspended_count) || (next_mutex != mutex_2.tx_mutex_created_next))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+#ifdef TX_MUTEX_ENABLE_PERFORMANCE_INFO
+
+ /* Call with NULL pointer. */
+ status = _tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(&mutex_2, &puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (puts != mutex_2.tx_mutex_performance_put_count) || (gets != mutex_2.tx_mutex_performance_get_count) ||
+ (suspensions != mutex_2.tx_mutex_performance_suspension_count) || (timeouts != mutex_2.tx_mutex_performance_timeout_count) ||
+ (inversions != mutex_2.tx_mutex_performance_priority_inversion_count) || (inheritances != mutex_2.tx_mutex_performance__priority_inheritance_count))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(&puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (puts != _tx_mutex_performance_put_count) || (gets != _tx_mutex_performance_get_count) ||
+ (suspensions != _tx_mutex_performance_suspension_count) || (timeouts != _tx_mutex_performance_timeout_count) ||
+ (inversions != _tx_mutex_performance_priority_inversion_count) || (inheritances != _tx_mutex_performance__priority_inheritance_count))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(&mutex_2, &puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, &puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance inforamtion. */
+ status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(&puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(TX_NULL, &gets, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inversions, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inheritances);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance inforamtion. */
+ status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete mutex. */
+ status = tx_mutex_delete(&mutex_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+ status = tx_mutex_delete(&mutex_3);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Attempt to get from mutex that is available. Should be successful! */
+ status = tx_mutex_get(&mutex_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+
+ /* Let other thread run again. */
+ tx_thread_relinquish();
+
+ /* Release mutex! */
+ status = tx_mutex_put(&mutex_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #39\n");
+ test_control_return(1);
+ }
+}
diff --git a/test/tx/regression/threadx_mutex_nested_priority_inheritance_test.c b/test/tx/regression/threadx_mutex_nested_priority_inheritance_test.c
new file mode 100644
index 00000000..7397b4e2
--- /dev/null
+++ b/test/tx/regression/threadx_mutex_nested_priority_inheritance_test.c
@@ -0,0 +1,701 @@
+/* This test is designed to test multiple mutex priority inheritance situations. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+#define DEMO_STACK_SIZE TEST_STACK_SIZE_PRINTF
+
+
+/* Define the ThreadX object control blocks... */
+
+static TX_THREAD thread_0;
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD thread_4;
+static TX_THREAD thread_5;
+static TX_THREAD thread_6;
+
+static TX_MUTEX mutex_0;
+static TX_MUTEX mutex_1;
+static TX_MUTEX mutex_2;
+static TX_MUTEX mutex_3;
+
+
+/* Define the counters used in the demo application... */
+
+static ULONG thread_0_counter;
+static ULONG thread_1_counter;
+static ULONG thread_2_counter;
+static ULONG thread_3_counter;
+static ULONG thread_4_counter;
+static ULONG thread_5_counter;
+static ULONG thread_6_counter;
+#endif
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+#endif
+
+/* 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_mutex_nested_priority_inheritance_application_define(void *first_unused_memory)
+#endif
+{
+
+CHAR *pointer;
+UINT status;
+
+
+ pointer = (CHAR *) first_unused_memory;
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
+ pointer, DEMO_STACK_SIZE,
+ 16, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, DEMO_STACK_SIZE,
+ 8, 8, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, DEMO_STACK_SIZE,
+ 4, 4, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, DEMO_STACK_SIZE,
+ 30, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, DEMO_STACK_SIZE,
+ 4, 4, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4a\n");
+ test_control_return(1);
+ }
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, DEMO_STACK_SIZE,
+ 2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4b\n");
+ test_control_return(1);
+ }
+
+ /* Create thread. */
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, DEMO_STACK_SIZE,
+ 30, 30, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4c\n");
+ test_control_return(1);
+ }
+
+ /* Create the mutexes. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+ status += tx_mutex_create(&mutex_1, "mutex 1", TX_INHERIT);
+ status += tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
+ status += tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #5\n");
+ test_control_return(1);
+ }
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+#ifdef TX_DISABLE_PREEMPTION_THRESHOLD
+
+ /* Preemption threshold is not enabled, skip this test. */
+
+ /* Inform user. */
+ printf("Running Mutex Nested Priority Inheritance Test...................... SUCCESS!\n");
+ test_control_return(0);
+
+#else
+
+UINT test_case = 0;
+UINT loop_count = 0;
+UINT priority;
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Nested Priority Inheritance Test...................... ");
+
+ /* Get the mutex that will be owned always.... */
+ tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ while(loop_count++ < 50)
+ {
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+ tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
+
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_0);
+
+ /* Resume thread thread 3. */
+ tx_thread_resume(&thread_3);
+
+ /* Thread priority should be 4. */
+ if (thread_0.tx_thread_priority != 4)
+ {
+
+ /* Test error! */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Release the mutexes... Depending on the order they are released should dictate
+ the thread's returned to priority. */
+ if (test_case == 0)
+ {
+
+
+ tx_mutex_put(&mutex_2);
+
+ /* Priority should now be returned to priority 8. */
+ if (thread_0.tx_thread_priority != 8)
+ {
+
+ /* Test error! */
+ printf("ERROR #7\n");
+ test_control_return(2);
+ }
+
+ tx_mutex_put(&mutex_1);
+
+ /* Priority should now be returned to priority 15. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #8\n");
+ test_control_return(3);
+ }
+
+ tx_mutex_put(&mutex_0);
+
+ /* No change. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #9\n");
+ test_control_return(4);
+ }
+ }
+ else if (test_case == 1)
+ {
+
+ priority = thread_0.tx_thread_priority;
+ tx_mutex_put(&mutex_0);
+
+ /* Should have no change in priority since nothing was inherited for this mutex. */
+ if (thread_0.tx_thread_priority != priority)
+ {
+
+ /* Test error! */
+ printf("ERROR #10\n");
+ test_control_return(4);
+ }
+
+ tx_mutex_put(&mutex_1);
+
+ /* Should not do anything since mutex 2 elevated to a higher priority. */
+ if (thread_0.tx_thread_priority != priority)
+ {
+
+ /* Test error! */
+ printf("ERROR #11\n");
+ test_control_return(5);
+ }
+
+ tx_mutex_put(&mutex_2);
+
+ /* Should go back to priority 15. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #12\n");
+ test_control_return(6);
+ }
+ }
+ else if (test_case == 2)
+ {
+
+ tx_mutex_put(&mutex_2);
+
+ /* Should go back to priority 8. */
+ if (thread_0.tx_thread_priority != 8)
+ {
+
+ /* Test error! */
+ printf("ERROR #13\n");
+ test_control_return(7);
+ }
+
+ tx_mutex_put(&mutex_0);
+
+ /* Should not do anything. */
+ if (thread_0.tx_thread_priority != 8)
+ {
+
+ /* Test error! */
+ printf("ERROR #14\n");
+ test_control_return(8);
+ }
+
+ tx_mutex_put(&mutex_1);
+
+ /* Should go back to priority 15. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #15\n");
+ test_control_return(9);
+ }
+ }
+ else if (test_case == 3)
+ {
+
+ priority = thread_0.tx_thread_priority;
+ tx_mutex_put(&mutex_1);
+
+ /* Should not do anything since mutex 2 is still owned. */
+ if (thread_0.tx_thread_priority != priority)
+ {
+
+ /* Test error! */
+ printf("ERROR #16\n");
+ test_control_return(10);
+ }
+
+ tx_mutex_put(&mutex_0);
+
+ /* Should not do anything. */
+ if (thread_0.tx_thread_priority != priority)
+ {
+
+ /* Test error! */
+ printf("ERROR #17\n");
+ test_control_return(11);
+ }
+
+ tx_mutex_put(&mutex_2);
+
+ /* Should finally go back to priority 15. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #18\n");
+ test_control_return(12);
+ }
+ }
+ else if (test_case == 4)
+ {
+
+ priority = thread_0.tx_thread_priority;
+ tx_mutex_put(&mutex_1);
+
+ /* Should not do anything since mutex 2 is still owned. */
+ if (thread_0.tx_thread_priority != priority)
+ {
+
+ /* Test error! */
+ printf("ERROR #19\n");
+ test_control_return(13);
+ }
+
+ tx_mutex_put(&mutex_2);
+
+ /* Should reurn us back to priority 15. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #20\n");
+ test_control_return(14);
+ }
+
+ tx_mutex_put(&mutex_0);
+
+ /* Should not do anything. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #21\n");
+ test_control_return(15);
+ }
+ }
+ else if (test_case == 5)
+ {
+
+ priority = thread_0.tx_thread_priority;
+ tx_mutex_put(&mutex_0);
+
+ /* Should not do anything since mutex 2 is still owned. */
+ if (thread_0.tx_thread_priority != priority)
+ {
+
+ /* Test error! */
+ printf("ERROR #22\n");
+ test_control_return(16);
+ }
+
+ tx_mutex_put(&mutex_2);
+
+ /* Should reurn us back to priority 8. */
+ if (thread_0.tx_thread_priority != 8)
+ {
+
+ /* Test error! */
+ printf("ERROR #23\n");
+ test_control_return(17);
+ }
+
+ tx_mutex_put(&mutex_1);
+
+ /* Should return us back to priority 15. */
+ if (thread_0.tx_thread_priority != 15)
+ {
+
+ /* Test error! */
+ printf("ERROR #24\n");
+ test_control_return(18);
+ }
+ }
+
+ test_case++;
+ if (test_case > 5)
+ test_case = 0;
+ }
+
+ /* Check for thread 3 running... this should not happen! */
+ if (thread_3_counter != 50)
+ {
+
+ printf("ERROR #25\n");
+ test_control_return(19);
+ }
+
+ /* At this point, mutex 3 owned by this thread. */
+
+ /* Resume thread 6, lowest priority thread. */
+ status = tx_thread_resume(&thread_6);
+
+ /* Check for an error. */
+ if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 15) || (thread_6_counter != 0))
+ {
+
+ printf("ERROR #27\n");
+ test_control_return(19);
+ }
+
+ /* Now resume thread 4. */
+ status = tx_thread_resume(&thread_4);
+
+ /* Check for an error. */
+ if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 4) || (thread_6_counter != 0))
+ {
+
+ printf("ERROR #28\n");
+ test_control_return(19);
+ }
+
+ /* Now resume thread 5. */
+ status = tx_thread_resume(&thread_5);
+
+ /* Check for an error. */
+ if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 2) || (thread_6_counter != 0))
+ {
+
+ printf("ERROR #29\n");
+ test_control_return(19);
+ }
+
+ /* Sleep to let thread 6 run, which is lower priority. */
+ tx_thread_sleep(1);
+
+ /* Now release the mutex. */
+ status = tx_mutex_put(&mutex_3);
+
+ /* Check for an error. */
+ if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 15) || (thread_6_counter != 0) || (thread_4_counter != 1) || (thread_5_counter != 1))
+ {
+
+ printf("ERROR #30\n");
+ test_control_return(19);
+ }
+
+ /* Sleep to let thread 6 run and release the mutex. */
+ tx_thread_sleep(2);
+
+
+ /* If we get here the test was successful! */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+#endif
+}
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT old_priority;
+UINT old_threshold;
+
+
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Update the thread priority and thread preemption-threshold of thread 0. */
+ tx_thread_priority_change(&thread_0, 15, &old_priority);
+ tx_thread_preemption_change(&thread_0, 14, &old_threshold);
+
+ /* Get mutex. */
+ tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ tx_mutex_put(&mutex_1);
+
+ tx_thread_suspend(&thread_1);
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Update the thread priority and thread preemption-threshold of thread 0. */
+ tx_thread_priority_change(&thread_0, 15, &old_priority);
+ tx_thread_preemption_change(&thread_0, 8, &old_threshold);
+
+ /* Get mutex. */
+ tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ tx_mutex_put(&mutex_1);
+
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT old_priority;
+UINT old_threshold;
+
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Update the thread priority and thread preemption-threshold of thread 0. */
+ tx_thread_priority_change(&thread_0, 15, &old_priority);
+ tx_thread_preemption_change(&thread_0, 14, &old_threshold);
+
+ /* Get mutex. */
+ tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
+ tx_mutex_put(&mutex_2);
+
+ tx_thread_suspend(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Update the thread priority and thread preemption-threshold of thread 0. */
+ tx_thread_priority_change(&thread_0, 15, &old_priority);
+ tx_thread_preemption_change(&thread_0, 8, &old_threshold);
+
+ /* Get mutex. */
+ tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
+ tx_mutex_put(&mutex_2);
+
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+
+ while(1)
+ {
+
+ /* Resume thread 0. */
+ tx_thread_resume(&thread_0);
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_3);
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+
+ while(1)
+ {
+
+ /* Get priority inherit mutex. */
+ tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+
+ /* Release the priority inherit mutex. */
+ tx_mutex_put(&mutex_3);
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_4);
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+
+ while(1)
+ {
+
+ /* Get priority inherit mutex. */
+ tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+
+ /* Release the priority inherit mutex. */
+ tx_mutex_put(&mutex_3);
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_5);
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+
+ while(1)
+ {
+
+ /* Get priority inherit mutex. */
+ tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+
+ /* Release the priority inherit mutex. */
+ tx_mutex_put(&mutex_3);
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_6);
+ }
+}
+#endif
+
+
diff --git a/test/tx/regression/threadx_mutex_no_preemption_test.c b/test/tx/regression/threadx_mutex_no_preemption_test.c
new file mode 100644
index 00000000..c26c3651
--- /dev/null
+++ b/test/tx/regression/threadx_mutex_no_preemption_test.c
@@ -0,0 +1,173 @@
+/* This test is designed to test the mutex suspension and another thread resuming the
+ same priority thread by doing a mutex put. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+
+static TX_MUTEX mutex_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_mutext_no_preemption_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 Mutex Put with No Preemption Test........................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Mutex Put with No Preemption Test........................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Put with No Preemption Test........................... ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Put with No Preemption Test........................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Get the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Should be successful. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to make the other thread suspend on the mutex. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Put the mutex, this should resume the other thread
+ but not preempt this thread. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow the other thread to run. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 2)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+}
+
diff --git a/test/tx/regression/threadx_mutex_preemption_test.c b/test/tx/regression/threadx_mutex_preemption_test.c
new file mode 100644
index 00000000..238dda03
--- /dev/null
+++ b/test/tx/regression/threadx_mutex_preemption_test.c
@@ -0,0 +1,161 @@
+/* This test is designed to test the mutex suspension and another thread resuming the
+ higher priority thread by doing a mutex put. Higher-priority thread should preempt. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+
+static TX_MUTEX mutex_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_mutex_preemption_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 Mutex Put with Preemption Test.............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Put with Preemption Test.............................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Put with Preemption Test.............................. ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Put with Preemption Test.............................. ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Get the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Should be successful. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Now resume the higher priority thread to cause suspension. */
+ tx_thread_resume(&thread_1);
+
+ /* The other thread should now be suspended on the mutex. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Release the mutex, this should cause the other thread
+ to preempt. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status and run counter of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+}
+
diff --git a/test/tx/regression/threadx_mutex_priority_inheritance_test.c b/test/tx/regression/threadx_mutex_priority_inheritance_test.c
new file mode 100644
index 00000000..68a7f0ce
--- /dev/null
+++ b/test/tx/regression/threadx_mutex_priority_inheritance_test.c
@@ -0,0 +1,573 @@
+/* This test is designed to test the mutex suspension and priority inheritance with another
+ thread resuming the higher priority thread by doing a mutex put. Higher-priority thread should preempt. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static unsigned long thread_7_counter = 0;
+static TX_THREAD thread_7;
+
+static TX_MUTEX mutex_0;
+static TX_MUTEX mutex_1;
+static TX_MUTEX mutex_2;
+static TX_MUTEX mutex_3;
+
+
+extern UINT test_mutex_from_init;
+extern TEST_FLAG test_forced_mutex_timeout;
+
+
+VOID _tx_mutex_priority_change(TX_THREAD *thread_ptr, UINT priority, UINT threshold);
+
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+static void thread_7_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_mutex_priority_inheritance_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;
+
+ /* Test for an error creating/using a mutex from initialization. */
+ if (test_mutex_from_init != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #0\n");
+ test_control_return(1);
+ }
+
+ /* 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 Mutex Priority Inheritance Test............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 14, 14, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a high-priority thread that will get all the priority inheritance mutexes and return from
+ it's entry function in order to test the auto delete feature. */
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 10, 10, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create a higher-priority thread that is used to get thread 4 into a priority inheritance state. */
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 8, 8, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+
+ /* Create a higher-priority thread that is used to suspend on priority inheritance mutex 3. */
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #6\n");
+ test_control_return(1);
+ }
+
+
+ /* Create a higher-priority thread that is used to suspend on priority inheritance mutex 3. */
+ status = tx_thread_create(&thread_7, "thread 7", thread_7_entry, 7,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 7, 7, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_1, "mutex 1", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Create another mutex. */
+ status = tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Priority Inheritance Test............................. ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Drive one path of the internal mutex priority change routine directly for code coverage. */
+ thread_3.tx_thread_user_priority = 1;
+ thread_3.tx_thread_user_preempt_threshold = 1;
+ thread_3.tx_thread_state = 4;
+ _tx_mutex_priority_change(&thread_3, 3, 3);
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Priority Inheritance Test............................. ");
+
+ /* Resume thread 4 to test the automatic release of the mutexes. */
+ tx_thread_resume(&thread_4);
+
+ /* Determine if thread 4 was able to get the mutexes before completion... and
+ have its original priority restored after the priority inheritance. */
+ if ((thread_4_counter != 1) || (thread_5_counter != 1) || (thread_4.tx_thread_priority != 10) ||
+ (thread_4.tx_thread_inherit_priority != TX_MAX_PRIORITIES))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Get all the mutexex. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+ status += tx_mutex_get(&mutex_1, TX_NO_WAIT);
+ status += tx_mutex_get(&mutex_2, TX_NO_WAIT);
+
+ /* Should be successful. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Release mutex 2 to be compatible with original test. */
+ tx_mutex_put(&mutex_2);
+
+ /* Now resume the higher priority thread to cause suspension. */
+ tx_thread_resume(&thread_1);
+
+ /* The other thread should now be suspended on the mutex. */
+ if ((thread_1_counter != 1) || (thread_0.tx_thread_priority != 15))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Release the mutex, this should cause the other thread
+ to preempt. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status and run counter of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2) || (thread_0.tx_thread_priority != 16))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* At this point, get the mutex again. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Should be successful. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Now sleep for 20 ticks in order to test the priority inheritance change of a
+ non-ready thread. */
+ tx_thread_sleep(20);
+
+ /* The other thread should now be suspended on the mutex. */
+ if ((thread_1_counter != 3) || (thread_0.tx_thread_priority != 15))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 2 in order to get two threads suspended on the mutex. */
+ tx_thread_resume(&thread_2);
+
+ /* Now do a mutex put to release both threads suspended on this mutex. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* The other thread should now be suspended on the mutex. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 4) || (thread_2_counter != 2) || (thread_0.tx_thread_priority != 16))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* At this point, get the mutex again. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Should be successful. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Abort the sleep. */
+ tx_thread_wait_abort(&thread_1);
+ tx_thread_wait_abort(&thread_2);
+
+ /* Now both threads are suspended again on mutex... and then terminate them. */
+ tx_thread_terminate(&thread_1);
+ tx_thread_terminate(&thread_2);
+
+ /* Now do a mutex put to release both threads suspended on this mutex. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* The other thread should now be suspended on the mutex. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 3) || (thread_0.tx_thread_priority != 16))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Now test the timeout on the suspension list of a priority inheritance mutex. */
+
+ /* First, obtain priority inheritance mutex 3. */
+ status = tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ /* Next resume threads 6 and 7 so they will block on trying to get this mutex forever. */
+ status += tx_thread_resume(&thread_7);
+ status += tx_thread_resume(&thread_6);
+
+ /* Now set the flag which will cause the last thread in the suspension list to timeout (abort)
+ resulting in a NULL suspension list and covering that branch condition in tx_mutex_put */
+ test_forced_mutex_timeout = 1;
+
+ /* Perform a mutex put to release the mutex. */
+ status += tx_mutex_put(&mutex_3);
+
+ /* Now check for errors. */
+#ifndef TX_MISRA_ENABLE
+#ifndef TX_MANUAL_TEST
+#ifndef TX_NOT_INTERRUPTABLE
+ if ((status != TX_SUCCESS) || (thread_6_counter != 1) || (thread_7_counter != 0))
+#else
+ if ((status != TX_SUCCESS) || (thread_6_counter != 1))
+#endif
+#else
+ if ((status != TX_SUCCESS) || (thread_6_counter != 1))
+#endif
+#else
+ if ((status != TX_SUCCESS) || (thread_6_counter != 1))
+#endif
+ {
+
+ /* Mutex error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while(1)
+ {
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+
+ /* Sleep for 10 ticks... to delay. */
+ tx_thread_sleep(10);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Get mutex to cause additional ownership linked-list processing. */
+ tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
+
+ while(1)
+ {
+
+ /* Increment thread run counter. */
+ thread_2_counter++;
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_2_counter++;
+
+ /* Sleep for 10 ticks... to delay. */
+ tx_thread_sleep(10);
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Get mutex to cause additional ownership linked-list processing. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+ status += tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ status += tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ status += tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ status += tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
+
+ /* Resume thread 5 to get into priority inheritance. */
+ tx_thread_resume(&thread_5);
+
+ /* Determine if all the mutex gets were successful... and we have
+ inherited priority 8. */
+ if ((status == TX_SUCCESS) && (thread_4.tx_thread_priority == 8))
+ {
+
+ /* Yes, increment the thread counter. */
+ thread_4_counter++;
+ }
+
+ /* Now fall through and make sure the mutex cleanup function
+ releases all the mutexes. */
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Get mutex to cause priority inheritance in thread 4. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Determine if all the mutex gets were successful. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Yes, increment the thread counter. */
+ thread_5_counter++;
+ }
+
+ /* Now fall through and make sure the mutex cleanup function
+ releases all the mutexes. */
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Get mutex to cause priority inheritance in thread 0. */
+ status = tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ /* Determine if all the mutex gets were successful. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Yes, increment the thread counter. */
+ thread_6_counter++;
+ }
+
+ /* Now fall through and make sure the mutex cleanup function
+ releases all the mutexes. */
+}
+
+
+static void thread_7_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Get mutex to cause priority inheritance in thread 0. */
+ status = tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
+
+ /* Determine if all the mutex gets were successful. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Yes, increment the thread counter. */
+ thread_7_counter++;
+ }
+
+ /* Now fall through and make sure the mutex cleanup function
+ releases all the mutexes. */
+}
+
diff --git a/test/tx/regression/threadx_mutex_proritize_test.c b/test/tx/regression/threadx_mutex_proritize_test.c
new file mode 100644
index 00000000..4e25673f
--- /dev/null
+++ b/test/tx/regression/threadx_mutex_proritize_test.c
@@ -0,0 +1,525 @@
+/* This test is designed to test the mutex suspension prioritization. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+
+static TX_MUTEX mutex_0;
+static TX_MUTEX mutex_1;
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Determine if thread 3 is at the front of the suspension list. */
+ if (mutex_0.tx_mutex_suspension_list == &thread_3)
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+ }
+ else
+ {
+
+ /* Abort the wait of thread 5. */
+ tx_thread_wait_abort(&thread_5);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_mutex_prioritize_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 Mutex Prioritize Test....................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 14, 14, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Prioritize Test....................................... ERROR #8\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Prioritize Test....................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to prioritize a NULL mutex. */
+ status = tx_mutex_prioritize(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to prioritize a non-created mutex. */
+ mutex_1.tx_mutex_id = 0;
+ status = tx_mutex_prioritize(&mutex_1);
+
+ /* Check status. */
+ if (status != TX_MUTEX_ERROR)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Prioritize the mutex with no suspended threads! */
+ status = tx_mutex_prioritize(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Grab the mutex so it is owned by this thread. */
+ status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Resume other threads run. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Other threads should now be suspended on the mutex. Thread 1 should be
+ in front of thread 2 since it was suspended first. */
+ if (mutex_0.tx_mutex_suspension_list != &thread_1)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the mutex to test it out! */
+ status = tx_mutex_prioritize(&mutex_0);
+
+ /* Check status and make sure thread 2 is now at the front of the list. */
+ if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_2))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the mutex again to make sure nothing has changed! */
+ status = tx_mutex_prioritize(&mutex_0);
+
+ /* Check status and make sure thread 2 is now at the front of the list. */
+ if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_2))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #14a\n");
+ test_control_return(1);
+ }
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the block pool suspension list. */
+ status = tx_mutex_prioritize(&mutex_0);
+
+ /* Check status and make sure thread 3 is at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_3))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the mutex suspension list. */
+ status = tx_mutex_prioritize(&mutex_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Now determine if thread 4 is at the front of the list... It should be! */
+ if (mutex_0.tx_mutex_suspension_list != &thread_4)
+ {
+
+ /* Mutex error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while (1)
+ {
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while (1)
+ {
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_2_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while (1)
+ {
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_3_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_3);
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while (1)
+ {
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_4_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_4);
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while (1)
+ {
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_5_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_5);
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while (1)
+ {
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ status += tx_mutex_put(&mutex_0);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_6_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_6);
+ }
+}
+
diff --git a/test/tx/regression/threadx_mutex_suspension_timeout_test.c b/test/tx/regression/threadx_mutex_suspension_timeout_test.c
new file mode 100644
index 00000000..cae257b5
--- /dev/null
+++ b/test/tx/regression/threadx_mutex_suspension_timeout_test.c
@@ -0,0 +1,319 @@
+/* This test is designed to test the mutex suspension and timeout functionality. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_mutex.h"
+
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD thread_4;
+static TX_THREAD low_priority;
+
+
+static TX_MUTEX mutex_0;
+static TX_MUTEX mutex_1;
+
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void low_priority_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+extern void test_control_return(UINT status);
+
+
+#ifndef TX_MANUAL_TEST
+
+/* Define test flags for automated test. */
+
+extern TEST_FLAG threadx_mutex_suspension_put_test;
+extern TEST_FLAG threadx_mutex_suspension_priority_test;
+
+#endif
+
+
+/* This test routine is used to get NULL suspension lists in various parts of tx_mutex_put. This is hooked up to IRQ 0 on this simulation and is entered manually at the
+ correct time. */
+void abort_all_threads_suspended_on_mutex(void)
+{
+
+TX_THREAD *thread_ptr;
+
+ thread_ptr = _tx_thread_created_ptr;
+ while (thread_ptr)
+ {
+ if (thread_ptr -> tx_thread_state == TX_MUTEX_SUSP)
+ tx_thread_wait_abort(thread_ptr);
+
+ thread_ptr = thread_ptr -> tx_thread_created_next;
+ if (thread_ptr == _tx_thread_created_ptr)
+ break;
+ }
+}
+
+
+/* This test routine is used to get a thread of a non ready state into _tx_mutex_change, called froim _tx_mutex_put. This is hooked up to IRQ 1 on this simulation and is entered manually at the
+ correct time. */
+void suspend_lowest_priority(void)
+{
+
+ tx_thread_suspend(&low_priority);
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_mutex_suspension_timeout_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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 1, 1, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 2, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&low_priority, "low priority", low_priority_entry, 30,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 30, 30, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Suspension Timeout Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create mutexes. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+ status += tx_mutex_create(&mutex_1, "mutex 1", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Suspension Timeout Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Get the mutex to prevent thread from getting it. */
+ tx_mutex_get(&mutex_0, TX_NO_WAIT);
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+UINT old_preempt;
+UINT old_priority;
+
+
+ /* Inform user. */
+ printf("Running Mutex Suspension Timeout Test............................... ");
+
+ /* Sleep for 2 ticks for fresh timer. */
+ tx_thread_sleep(2);
+
+ /* Set clock to 0. */
+ tx_time_set(0);
+
+ /* Suspend on the mutex. */
+ status = tx_mutex_get(&mutex_0, 33);
+
+ /* Did we get the right status at the right time? */
+ if ((status != TX_NOT_AVAILABLE) || (tx_time_get() != 33))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Get the mutex. */
+ status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+
+ /* Make sure the three higher priority threads suspend on the mutex. */
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_1);
+
+
+#ifdef TX_MANUAL_TEST
+
+ /* Set BP hear and step into code and generate appropriate interrupt IRQ 0 by hand right after the prioritize function with interrupts enabled. This is to achieve the empty list branch coverage after the prioritize function. */
+ tx_mutex_put(&mutex_1);
+#else
+
+ /* Set the flag such that generate the condition wehre the empty list condition is satisfied in the branch coverage. */
+ threadx_mutex_suspension_put_test = 1;
+ tx_mutex_put(&mutex_1);
+#endif
+
+ /* Now some hand testing for tx_mutex_priority_change. */
+
+ /* Resume the low priority thread. */
+ tx_thread_resume(&low_priority);
+
+ /* Simulate a call from inside of mutex put, but doing it here makes life easier. */
+ _tx_thread_preempt_disable++;
+
+#ifdef TX_MANUAL_TEST
+
+ /* Set BP here and step into code and step through the code until the internal thread resume function returns, then issue an IRQ 1 to cause an ISR to suspend the thread and test the first condition. */
+ _tx_mutex_priority_change(&low_priority, 30);
+#else
+
+ /* Set the flag to suspend the thread and test the first condition after internal resume is called. */
+ threadx_mutex_suspension_priority_test = 1;
+ _tx_mutex_priority_change(&low_priority, 30);
+#endif
+
+ /* Resume the low priority thread. */
+ tx_thread_resume(&low_priority);
+
+ /* Now call internal _tx_mutex_priority_change, this should test the preemption-threshold throw-away path. */
+ _tx_mutex_priority_change(&low_priority, 30);
+
+ /* Now make it so we can have a higher-priority thread ready but not the execute pointer because of preemption-threshold. */
+ tx_thread_preemption_change(&thread_0, 10, &old_preempt);
+ tx_thread_priority_change(&low_priority, 10, &old_priority);
+
+ /* Now call the internal mutex priority change on this thread to get the throw-away path on original priority being the same when execute ptr is different. */
+ _tx_thread_execute_ptr = &low_priority;
+ _tx_mutex_priority_change(&low_priority, 10);
+ _tx_thread_execute_ptr = &thread_0;
+
+ /* Now make the low priority thread lower again, but with a preemption-threshold equal to thread_0. This will test yet another throw away condition. */
+ low_priority.tx_thread_inherit_priority = ((UINT) TX_MAX_PRIORITIES);
+ tx_thread_priority_change(&low_priority, 30, &old_priority);
+ tx_thread_preemption_change(&low_priority, 10, &old_preempt);
+
+ /* Now call the internal mutex priority change on this thread with the same priority. */
+ _tx_mutex_priority_change(&low_priority, 30);
+ _tx_thread_preempt_disable--;
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+
+ /* Loop to get the mutex. */
+ while(1)
+ {
+
+ /* Get and release the mutex. */
+ status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ if (status == TX_SUCCESS)
+ tx_mutex_put(&mutex_1);
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Loop to get the mutex. */
+ while(1)
+ {
+
+ /* Get and release the mutex. */
+ status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ if (status == TX_SUCCESS)
+ tx_mutex_put(&mutex_1);
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Loop to get the mutex. */
+ while(1)
+ {
+
+ /* Get and release the mutex. */
+ status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ if (status == TX_SUCCESS)
+ tx_mutex_put(&mutex_1);
+ tx_thread_suspend(&thread_3);
+ }
+}
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Loop to get the mutex. */
+ while(1)
+ {
+
+ /* Get and release the mutex. */
+ status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
+ if (status == TX_SUCCESS)
+ tx_mutex_put(&mutex_1);
+ tx_thread_suspend(&thread_4);
+ }
+}
+
+
+static void low_priority_entry(ULONG thread_input)
+{
+}
diff --git a/test/tx/regression/threadx_mutex_thread_terminate_test.c b/test/tx/regression/threadx_mutex_thread_terminate_test.c
new file mode 100644
index 00000000..9b552f54
--- /dev/null
+++ b/test/tx/regression/threadx_mutex_thread_terminate_test.c
@@ -0,0 +1,198 @@
+/* This test is designed to test thread terminate calls when threads are suspended on
+ a mutex. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_MUTEX mutex_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_mutex_thread_terminate_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 Mutex Thread Terminate Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Mutex Thread Terminate Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_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 Mutex Thread Terminate Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a mutex. */
+ status = tx_mutex_create(&mutex_0, "mutex 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Mutex Thread Terminate Test................................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Get the mutex. */
+ tx_mutex_get(&mutex_0, TX_NO_WAIT);
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Mutex Thread Terminate Test................................. ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Relinquish to let other threads run. */
+ tx_thread_relinquish();
+
+ /* Other threads should now be suspended on the mutex. */
+ if ((thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Terminate the other threads to make sure the mutex gets
+ cleaned up. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Terminate the other thread. */
+ status = tx_thread_terminate(&thread_2);
+
+ /* Relinquish just to make sure. */
+ tx_thread_relinquish();
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Mutex error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+//UINT status;
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the mutex. */
+ tx_mutex_get(&mutex_0, 33);
+
+ /* Should never get here! */
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+//UINT status;
+
+ /* Increment thread run counter. */
+ thread_2_counter++;
+
+ /* Suspend on the mutex. */
+ tx_mutex_get(&mutex_0, 44);
+
+ /* Should never get here! */
+ thread_2_counter++;
+}
diff --git a/test/tx/regression/threadx_queue_basic_eight_word_test.c b/test/tx/regression/threadx_queue_basic_eight_word_test.c
new file mode 100644
index 00000000..c201fdee
--- /dev/null
+++ b/test/tx/regression/threadx_queue_basic_eight_word_test.c
@@ -0,0 +1,423 @@
+/* This test is designed to test immediate response queue services including create
+ and delete. This test is for queue sizes of 8 ULONG. Two queues are used one with
+ a capacity of 1 message and another with a capacity of 3 messages. */
+
+#include <stdio.h>
+#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_eight_word_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 Eight Word Queue Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_8_ULONG, pointer, 8*sizeof(ULONG));
+ pointer = pointer + (8*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Eight Word Queue Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_8_ULONG, pointer, 8*3*sizeof(ULONG));
+ pointer = pointer + 8*3*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Eight Word Queue 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[8];
+ULONG dest_message[8];
+ULONG expected_message[8];
+
+
+ /* Inform user. */
+ printf("Running Queue Eight Word Queue Test................................. ");
+
+ source_message[0] = 0x01234567;
+ source_message[7] = 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[7] != dest_message[7]))
+ {
+
+ /* 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[7]++;
+
+ /* 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[7] != dest_message[7]))
+ {
+
+ /* 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[7]++;
+ expected_message[0] = source_message[0];
+ expected_message[7] = source_message[7];
+
+ /* Place something on queue 1. */
+ status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[7]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[7]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[7]++;
+
+
+ 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[7] != dest_message[7]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[7]++;
+
+ /* 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[7] != dest_message[7]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[7]++;
+
+ /* 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[7] != dest_message[7]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[7]++;
+
+ /* 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[7]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[7]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[7]++;
+
+ 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[7] != dest_message[7]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[7]++;
+
+ /* 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[7] != dest_message[7]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[7]++;
+
+ /* 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[7] != dest_message[7]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[7]++;
+
+ /* 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);
+ }
+}
+
+
diff --git a/test/tx/regression/threadx_queue_basic_four_word_test.c b/test/tx/regression/threadx_queue_basic_four_word_test.c
new file mode 100644
index 00000000..5e01bc5b
--- /dev/null
+++ b/test/tx/regression/threadx_queue_basic_four_word_test.c
@@ -0,0 +1,423 @@
+/* This test is designed to test immediate response queue services including create
+ and delete. This test is for queue sizes of 4 ULONG. Two queues are used one with
+ a capacity of 1 message and another with a capacity of 3 messages. */
+
+#include <stdio.h>
+#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_four_word_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 Four Word Test........................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_4_ULONG, pointer, 4*sizeof(ULONG));
+ pointer = pointer + (4*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Four Word Test........................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_4_ULONG, pointer, 4*3*sizeof(ULONG));
+ pointer = pointer + 4*3*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Four Word 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[4];
+ULONG dest_message[4];
+ULONG expected_message[4];
+
+
+ /* Inform user. */
+ printf("Running Queue Four Word Test........................................ ");
+
+ source_message[0] = 0x01234567;
+ source_message[3] = 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[3] != dest_message[3]))
+ {
+
+ /* 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[3]++;
+
+ /* 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[3] != dest_message[3]))
+ {
+
+ /* 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[3]++;
+ expected_message[0] = source_message[0];
+ expected_message[3] = source_message[3];
+
+ /* Place something on queue 1. */
+ status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[3]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[3]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[3]++;
+
+
+ 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[3] != dest_message[3]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[3]++;
+
+ /* 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[3] != dest_message[3]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[3]++;
+
+ /* 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[3] != dest_message[3]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[3]++;
+
+ /* 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[3]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[3]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[3]++;
+
+ 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[3] != dest_message[3]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[3]++;
+
+ /* 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[3] != dest_message[3]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[3]++;
+
+ /* 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[3] != dest_message[3]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[3]++;
+
+ /* 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);
+ }
+}
+
+
diff --git a/test/tx/regression/threadx_queue_basic_one_word_test.c b/test/tx/regression/threadx_queue_basic_one_word_test.c
new file mode 100644
index 00000000..142a9b60
--- /dev/null
+++ b/test/tx/regression/threadx_queue_basic_one_word_test.c
@@ -0,0 +1,867 @@
+/* This test is designed to test immediate response queue services including create
+ and delete. This test is for queue sizes of 1 ULONG. Two queues are used one with
+ a capacity of 1 message and another with a capacity of 3 messages. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+
+
+static TX_TIMER timer_0;
+
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+static TX_QUEUE queue_0;
+static TX_QUEUE queue_1;
+static TX_QUEUE queue_2;
+static TX_QUEUE queue_3;
+
+
+/* Define the external reference to the status for queue create from initialization. */
+
+extern UINT test_queue_from_init;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+UINT _txe_queue_create(TX_QUEUE *queue_ptr, CHAR *name_ptr, UINT message_size,
+ VOID *queue_start, ULONG queue_size, UINT queue_control_block_size);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+CHAR *pointer;
+ULONG source = 1234;
+ULONG destination;
+
+
+ /* Determine if calling queue create from initialization was successful. */
+ if (test_queue_from_init != TX_SUCCESS)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a queue from a timer. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, pointer, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a queue from a timer. */
+ status = tx_queue_delete(&queue_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to send something with suspension from a timer. */
+ status = tx_queue_front_send(&queue_0, &source, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to send something with suspension from a timer. */
+ status = tx_queue_send(&queue_0, &source, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to receive something with suspension from a timer. */
+ status = tx_queue_receive(&queue_0, &destination, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+CHAR *pointer;
+UINT status;
+ULONG source = 1234;
+ULONG destination;
+
+
+ /* Attempt to create a queue from an ISR. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, pointer, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a queue from an ISR. */
+ status = tx_queue_delete(&queue_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to send something with suspension from an ISR. */
+ status = tx_queue_front_send(&queue_0, &source, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to send something with suspension from an ISR. */
+ status = tx_queue_send(&queue_0, &source, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to receive something with suspension from an ISR. */
+ status = tx_queue_receive(&queue_0, &destination, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+}
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_basic_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;
+
+ status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue One Word Queue Test................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, sizeof(ULONG));
+ pointer = pointer + sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue One Word Queue Test................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG));
+ pointer = pointer + 3*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue One Word Queue 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 = 0x12345678UL;
+ULONG dest_message;
+ULONG expected_message;
+#ifndef TX_DISABLE_ERROR_CHECKING
+CHAR *pointer;
+#endif
+
+ /* Inform user. */
+ printf("Running Queue One Word Queue Test................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to create with NULL queue. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_queue_create(TX_NULL, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create with bad sized queue control block. */
+ status = _txe_queue_create(&queue_3, "queue 3", TX_1_ULONG, pointer, 3*sizeof(ULONG), (sizeof(TX_QUEUE)+1));
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create with bad sized message. */
+ status = tx_queue_create(&queue_3, "queue 3", 0, pointer, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a queue that has already been created. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_queue_create(&queue_0, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a queue with an invalid message size. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_queue_create(&queue_2, "queue 2", 47, pointer, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a queue with a NULL queue area. */
+ status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, TX_NULL, 3*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a queue with a too small queue area. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, pointer, 1);
+
+ /* Check for status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a NULL pointer. */
+ status = tx_queue_delete(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-created queue. */
+ queue_2.tx_queue_id = 0;
+ status = tx_queue_delete(&queue_2);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to flush a NULL pointer. */
+ status = tx_queue_flush(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to flush a non-created queue. */
+ queue_2.tx_queue_id = 0;
+ status = tx_queue_flush(&queue_2);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to send something to the front of a non-queue. */
+ status = tx_queue_front_send(TX_NULL, &source_message, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to send something to the front of a non-created queue. */
+ queue_2.tx_queue_id = 0;
+ status = tx_queue_front_send(&queue_2, &source_message, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to send something with a NULL source pointer. */
+ status = tx_queue_front_send(&queue_0, TX_NULL, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to send something to a non-queue. */
+ status = tx_queue_send(TX_NULL, &source_message, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to send something to a non-created queue. */
+ queue_2.tx_queue_id = 0;
+ status = tx_queue_send(&queue_2, &source_message, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to send something with a NULL source pointer. */
+ status = tx_queue_send(&queue_0, TX_NULL, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive something from a non-queue. */
+ status = tx_queue_receive(TX_NULL, &dest_message, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive something from a non-created queue. */
+ queue_2.tx_queue_id = 0;
+ status = tx_queue_receive(&queue_2, &dest_message, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive something to a NULL destination. */
+ status = tx_queue_receive(&queue_0, TX_NULL, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Place something on queue 0. */
+ status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #24\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 #25\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 != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #26\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 #27\n");
+ test_control_return(1);
+ }
+
+ /* Make sure we can do the same thing again! */
+ source_message++;
+
+ /* Place something on queue 0. */
+ status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #28\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 #29\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 != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #30\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 #31\n");
+ test_control_return(1);
+ }
+
+ /* Now we need to do the same thing with the queue with three entries. */
+
+ source_message++;
+ expected_message = source_message;
+
+ /* Place something on queue 1. */
+ status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #32\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 #33\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #34\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #35\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #36\n");
+ test_control_return(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 #37\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++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #38\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 #39\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #40\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #41\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #42\n");
+ test_control_return(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 #43\n");
+ test_control_return(1);
+ }
+
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Resume thread 1 so that we can take an interrupt on top of it. */
+ tx_thread_resume(&thread_1);
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #44\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete the queues. */
+ status = tx_queue_delete(&queue_1);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #45\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_delete(&queue_0);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #46\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+ }
+}
+
diff --git a/test/tx/regression/threadx_queue_basic_sixteen_word_test.c b/test/tx/regression/threadx_queue_basic_sixteen_word_test.c
new file mode 100644
index 00000000..703a1cf4
--- /dev/null
+++ b/test/tx/regression/threadx_queue_basic_sixteen_word_test.c
@@ -0,0 +1,423 @@
+/* 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 <stdio.h>
+#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_sixteen_word_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 Sixteen Word Test..................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_16_ULONG, pointer, 16*sizeof(ULONG));
+ pointer = pointer + (16*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Sixteen Word Test..................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_16_ULONG, pointer, 16*3*sizeof(ULONG));
+ pointer = pointer + 16*3*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Sixteen Word 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[16];
+ULONG dest_message[16];
+ULONG expected_message[16];
+
+
+ /* Inform user. */
+ printf("Running Queue Sixteen Word Test..................................... ");
+
+ source_message[0] = 0x01234567;
+ source_message[15] = 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[15] != dest_message[15]))
+ {
+
+ /* 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[15]++;
+
+ /* 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[15] != dest_message[15]))
+ {
+
+ /* 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[15]++;
+ expected_message[0] = source_message[0];
+ expected_message[15] = source_message[15];
+
+ /* Place something on queue 1. */
+ status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[15]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[15]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[15]++;
+
+
+ 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[15] != dest_message[15]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[15]++;
+
+ /* 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[15] != dest_message[15]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[15]++;
+
+ /* 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[15] != dest_message[15]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[15]++;
+
+ /* 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[15]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[15]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[15]++;
+
+ 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[15] != dest_message[15]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[15]++;
+
+ /* 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[15] != dest_message[15]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[15]++;
+
+ /* 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[15] != dest_message[15]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[15]++;
+
+ /* 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);
+ }
+}
+
+
diff --git a/test/tx/regression/threadx_queue_basic_two_word_test.c b/test/tx/regression/threadx_queue_basic_two_word_test.c
new file mode 100644
index 00000000..ab24d08e
--- /dev/null
+++ b/test/tx/regression/threadx_queue_basic_two_word_test.c
@@ -0,0 +1,463 @@
+/* This test is designed to test immediate response queue services including create
+ and delete. This test is for queue sizes of 2 ULONG. Two queues are used one with
+ a capacity of 1 message and another with a capacity of 3 messages. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+typedef struct QUEUE_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_QUEUE queue;
+ ULONG first_middle;
+ ULONG second_middle;
+ ULONG queue_area[2048/sizeof(ULONG)];
+ ULONG next_to_last;
+ ULONG last;
+
+} QUEUE_MEMORY_TEST;
+
+static QUEUE_MEMORY_TEST queue_memory;
+
+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_two_word_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 Two Word Test......................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 2*sizeof(ULONG));
+ pointer = pointer + (2*sizeof(ULONG));
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Two Word Test......................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_2_ULONG, pointer, 2*3*sizeof(ULONG));
+ pointer = pointer + 2*3*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Two Word 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[2];
+ULONG dest_message[2];
+ULONG expected_message[2];
+
+
+ /* Inform user. */
+ printf("Running Queue Two Word Test......................................... ");
+
+ /* Perform queue memory test. */
+ queue_memory.first = 0x11223344;
+ queue_memory.second = 0x55667788;
+ queue_memory.first_middle = 0x21314151;
+ queue_memory.second_middle= 0x61718191;
+ queue_memory.next_to_last = 0x99aabbcc;
+ queue_memory.last = 0xddeeff00;
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_memory.queue, "queue memory", TX_2_ULONG, &queue_memory.queue_area[0], (2048*sizeof(ULONG))/sizeof(ULONG));
+ tx_queue_delete(&queue_memory.queue);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (queue_memory.first != 0x11223344) ||
+ (queue_memory.second != 0x55667788) ||
+ (queue_memory.first_middle != 0x21314151) ||
+ (queue_memory.second_middle != 0x61718191) ||
+ (queue_memory.next_to_last != 0x99aabbcc) ||
+ (queue_memory.last != 0xddeeff00))
+ {
+ /* Queue error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ source_message[0] = 0x01234567;
+ source_message[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 #5\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 #6\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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\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 #8\n");
+ test_control_return(1);
+ }
+
+ /* Make sure we can do the same thing again! */
+ source_message[0]++;
+ source_message[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 #9\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 #10\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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #11\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 #12\n");
+ test_control_return(1);
+ }
+
+ /* Now we need to do the same thing with the queue with three entries. */
+
+ source_message[0]++;
+ source_message[1]++;
+ expected_message[0] = source_message[0];
+ expected_message[1] = source_message[1];
+
+ /* Place something on queue 1. */
+ status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[1]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[1]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[1]++;
+
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #13\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 #14\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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[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 #18\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[1]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[1]++;
+ status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
+ source_message[0]++;
+ source_message[1]++;
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #19\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 #20\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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[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[1] != dest_message[1]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ expected_message[0]++;
+ expected_message[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 #24\n");
+ test_control_return(1);
+ }
+
+ /* Delete the queues. */
+ status = tx_queue_delete(&queue_1);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_delete(&queue_0);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
diff --git a/test/tx/regression/threadx_queue_empty_suspension_test.c b/test/tx/regression/threadx_queue_empty_suspension_test.c
new file mode 100644
index 00000000..59d53e70
--- /dev/null
+++ b/test/tx/regression/threadx_queue_empty_suspension_test.c
@@ -0,0 +1,271 @@
+/* This test is designed to test empty queue suspension of queue that supports 3 messages
+ that are each 2 ULONG in size. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_QUEUE queue_0;
+static TX_QUEUE queue_1;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_empty_suspension_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 Empty Suspension Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Empty Suspension Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Empty Suspension Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Empty Suspension Test................................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Empty Suspension Test................................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Empty Suspension Test................................. ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG source_message[2] = {0x12345678, 0};
+
+
+ /* Inform user. */
+ printf("Running Queue Empty Suspension Test................................. ");
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to setup notify on a non-queue. */
+ status = tx_queue_send_notify(TX_NULL, queue_notify);
+
+ /* Check status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to setup notify on a non-created queue. */
+ queue_1.tx_queue_id = 0;
+ status = tx_queue_send_notify(&queue_1, queue_notify);
+
+ /* Check status. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Send message that should go directly into the the other thread's
+ destination area! We should also preempt and the queue should
+ be empty by the next time we get around! */
+ status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+
+ /* Check status and run count of other thread - it should have got the
+ message already. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Now resume thread 2 to get another thread suspended on an empty queue. */
+ tx_thread_resume(&thread_2);
+
+ /* Now send 2 messages to wakeup both threads! */
+ source_message[0]++;
+ status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+
+ /* Check status and run count of other thread - it should have got the
+ message already. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2) || (thread_2_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG expected_message[2] = {0x12345678, 0};
+ULONG dest_message[2];
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue with suspension. We should always
+ suspend until thread 0 executes. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
+
+ if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG expected_message[2] = {0x12345679, 0};
+ULONG dest_message[2];
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue with suspension. We should always
+ suspend until thread 0 executes. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
+
+ if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
diff --git a/test/tx/regression/threadx_queue_flush_no_suspension_test.c b/test/tx/regression/threadx_queue_flush_no_suspension_test.c
new file mode 100644
index 00000000..940259f2
--- /dev/null
+++ b/test/tx/regression/threadx_queue_flush_no_suspension_test.c
@@ -0,0 +1,216 @@
+/* This test is designed to test the queue flush operation on a queue that has no threads
+ suspended on it. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static TX_QUEUE queue_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_flush_no_suspension_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush No Suspension Test.............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush No Suspension Test.............................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush No Suspension Test.............................. ERROR #3\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Flush No Suspension Test.............................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ULONG message[2] = {0x12345678, 0};
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Queue Flush No Suspension Test.............................. ");
+
+ /* Fill up the queue. */
+ status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
+
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Flush queue 0 to make more room. */
+ status = tx_queue_flush(&queue_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+
+ /* Fill up the queue. */
+ status = tx_queue_send(&queue_0, &message[2], TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_send(&queue_0, &message[2], TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_send(&queue_0, &message[2], TX_NO_WAIT);
+
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Flush queue again to empty and then flush to test on an empty queue. */
+ status = tx_queue_flush(&queue_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_flush(&queue_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Success if we get here. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+}
+
diff --git a/test/tx/regression/threadx_queue_flush_test.c b/test/tx/regression/threadx_queue_flush_test.c
new file mode 100644
index 00000000..6d65c971
--- /dev/null
+++ b/test/tx/regression/threadx_queue_flush_test.c
@@ -0,0 +1,249 @@
+/* This test is designed to test the queue flush operation on a queue that has two threads
+ suspended on it. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_QUEUE queue_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_flush_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ULONG message[2] = {0x12345678, 0};
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Queue Flush w/Suspended Threads Test........................ ");
+
+ /* Fill up the queue. */
+ status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
+
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to get other threads suspended on the queue full. */
+ tx_thread_relinquish();
+
+ /* Flush queue 0 which has the threads suspended on it. */
+ status = tx_queue_flush(&queue_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to let other threads run and finish! */
+ tx_thread_relinquish();
+
+ /* Determine if the queue flush test was successful. */
+ if ((thread_1_counter == 1) && (thread_2_counter == 1))
+ {
+
+ /* Successful queue flush test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ else
+ {
+
+ /* Queue Flush error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+ULONG message[2] = {0x1, 0};
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_send(&queue_0, &message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+UINT status;
+ULONG message[2] = {0x2, 0};
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_send(&queue_0, &message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+}
+
diff --git a/test/tx/regression/threadx_queue_front_send_test.c b/test/tx/regression/threadx_queue_front_send_test.c
new file mode 100644
index 00000000..5329670b
--- /dev/null
+++ b/test/tx/regression/threadx_queue_front_send_test.c
@@ -0,0 +1,686 @@
+/* This test is designed to test immediate response queue services including queue front send.
+ This test is for queue sizes of 2 ULONG. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static TX_THREAD thread_2;
+
+static TX_QUEUE queue_0;
+
+
+static unsigned long thread_1a_counter = 0;
+static TX_THREAD thread_1a;
+
+static TX_THREAD thread_2a;
+
+static TX_QUEUE queue_0a;
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_1a_entry(ULONG thread_input);
+static void thread_2a_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_front_send_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, 0,
+ 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 Front Test............................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status = tx_thread_create(&thread_1a, "thread 1a", thread_1a_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Front Test............................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status = tx_thread_create(&thread_2a, "thread 2a", thread_2a_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Front Test............................................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 2*2*sizeof(ULONG));
+ pointer = pointer + 2*2*sizeof(ULONG);
+ status = tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, pointer, 2*1*sizeof(ULONG));
+ pointer = pointer + 2*1*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Front Test............................................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Front Test............................................ ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Front Test............................................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG source_message[2] = {0x12345678, 0};
+ULONG dest_message[2];
+ULONG temp[2];
+
+
+ /* Inform user. */
+ printf("Running Queue Front Test............................................ ");
+
+ /* Perform the 1 word queue front send test. */
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Place something on queue 0a. */
+ status = tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #7a\n");
+ test_control_return(1);
+ }
+
+ /* Place a new message on the front of the queue. */
+ temp[0] = 0xF000001;
+ status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #8a\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive something from queue 0a. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be successful and dest_message should equal source. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != temp[0]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #9a\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive something from queue 0a. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be successful and dest_message should equal source. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != source_message[0]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #10a\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive another message from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if (status != TX_QUEUE_EMPTY)
+ {
+
+ /* Queue error. */
+ printf("ERROR #11a\n");
+ test_control_return(1);
+ }
+
+ /* At this point the queue is empty. Resume another thread to
+ suspend on an empty queue. */
+ tx_thread_resume(&thread_1a);
+
+ /* Relinquish to get this thread suspended on the empty queue. */
+ tx_thread_relinquish();
+
+ /* Resume thread 2a to get another thread suspended on the empty queue. */
+ tx_thread_resume(&thread_2a);
+
+ /* Now send something to the front of the queue, which will resume
+ the first waiting thread. */
+ temp[0] = 0xFF00002;
+ status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #12a\n");
+ test_control_return(1);
+ }
+
+ /* Now send something to the front of the queue, which will resume
+ the second waiting thread. */
+ temp[0] = 0xFF00002;
+ status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #13a\n");
+ test_control_return(1);
+ }
+
+ /* Now relinquish again to let the other thread process the message. */
+ tx_thread_relinquish();
+
+ /* At this point, the other thread should have placed 2 messages on the queue
+ so we will now send to the front, but without suspension. */
+ temp[0] = 0xFF00003;
+ status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_QUEUE_FULL)
+ {
+
+ /* Queue error. */
+ printf("ERROR #14a\n");
+ test_control_return(1);
+ }
+
+ /* Now, we will now send to the front, but with suspension. */
+ temp[0] = 0xFF00003;
+ status = tx_queue_front_send(&queue_0a, &temp[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #15a\n");
+ test_control_return(1);
+ }
+
+ /* Now resume thread 2a to get another thread suspended on the queue. */
+ tx_thread_resume(&thread_2a);
+
+ temp[0] = 0xFF00004;
+ status = tx_queue_front_send(&queue_0a, &temp[0], TX_WAIT_FOREVER);
+
+ /* When we get back, the other thread has received all the messages and
+ verified they are in order AND relinquished. */
+ if ((status != TX_SUCCESS) || (thread_1a_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16a\n");
+ test_control_return(1);
+ }
+
+
+ /* Perform the multiword queue front send test. */
+
+
+ /* Increment thread 0 counter. */
+ thread_0_counter = 1;
+
+ /* Reset the source message. */
+ source_message[0] = 0x12345678;
+ source_message[1] = 0;
+
+ /* Place something on queue 0. */
+ status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Place a new message on the front of the queue. */
+ temp[0] = 0xF000001;
+ status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive something from queue 0. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be successful and dest_message should equal source. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != temp[0]))
+ {
+
+ /* 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[0], TX_NO_WAIT);
+
+ /* Should be successful and dest_message should equal source. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != source_message[0]))
+ {
+
+ /* Queue error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to receive another message from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if (status != TX_QUEUE_EMPTY)
+ {
+
+ /* Queue error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* At this point the queue is empty. Resume another thread to
+ suspend on an empty queue. */
+ tx_thread_resume(&thread_1);
+
+ /* Relinquish to get this thread suspended on the empty queue. */
+ tx_thread_relinquish();
+
+ /* Resume thread 2 to get another thread suspended on the empty queue. */
+ tx_thread_resume(&thread_2);
+
+ /* Now send something to the front of the queue, which will resume
+ the first waiting thread. */
+ temp[0] = 0xFF00002;
+ status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Now send something to the front of the queue, which will resume
+ the second waiting thread. */
+ temp[0] = 0xFF00002;
+ status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Now relinquish again to let the other thread process the message. */
+ tx_thread_relinquish();
+
+ /* At this point, the other thread should have placed 2 messages on the queue
+ so we will now send to the front, but without suspension. */
+ temp[0] = 0xFF00003;
+ status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT);
+
+ if (status != TX_QUEUE_FULL)
+ {
+
+ /* Queue error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Now, we will now send to the front, but with suspension. */
+ temp[0] = 0xFF00003;
+ status = tx_queue_front_send(&queue_0, &temp[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Now resume thread 2 to get another thread suspended on the queue. */
+ tx_thread_resume(&thread_2);
+
+ temp[0] = 0xFF00004;
+ status = tx_queue_front_send(&queue_0, &temp[0], TX_WAIT_FOREVER);
+
+ /* When we get back, the other thread has received all the messages and
+ verified they are in order AND relinquished. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG source_message[2] = {0xEE000001, 0};
+ULONG dest_message[2];
+
+
+ /* First, suspend on an empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
+
+ /* Determine if the message is good. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00002))
+ return;
+
+ /* Now fill the queue with two messages. */
+ status = tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+ source_message[0]++;
+ status += tx_queue_front_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Now let thread 0 send to the front of the queue with suspension. */
+ tx_thread_relinquish();
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00003))
+ return;
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000002))
+ return;
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000001))
+ return;
+
+ /* At this point, we are going to fill up the queue again. */
+ source_message[0]++;
+ status = tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+ source_message[0]++;
+ status += tx_queue_front_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Now let thread 0 send to the front of the queue with suspension. */
+ tx_thread_relinquish();
+
+ /* Attempt to receive four messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00004))
+ return;
+
+ /* Attempt to receive four messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xDD000001))
+ return;
+
+ /* Attempt to receive four messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000004))
+ return;
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000003))
+ return;
+
+ /* Increment this threads counter. */
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ULONG source_message[2] = {0xDD000001, 0};
+ULONG destination_message[2];
+
+
+ /* Receive message. */
+ tx_queue_receive(&queue_0, &destination_message[0], TX_WAIT_FOREVER);
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_2);
+
+ /* Send another message to the front of the queue. */
+ tx_queue_front_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+}
+
+
+static void thread_1a_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG source_message[2] = {0xEE000001, 0};
+ULONG dest_message[2];
+
+
+ /* First, suspend on an empty queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER);
+
+ /* Determine if the message is good. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00002))
+ return;
+
+ /* Now fill the queue with two messages. */
+ status = tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+ source_message[0]++;
+ status += tx_queue_front_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Now let thread 0 send to the front of the queue with suspension. */
+ tx_thread_relinquish();
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00003))
+ return;
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000002))
+ return;
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000001))
+ return;
+
+ /* At this point, we are going to fill up the queue again. */
+ source_message[0]++;
+ status = tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+ source_message[0]++;
+ status += tx_queue_front_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Now let thread 0 send to the front of the queue with suspension. */
+ tx_thread_relinquish();
+
+ /* Attempt to receive four messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00004))
+ return;
+
+ /* Attempt to receive four messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xDD000001))
+ return;
+
+ /* Attempt to receive four messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000004))
+ return;
+
+ /* Attempt to receive three messages from the queue. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+
+ /* Should be an error. */
+ if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000003))
+ return;
+
+ /* Increment this threads counter. */
+ thread_1a_counter++;
+}
+
+
+static void thread_2a_entry(ULONG thread_input)
+{
+
+ULONG source_message[2] = {0xDD000001, 0};
+ULONG destination_message[2];
+
+
+ /* Receive message. */
+ tx_queue_receive(&queue_0a, &destination_message[0], TX_WAIT_FOREVER);
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_2a);
+
+ /* Send another message to the front of the queue. */
+ tx_queue_front_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+}
diff --git a/test/tx/regression/threadx_queue_full_suspension_test.c b/test/tx/regression/threadx_queue_full_suspension_test.c
new file mode 100644
index 00000000..556a4c77
--- /dev/null
+++ b/test/tx/regression/threadx_queue_full_suspension_test.c
@@ -0,0 +1,368 @@
+/* This test is designed to test queue full suspension of queue that supports 3 messages
+ that are each 2 ULONG in size. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_QUEUE queue_0;
+
+
+static unsigned long thread_1a_counter = 0;
+static TX_THREAD thread_1a;
+
+static unsigned long thread_2a_counter = 0;
+static TX_THREAD thread_2a;
+
+static TX_QUEUE queue_0a;
+
+
+static ULONG queue_area[3];
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_1a_entry(ULONG thread_input);
+static void thread_2a_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_full_suspension_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 Full Suspension Test.................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_1a, "thread 1a", thread_1a_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 16, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Full Suspension Test.................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_2a, "thread 2a", thread_2a_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Full Suspension Test.................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+ status += tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, pointer, 3*1*sizeof(ULONG));
+ pointer = pointer + 3*1*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Full Suspension Test.................................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Full Suspension Test.................................. ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Full Suspension Test.................................. ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG source_message[2] = {0x12345678, 0};
+ULONG dest_message[2];
+
+
+ /* Inform user. */
+ printf("Running Queue Full Suspension Test.................................. ");
+
+ /* Perform the one word queue version. */
+
+ /* Suspend to get thread 1a to pend on the queue. */
+ tx_thread_suspend(&thread_0);
+ status = tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+ tx_thread_suspend(&thread_0);
+ tx_thread_resume(&thread_1a);
+ tx_thread_resume(&thread_2a);
+ tx_queue_delete(&queue_0a);
+ status += tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, queue_area, sizeof(queue_area));
+
+
+ /* Fill the queue with an initial 3 messages! */
+ status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+
+ /* Receive two of the messages back to put the first received message at the end
+ of the queue. */
+ status += tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+ status += tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+ status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+
+ /* Check status and run count of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1a_counter != 0))
+ {
+
+ /* Queue error. */
+ printf("ERROR #6a\n");
+ test_control_return(1);
+ }
+
+ /* Send message that should cause this thread to suspend, until the
+ lower priority thread receives a message. */
+ status = tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+
+ /* Check status and run count of other thread - it should have got the
+ message already even though its counter is still 0 (it was preempted
+ in the queue receive call. */
+ if ((status != TX_SUCCESS) || (thread_1a_counter != 5) || (thread_2a_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #7a\n");
+ test_control_return(1);
+ }
+
+ /* Perform the two word queue version. */
+
+ /* Reset the source message. */
+ source_message[0] = 0x12345678;
+ source_message[1] = 0;
+
+ /* Resume threads 1 and 2. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Fill the queue with an initial 3 messages! */
+ status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+
+ /* Receive two of the messages back to put the first received message at the end
+ of the queue. */
+ status += tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+ status += tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+
+ /* Check status and run count of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0))
+ {
+
+ /* Queue error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Send message that should cause this thread to suspend, until the
+ lower priority thread receives a message. */
+ status = tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+
+ /* Check status and run count of other thread - it should have got the
+ message already even though its counter is still 0 (it was preempted
+ in the queue receive call. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+ULONG expected_message[2] = {0x12345678, 0};
+ULONG dest_message[2];
+UINT old_priority;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+ /* Receive messages and suspend. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
+
+ if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
+ break;
+
+ /* Change thread 2 priority. */
+ tx_thread_priority_change(&thread_2, 15, &old_priority);
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ULONG source_message[2] = {0x1234567C, 0};
+
+
+ /* Send one message to the queue. */
+ tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+}
+
+
+static void thread_1a_entry(ULONG thread_input)
+{
+UINT status;
+ULONG expected_message[2] = {0x12345678, 0};
+ULONG dest_message[2];
+UINT old_priority;
+
+
+ /* Receive message and suspend. */
+ status = tx_thread_resume(&thread_0);
+ status += tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER);
+ status += tx_thread_resume(&thread_0);
+ status += tx_thread_suspend(&thread_1a);
+
+ if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]))
+ return;
+
+ /* Loop forever! */
+ while(1)
+ {
+
+ /* Receive messages and suspend. */
+ status = tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER);
+
+ if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
+ break;
+
+ /* Change thread 2a priority. */
+ tx_thread_priority_change(&thread_2a, 15, &old_priority);
+
+ /* Increment the thread counter. */
+ thread_1a_counter++;
+ }
+}
+
+
+static void thread_2a_entry(ULONG thread_input)
+{
+
+ULONG source_message[2] = {0x1234567C, 0};
+
+
+ /* Send one message to the queue. */
+ tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
+
+ /* Increment the thread counter. */
+ thread_2a_counter++;
+}
diff --git a/test/tx/regression/threadx_queue_information_test.c b/test/tx/regression/threadx_queue_information_test.c
new file mode 100644
index 00000000..c1db82ca
--- /dev/null
+++ b/test/tx/regression/threadx_queue_information_test.c
@@ -0,0 +1,664 @@
+/* This test is designed to test the queue information services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_queue.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static TX_QUEUE queue_0;
+static TX_QUEUE queue_1;
+static TX_QUEUE queue_2;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+UINT _tx_queue_performance_info_get(TX_QUEUE *queue_ptr, ULONG *messages_sent, ULONG *messages_received,
+ ULONG *empty_suspensions, ULONG *full_suspensions, ULONG *full_errors, ULONG *timeouts);
+
+/* 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_information_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 Information Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, sizeof(ULONG));
+ pointer = pointer + sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Information Test...................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG));
+ pointer = pointer + 3*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Information 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 = 0x12345678UL;
+ULONG dest_message;
+ULONG expected_message;
+CHAR *name;
+ULONG enqueued;
+ULONG available_storage;
+TX_THREAD *first_suspended;
+ULONG suspended_count;
+TX_QUEUE *next_queue;
+ULONG messages_sent;
+ULONG messages_received;
+ULONG empty_suspensions;
+ULONG full_suspensions;
+ULONG full_errors;
+ULONG timeouts;
+
+
+ /* Inform user. */
+ printf("Running Queue Information Test...................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to get info from a non-queue. */
+ status = tx_queue_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get info from a non-created queue. */
+ queue_2.tx_queue_id = 0;
+ status = tx_queue_info_get(&queue_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Place something on queue 0. */
+ status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #5\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 #6\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 != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\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 #8\n");
+ test_control_return(1);
+ }
+
+ /* Make sure we can do the same thing again! */
+ source_message++;
+
+ /* Place something on queue 0. */
+ status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #9\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 #10\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 != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #11\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 #12\n");
+ test_control_return(1);
+ }
+
+ /* Now we need to do the same thing with the queue with three entries. */
+
+ source_message++;
+ expected_message = source_message;
+
+ /* Place something on queue 1. */
+ status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #13\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 #14\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #17\n");
+ test_control_return(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 #18\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++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+ status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
+ source_message++;
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #19\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 #20\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #21\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #22\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++ != dest_message))
+ {
+
+ /* Queue error. */
+ printf("ERROR #23\n");
+ test_control_return(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 #24\n");
+ test_control_return(1);
+ }
+
+ /* Get queue information. */
+ status = tx_queue_info_get(&queue_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_queue_info_get(&queue_0, &name, &enqueued, &available_storage, &first_suspended, &suspended_count, &next_queue);
+
+ /* Check for errors. */
+ if ((status != TX_SUCCESS) || (enqueued != queue_0.tx_queue_enqueued) || (available_storage != queue_0.tx_queue_available_storage) ||
+ (first_suspended != queue_0.tx_queue_suspension_list) || (suspended_count != queue_0.tx_queue_suspended_count) ||
+ (next_queue != queue_0.tx_queue_created_next))
+ {
+
+ /* Queue error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+#ifdef TX_QUEUE_ENABLE_PERFORMANCE_INFO
+
+ /* Test null pointer for queue performance info get. */
+ status = _tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Should be an error! */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(&queue_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_queue_performance_info_get(&queue_0, &messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Check for errors. */
+ if ((status != TX_SUCCESS) || (messages_sent != queue_0.tx_queue_performance_messages_sent_count) || (messages_received != queue_0.tx_queue_performance_messages_received_count) ||
+ (empty_suspensions != queue_0.tx_queue_performance_empty_suspension_count) || (full_suspensions != queue_0.tx_queue_performance_full_suspension_count) ||
+ (full_errors != queue_0.tx_queue_performance_full_error_count) || (timeouts != queue_0.tx_queue_performance_timeout_count))
+ {
+
+ /* Queue error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_queue_performance_system_info_get(&messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Check for errors. */
+ if ((status != TX_SUCCESS) || (messages_sent != _tx_queue_performance_messages_sent_count) || (messages_received != _tx_queue_performance__messages_received_count) ||
+ (empty_suspensions != _tx_queue_performance_empty_suspension_count) || (full_suspensions != _tx_queue_performance_full_suspension_count) ||
+ (full_errors != _tx_queue_performance_full_error_count) || (timeouts != _tx_queue_performance_timeout_count))
+ {
+
+ /* Queue error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(&queue_0, &messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, &messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, TX_NULL, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+ /* Get performance information. */
+ status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(&messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #39\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &full_suspensions, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #40\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &full_errors, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #41\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #42\n");
+ test_control_return(1);
+ }
+
+ /* Get system performance information. */
+ status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Should be an error! */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Queue error. */
+ printf("ERROR #43\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete the queues. */
+ status = tx_queue_delete(&queue_1);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #44\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_delete(&queue_0);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #45\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
diff --git a/test/tx/regression/threadx_queue_prioritize.c b/test/tx/regression/threadx_queue_prioritize.c
new file mode 100644
index 00000000..7a9d2b44
--- /dev/null
+++ b/test/tx/regression/threadx_queue_prioritize.c
@@ -0,0 +1,534 @@
+/* This test is designed to test queue prioritize. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static TX_QUEUE queue_0;
+static TX_QUEUE queue_1;
+
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Determine if thread 3 is at the front of the suspension list. */
+ if (queue_0.tx_queue_suspension_list == &thread_3)
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+ }
+ else
+ {
+
+ /* Abort the wait of thread 5. */
+ tx_thread_wait_abort(&thread_5);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+ }
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_prioritize_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #9\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Prioritize Test....................................... ERROR #10\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Queue Prioritize Test....................................... ");
+
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to prioritize a non-queue. */
+ status = tx_queue_prioritize(TX_NULL);
+
+ /* Check for an error condition. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to prioritize a non-created queue. */
+ queue_1.tx_queue_id = 0;
+ status = tx_queue_prioritize(&queue_1);
+
+ /* Check for an error condition. */
+ if (status != TX_QUEUE_ERROR)
+ {
+
+ /* Queue error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Nothing to do here, but check prioritization with no suspended threads. */
+ status = tx_queue_prioritize(&queue_0);
+
+ /* Check for an error condition. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Queue error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 and 2 are suspended on the queue. */
+ if ((thread_1.tx_thread_state != TX_QUEUE_SUSP) || (thread_2.tx_thread_state != TX_QUEUE_SUSP) ||
+ (queue_0.tx_queue_suspension_list != &thread_1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the queue suspension list. */
+ status = tx_queue_prioritize(&queue_0);
+
+ /* Check status and make sure thread 2 is not at the head of the list. */
+ if ((status != TX_SUCCESS) || (queue_0.tx_queue_suspension_list != &thread_2))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the queue suspension list again, but slightly different path because it was previously prioritized. */
+ status = tx_queue_prioritize(&queue_0);
+
+ /* Check status and make sure thread 2 not at the head of the list. */
+ if ((status != TX_SUCCESS) || (queue_0.tx_queue_suspension_list != &thread_2))
+ {
+
+ /* Queue error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the queue suspension list. */
+ status = tx_queue_prioritize(&queue_0);
+
+ /* Check status and make sure thread 3 is at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (queue_0.tx_queue_suspension_list != &thread_3))
+ {
+
+ /* Queue error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the queue suspension list. */
+ status = tx_queue_prioritize(&queue_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Block Pool error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Now determine if thread 4 is at the front of the list... It should be! */
+ if (queue_0.tx_queue_suspension_list != &thread_4)
+ {
+
+ /* Queue error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+ }
+}
+
+
diff --git a/test/tx/regression/threadx_queue_suspension_timeout_test.c b/test/tx/regression/threadx_queue_suspension_timeout_test.c
new file mode 100644
index 00000000..a3c390ed
--- /dev/null
+++ b/test/tx/regression/threadx_queue_suspension_timeout_test.c
@@ -0,0 +1,254 @@
+/* This test is designed to test queue full and empty suspension with timeouts on queues
+ that supports 3 messages that are each 2 ULONG in size. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+
+static TX_THREAD thread_1;
+
+static TX_THREAD thread_2;
+static unsigned long thread_2_counter = 0;
+
+static TX_QUEUE queue_0;
+static TX_QUEUE queue_1;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_suspension_timeout_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create the queues. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_queue_create(&queue_1, "queue 1", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #6\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Suspension Timeout Test............................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG source_message[2] = {0x12345678, 0};
+
+
+ /* Inform user. */
+ printf("Running Queue Suspension Timeout Test............................... ");
+
+ /* Fill the queue with an initial 3 messages! */
+ status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+ status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
+ source_message[0]++;
+
+ /* Check status and run count of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0))
+ {
+
+ /* Queue error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Send message to the front of the queue that should cause this thread to suspend. The timeout
+ should cause it to resume with a TX_QUEUE_FULL error code. */
+ status = tx_queue_front_send(&queue_0, &source_message[0], 3);
+
+ if ((status != TX_QUEUE_FULL) || (thread_1_counter != 0) || (thread_2_counter != 0))
+ {
+
+ /* Queue error. */
+ printf("ERROR #9a\n");
+ test_control_return(1);
+ }
+
+ /* Send message that should cause this thread to suspend. The timeout
+ should cause it to resume with a TX_QUEUE_FULL error code. */
+ status = tx_queue_send(&queue_0, &source_message[0], 32);
+
+ if ((status != TX_QUEUE_FULL) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Queue error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message[2];
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue with suspension and timeout.
+ We should wakeup after the timeout expires with an empty status. */
+ status = tx_queue_receive(&queue_1, &dest_message[0], 20);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message[2];
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue with suspension and timeout.
+ We should wakeup after the timeout expires with an empty status. */
+ status = tx_queue_receive(&queue_1, &dest_message[0], 20);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
diff --git a/test/tx/regression/threadx_queue_thread_terminate_test.c b/test/tx/regression/threadx_queue_thread_terminate_test.c
new file mode 100644
index 00000000..d0834704
--- /dev/null
+++ b/test/tx/regression/threadx_queue_thread_terminate_test.c
@@ -0,0 +1,183 @@
+/* This test is designed to test thread terminate when the terminated thread is suspeded
+ on a queue. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static TX_QUEUE queue_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+static void queue_notify(TX_QUEUE *queue_ptr)
+{
+
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_queue_thread_terminate_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Thread Terminate Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Thread Terminate Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create the queue. */
+ status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
+ pointer = pointer + 3*2*sizeof(ULONG);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Thread Terminate Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Setup queue send notification. */
+ status = tx_queue_send_notify(&queue_0, queue_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Queue Thread Terminate Test................................. ERROR #4\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Queue Thread Terminate Test................................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Queue Thread Terminate Test................................. ");
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 is suspended on the queue. */
+ if (thread_1.tx_thread_state != TX_QUEUE_SUSP)
+ {
+
+ /* Queue error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Terminate thread 1 which is suspended on queue 0. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_TERMINATED) ||
+ (thread_1_counter != 0) || (queue_0.tx_queue_suspended_count))
+ {
+
+ /* Queue error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+ULONG dest_message[2];
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Receive message from empty queue. */
+ status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
+
+ if (status != TX_QUEUE_EMPTY)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
diff --git a/test/tx/regression/threadx_semaphore_basic_test.c b/test/tx/regression/threadx_semaphore_basic_test.c
new file mode 100644
index 00000000..f554257d
--- /dev/null
+++ b/test/tx/regression/threadx_semaphore_basic_test.c
@@ -0,0 +1,545 @@
+/* This test is designed to test the semaphore create/delete and immediate return gets and puts. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+typedef struct SEMAPHORE_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_SEMAPHORE semaphore;
+ ULONG next_to_last;
+ ULONG last;
+
+} SEMAPHORE_MEMORY_TEST;
+
+static SEMAPHORE_MEMORY_TEST semaphore_memory;
+
+
+/* Define the external symbol to obtain the status from a create call in initialization. */
+
+extern UINT test_semaphore_from_init;
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+
+
+static TX_TIMER timer_0;
+
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+
+static TX_SEMAPHORE semaphore_0;
+static TX_SEMAPHORE semaphore_1;
+static TX_SEMAPHORE semaphore_2;
+static TX_SEMAPHORE semaphore_3;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+UINT _txe_semaphore_create(TX_SEMAPHORE *semaphore_ptr, CHAR *name_ptr, ULONG initial_count, UINT semaphore_control_block_size);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+
+
+ /* Determine if calling semaphore create from initialization was successful. */
+ if (test_semaphore_from_init != TX_SUCCESS)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a semaphore from a timer. */
+ status = tx_semaphore_create(&semaphore_2, "semaphore 2", 1);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a semaphore from a timer. */
+ status = tx_semaphore_delete(&semaphore_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to get a semaphore with suspension from a timer. */
+ status = tx_semaphore_get(&semaphore_0, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+
+
+ /* Attempt to create a semaphore from an ISR. */
+ status = tx_semaphore_create(&semaphore_2, "semaphore 2", 1);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a semaphore from an ISR. */
+ status = tx_semaphore_delete(&semaphore_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to get a semaphore with suspension from an ISR. */
+ status = tx_semaphore_get(&semaphore_0, 100);
+
+ /* Check for status. */
+ if (status != TX_WAIT_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+}
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_basic_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;
+
+ status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Basic Test........................................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 1. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Basic Test........................................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_1, "semaphore 1", 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Basic Test........................................ ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Semaphore Basic Test........................................ ");
+
+ /* Perform semaphore memory test. */
+ semaphore_memory.first = 0x11223344;
+ semaphore_memory.second = 0x55667788;
+ semaphore_memory.next_to_last = 0x99aabbcc;
+ semaphore_memory.last = 0xddeeff00;
+
+ /* Create the semaphore. */
+ status = tx_semaphore_create(&semaphore_memory.semaphore, "semaphore memory", 0);
+ tx_semaphore_delete(&semaphore_memory.semaphore);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (semaphore_memory.first != 0x11223344) ||
+ (semaphore_memory.second != 0x55667788) ||
+ (semaphore_memory.next_to_last != 0x99aabbcc) ||
+ (semaphore_memory.last != 0xddeeff00))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to create a non-semaphore. */
+ status = tx_semaphore_create(TX_NULL, "semaphore 0", 1);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a semaphore with a bad sized block. */
+ status = _txe_semaphore_create(&semaphore_3, "semaphore 3", 1, (sizeof(TX_SEMAPHORE)+1));
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create an already created semaphore. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-semaphore. */
+ status = tx_semaphore_delete(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-created semaphore. */
+ semaphore_2.tx_semaphore_id = 0;
+ status = tx_semaphore_delete(&semaphore_2);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get a non-semaphore. */
+ status = tx_semaphore_get(TX_NULL, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get a non-created semaphore. */
+ semaphore_2.tx_semaphore_id = 0;
+ status = tx_semaphore_get(&semaphore_2, TX_NO_WAIT);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to put a non-semaphore. */
+ status = tx_semaphore_put(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to put a non-created semaphore. */
+ semaphore_2.tx_semaphore_id = 0;
+ status = tx_semaphore_put(&semaphore_2);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to ceiling put a non-semaphore. */
+ status = tx_semaphore_ceiling_put(TX_NULL, 0);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to ceiling put a non-created semaphore. */
+ semaphore_2.tx_semaphore_id = 0;
+ status = tx_semaphore_ceiling_put(&semaphore_2, 0);
+
+ /* Check for status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to ceiling put with an invalid ceiling of 0. */
+ status = tx_semaphore_ceiling_put(&semaphore_0, 0);
+
+ /* Check for status. */
+ if (status != TX_INVALID_CEILING)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Attempt to get from semaphore with an instance. Should be successful! */
+ status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get from semaphore without an instance. Should be unsuccessful. */
+ status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_INSTANCE)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Put to semaphore that has an instance already. Should now be 2! */
+ status = tx_semaphore_put(&semaphore_1);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (semaphore_1.tx_semaphore_count != 2))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+
+ /* Attempt to get from semaphore with an instance. Should be successful! */
+ status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get from semaphore with an instance. Should be successful. */
+ status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Resume the thread 1 so we can take an interrupt on top of it. */
+ tx_thread_resume(&thread_1);
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Delete semaphores. */
+ status = tx_semaphore_delete(&semaphore_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ status = tx_semaphore_delete(&semaphore_1);
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+ }
+} \ No newline at end of file
diff --git a/test/tx/regression/threadx_semaphore_ceiling_put_test.c b/test/tx/regression/threadx_semaphore_ceiling_put_test.c
new file mode 100644
index 00000000..5364d2d9
--- /dev/null
+++ b/test/tx/regression/threadx_semaphore_ceiling_put_test.c
@@ -0,0 +1,334 @@
+/* This test is designed to test the semaphore ceiling put. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_SEMAPHORE semaphore_0;
+static TX_SEMAPHORE semaphore_1;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_ceiling_put_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 Semaphore Ceiling Put Test.................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Semaphore Ceiling Put Test.................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Ceiling Put Test.................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+ status += tx_semaphore_create(&semaphore_1, "semaphore 1", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Ceiling Put Test.................................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Ceiling Put Test.................................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Ceiling Put Test.................................. ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Ceiling Put Test.................................. ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Perform semaphore puts in order to exercise the ceiling put logic. */
+ status = tx_semaphore_ceiling_put(&semaphore_0, 2);
+ status += tx_semaphore_ceiling_put(&semaphore_0, 2);
+ status += tx_semaphore_ceiling_put(&semaphore_0, 2);
+ status += tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+ status += tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_CEILING_EXCEEDED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to make the other thread suspend on the semaphore. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Place an instance on the semaphore, this should resume the other thread
+ but not preempt this thread. */
+ status = tx_semaphore_ceiling_put(&semaphore_0, 2);
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow the other thread to run. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 3)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* At this point, we need to resume thread 2 and relinquish in order to get that thread suspended on the
+ semaphore as well. */
+ tx_thread_resume(&thread_2);
+ tx_thread_relinquish();
+
+ /* Perform 2 semaphore put operations to resume both threads. */
+ status = tx_semaphore_ceiling_put(&semaphore_0, 2);
+ status += tx_semaphore_ceiling_put(&semaphore_0, 2);
+
+ /* Let both threads run again. */
+ tx_thread_relinquish();
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 3))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Now turn off the semaphore notification. */
+ status = tx_semaphore_put_notify(&semaphore_0, TX_NULL);
+
+#ifdef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Clear the status since we know this feature is disabled and will return an error. */
+ status = TX_SUCCESS;
+#endif
+
+ /* Put a semaphore on a semaphore that does not have suspension. */
+ status += tx_semaphore_ceiling_put(&semaphore_1, 2);
+
+ /* Repeat the semaphore ceiling put without notification process! */
+
+ /* Place an instance on the semaphore, this should resume the other thread
+ but not preempt this thread. */
+ status += tx_semaphore_ceiling_put(&semaphore_0, 2);
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 5))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #9a\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow the other thread to run. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 7)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #10a\n");
+ test_control_return(1);
+ }
+
+ /* At this point, we need to resume thread 2 and relinquish in order to get that thread suspended on the
+ semaphore as well. */
+ tx_thread_resume(&thread_2);
+ tx_thread_relinquish();
+
+ /* Perform 2 semaphore put operations to resume both threads. */
+ status = tx_semaphore_ceiling_put(&semaphore_0, 2);
+ status += tx_semaphore_ceiling_put(&semaphore_0, 2);
+
+ /* Let both threads run again. */
+ tx_thread_relinquish();
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 9) || (thread_2_counter != 5))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #11a\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ while(1)
+ {
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ while(1)
+ {
+
+ /* Increment thread run counter. */
+ thread_2_counter++;
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_2_counter++;
+ }
+}
diff --git a/test/tx/regression/threadx_semaphore_delete_test.c b/test/tx/regression/threadx_semaphore_delete_test.c
new file mode 100644
index 00000000..f18d31dc
--- /dev/null
+++ b/test/tx/regression/threadx_semaphore_delete_test.c
@@ -0,0 +1,213 @@
+/* This test is designed to test the semaphore suspension and semaphore delete with
+ suspended threads. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_delete_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 Semaphore Delete Test....................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Semaphore Delete Test....................................... ERROR #2!\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_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 Semaphore Delete Test....................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Delete Test....................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Delete Test....................................... ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Delete Test....................................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Delete Test....................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Relinquish to let other threads run. */
+ tx_thread_relinquish();
+
+ /* Other threads should now be suspended on the semaphore. */
+
+ /* Delete the semaphore to test it out! */
+ status = tx_semaphore_delete(&semaphore_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow other threads to run again before we return. */
+ tx_thread_relinquish();
+
+ /* Now check the run counter of each thread. */
+ if ((thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_DELETED)
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_DELETED)
+ thread_2_counter++;
+}
diff --git a/test/tx/regression/threadx_semaphore_information_test.c b/test/tx/regression/threadx_semaphore_information_test.c
new file mode 100644
index 00000000..a8f6d242
--- /dev/null
+++ b/test/tx/regression/threadx_semaphore_information_test.c
@@ -0,0 +1,418 @@
+/* This test is designed to test the semaphore information services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_semaphore.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static TX_SEMAPHORE semaphore_0;
+static TX_SEMAPHORE semaphore_1;
+static TX_SEMAPHORE semaphore_2;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+UINT _tx_semaphore_performance_info_get(TX_SEMAPHORE *semaphore_ptr, ULONG *puts, ULONG *gets,
+ ULONG *suspensions, ULONG *timeouts);
+
+
+/* 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_semaphore_information_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 Semaphore Information Test.................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 1. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Information Test.................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_1, "semaphore 1", 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Information Test.................................. ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *name;
+ULONG current_value;
+TX_THREAD *first_suspended;
+ULONG suspended_count;
+TX_SEMAPHORE *next_semaphore;
+ULONG puts;
+ULONG gets;
+ULONG suspensions;
+ULONG timeouts;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Information Test.................................. ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to get semaphore information from a non-semaphore. */
+ status = tx_semaphore_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get semaphore information from a non-created semaphore. */
+ semaphore_2.tx_semaphore_id = 0;
+ status = tx_semaphore_info_get(&semaphore_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Attempt to get from semaphore with an instance. Should be successful! */
+ status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get from semaphore without an instance. Should be unsuccessful. */
+ status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_NO_INSTANCE)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Put to semaphore that has an instance already. Should now be 2! */
+ status = tx_semaphore_put(&semaphore_1);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (semaphore_1.tx_semaphore_count != 2))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+
+ /* Attempt to get from semaphore with an instance. Should be successful! */
+ status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get from semaphore with an instance. Should be successful. */
+ status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore information. */
+ status = tx_semaphore_info_get(&semaphore_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_semaphore_info_get(&semaphore_0, &name, &current_value, &first_suspended, &suspended_count, &next_semaphore);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (current_value != semaphore_0.tx_semaphore_count) ||
+ (first_suspended != semaphore_0.tx_semaphore_suspension_list) || (suspended_count != semaphore_0.tx_semaphore_suspended_count) ||
+ (next_semaphore != semaphore_0.tx_semaphore_created_next))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+#ifdef TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
+
+ /* Get semaphore performance information with NULL pointer. */
+ status = _tx_semaphore_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(&semaphore_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_semaphore_performance_info_get(&semaphore_0, &puts, &gets, &suspensions, &timeouts);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (puts != semaphore_0.tx_semaphore_performance_put_count) || (gets != semaphore_0.tx_semaphore_performance_get_count) ||
+ (suspensions != semaphore_0.tx_semaphore_performance_suspension_count) || (timeouts != semaphore_0.tx_semaphore_performance_timeout_count))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore system performance information. */
+ status = tx_semaphore_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_semaphore_performance_system_info_get(&puts, &gets, &suspensions, &timeouts);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (puts != _tx_semaphore_performance_put_count) || (gets != _tx_semaphore_performance_get_count) ||
+ (suspensions != _tx_semaphore_performance_suspension_count) || (timeouts != _tx_semaphore_performance_timeout_count))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(&semaphore_0, &puts, &gets, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(TX_NULL, &puts, &gets, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(TX_NULL, TX_NULL, &gets, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore performance information. */
+ status = tx_semaphore_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore system performance information. */
+ status = tx_semaphore_performance_system_info_get(&puts, &gets, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore system performance information. */
+ status = tx_semaphore_performance_system_info_get(TX_NULL, &gets, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore system performance information. */
+ status = tx_semaphore_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore system performance information. */
+ status = tx_semaphore_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Get semaphore system performance information. */
+ status = tx_semaphore_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Delete semaphores. */
+ status = tx_semaphore_delete(&semaphore_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ status = tx_semaphore_delete(&semaphore_1);
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
diff --git a/test/tx/regression/threadx_semaphore_non_preemption_test.c b/test/tx/regression/threadx_semaphore_non_preemption_test.c
new file mode 100644
index 00000000..40219546
--- /dev/null
+++ b/test/tx/regression/threadx_semaphore_non_preemption_test.c
@@ -0,0 +1,271 @@
+/* This test is designed to test the semaphore suspension and another thread resuming the
+ same priority thread by doing a semaphore put. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_non_preemption_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 Semaphore Non Preemption Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Semaphore Non Preemption Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Non Preemption Test............................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Non Preemption Test............................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Non Preemption Test............................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Non Preemption Test............................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Non Preemption Test............................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Perform a semaphore put and get, just to exercise the notify path of a non-resumption
+ semaphore put. */
+ status = tx_semaphore_put(&semaphore_0);
+ status += tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to make the other thread suspend on the semaphore. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Place an instance on the semaphore, this should resume the other thread
+ but not preempt this thread. */
+ status = tx_semaphore_put(&semaphore_0);
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow the other thread to run. */
+ tx_thread_relinquish();
+
+ /* Make sure the other thread has run. */
+ if (thread_1_counter != 3)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* At this point, we need to resume thread 2 and relinquish in order to get that thread suspended on the
+ semaphore as well. */
+ tx_thread_resume(&thread_2);
+ tx_thread_relinquish();
+
+ /* Perform 2 semaphore put operations to resume both threads. */
+ status = tx_semaphore_put(&semaphore_0);
+ status += tx_semaphore_put(&semaphore_0);
+
+ /* Let both threads run again. */
+ tx_thread_relinquish();
+
+ /* Check the status and the run counter of the other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 3))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ while(1)
+ {
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ while(1)
+ {
+
+ /* Increment thread run counter. */
+ thread_2_counter++;
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_2_counter++;
+ }
+}
+
diff --git a/test/tx/regression/threadx_semaphore_preemption_test.c b/test/tx/regression/threadx_semaphore_preemption_test.c
new file mode 100644
index 00000000..347042bc
--- /dev/null
+++ b/test/tx/regression/threadx_semaphore_preemption_test.c
@@ -0,0 +1,179 @@
+/* This test is designed to test the semaphore suspension and another thread resuming the
+ higher priority thread by doing a semaphore put. Higher-priority thread should preempt. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_preemption_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 Semaphore Preemption Test................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Preemption Test................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Preemption Test................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Preemption Test................................... ERROR #4\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Preemption Test................................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Preemption Test................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* The other thread should now be suspended on the semaphore. */
+ if (thread_1_counter != 1)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Place an instance on the semaphore, this should cause the other thread
+ to preempt. */
+ status = tx_semaphore_put(&semaphore_0);
+
+ /* Check status and run counter of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 2))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Did we get the right status? */
+ if (status == TX_SUCCESS)
+ thread_1_counter++;
+}
+
diff --git a/test/tx/regression/threadx_semaphore_prioritize.c b/test/tx/regression/threadx_semaphore_prioritize.c
new file mode 100644
index 00000000..79622667
--- /dev/null
+++ b/test/tx/regression/threadx_semaphore_prioritize.c
@@ -0,0 +1,525 @@
+/* This test is designed to test semaphore prioritize. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+static unsigned long thread_6_counter = 0;
+static TX_THREAD thread_6;
+
+static TX_SEMAPHORE semaphore_0;
+static TX_SEMAPHORE semaphore_1;
+
+static int test_status;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_entry(ULONG thread_input);
+static void thread_6_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Determine if the test case we are looking for is present. */
+ if ((_tx_thread_preempt_disable) && (test_status == 1))
+ {
+
+ /* Determine if thread 3 is at the front of the suspension list. */
+ if (semaphore_0.tx_semaphore_suspension_list == &thread_3)
+ {
+
+ /* Abort the wait of thread 3. */
+ tx_thread_wait_abort(&thread_3);
+ }
+ else
+ {
+
+ /* Abort the wait of thread 5. */
+ tx_thread_wait_abort(&thread_5);
+
+ /* End the ISR processing. */
+ test_status = 2;
+ test_isr_dispatch = TX_NULL;
+ }
+ }
+}
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_prioritize_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 3, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 4, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, 100, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Create the semaphore with no instances. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #9\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Prioritize Test................................... ERROR #10\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Prioritize Test................................... ");
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to prioritize a non-semaphore. */
+ status = tx_semaphore_prioritize(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to prioritize a non-created semaphore. */
+ semaphore_1.tx_semaphore_id = 0;
+ status = tx_semaphore_prioritize(&semaphore_1);
+
+ /* Check status. */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Prioritize the semaphore suspension list - empty list case! */
+ status = tx_semaphore_prioritize(&semaphore_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != TX_NULL))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Make sure thread 1 and 2 are suspended on the semaphore. */
+ if ((thread_1.tx_thread_state != TX_SEMAPHORE_SUSP) || (thread_2.tx_thread_state != TX_SEMAPHORE_SUSP) ||
+ (semaphore_0.tx_semaphore_suspension_list != &thread_1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the semaphore suspension list. */
+ status = tx_semaphore_prioritize(&semaphore_0);
+
+ /* Check status and make sure thread 2 is not at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_2))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Prioritize the semaphore suspension list again - in this case, the list is already prioritized. */
+ status = tx_semaphore_prioritize(&semaphore_0);
+
+ /* Check status and make sure thread 2 is not at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_2))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #15a\n");
+ test_control_return(1);
+ }
+
+ /* At this point we are going to get more than 2 threads suspended. */
+ tx_thread_resume(&thread_1);
+ tx_thread_resume(&thread_2);
+ tx_thread_resume(&thread_3);
+ tx_thread_resume(&thread_4);
+ tx_thread_resume(&thread_5);
+ tx_thread_resume(&thread_6);
+
+ /* Prioritize the semaphore suspension list. */
+ status = tx_semaphore_prioritize(&semaphore_0);
+
+ /* Check status and make sure thread 3 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_3))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Now loop to test the interrupt of the prioritize loop logic. */
+ test_status = 1;
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ /* Prioritize the semaphore suspension list. */
+ status = tx_semaphore_prioritize(&semaphore_0);
+
+ /* Check status and make sure thread 1 is terminated. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ } while (test_status == 1);
+
+ /* Check status and make sure thread 3 is now at the front of the suspension list. */
+ if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_4))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+UINT status;
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+UINT status;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+UINT status;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_3_counter++;
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+UINT status;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_4_counter++;
+ }
+}
+
+
+static void thread_5_entry(ULONG thread_input)
+{
+UINT status;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+ }
+}
+
+
+static void thread_6_entry(ULONG thread_input)
+{
+UINT status;
+
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the thread counter. */
+ thread_6_counter++;
+ }
+}
+
diff --git a/test/tx/regression/threadx_semaphore_thread_terminate_test.c b/test/tx/regression/threadx_semaphore_thread_terminate_test.c
new file mode 100644
index 00000000..b8beeff2
--- /dev/null
+++ b/test/tx/regression/threadx_semaphore_thread_terminate_test.c
@@ -0,0 +1,224 @@
+/* This test is designed to test thread terminate calls when threads are suspended on
+ a semaphore. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_thread_terminate_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 Semaphore Thread Terminate Test............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_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 Semaphore Thread Terminate Test............................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_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 Semaphore Thread Terminate Test............................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Thread Terminate Test............................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Thread Terminate Test............................. ERROR #5\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Thread Terminate Test............................. ERROR #6\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Semaphore Thread Terminate Test............................. ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Relinquish to let other threads run. */
+ tx_thread_relinquish();
+
+ /* Other threads should now be suspended on the semaphore. */
+ if ((thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Terminate the other threads to make sure the semaphore gets
+ cleaned up. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Terminate the other thread. */
+ status = tx_thread_terminate(&thread_2);
+
+ /* Relinquish just to make sure. */
+ tx_thread_relinquish();
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Increment thread run counter. */
+ thread_1_counter++;
+
+ /* Suspend on the semaphore. */
+ tx_semaphore_get(&semaphore_0, 33);
+
+ /* Should never get here! */
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Increment thread run counter. */
+ thread_2_counter++;
+
+ /* Suspend on the semaphore. */
+ tx_semaphore_get(&semaphore_0, 44);
+
+ /* Should never get here! */
+ thread_2_counter++;
+}
diff --git a/test/tx/regression/threadx_semaphore_timeout_test.c b/test/tx/regression/threadx_semaphore_timeout_test.c
new file mode 100644
index 00000000..ec16a7c0
--- /dev/null
+++ b/test/tx/regression/threadx_semaphore_timeout_test.c
@@ -0,0 +1,167 @@
+/* This test is designed to test the semaphore suspension and timeout functionality. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static TX_SEMAPHORE semaphore_0;
+static TX_SEMAPHORE semaphore_1;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void put_notify(TX_SEMAPHORE *semaphore_ptr)
+{
+
+ /* Don't need to do anything in here... */
+}
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_semaphore_timeout_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 Semaphore Suspension Timeout Test........................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create a semaphore with an initial count of 0. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Suspension Timeout Test........................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Setup the semaphore notify callback. */
+ status = tx_semaphore_put_notify(&semaphore_0, put_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Semaphore Suspension Timeout Test........................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Semaphore Suspension Timeout Test........................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG now;
+
+ /* Inform user. */
+ printf("Running Semaphore Suspension Timeout Test........................... ");
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to setup semaphore notify callback on non-semaphore. */
+ status = tx_semaphore_put_notify(TX_NULL, put_notify);
+
+ /* Check status */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to setup semaphore notify callback on non-created semaphore. */
+ semaphore_1.tx_semaphore_id = 0;
+ status = tx_semaphore_put_notify(&semaphore_1, put_notify);
+
+ /* Check status */
+ if (status != TX_SEMAPHORE_ERROR)
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Sleep for 2 ticks for fresh timer. */
+ tx_thread_sleep(2);
+
+ /* Set clock to 0. */
+ tx_time_set(0);
+
+ /* Suspend on the semaphore. */
+ status = tx_semaphore_get(&semaphore_0, 33);
+
+ /* Did we get the right status at the right time? */
+ now = tx_time_get();
+ if ((status != TX_NO_INSTANCE) || (now != 33))
+ {
+
+ /* Semaphore error. */
+ printf("ERROR #7, now = %lu\n", now);
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
diff --git a/test/tx/regression/threadx_thread_basic_execution_test.c b/test/tx/regression/threadx_thread_basic_execution_test.c
new file mode 100644
index 00000000..7a5ae864
--- /dev/null
+++ b/test/tx/regression/threadx_thread_basic_execution_test.c
@@ -0,0 +1,979 @@
+/* This test is designed to see if one thread can be created and executed.
+ It thread_0_entry is hit, then the thread was successfully scheduled.
+ On success, thread_0_counter gets incremented. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_block_pool.h"
+#include "tx_byte_pool.h"
+#include "tx_event_flags.h"
+#include "tx_mutex.h"
+#include "tx_queue.h"
+#include "tx_semaphore.h"
+#include "tx_thread.h"
+
+
+typedef struct THREAD_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_THREAD thread_block;
+ ULONG first_middle;
+ ULONG second_middle;
+ ULONG stack[2048/sizeof(ULONG)];
+ ULONG next_to_last;
+ ULONG last;
+
+} THREAD_MEMORY_TEST;
+
+static THREAD_MEMORY_TEST thread_memory;
+
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD thread_3;
+static TX_THREAD test_thread;
+
+static TX_TIMER timer_0;
+
+
+static UCHAR not_used_stack[TEST_STACK_SIZE_PRINTF];
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+
+/* Define task prototypes. */
+
+static void thread_0_entry(ULONG task_input);
+
+UINT _txe_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr,
+ VOID (*entry_function)(ULONG), ULONG entry_input,
+ VOID *stack_start, ULONG stack_size,
+ UINT priority, UINT preempt_threshold,
+ ULONG time_slice, UINT auto_start, UINT thread_control_block_size);
+
+#ifndef TX_INLINE_THREAD_RESUME_SUSPEND
+#ifndef TX_NOT_INTERRUPTABLE
+
+static TX_THREAD thread_4;
+static ULONG thread_4_counter = 0;
+static ULONG isr1_counter = 0;
+static ULONG test_case_found = TX_FALSE;
+static void thread_4_entry(ULONG task_input);
+
+#endif
+#endif
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+CHAR *pointer;
+
+ /* Attempt to create a thread from a timer. */
+ pointer = (CHAR *) 0x3000;
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt a thread reset from a timer. */
+ status = tx_thread_reset(&thread_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+CHAR *pointer;
+UINT status;
+UINT old_value;
+ULONG old_time_slice;
+
+
+ /* Call tx_thread_relinquish from ISR to make sure the error checking discards the call. */
+ tx_thread_relinquish();
+
+ /* Attempt to create a thread from a timer. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a thread from an ISR. */
+ status = tx_thread_delete(&thread_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to change preemption from an ISR. */
+ status = tx_thread_preemption_change(&thread_0, 1, &old_value);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to change priority from an ISR. */
+ status = tx_thread_priority_change(&thread_0, 1, &old_value);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt a thread reset from an ISR. */
+ status = tx_thread_reset(&thread_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt a thread terminate from an ISR. */
+ status = tx_thread_terminate(&thread_0);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt a thread time slice change from an ISR. */
+ status = tx_thread_time_slice_change(&thread_0, 1, &old_time_slice);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+
+ /* Test thread sleep call from ISR. */
+ status = tx_thread_sleep(11);
+
+ /* Check for status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+}
+
+#ifndef TX_INLINE_THREAD_RESUME_SUSPEND
+#ifndef TX_NOT_INTERRUPTABLE
+
+static void test_isr1(void)
+{
+
+UINT status;
+TX_THREAD *current_thread;
+
+
+ /* Suspend thread 4 while preempt disable is set. */
+
+ /* Increment the ISR counter. */
+ isr1_counter++;
+
+ /* Pickup the current thread. */
+ current_thread = tx_thread_identify();
+
+ /* Determine if the condition is present. */
+ if ((current_thread == &thread_4) && (_tx_thread_preempt_disable) && (thread_4.tx_thread_state == TX_READY))
+ {
+
+ /* Suspend the currently running thread 4 with the preemption-threshold flag set to ensure tx_thread_suspend from an ISR works
+ in this case. */
+ status = tx_thread_suspend(&thread_4);
+
+ /* Check for error. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Set error flag. */
+ error++;
+ }
+
+ /* Resume thread 4. */
+ tx_thread_resume(&thread_4);
+
+ /* Indicate the test case has been found. */
+ test_case_found = TX_TRUE;
+ }
+}
+
+#endif
+#endif
+
+
+#if 0
+static void test_thread_entry(ULONG thread_input)
+{
+ /* Do nothing here! */
+}
+#endif
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_basic_execution_application_define(void *first_unused_memory)
+#endif
+{
+
+INT status;
+CHAR *pointer;
+TX_THREAD fake_thread;
+
+
+ /* Setup a pointer. */
+ pointer = (CHAR *) first_unused_memory;
+
+ /* Adjust it forward just to make sure there is some space for the test below. */
+ pointer = pointer + 200;
+
+ /* 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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+#ifndef TX_INLINE_THREAD_RESUME_SUSPEND
+#ifndef TX_NOT_INTERRUPTABLE
+
+ status += tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+#endif
+#endif
+
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Basic Execution Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Now setup a fake thread to generate the other NULL pointer test in the cleanup routines. */
+ fake_thread.tx_thread_suspend_control_block = TX_NULL;
+ _tx_semaphore_cleanup(&fake_thread, 0);
+ _tx_queue_cleanup(&fake_thread, 0);
+ _tx_mutex_cleanup(&fake_thread, 0);
+ _tx_event_flags_cleanup(&fake_thread, 0);
+ _tx_byte_pool_cleanup(&fake_thread, 0);
+ _tx_block_pool_cleanup(&fake_thread, 0);
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+UINT status;
+CHAR *pointer;
+UINT old_value;
+ULONG old_time_slice;
+#endif
+
+VOID (*temp_mutex_release)(TX_THREAD *thread_ptr);
+
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Inform user of success getting to this test. */
+ printf("Running Thread Basic Execution Test................................. ");
+
+ /* Setup test thread to make sure _tx_thread_wait_abort can handle a NULL cleanup. */
+ test_thread.tx_thread_state = TX_IO_DRIVER;
+ test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ test_thread.tx_thread_suspending = TX_TRUE;
+ test_thread.tx_thread_delayed_suspend = TX_TRUE;
+ if(_tx_thread_wait_abort(&test_thread) != TX_WAIT_ABORT_ERROR)
+ {
+ printf("ERROR #XX\n");
+ test_control_return(1);
+ }
+
+ /* Setup test thread to make sure _tx_thread_timeout can handle a NULL cleanup. */
+ test_thread.tx_thread_state = TX_IO_DRIVER;
+ test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ test_thread.tx_thread_suspending = TX_TRUE;
+ test_thread.tx_thread_delayed_suspend = TX_TRUE;
+ _tx_thread_timeout((ULONG) &test_thread);
+
+ /* Setup test thread to make sure _tx_thread_terminate can handle a NULL mutex release function pointer. */
+ temp_mutex_release = _tx_thread_mutex_release;
+ _tx_thread_mutex_release = TX_NULL;
+ test_thread.tx_thread_state = TX_TERMINATED;
+ test_thread.tx_thread_suspend_cleanup = TX_NULL;
+ test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ test_thread.tx_thread_suspending = TX_TRUE;
+ test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
+ test_thread.tx_thread_delayed_suspend = TX_TRUE;
+ status = _tx_thread_terminate(&test_thread);
+ _tx_thread_mutex_release = temp_mutex_release; /* Recover Mutex release pointer. */
+
+ /* Perform thread memory test. */
+ thread_memory.first = 0x11223344;
+ thread_memory.second = 0x55667788;
+ thread_memory.first_middle = 0x21314151;
+ thread_memory.second_middle= 0x61718191;
+ thread_memory.next_to_last = 0x99aabbcc;
+ thread_memory.last = 0xddeeff00;
+
+ /* Create the thread. */
+ status += tx_thread_create(&thread_memory.thread_block, "thread memory", thread_0_entry, 1,
+ &thread_memory.stack[0], (2048*sizeof(ULONG))/sizeof(ULONG),
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ tx_thread_delete(&thread_memory.thread_block);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (thread_memory.first != 0x11223344) ||
+ (thread_memory.second != 0x55667788) ||
+ (thread_memory.first_middle != 0x21314151) ||
+ (thread_memory.second_middle != 0x61718191) ||
+ (thread_memory.next_to_last != 0x99aabbcc) ||
+ (thread_memory.last != 0xddeeff00))
+ {
+
+ /* Memory overwrite error. */
+ printf("ERROR #2\n");
+ test_control_return(1);
+ }
+
+
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to create a thread with a null pointer. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(TX_NULL, "thread 0", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with a bad control block size. */
+ pointer = (CHAR *) not_used_stack;
+ status = _txe_thread_create(&thread_3, "thread 3", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START, (sizeof(TX_THREAD)+1));
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with a NULL entry function. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_3, "thread 3", TX_NULL, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread that has already been created. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with an overlapping stack. */
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ thread_0.tx_thread_stack_ptr, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with another variation of an overlapping stack. */
+ pointer = thread_0.tx_thread_stack_start;
+ pointer = pointer - 20;
+ status = tx_thread_create(&thread_1, "thread 1", TX_NULL, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread an extra small stack. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ pointer, 1,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with an invalid thread priority. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5000, 5000, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_PRIORITY_ERROR)
+ {
+
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with an invalid preemption-threshold. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 17, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_THRESH_ERROR)
+ {
+
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a thread with an invalid auto start. */
+ pointer = (CHAR *) not_used_stack;
+ status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, 3456);
+
+ /* Check for status. */
+ if (status != TX_START_ERROR)
+ {
+
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-thread. */
+ status = tx_thread_delete(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_delete(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to register a entry/exit callback on a non-thread. */
+ status = tx_thread_entry_exit_notify(TX_NULL, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to register a entry/exit callback on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_entry_exit_notify(&thread_2, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get info on a non-thread. */
+ status = tx_thread_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get info on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_info_get(&thread_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change preemption of a non-thread. */
+ status = tx_thread_preemption_change(TX_NULL, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change preemption of a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_preemption_change(&thread_2, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change preemption with a NULL return value. */
+ status = tx_thread_preemption_change(&thread_0, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change preemption with a bad threshold value. */
+ status = tx_thread_preemption_change(&thread_0, 17, &old_value);
+
+ /* Check for status. */
+ if (status != TX_THRESH_ERROR)
+ {
+
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+
+ /* Attempt to change priority of a non-thread. */
+ status = tx_thread_priority_change(TX_NULL, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change priority of a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_priority_change(&thread_2, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change priority with a NULL return value. */
+ status = tx_thread_priority_change(&thread_0, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change priority with a bad priority value. */
+ status = tx_thread_priority_change(&thread_0, 2046, &old_value);
+
+ /* Check for status. */
+ if (status != TX_PRIORITY_ERROR)
+ {
+
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread reset for a non-thread. */
+ status = tx_thread_reset(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread reset from same thread. */
+ status = tx_thread_reset(&thread_0);
+
+ /* Check for status. */
+ if (status != TX_NOT_DONE)
+ {
+
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread reset for a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_reset(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread resume with a NULL pointer. */
+ status = tx_thread_resume(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread resume on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_resume(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread suspend with a NULL pointer. */
+ status = tx_thread_suspend(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread suspend on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_suspend(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread termiante with a NULL pointer. */
+ status = tx_thread_terminate(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread terminate on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_terminate(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread time-slice chagne with a NULL pointer. */
+ status = tx_thread_time_slice_change(TX_NULL, 1, &old_time_slice);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #36\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread time-slice change on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_time_slice_change(&thread_2, 1, &old_time_slice);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #37\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread time-slice change with a null return pointer. */
+ status = tx_thread_time_slice_change(&thread_0, 1, TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ printf("ERROR #38\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread wait abort with a NULL pointer. */
+ status = tx_thread_wait_abort(TX_NULL);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #39\n");
+ test_control_return(1);
+ }
+
+ /* Attempt a thread wait abort on a non-created thread. */
+ thread_2.tx_thread_id = 0;
+ status = tx_thread_wait_abort(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_THREAD_ERROR)
+ {
+
+ printf("ERROR #40\n");
+ test_control_return(1);
+ }
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #41\n");
+ test_control_return(1);
+ }
+
+#endif
+
+#ifndef TX_INLINE_THREAD_RESUME_SUSPEND
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* At this point setup the ISR. */
+ test_isr_dispatch = test_isr1;
+
+ /* Resume thread 4. */
+ tx_thread_resume(&thread_4);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Now check for an error. */
+ if ((error) || (test_case_found == TX_FALSE))
+ {
+
+ /* Basic execution error. */
+ printf("ERROR #42\n");
+ test_control_return(1);
+ }
+
+#endif
+#endif
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+#ifndef TX_INLINE_THREAD_RESUME_SUSPEND
+#ifndef TX_NOT_INTERRUPTABLE
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+
+ /* Loop until we achieve as suspend request while inside of the tx_thread_resume API. */
+ while (test_case_found == TX_FALSE)
+ {
+
+ /* Temporarily disable preemption for the test. */
+ TX_DISABLE
+ _tx_thread_preempt_disable++;
+ TX_RESTORE
+
+ /* Increment the run counter for this test. */
+ thread_4_counter++;
+
+ TX_DISABLE
+ _tx_thread_preempt_disable--;
+ TX_RESTORE
+ }
+}
+
+#endif
+#endif
+
+
diff --git a/test/tx/regression/threadx_thread_basic_time_slice_test.c b/test/tx/regression/threadx_thread_basic_time_slice_test.c
new file mode 100644
index 00000000..9da8350c
--- /dev/null
+++ b/test/tx/regression/threadx_thread_basic_time_slice_test.c
@@ -0,0 +1,73 @@
+/* This test is designed to see if a thread can be created with a time-slice.
+ No time-slice occurs, only the processing to check for time-slicing. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+/* 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_thread_basic_time_slice_application_define(void *first_unused_memory)
+#endif
+{
+
+UINT status;
+
+ /* 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,
+ first_unused_memory, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 1, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Basic Time-Slice Test................................ ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+
+ /* Inform user. */
+ printf("Running Thread Basic Time-Slice Test................................ ");
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Determine if we are done. */
+ if (tx_time_get() > 18)
+ {
+
+ /* Successful Time-slice test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ }
+}
diff --git a/test/tx/regression/threadx_thread_completed_test.c b/test/tx/regression/threadx_thread_completed_test.c
new file mode 100644
index 00000000..068058d0
--- /dev/null
+++ b/test/tx/regression/threadx_thread_completed_test.c
@@ -0,0 +1,258 @@
+/* This test is designed to see if one thread can be created, executed, and
+ return to the thread shell function. The thread shell function places
+ the thread in a finished state. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+
+static unsigned long thread_0_counter = 0;
+static unsigned long thread_0_enter = 0;
+static unsigned long thread_0_exit = 0;
+static unsigned long thread_1_counter = 0;
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static TX_THREAD *saved_ptr;
+static ULONG saved_count;
+
+/* Define task prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void entry_exit_notify(TX_THREAD *thread_ptr, UINT type)
+{
+
+ /* Check for the appropriate thread. */
+ if (thread_ptr != &thread_0)
+ return;
+
+ /* Check for type. */
+ if (type == TX_THREAD_ENTRY)
+ thread_0_enter++;
+ else if (type == TX_THREAD_EXIT)
+ thread_0_exit++;
+}
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_completed_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Setup the notify call to test that logic. */
+ status += tx_thread_entry_exit_notify(&thread_0, entry_exit_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Completed Test....................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Thread Completed Test....................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Completed Test....................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Completed Test....................................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Move the created pointer to thread 1 to test the delete path fully. */
+ saved_ptr = _tx_thread_created_ptr;
+ _tx_thread_created_ptr = &thread_0;
+}
+
+
+
+/* Define the test thread. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Fall through to the return in order to place the thread in a finished
+ state. */
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Thread Completed Test....................................... ");
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Attempt to delete thread 2, which is in the wrong stat for deleting. */
+ status = tx_thread_delete(&thread_2);
+
+ /* Check for the proper status. */
+ if (status != TX_DELETE_ERROR)
+ {
+
+ /* Thread delete error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to suspend thread 0, which is in a completed state. */
+ status = tx_thread_suspend(&thread_0);
+
+ /* Check for the correct status. */
+ if (status != TX_SUSPEND_ERROR)
+ {
+
+ /* Thread suspend error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete thread 0. */
+ status = tx_thread_delete(&thread_0);
+
+ /* Check for the proper status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread delete error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Sleep to let thread 2 run. */
+ tx_thread_sleep(2);
+
+ /* Save the created count. */
+ saved_count = _tx_thread_created_count;
+
+ /* Now setup things so we can fake a delete of one thread. */
+ _tx_thread_created_ptr = &thread_2;
+ thread_2.tx_thread_created_next = &thread_2;
+ thread_2.tx_thread_created_previous = &thread_2;
+ _tx_thread_created_count = 1;
+
+ /* Attempt to delete thread 2. */
+ status = tx_thread_delete(&thread_2);
+
+ /* Check for the proper status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread delete error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* if still okay, restore the saved thread pointer. */
+ if (saved_ptr -> tx_thread_id == TX_THREAD_ID)
+ {
+ /* Restore. */
+ _tx_thread_created_ptr = saved_ptr;
+
+ /* Setup the link pointers again. */
+ saved_ptr -> tx_thread_created_previous = &thread_1;
+ thread_1.tx_thread_created_next = saved_ptr;
+
+ /* Setup the created count. */
+ _tx_thread_created_count = saved_count - 1;
+ }
+
+ /* Determine if the first Thread has run and if it's current state is
+ finished. */
+ if ((thread_0.tx_thread_state == TX_COMPLETED) && (thread_0_counter == 1) &&
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+ (thread_0_enter == 1) && (thread_0_exit == 1))
+#else
+ (thread_0_enter == 0) && (thread_0_exit == 0))
+#endif
+ {
+
+ /* Successful thread finish test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ else
+ {
+
+ /* Thread Finish error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Fall through to the return in order to place the thread in a finished
+ state. */
+}
diff --git a/test/tx/regression/threadx_thread_create_preemption_threshold_test.c b/test/tx/regression/threadx_thread_create_preemption_threshold_test.c
new file mode 100644
index 00000000..ad0d1d4e
--- /dev/null
+++ b/test/tx/regression/threadx_thread_create_preemption_threshold_test.c
@@ -0,0 +1,140 @@
+/* This test is designed to test for preemption-threshold use during thread creation during initialization. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_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_thread_create_preemption_threshold_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_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 0, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Create Preemption-Threshold from Init Test........... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 0, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Create Preemption-Threshold from Init Test........... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 0, 100, TX_DONT_START);
+ status += tx_thread_resume(&thread_0);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Create Preemption-Threshold from Init Test........... ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ /* Inform user. */
+ printf("Running Thread Create Preemption-Threshold from Init Test........... ");
+
+ /* If either of the other threads have run, an error is present. */
+ if ((thread_1_counter) || (thread_2_counter))
+ {
+
+ /* Test error! */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for two ticks (one is insufficient to guarantee the other
+ tasks will run, if this executes too close to the tick interrupt. */
+ tx_thread_sleep(2);
+
+
+ /* Now, both threads should have run. */
+ if ((thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Test error! */
+ printf("ERROR #5\n");
+ test_control_return(2);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Increment this thread's counter. */
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+}
+
diff --git a/test/tx/regression/threadx_thread_delayed_suspension_test.c b/test/tx/regression/threadx_thread_delayed_suspension_test.c
new file mode 100644
index 00000000..6d6d27d0
--- /dev/null
+++ b/test/tx/regression/threadx_thread_delayed_suspension_test.c
@@ -0,0 +1,390 @@
+/* This test checks out the delayed suspension clear from tx_thread_resume. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_timer.h"
+
+
+#define DEMO_STACK_SIZE TEST_STACK_SIZE_PRINTF
+
+
+/* Define the ThreadX object control blocks... */
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+#if defined(TX_WIN32_MEMORY_SIZE) || defined(TX_LINUX_MEMORY_SIZE)
+/* Use larger array size when running on Win32 test platform because of greater speed. */
+#define ARRAY_SIZE 100
+#else
+#define ARRAY_SIZE 10
+#endif
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+static void thread_2_entry(ULONG thread_input);
+
+static UINT delayed_suspend_set;
+
+static ULONG thread_2_counter;
+static ULONG thread_2_counter_capture;
+
+static ULONG min_loop_count;
+static ULONG max_loop_count;
+static ULONG loop_count;
+static volatile ULONG count;
+static volatile ULONG destination = 0;
+static ULONG start_time;
+static ULONG lower_bound;
+static ULONG upper_bound;
+static ULONG current_itterations;
+#ifdef DEBUG_1
+static ULONG last_loop_count;
+#endif
+static TX_THREAD thread_2;
+static TX_SEMAPHORE semaphore_1;
+
+static ULONG array_delay[ARRAY_SIZE];
+
+static ULONG delay_function(void)
+{
+
+ULONG accumulator;
+ULONG i;
+
+ for (i = 0; i < ARRAY_SIZE; i++)
+ array_delay[i] = i;
+
+ for (i = 0; i < ARRAY_SIZE-4; i++)
+ {
+ array_delay[i] = (array_delay[i+1] * array_delay[i+2]) * (array_delay[i+3] * array_delay[i+4]);
+ }
+
+ accumulator = 0;
+ for (i = 0; i < ARRAY_SIZE; i++)
+ accumulator = accumulator + array_delay[i];
+
+ return(accumulator);
+}
+
+
+static void test_isr(void)
+{
+ULONG i;
+
+ /* Determine if we are in calibration mode. */
+ if (loop_count != 0xFFFFFFFF)
+ {
+ if (loop_count < min_loop_count)
+ min_loop_count = loop_count;
+ if (loop_count > max_loop_count)
+ max_loop_count = loop_count;
+
+ lower_bound = loop_count - 1;
+ upper_bound = loop_count + 1;
+ if (lower_bound < min_loop_count)
+ lower_bound = min_loop_count;
+ if (upper_bound > max_loop_count)
+ lower_bound = max_loop_count;
+
+ if ((current_itterations < lower_bound) || (current_itterations > upper_bound))
+ current_itterations = lower_bound;
+
+#ifdef DEBUG_1
+ /* Last loop count. */
+ last_loop_count = loop_count;
+#endif
+
+ /* Reset the loop count to all ones! */
+ loop_count = 0xFFFFFFFF;
+ }
+ count++;
+ for (i = 0; i < (count%32); i++)
+ destination++;
+
+ /* Check to see if the interrupt occurred in the middle of the suspension. */
+ if ((thread_2.tx_thread_suspending) && (delayed_suspend_set == 0))
+ {
+
+ /* Yes, we have taken the interrupt in the middle of a thread suspension. */
+
+ /* Indicate we have got the condition. */
+ delayed_suspend_set = 1;
+
+ /* Capture the current thread 2 counter. */
+ thread_2_counter_capture = thread_2_counter;
+
+ /* Now attempt to set the delayed suspension. */
+ tx_thread_suspend(&thread_2);
+
+ /* Check for the delayed suspension flag being set. */
+ if (thread_2.tx_thread_delayed_suspend != 1)
+ {
+
+ /* Error! Setup the counters to indicate an error. */
+ thread_2_counter = 0xEEEEEEEE;
+ thread_2_counter_capture = 0xFFFFFFFF;
+ }
+
+ /* Now, abort the suspension for thread 2... the thread should switch to a pure suspended state. */
+ tx_thread_wait_abort(&thread_2);
+
+ /* Check for the proper state. */
+ if (thread_2.tx_thread_state != TX_SUSPENDED)
+ {
+
+ /* Error! Setup the counters to indicate an error. */
+ thread_2_counter = 0xEEEEEEEE;
+ thread_2_counter_capture = 0xFFFFFFFF;
+ }
+ }
+
+}
+#endif
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_delayed_suspension_application_define(void *first_unused_memory)
+#endif
+{
+
+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. */
+
+ /* Create the main thread. */
+ tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
+ pointer, DEMO_STACK_SIZE,
+ 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Create threads 1 and 2. */
+ tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, DEMO_STACK_SIZE,
+ 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ /* Create the semaphore. */
+ tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, DEMO_STACK_SIZE,
+ 1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + DEMO_STACK_SIZE;
+
+ tx_semaphore_create(&semaphore_1, "semaphore 1", 0);
+
+ thread_2_counter = 0;
+ thread_2_counter_capture = 0;
+ min_loop_count = 0xFFFFFFFF;
+ max_loop_count = 0;
+ loop_count = 0xFFFFFFFF;
+#ifdef DEBUG_1
+ last_loop_count = 0;
+#endif
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Thread Delayed Suspension Clearing Test..................... ");
+
+ /* Relinquish to the other thread. */
+ tx_thread_relinquish();
+
+ /* At this point thread 1 has suspended on the semaphore. */
+
+ /* Suspend the already suspended thread. */
+ tx_thread_suspend(&thread_1);
+
+ /* Set the semaphore, which should make it go into a suspend state. */
+ tx_semaphore_put(&semaphore_0);
+
+ /* Resume the other thread so it runs again. */
+ tx_thread_resume(&thread_1);
+
+ /* Relinquish so it can run again. */
+ tx_thread_relinquish();
+
+ /* Suspend the already suspended thread. */
+ tx_thread_suspend(&thread_1);
+
+ /* Now, clear the delayed suspension. */
+ status = tx_thread_resume(&thread_1);
+
+ if (status != TX_SUSPEND_LIFTED)
+ {
+
+ /* Delayed suspension error. */
+ printf("ERROR #1\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Setup the test ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Resume the test thread. */
+ tx_thread_resume(&thread_2);
+
+ /* Wait until we see the delayed suspension set flag. */
+ while(delayed_suspend_set == 0)
+ {
+
+ /* Abort the suspension for thread 2. */
+ tx_thread_wait_abort(&thread_2);
+
+ /* Just relinquish. */
+ tx_thread_relinquish();
+ }
+
+ /* Relinquish one more time to make sure thread 2 could run if it is ready. */
+ tx_thread_relinquish();
+
+ /* At this point, check for an error. */
+ if (thread_2_counter != thread_2_counter_capture)
+ {
+
+ /* Delayed suspension error... thread kept running! */
+ printf("ERROR #2\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* This thread simply gets the semaphore... */
+ while(1)
+ {
+
+ /* Get semaphore. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Check completion status. */
+ if (status != TX_SUCCESS)
+ break;
+ }
+}
+
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ULONG i;
+
+ /* Callibrate the loop count from thread sleep. */
+ for (i = 0; i < 10; i++)
+ {
+
+ /* Sleep to get a fresh time. */
+ tx_thread_sleep(1);
+
+ start_time = _tx_timer_system_clock;
+ do
+ {
+
+ /* Call delay function. */
+ delay_function();
+ loop_count++;
+ } while (start_time == _tx_timer_system_clock);
+
+ /* Wait to reset the loop count. */
+ tx_thread_sleep(1);
+ }
+
+ /* Setup the lower and upper bounds. */
+ lower_bound = min_loop_count;
+ if (lower_bound > 5)
+ lower_bound = lower_bound - 5;
+ upper_bound = max_loop_count + 5;
+
+ current_itterations = lower_bound;
+
+ /* This thread simply suspends over and over... */
+ while(1)
+ {
+
+ /* Sleep to get a fresh starting time. */
+ tx_thread_sleep(1);
+
+ loop_count = 0;
+ start_time = _tx_timer_system_clock;
+ do
+ {
+ /* Call delay function. */
+ delay_function();
+ loop_count++;
+ } while (loop_count < current_itterations);
+
+ /* Suspend this thread. */
+ tx_semaphore_get(&semaphore_1, TX_WAIT_FOREVER);
+
+ /* Adjust the current itterations. */
+ current_itterations++;
+ if (current_itterations > upper_bound)
+ {
+ if (lower_bound > min_loop_count)
+ lower_bound--;
+ if (upper_bound < max_loop_count)
+ upper_bound++;
+ current_itterations = lower_bound;
+ }
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+ }
+}
+
+#endif
diff --git a/test/tx/regression/threadx_thread_information_test.c b/test/tx/regression/threadx_thread_information_test.c
new file mode 100644
index 00000000..b72a2363
--- /dev/null
+++ b/test/tx/regression/threadx_thread_information_test.c
@@ -0,0 +1,474 @@
+/* This test is for the thread information services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+/* Define task prototypes. */
+
+static void thread_0_entry(ULONG task_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_thread_information_application_define(void *first_unused_memory)
+#endif
+{
+
+INT status;
+
+ /* 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,
+ first_unused_memory, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Information Test..................................... ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+CHAR *name;
+UINT state;
+ULONG run_count;
+UINT priority;
+UINT preemption_threshold;
+ULONG time_slice;
+TX_THREAD *next_thread;
+TX_THREAD *suspended_thread;
+ULONG resumptions;
+ULONG suspensions;
+ULONG solicited_preemptions;
+ULONG interrupt_preemptions;
+ULONG priority_inversions;
+ULONG time_slices;
+ULONG relinquishes;
+ULONG timeouts;
+ULONG wait_aborts;
+TX_THREAD *last_preempted_by;
+ULONG non_idle_returns;
+ULONG idle_returns;
+
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Inform user of success getting to this test. */
+ printf("Running Thread Information Test..................................... ");
+
+ /* Get information about this thread. */
+ status = tx_thread_info_get(&thread_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_thread_info_get(&thread_0, &name, &state, &run_count, &priority, &preemption_threshold, &time_slice, &next_thread, &suspended_thread);
+
+ /* Check for error status. */
+ if ((status != TX_SUCCESS) || (state != TX_READY) || (run_count != thread_0.tx_thread_run_count) || (priority != 16) || (preemption_threshold != 16) ||
+ (time_slice != 0) || (next_thread != thread_0.tx_thread_created_next) || (suspended_thread != thread_0.tx_thread_suspended_next))
+ {
+
+ /* Thread error. */
+ printf("ERROR #2\n");
+ test_control_return(1);
+ }
+
+
+#ifdef TX_THREAD_ENABLE_PERFORMANCE_INFO
+
+ /* Get the performance information about a NULL thread pointer. */
+ status = _tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Thread error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(&thread_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_thread_performance_info_get(&thread_0, &resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check for error. */
+ if ((status != TX_SUCCESS) || (resumptions != thread_0.tx_thread_performance_resume_count) || (suspensions != thread_0.tx_thread_performance_suspend_count) ||
+ (solicited_preemptions != thread_0.tx_thread_performance_solicited_preemption_count) || (interrupt_preemptions != thread_0.tx_thread_performance_interrupt_preemption_count) ||
+ (priority_inversions != thread_0.tx_thread_performance_priority_inversion_count) || (time_slices != thread_0.tx_thread_performance_time_slice_count) ||
+ (relinquishes != thread_0.tx_thread_performance_relinquish_count) || (timeouts != thread_0.tx_thread_performance_timeout_count) || (wait_aborts != thread_0.tx_thread_performance_wait_abort_count) ||
+ (last_preempted_by != thread_0.tx_thread_performance_last_preempting_thread))
+ {
+
+ /* Thread error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_thread_performance_system_info_get(&resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check for error. */
+ if ((status != TX_SUCCESS) || (resumptions != _tx_thread_performance_resume_count) || (suspensions != _tx_thread_performance_suspend_count) ||
+ (solicited_preemptions != _tx_thread_performance_solicited_preemption_count) || (interrupt_preemptions != _tx_thread_performance_interrupt_preemption_count) ||
+ (priority_inversions != _tx_thread_performance_priority_inversion_count) || (time_slices != _tx_thread_performance_time_slice_count) ||
+ (relinquishes != _tx_thread_performance_relinquish_count) || (timeouts != _tx_thread_performance_timeout_count) || (wait_aborts != _tx_thread_performance_wait_abort_count) ||
+ (non_idle_returns != _tx_thread_performance_non_idle_return_count) || (idle_returns != _tx_thread_performance_idle_return_count))
+ {
+
+ /* Thread error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Success! */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+#else
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(&thread_0, &resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, &resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ &relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, &timeouts, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, &wait_aborts, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, TX_NULL, &last_preempted_by);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Get the performance information about this thread. */
+ status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(&resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &interrupt_preemptions, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &priority_inversions, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &time_slices,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, &wait_aborts, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, TX_NULL, &non_idle_returns, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, TX_NULL, TX_NULL, &idle_returns);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Get the system performance information. */
+ status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
+ TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+ /* Success! */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+
+#endif
+
+}
diff --git a/test/tx/regression/threadx_thread_multi_level_preemption_threshold_test.c b/test/tx/regression/threadx_thread_multi_level_preemption_threshold_test.c
new file mode 100644
index 00000000..a65410fa
--- /dev/null
+++ b/test/tx/regression/threadx_thread_multi_level_preemption_threshold_test.c
@@ -0,0 +1,982 @@
+/* This test is designed to test multi-level preemption threshold. The protection placed
+ by a thread must be preserved after higher-priority thread preemption that is above the threshold. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_2a_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static unsigned long thread_1_counter = 0;
+
+static unsigned long thread_2_counter = 0;
+
+static unsigned long thread_2a_counter = 0;
+static TX_THREAD thread_2a;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+#endif
+
+static TX_THREAD thread_0;
+
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+/* Define new preemption-threshold threads for complete bit map checking. */
+
+static TX_THREAD thread_1_0;
+static TX_THREAD thread_2_1;
+static TX_THREAD thread_3_2;
+static TX_THREAD thread_4_3;
+static TX_THREAD thread_6_5;
+static TX_THREAD thread_8_7;
+static TX_THREAD thread_10_9;
+static TX_THREAD thread_12_11;
+static TX_THREAD thread_14_13;
+static TX_THREAD thread_16_15;
+static TX_THREAD thread_18_17;
+static TX_THREAD thread_20_19;
+static TX_THREAD thread_22_21;
+static TX_THREAD thread_24_23;
+static TX_THREAD thread_26_25;
+static TX_THREAD thread_28_27;
+static TX_THREAD thread_30_29;
+
+
+/* Define timer for preemption of priority 1 test. */
+
+static TX_TIMER timer_0;
+
+
+/* Define counters. */
+
+static unsigned long timer_0_counter = 0;
+static unsigned long thread_1_0_counter = 0;
+static unsigned long thread_2_1_counter = 0;
+static unsigned long thread_3_2_counter = 0;
+static unsigned long thread_4_3_counter = 0;
+static unsigned long thread_6_5_counter = 0;
+static unsigned long thread_8_7_counter = 0;
+static unsigned long thread_10_9_counter = 0;
+static unsigned long thread_12_11_counter = 0;
+static unsigned long thread_14_13_counter = 0;
+static unsigned long thread_16_15_counter = 0;
+static unsigned long thread_18_17_counter = 0;
+static unsigned long thread_20_19_counter = 0;
+static unsigned long thread_22_21_counter = 0;
+static unsigned long thread_24_23_counter = 0;
+static unsigned long thread_26_25_counter = 0;
+static unsigned long thread_28_27_counter = 0;
+static unsigned long thread_30_29_counter = 0;
+
+
+/* Define new preemption-threshold test thread entry points. */
+
+static void thread_1_0_entry(ULONG thread_input);
+static void thread_2_1_entry(ULONG thread_input);
+static void thread_3_2_entry(ULONG thread_input);
+static void thread_4_3_entry(ULONG thread_input);
+static void thread_6_5_entry(ULONG thread_input);
+static void thread_8_7_entry(ULONG thread_input);
+static void thread_10_9_entry(ULONG thread_input);
+static void thread_12_11_entry(ULONG thread_input);
+static void thread_14_13_entry(ULONG thread_input);
+static void thread_16_15_entry(ULONG thread_input);
+static void thread_18_17_entry(ULONG thread_input);
+static void thread_20_19_entry(ULONG thread_input);
+static void thread_22_21_entry(ULONG thread_input);
+static void thread_24_23_entry(ULONG thread_input);
+static void thread_26_25_entry(ULONG thread_input);
+static void thread_28_27_entry(ULONG thread_input);
+static void thread_30_29_entry(ULONG thread_input);
+
+/* Define timer 1 entry. */
+
+static void timer_0_entry(ULONG id);
+
+
+#endif
+
+
+/* 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_thread_multi_level_preemption_threshold_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,
+ (TX_MAX_PRIORITIES-1), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ (TX_MAX_PRIORITIES/2), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 10, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2a, "thread 2a", thread_2a_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 11, 11, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 9, 9, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Create new cascading preemption-threshold test threads. */
+
+ status = tx_thread_create(&thread_30_29, "thread 30-29", thread_30_29_entry, 30,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 30, 29, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #7\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_28_27, "thread 28-27", thread_28_27_entry, 28,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 28, 27, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #8\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_26_25, "thread 26-25", thread_26_25_entry, 26,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 26, 25, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #9\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_24_23, "thread 24-23", thread_24_23_entry, 24,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 24, 23, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_22_21, "thread 22-21", thread_22_21_entry, 22,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 22, 21, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #11\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_20_19, "thread 20-19", thread_20_19_entry, 20,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 20,19, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_18_17, "thread 18-17", thread_18_17_entry, 18,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 17, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #13\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_16_15, "thread 16-15", thread_16_15_entry, 16,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_14_13, "thread 14-13", thread_14_13_entry, 14,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 14, 13, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #15\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_12_11, "thread 12-11", thread_12_11_entry, 12,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 12, 11, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #16\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_10_9, "thread 10-9", thread_10_9_entry, 10,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 10, 9, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #17\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_8_7, "thread 8-7", thread_8_7_entry, 8,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 8, 7, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #18\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_6_5, "thread 6-5", thread_6_5_entry, 6,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 5, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #19\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4_3, "thread 4-3", thread_4_3_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 4, 3, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #20\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3_2, "thread 3-2", thread_3_2_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 3, 2, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #21\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2_1, "thread 2-1", thread_2_1_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 2, 1, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #22\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1_0, "thread 1-0", thread_1_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #23\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 0, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #24\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+UINT status;
+UINT old_preempt;
+#endif
+
+
+ /* Inform user. */
+ printf("Running Thread Multi-Level Preemption Threshold Test................ ");
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */
+
+ /* Wakeup Thread 1. It has a higher-priority but should be blocked by
+ preemption threshold. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Check status and make sure the other run counters are proper. */
+ if ((status != TX_SUCCESS) || (thread_1_counter) || (thread_2_counter) ||
+ (thread_3_counter) || (thread_4_counter))
+ {
+
+ /* Thread Preempt Threshold error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 2 which will preempt this thread. */
+ status = tx_thread_resume(&thread_2);
+
+ /* Check for good status and proper run counters. All other threads except for
+ thread 1 should have executed. */
+ if ((status != TX_SUCCESS) || (thread_1_counter) || (thread_2_counter != 1) ||
+ (thread_3_counter != 1) || (thread_4_counter != 1))
+ {
+
+ /* Thread Preempt Threshold error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Set preemption threshold low enough to allow thread 1 to execute. */
+ status = tx_thread_preemption_change(&thread_0, ((TX_MAX_PRIORITIES/2)+1), &old_preempt);
+
+ /* Check for good status and proper run counters. All other threads except for
+ thread 1 should have executed. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1) ||
+ (thread_3_counter != 1) || (thread_4_counter != 1) ||
+ (_tx_thread_preempted_maps[0]) || (_tx_thread_preempt_disable))
+ {
+
+ /* Thread Preempt Threshold error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Set preemption threshold to keep new test threads from running. */
+ status = tx_thread_preemption_change(&thread_0, 17, &old_preempt);
+
+ /* Now wakup the lowest priority preemption-threshold thread. */
+ status += tx_thread_resume(&thread_30_29);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread Preempt Threshold error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Now, self suspend. */
+ status = tx_thread_suspend(&thread_0);
+
+ /* Check to make sure all the preemption-threshold threads ran. */
+ if ((thread_1_0_counter != 1) ||
+ (thread_2_1_counter != 1) ||
+ (thread_3_2_counter != 1) ||
+ (thread_4_3_counter != 1) ||
+ (thread_6_5_counter != 1) ||
+ (thread_8_7_counter != 1) ||
+ (thread_10_9_counter != 1) ||
+ (thread_12_11_counter != 1) ||
+ (thread_14_13_counter != 1) ||
+ (thread_16_15_counter != 1) ||
+ (thread_18_17_counter != 1) ||
+ (thread_20_19_counter != 1) ||
+ (thread_22_21_counter != 1) ||
+ (thread_24_23_counter != 1) ||
+ (thread_26_25_counter != 1) ||
+ (thread_28_27_counter != 1) ||
+ (thread_30_29_counter != 1))
+ {
+
+ /* Thread Preempt Threshold error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Successful Thread Suspend non-current thread test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ thread_1_counter++;
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Resume thread 3 which will not preempt because of thread 2's preemption
+ threshold. */
+ status = tx_thread_resume(&thread_3);
+
+ /* Resume thread 2a which will not preempt this thread because it is at
+ the same priority. */
+ status += tx_thread_resume(&thread_2a);
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_3_counter) ||
+ (thread_4_counter))
+ return;
+
+ /* Resume thread 4 which will preempt. We should get back here before thread
+ three runs because of preemption threshold. */
+ status = tx_thread_resume(&thread_4);
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_3_counter) ||
+ (thread_4_counter != 1))
+ return;
+
+ /* Relinquish to the other thread at this priority level. This should
+ clear the preemption threshold condition and allow thread 3 to run. */
+ tx_thread_relinquish();
+
+ /* Check status and run counters. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_2a_counter != 1) ||
+ (thread_3_counter != 1) || (thread_4_counter != 1))
+ return;
+
+ /* If all is okay, increment thread 2's counter. */
+ thread_2_counter++;
+}
+
+
+static void thread_2a_entry(ULONG thread_input)
+{
+
+ if (thread_3_counter == 1)
+ thread_2a_counter++;
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+ thread_3_counter++;
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+ thread_4_counter++;
+}
+
+
+
+static void timer_0_entry(ULONG id)
+{
+
+ /* Pretend like a preemption occurred on a thread priority of 1 with preemption-threshold set to 0. */
+ _tx_thread_preempted_maps[0] = _tx_thread_preempted_maps[0] | 2;
+
+ /* Set the thread's preemption threshold as well. */
+ thread_1_0.tx_thread_preempt_threshold = 0;
+
+ /* Increment timer 0 counter. */
+ timer_0_counter++;
+}
+
+
+static void thread_1_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Activate the timer to force a priority 0 thread to interrupt. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Loop to wait until timer 0 runs. */
+ while (timer_0_counter == 0)
+ {
+ }
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_1_0_counter++;
+ }
+}
+
+
+static void thread_2_1_entry(ULONG thread_input)
+{
+
+ /* Increment this thread's counter. */
+ thread_2_1_counter++;
+}
+
+
+static void thread_3_2_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_1_0);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_3_2_counter++;
+ }
+}
+
+
+static void thread_4_3_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_2_1);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_4_3_counter++;
+ }
+}
+
+
+static void thread_6_5_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_4_3);
+
+ /* In this particular case, we have two different preemptions to make
+ sure we exercise all the code. */
+
+ /* Now resume next highest priority thread. */
+ status = tx_thread_resume(&thread_3_2);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_6_5_counter++;
+ }
+}
+
+
+static void thread_8_7_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_6_5);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_8_7_counter++;
+ }
+}
+
+
+static void thread_10_9_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_8_7);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_10_9_counter++;
+ }
+}
+
+static void thread_12_11_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_10_9);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_12_11_counter++;
+ }
+}
+
+
+static void thread_14_13_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_12_11);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_14_13_counter++;
+ }
+}
+
+
+static void thread_16_15_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_14_13);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_16_15_counter++;
+ }
+}
+
+
+static void thread_18_17_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_16_15);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_18_17_counter++;
+ }
+}
+
+
+static void thread_20_19_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_18_17);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_20_19_counter++;
+ }
+}
+
+
+static void thread_22_21_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_20_19);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_22_21_counter++;
+ }
+}
+
+
+static void thread_24_23_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_22_21);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_24_23_counter++;
+ }
+}
+
+static void thread_26_25_entry(ULONG thread_input)\
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_24_23);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_26_25_counter++;
+ }
+}
+
+static void thread_28_27_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_26_25);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_28_27_counter++;
+ }
+}
+
+static void thread_30_29_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Resume next highest priority thread. */
+ status = tx_thread_resume(&thread_28_27);
+
+ /* Check for good status. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment this thread's counter. */
+ thread_30_29_counter++;
+ }
+
+ /* Resume thread_0. */
+ tx_thread_resume(&thread_0);
+}
+
+
+#endif
diff --git a/test/tx/regression/threadx_thread_multiple_non_current_test.c b/test/tx/regression/threadx_thread_multiple_non_current_test.c
new file mode 100644
index 00000000..51212b3b
--- /dev/null
+++ b/test/tx/regression/threadx_thread_multiple_non_current_test.c
@@ -0,0 +1,222 @@
+/* This test is designed to see if multiple non-current threads can be suspended.
+ The order the suspension and resumption occurs makes sure everything is working
+ right. Thread execution should remain predictable even after suspension and
+ resumption of threads within a priority group. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_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_thread_multiple_non_current_suspension_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Non-Current Suspend Test............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Non-Current Suspend Test............................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Non-Current Suspend Test............................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Non-Current Suspend Test............................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Non-Current Suspend Test............................. ERROR #5\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Thread Non-Current Suspend Test............................. ");
+
+ /* Wakeup all other threads at same priority. */
+ status = tx_thread_resume(&thread_1);
+ status += tx_thread_resume(&thread_2);
+
+ /* Check for good status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Wakeup thread with preempt. */
+ status = tx_thread_resume(&thread_3);
+
+ /* Check for good status and proper counters. */
+ if ((status != TX_SUCCESS) || (thread_3_counter != 1) || (thread_1_counter) ||
+ (thread_2_counter) || (thread_4_counter))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Suspend thread 1. */
+ status = tx_thread_suspend(&thread_1);
+
+ /* Resume thread 4. */
+ status += tx_thread_resume(&thread_4);
+
+ /* Check for good status and proper counters. */
+ if ((status != TX_SUCCESS) || (thread_3_counter != 1) || (thread_1_counter) ||
+ (thread_2_counter) || (thread_4_counter))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to thread 2 and 4 before we get back. */
+ tx_thread_relinquish();
+
+ /* Check for good status and proper counters. */
+ if ((status != TX_SUCCESS) || (thread_3_counter != 1) || (thread_1_counter) ||
+ (thread_2_counter != 1) || (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Successful Thread Suspend non-current thread test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ thread_1_counter++;
+}
+
+static void thread_2_entry(ULONG thread_input)
+{
+ if (thread_4_counter == 0)
+ thread_2_counter++;
+}
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+ thread_3_counter++;
+}
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+ if (thread_2_counter == 1)
+ thread_4_counter++;
+}
+
diff --git a/test/tx/regression/threadx_thread_multiple_sleep_test.c b/test/tx/regression/threadx_thread_multiple_sleep_test.c
new file mode 100644
index 00000000..9a876295
--- /dev/null
+++ b/test/tx/regression/threadx_thread_multiple_sleep_test.c
@@ -0,0 +1,184 @@
+/* This test is designed to test multiple threads sleeping for 33 ticks. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+//static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_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_thread_multiple_sleep_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(33);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(33);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 0 counter. */
+ thread_2_counter++;
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(33);
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+
+ /* Inform user. */
+ printf("Running Thread Multiple Thread Sleep for 33 Test.................... ");
+
+ /* Clear the tick count. */
+ tx_time_set(0);
+
+ /* Sleep for 100 ticks (+1 in case tick before threads 0,1,2 have run). */
+ tx_thread_sleep(101);
+
+ /* Determine if the sleep was accurate. */
+ if ((thread_0_counter == 4) && (thread_1_counter == 4) &&
+ (thread_2_counter == 4))
+ {
+
+ /* Successful Multiple Sleep test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ else
+ {
+
+ /* Thread Multiple Sleep error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+}
+
diff --git a/test/tx/regression/threadx_thread_multiple_suspension_test.c b/test/tx/regression/threadx_thread_multiple_suspension_test.c
new file mode 100644
index 00000000..0e4e5c06
--- /dev/null
+++ b/test/tx/regression/threadx_thread_multiple_suspension_test.c
@@ -0,0 +1,432 @@
+/* This test is designed to see if multiple threads can be created and suspend.
+ The order the suspension and resumption occurs makes sure everything is working
+ right. All the counters should increment at the same rate. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_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_thread_multiple_suspension_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. */
+
+ /* Create thread 0. */
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 13, 13, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 1. */
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ (TX_MAX_PRIORITIES/2), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 2. */
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ (TX_MAX_PRIORITIES/2), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 3. */
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ (TX_MAX_PRIORITIES/2), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 4. */
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 5. Make this thread non-preemptable for the range of priorities here... */
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ (TX_MAX_PRIORITIES-1), 13, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #6\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Suspend this thread... */
+ tx_thread_suspend(&thread_0);
+
+ /* Resume thread 5... */
+ tx_thread_resume(&thread_5);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 2 counter. */
+ thread_2_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 3 counter. */
+ thread_3_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_3);
+ }
+}
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 4 counter. */
+ thread_4_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_4);
+ }
+}
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Thread Multiple Thread Suspend/Resume Test.................. ");
+
+ /* Determine if all the other threads are in a suspended state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Resume all of the threads. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_1);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_READY) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_2);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_READY) ||
+ (thread_2.tx_thread_state != TX_READY) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_3);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_READY) ||
+ (thread_2.tx_thread_state != TX_READY) || (thread_3.tx_thread_state != TX_READY) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_4);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_READY) ||
+ (thread_2.tx_thread_state != TX_READY) || (thread_3.tx_thread_state != TX_READY) ||
+ (thread_4.tx_thread_state != TX_READY) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish to allow other threads to run. */
+ tx_thread_relinquish();
+
+ /* Determine if all the other threads are in a suspended state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run twice. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2) || (thread_3_counter != 2) ||
+ (thread_4_counter != 2))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Suspend a thread that is already suspended. */
+ status = tx_thread_suspend(&thread_4);
+
+ /* Check for error condition. */
+ if (status != TX_SUCCESS)
+ {
+ /* Thread Suspend error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Increment thread 5 counter. */
+ thread_5_counter++;
+
+ /* Successful Thread Suspend test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
diff --git a/test/tx/regression/threadx_thread_multiple_time_slice_test.c b/test/tx/regression/threadx_thread_multiple_time_slice_test.c
new file mode 100644
index 00000000..6e1f61fd
--- /dev/null
+++ b/test/tx/regression/threadx_thread_multiple_time_slice_test.c
@@ -0,0 +1,269 @@
+/* This test is designed to see if two threads can be created and execute with a time-slice.
+ Thread 7 should run twice as long because it has more of a time-slice. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static volatile unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static volatile unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+static volatile unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+static volatile unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+static volatile unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+#endif
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+#endif
+
+
+/* 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_thread_multiple_time_slice_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, 2, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, 4, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create control thread. */
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+ /* Create threads with preemption-threshold and time-slice, such and make sure time-slice is defeated by
+ preemption-threshold. */
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 17, 2, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 4, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #5\n");
+ test_control_return(1);
+ }
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Call thread identify for Win32 test case. */
+ tx_thread_identify();
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Call thread identify for Win32 test case. */
+ tx_thread_identify();
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+unsigned long counter_sum;
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+UINT status;
+#endif
+
+
+ /* Inform user. */
+ printf("Running Thread Multiple Thread Time-Slice Test...................... ");
+
+ /* Sleep for some multiple of 6. */
+ tx_thread_sleep(48);
+
+ /* Increment thread 2 counter. */
+ thread_2_counter++;
+
+ /* Compute the delta. Should be twice as much, but some test environments (Windows/Linux) are
+ not as good in terms of real time processing. */
+ counter_sum = thread_0_counter;
+ counter_sum = counter_sum + (thread_0_counter/4);
+ if (thread_1_counter <= counter_sum)
+ {
+
+ /* Thread Time-slice error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+#ifdef TX_DISABLE_PREEMPTION_THRESHOLD
+ else
+ {
+ /* Successful Thread Time-slice test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+#else
+ /* Now suspend threads 0 and 1 so we can let 3 and 4 run. */
+ status = tx_thread_suspend(&thread_0);
+ status += tx_thread_suspend(&thread_1);
+
+ /* Check status. */
+ if (status)
+ {
+ /* Thread Time-slice error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Now sleep and see if thread 4 ever runs. */
+ tx_thread_sleep(4);
+
+ /* Determine if thread 3 ran and thread 4 didn't. */
+ if ((thread_3_counter) && (thread_4_counter == 0))
+ {
+ /* Successful Thread Time-slice test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ else
+ {
+
+ /* Thread Time-slice error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+#endif
+}
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+
+/* Define the test threads. */
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 3 counter. */
+ thread_3_counter++;
+
+ /* Call thread identify for Win32 test case. */
+ tx_thread_identify();
+ }
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* We should never get here! */
+
+ /* Increment thread 4 counter. */
+ thread_4_counter++;
+
+ /* Call thread identify for Win32 test case. */
+ tx_thread_identify();
+ }
+}
+#endif
+
diff --git a/test/tx/regression/threadx_thread_preemptable_suspension_test.c b/test/tx/regression/threadx_thread_preemptable_suspension_test.c
new file mode 100644
index 00000000..b1c1bc52
--- /dev/null
+++ b/test/tx/regression/threadx_thread_preemptable_suspension_test.c
@@ -0,0 +1,416 @@
+/* This test is designed to see if multiple threads can be created and suspended.
+ The order the suspension and resumption occurs makes sure everything is working right.
+ All the counters should increment at the same rate. This test differs from test 4 in
+ that thread 5 is preemptable. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+static unsigned long thread_4_counter = 0;
+static TX_THREAD thread_4;
+
+static unsigned long thread_5_counter = 0;
+static TX_THREAD thread_5;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+static void thread_5_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_thread_preemptable_suspension_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. */
+
+ /* Create thread 0. */
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 13, 13, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 1. */
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 2. */
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 3. */
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 4. */
+ status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 5. Make this thread fully preemptable... */
+ status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #6\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Suspend this thread... */
+ tx_thread_suspend(&thread_0);
+
+ /* Resume thread 5... */
+ tx_thread_resume(&thread_5);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 2 counter. */
+ thread_2_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 3 counter. */
+ thread_3_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_3);
+ }
+}
+
+static void thread_4_entry(ULONG thread_input)
+{
+
+
+ /* Enter into a forever loop. */
+ while(1)
+ {
+
+ /* Increment thread 4 counter. */
+ thread_4_counter++;
+
+ /* Suspend this thread. */
+ tx_thread_suspend(&thread_4);
+ }
+}
+
+static void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Thread Suspend/Resume W/Preemption Test..................... ");
+
+ /* Determine if all the other threads are in a suspended state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Resume all of the threads. */
+ status = tx_thread_resume(&thread_0);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run the proper amount. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_1);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run the proper amount. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
+ (thread_2_counter != 1) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_2);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has the proper amount. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2) || (thread_3_counter != 1) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_3);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run the proper amount. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2) || (thread_3_counter != 2) ||
+ (thread_4_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_resume(&thread_4);
+
+ /* Determine if all the other threads are in the proper state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run once. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2) || (thread_3_counter != 2) ||
+ (thread_4_counter != 2))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Relinquish - this should not do anything! */
+ tx_thread_relinquish();
+
+ /* Determine if all the other threads are in a suspended state. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) ||
+ (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) ||
+ (thread_4.tx_thread_state != TX_SUSPENDED))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Make sure that each thread has run twice. */
+ if ((thread_0_counter != 2) || (thread_1_counter != 2) ||
+ (thread_2_counter != 2) || (thread_3_counter != 2) ||
+ (thread_4_counter != 2))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 5 counter. */
+ thread_5_counter++;
+
+ /* Successful Thread Suspend test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
diff --git a/test/tx/regression/threadx_thread_preemption_change_test.c b/test/tx/regression/threadx_thread_preemption_change_test.c
new file mode 100644
index 00000000..1633ef92
--- /dev/null
+++ b/test/tx/regression/threadx_thread_preemption_change_test.c
@@ -0,0 +1,363 @@
+/* This test is designed to test the change preemption service call. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_initialize.h"
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+static unsigned long thread_0_counter = 0;
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_MUTEX mutex_0;
+#endif
+
+static TX_THREAD thread_0;
+
+
+/* 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_thread_preemption_change_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, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Preemption Change Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Preemption Change Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 14, 14, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Preemption Change Test............................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_mutex_create(&mutex_0, "mutex 0", TX_INHERIT);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Preemption Change Test............................... ERROR #4\n");
+ test_control_return(1);
+ }
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+UINT old_threshold;
+UINT status;
+UINT i;
+#endif
+
+
+ /* Inform user. */
+ printf("Running Thread Preemption Change Test............................... ");
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Resume thread 1, which has a higher priority. Preemption is disabled
+ though so thread 1 should not run yet. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_2_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Change the preemption-threshold such that thread 1 doesn't run yet... just for code coverage. */
+ status = tx_thread_preemption_change(&thread_0, 15, &old_threshold);
+
+ /* Change the preemption threshold. This should cause thread 1 to execute! */
+ status += tx_thread_preemption_change(&thread_0, 16, &old_threshold);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) ||
+ (old_threshold != 15))
+ {
+
+ /* Thread error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Change the preemption threshold of another thread. */
+ status = tx_thread_preemption_change(&thread_2, 11, &old_threshold);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) ||
+ (old_threshold != 14))
+ {
+
+ /* Thread error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Change the preemption threshold back to 15. */
+ status = tx_thread_preemption_change(&thread_0, 15, &old_threshold);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) ||
+ (old_threshold != 16))
+ {
+
+ /* Thread error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 2. This should preempt because it is priority 14 and the
+ current preemption threshold is 15. */
+ status = tx_thread_resume(&thread_2);
+
+ /* Check status and run counters of other threads. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* At this point, we are going to loop through preemption changes that result in
+ preemption. */
+ for (i = 0; i < (TX_THREAD_EXECUTE_LOG_SIZE*3); i++)
+ {
+
+ /* Change the preemption threshold back to 14. */
+ status = tx_thread_preemption_change(&thread_0, 14, &old_threshold);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 2 again. */
+ status = tx_thread_resume(&thread_2);
+
+ /* Check status an thread 2 run counter. */
+ if ((status != TX_SUCCESS) && (thread_2_counter != (i+1)))
+ {
+
+ /* Thread error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Change the preemption threshold back to 15 to allow thread 2 to run. */
+ status = tx_thread_preemption_change(&thread_0, 15, &old_threshold);
+
+ /* Check status an thread 2 run counter. */
+ if ((status != TX_SUCCESS) && (thread_2_counter != (i+2)))
+ {
+
+ /* Thread error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+ }
+
+ /* Change the priority of threads 0 and 1. */
+ status = tx_thread_priority_change(&thread_0, 7, &old_threshold);
+ status += tx_thread_priority_change(&thread_1, 5, &old_threshold);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Change the preemption-threshold of this thread. */
+ status = tx_thread_preemption_change(&thread_0, 0, &old_threshold);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (old_threshold != 7))
+ {
+
+ /* Thread error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Get the mutex that has priority inheritance. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Resume thread 1 so that it can suspend on the mutex and automatically raise its priority. */
+ tx_thread_resume(&thread_1);
+
+ /* Self suspend so that thread 1 and run. */
+ tx_thread_suspend(&thread_0);
+
+ /* Restore the preemption-threshold of this thread. */
+ status = tx_thread_preemption_change(&thread_0, old_threshold, &old_threshold);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (old_threshold != 0) || (thread_0.tx_thread_priority != 5) || (thread_0.tx_thread_preempt_threshold != 5))
+ {
+
+ /* Thread error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Let thread 1 run again so it can release the mutex and undo the priority inheritance. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 7) || (thread_0.tx_thread_preempt_threshold != 7))
+ {
+
+ /* Thread error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Test direct call to the thread preemption change routine with a threshold greater than the current priority. */
+ status = _tx_thread_preemption_change(&thread_0, 8, &old_threshold);
+
+ /* Check status. */
+ if (status != TX_THRESH_ERROR)
+ {
+
+ /* Thread error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+
+}
+
+#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Self suspend after initial run. */
+ tx_thread_suspend(&thread_1);
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_1);
+
+ /* Resume thread 0. */
+ tx_thread_resume(&thread_0);
+
+ /* Get the mutex, which will cause suspension. */
+ tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Release the mutex. */
+ tx_mutex_put(&mutex_0);
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* Increment thread counter. */
+ thread_2_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_2);
+ }
+}
+#endif
diff --git a/test/tx/regression/threadx_thread_priority_change.c b/test/tx/regression/threadx_thread_priority_change.c
new file mode 100644
index 00000000..a7649b8e
--- /dev/null
+++ b/test/tx/regression/threadx_thread_priority_change.c
@@ -0,0 +1,378 @@
+/* This test is designed to test the change priority service call. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_THREAD thread_3;
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_4;
+static unsigned long thread_4_counter = 0;
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+static void thread_4_entry(ULONG thread_input);
+
+
+extern unsigned long _tx_thread_priority_map;
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+UINT saved_preempt_disable;
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Determine if we have the interrupt condition we are looking for. */
+ if ((thread_3.tx_thread_priority == 6) &&
+ (thread_3.tx_thread_state == TX_READY) &&
+ (_tx_thread_priority_list[6] != &thread_3) &&
+ (thread_3_counter > 100))
+ {
+
+ /* Save the preempt disable flag. */
+ saved_preempt_disable = _tx_thread_preempt_disable;
+
+ /* Clear the preempt disable flag to ensure the API works correctly. */
+ _tx_thread_preempt_disable = 0;
+
+ /* Suspend the thread to generate the condition. */
+ tx_thread_suspend(&thread_3);
+
+ /* Restore the preempt disable flag. */
+ _tx_thread_preempt_disable = saved_preempt_disable;
+
+ /* Done trying to generate this test condition. */
+ test_isr_dispatch = TX_NULL;
+ }
+#else
+
+ /* Can't get the interrupt inside the code wit TX_NOT_INTERRUPTABLE defined, so simply stop after thread_3_counter > 100. */
+ if (thread_3_counter > 100)
+ {
+
+ /* Done trying to generate this test condition. */
+ test_isr_dispatch = TX_NULL;
+ }
+#endif
+}
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_priority_change_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Priority Change Test................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 22, 22, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Priority Change Test................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 30, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 5, 5, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+ status += tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 6, 6, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Priority Change Test................................. ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+//ULONG current_time;
+UINT old_priority;
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Thread Priority Change Test................................. ");
+
+ /* Resume thread 3. */
+ tx_thread_resume(&thread_3);
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Change priority to 22, to match that of the next highest priority ready thread.
+ This is to test the update of the priority list when a thread is moved to a
+ priority with already ready threads. */
+ status = tx_thread_priority_change(&thread_0, 22, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 16) || (thread_1_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Restore original priority. */
+ tx_thread_priority_change(&thread_0, old_priority, &old_priority);
+
+ /* See if we can change priority of this thread. */
+ status = tx_thread_priority_change(&thread_0, 7, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 16) || (thread_1_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* See if we can change priority of another ready thread. */
+ status = tx_thread_priority_change(&thread_1, 21, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 22) || (thread_1_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* See if we can cause preemption by lowering this thread's priority. */
+ status = tx_thread_priority_change(&thread_0, 22, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 7) || (thread_1_counter != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Thread 1 should have run already... Raise this threads priority
+ back up. */
+ status = tx_thread_priority_change(&thread_0, 8, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 22) || (thread_1_counter != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* See if we can change the priority of a suspended thread. */
+ status = tx_thread_priority_change(&thread_1, 19, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 21) || (thread_1_counter != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Resume the suspended thread so it is in a ready condition. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Should not have run yet. Raise its priority to 8 still should not run yet! */
+ status = tx_thread_priority_change(&thread_1, 8, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 19) || (thread_1_counter != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Raise its priority to 7, now it should run. */
+ status = tx_thread_priority_change(&thread_1, 7, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 8) || (thread_1_counter != 2) || (thread_2_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Now thread 1 should be suspended. Let's change thread 0's priority and make sure thread 2 doesn't run yet! */
+ status = tx_thread_priority_change(&thread_0, 7, &old_priority);
+
+ /* Check status, return priority, and run count of other thread. */
+ if ((status != TX_SUCCESS) || (old_priority != 8) || (thread_1_counter != 2) || (thread_2_counter != 0))
+ {
+
+ /* Thread error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Suspend self and wait for upper thread to resume. */
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* This thread should never run! */
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Self suspend. */
+ tx_thread_suspend(&thread_2);
+ }
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+UINT old_priority;
+UINT loop;
+
+
+ /* Resume threads 4. */
+ tx_thread_resume(&thread_4);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+ do
+ {
+
+ loop = rand() % 100;
+ while (loop--)
+ {
+ thread_3_counter++;
+ }
+
+ /* Raise priority of thread 3 for code coverage. */
+ tx_thread_priority_change(&thread_3, 6, &old_priority);
+ tx_thread_priority_change(&thread_3, 5, &old_priority);
+
+ /* Check to see if thread 4 has run... it should not have executed
+ yet. If it does, set the thread_1_counter to indicate an error! */
+ if (thread_4_counter)
+ thread_1_counter++;
+
+ } while (test_isr_dispatch);
+}
+
+
+static void thread_4_entry(ULONG thread_input)
+{
+ thread_4_counter++;
+}
+
diff --git a/test/tx/regression/threadx_thread_relinquish_test.c b/test/tx/regression/threadx_thread_relinquish_test.c
new file mode 100644
index 00000000..e8b4ada7
--- /dev/null
+++ b/test/tx/regression/threadx_thread_relinquish_test.c
@@ -0,0 +1,193 @@
+/* This test is designed to see if multiple threads can be created and relinquish control between them. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static unsigned long thread_3_counter = 0;
+static TX_THREAD thread_3;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_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_thread_relinquish_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. */
+
+ /* Create thread 0. */
+ status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 1. */
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 2. */
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create thread 3. */
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Relinquish Test...................................... ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ /* Check for correct input value and execution of other threads. */
+ if ((thread_input != 0) || (thread_1_counter) || (thread_2_counter) ||
+ (thread_3_counter))
+ return;
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Relinquish to other thread(s). */
+ tx_thread_relinquish();
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Check for correct input value and execution of other threads. */
+ if ((thread_input != 1) || (thread_0_counter != 1) || (thread_2_counter) ||
+ (thread_3_counter))
+ return;
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Relinquish to other thread(s). */
+ tx_thread_relinquish();
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Check for correct input value and execution of other threads. */
+ if ((thread_input != 2) || (thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_3_counter))
+ return;
+
+ /* Increment thread 2 counter. */
+ thread_2_counter++;
+
+ /* Relinquish to other thread(s). */
+ tx_thread_relinquish();
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+ /* Inform user. */
+ printf("Running Thread Relinquish Test...................................... ");
+
+ /* Check for correct input value and execution of other threads. */
+ if ((thread_input != 3) || (thread_0_counter != 1) || (thread_1_counter != 1) ||
+ (thread_2_counter != 1) || (thread_0.tx_thread_state != TX_READY) ||
+ (thread_1.tx_thread_state != TX_READY) || (thread_2.tx_thread_state != TX_READY))
+ return;
+
+ /* Increment thread 3 counter. */
+ thread_3_counter++;
+
+ /* Immediate response relinquish. */
+ tx_thread_relinquish();
+
+ /* All other threads should be completed now. */
+ if ((thread_0.tx_thread_state != TX_COMPLETED) || (thread_1.tx_thread_state != TX_COMPLETED) ||
+ (thread_2.tx_thread_state != TX_COMPLETED))
+ {
+
+ /* Thread Relinquish error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Execute immediate response relinquish. */
+ tx_thread_relinquish();
+
+ /* Successful thread relinquish test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
diff --git a/test/tx/regression/threadx_thread_reset_test.c b/test/tx/regression/threadx_thread_reset_test.c
new file mode 100644
index 00000000..ff3531a5
--- /dev/null
+++ b/test/tx/regression/threadx_thread_reset_test.c
@@ -0,0 +1,248 @@
+/* This test is designed to test the tx_thread_reset function. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+
+
+static unsigned long thread_0_counter = 0;
+static unsigned long thread_0_enter = 0;
+static unsigned long thread_0_exit = 0;
+static unsigned long thread_1_counter = 0;
+static unsigned long thread_2_counter = 0;
+
+
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+
+
+/* Define task prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void entry_exit_notify(TX_THREAD *thread_ptr, UINT type)
+{
+
+ /* Check for the appropriate thread. */
+ if (thread_ptr != &thread_0)
+ return;
+
+ /* Check for type. */
+ if (type == TX_THREAD_ENTRY)
+ thread_0_enter++;
+ else if (type == TX_THREAD_EXIT)
+ thread_0_exit++;
+}
+
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_reset_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Setup the notify call to test that logic. */
+ status += tx_thread_entry_exit_notify(&thread_0, entry_exit_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Reset Test........................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Thread Reset Test........................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+#endif
+
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Reset Test........................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Reset Test........................................... ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test thread. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Fall through to the return in order to place the thread in a finished
+ state. */
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Thread Reset Test........................................... ");
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Attempt to delete thread 2, which is in the wrong stat for deleting. */
+ status = tx_thread_delete(&thread_2);
+
+ /* Check for the proper status. */
+ if (status != TX_DELETE_ERROR)
+ {
+
+ /* Thread delete error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Determine if the first Thread has run and if it's current state is
+ finished. */
+ if ((thread_0.tx_thread_state != TX_COMPLETED) || (thread_0_counter != 1) ||
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+ (thread_0_enter != 1) || (thread_0_exit != 1) || (thread_2_counter != 0))
+#else
+ (thread_0_enter != 0) || (thread_0_exit != 0) || (thread_2_counter != 0))
+#endif
+ {
+
+ /* Thread reset error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Call thread reset on thread 2, which should result in an error. */
+ status = tx_thread_reset(&thread_2);
+
+ /* Check for proper status. */
+ if (status != TX_NOT_DONE)
+ {
+
+ /* Thread reset error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Now call the thread reset function on thread 0. */
+ status = tx_thread_reset(&thread_0);
+
+ /* Determine if the first Thread has been reset but not executed. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_0_counter != 1) ||
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+ (thread_0_enter != 1) || (thread_0_exit != 1) || (thread_2_counter != 0))
+#else
+ (thread_0_enter != 0) || (thread_0_exit != 0) || (thread_2_counter != 0))
+#endif
+ {
+
+ /* Thread reset error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Terminate thread 0. */
+ status = tx_thread_terminate(&thread_0);
+ status += tx_thread_reset(&thread_0);
+
+
+ /* Now resume thread 0 to let it run. */
+ status += tx_thread_resume(&thread_0);
+
+ /* Determine if the first Thread has run and if it's current state is
+ finished. */
+ if ((thread_0.tx_thread_state != TX_COMPLETED) || (thread_0_counter != 2) ||
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+ (thread_0_enter != 2) || (thread_0_exit != 3) || (thread_2_counter != 0))
+#else
+ (thread_0_enter != 0) || (thread_0_exit != 0) || (thread_2_counter != 0))
+#endif
+ {
+
+ /* Thread reset error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+
+ /* Successful thread finish test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Increment thread 2 counter. */
+ thread_2_counter++;
+
+ /* Fall through to the return in order to place the thread in a finished
+ state. */
+}
diff --git a/test/tx/regression/threadx_thread_simple_sleep_non_clear_test.c b/test/tx/regression/threadx_thread_simple_sleep_non_clear_test.c
new file mode 100644
index 00000000..f406924c
--- /dev/null
+++ b/test/tx/regression/threadx_thread_simple_sleep_non_clear_test.c
@@ -0,0 +1,92 @@
+/* This test is designed to test a simple sleep for 18 ticks, with something in the
+ remaining field of the thread control block. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+
+/* 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_thread_simple_sleep_non_clear_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;
+
+ /* Place a 1 in the thread control block to simulate a control block created in
+ random memory. */
+ thread_0.tx_thread_timer.tx_timer_internal_re_initialize_ticks = 1;
+
+ /* 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, 3, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Sleep with non-zero TX_THREAD........................ ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+ULONG now;
+
+
+ /* Inform user. */
+ printf("Running Thread Sleep with non-zero TX_THREAD........................ ");
+
+ /* Clear the tick count. */
+ tx_time_set(0);
+
+ /* Sleep for 18 ticks. */
+ tx_thread_sleep(9);
+ tx_thread_sleep(9);
+
+ /* Determine if the sleep was accurate. */
+ now = tx_time_get();
+ if ((now == 18) ||
+ (now == 19))
+ {
+
+ /* Successful Simple Sleep test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ else
+ {
+
+ /* Thread Simple Sleep error. */
+ printf("ERROR #2, now = %lu\n", now);
+ test_control_return(1);
+ }
+}
+
diff --git a/test/tx/regression/threadx_thread_simple_sleep_test.c b/test/tx/regression/threadx_thread_simple_sleep_test.c
new file mode 100644
index 00000000..6b7afbe1
--- /dev/null
+++ b/test/tx/regression/threadx_thread_simple_sleep_test.c
@@ -0,0 +1,87 @@
+/* This test is designed to test a simple sleep for 18 ticks. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+
+/* 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_thread_simple_sleep_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, 3, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Simple Sleep for 18 Ticks Test....................... ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+ULONG now;
+
+
+ /* Inform user. */
+ printf("Running Thread Simple Sleep for 18 Ticks Test....................... ");
+
+ /* Clear the tick count. */
+ tx_time_set(0);
+
+ /* Sleep for 18 ticks. */
+ tx_thread_sleep(18);
+
+ /* Determine if the sleep was accurate. */
+ now = tx_time_get();
+ if ((now == 18) ||
+ (now == 19))
+ {
+
+ /* Successful Simple Sleep test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+ else
+ {
+
+ /* Thread Simple Sleep error. */
+ printf("ERROR #2, now = %lu\n", now);
+ test_control_return(1);
+ }
+}
+
diff --git a/test/tx/regression/threadx_thread_simple_suspend_test.c b/test/tx/regression/threadx_thread_simple_suspend_test.c
new file mode 100644
index 00000000..52215a75
--- /dev/null
+++ b/test/tx/regression/threadx_thread_simple_suspend_test.c
@@ -0,0 +1,116 @@
+/* This test is designed to see if a thread can successfully suspend itself in a single
+ thread system. This also tests a thread created that is not automatically enabled. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static TX_THREAD thread_1;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_thread_simple_supsend_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Simple Suspend Test.................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Simple Suspend Test.................................. ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test thread. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Resume the test control thread. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ return;
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Suspend the running thread. */
+ tx_thread_suspend(&thread_0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Inform user. */
+ printf("Running Thread Simple Suspend Test.................................. ");
+
+ /* The other thread should be in a suspended state now. */
+ if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_0_counter != 1))
+ {
+
+ /* Thread Suspend error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful Thread Suspend test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
diff --git a/test/tx/regression/threadx_thread_sleep_for_100ticks_test.c b/test/tx/regression/threadx_thread_sleep_for_100ticks_test.c
new file mode 100644
index 00000000..69eadbc6
--- /dev/null
+++ b/test/tx/regression/threadx_thread_sleep_for_100ticks_test.c
@@ -0,0 +1,435 @@
+/* This test is designed to test a simple sleep for 100 ticks. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_timer.h"
+
+//#define DEBUG
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+
+static TX_THREAD thread_0;
+
+static int error = 0;
+
+static int isr_count = 0;
+
+#ifdef TEST_INTERRUPT_CONDITION
+#ifndef TX_NOT_INTERRUPTABLE
+
+#if defined(TX_WIN32_MEMORY_SIZE) || defined(TX_LINUX_MEMORY_SIZE)
+/* Use larger array size when running on Win32 test platform because of greater speed. */
+#define ARRAY_SIZE 100
+#else
+#define ARRAY_SIZE 10
+#endif
+
+
+static UINT isr_test_suspend_interrupt = TX_TRUE;
+static UINT isr_test_suspend_interrupted_condition = TX_FALSE;
+static ULONG min_loop_count;
+static ULONG max_loop_count;
+static TX_SEMAPHORE test_semaphore;
+static ULONG loop_count;
+static volatile ULONG count;
+static volatile ULONG destination = 0;
+static ULONG array_delay[ARRAY_SIZE];
+static ULONG start_time;
+static ULONG lower_bound;
+static ULONG upper_bound;
+static ULONG current_itterations;
+#ifdef DEBUG_1
+static ULONG last_loop_count;
+#endif
+static ULONG delay_function(void)
+{
+
+ULONG accumulator;
+ULONG i;
+
+ for (i = 0; i < ARRAY_SIZE; i++)
+ array_delay[i] = i;
+
+ for (i = 0; i < ARRAY_SIZE-4; i++)
+ {
+ array_delay[i] = (array_delay[i+1] * array_delay[i+2]) * (array_delay[i+3] * array_delay[i+4]);
+ }
+
+ accumulator = 0;
+ for (i = 0; i < ARRAY_SIZE; i++)
+ accumulator = accumulator + array_delay[i];
+
+ return(accumulator);
+}
+
+#endif
+#endif
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+UINT status;
+
+#ifdef TEST_INTERRUPT_CONDITION
+#ifndef TX_NOT_INTERRUPTABLE
+ULONG i;
+
+ /* Determine if we are in calibration mode. */
+ if ((loop_count) && (loop_count != 0xFFFFFFFF))
+ {
+ if (loop_count < min_loop_count)
+ min_loop_count = loop_count;
+ if (loop_count > max_loop_count)
+ max_loop_count = loop_count;
+
+ lower_bound = loop_count - 1;
+ upper_bound = loop_count + 1;
+ if (lower_bound < min_loop_count)
+ lower_bound = min_loop_count;
+ if (upper_bound > max_loop_count)
+ lower_bound = max_loop_count;
+
+ if ((current_itterations < lower_bound) || (current_itterations > upper_bound))
+ current_itterations = lower_bound;
+
+#ifdef DEBUG_1
+ /* Last loop count. */
+ last_loop_count = loop_count;
+#endif
+
+ /* Reset the loop count to all ones! */
+ loop_count = 0xFFFFFFFF;
+ }
+ count++;
+ for (i = 0; i < (count%32); i++)
+ destination++;
+
+ /* Determine if the ISR is in the mode to wakeup the thread suspending with a timeout. */
+ if (isr_test_suspend_interrupt)
+ {
+
+ /* Determine if the thread is suspended on the semaphore... */
+ if (thread_0.tx_thread_state == TX_SEMAPHORE_SUSP)
+ {
+
+ /* Determine if the test condition is present... */
+ if ((_tx_thread_preempt_disable) &&
+ (thread_0.tx_thread_timer.tx_timer_internal_list_head == TX_NULL))
+ {
+
+ /* Set the flag showing the condition is present. */
+ isr_test_suspend_interrupted_condition = TX_TRUE;
+
+ /* All done with the test. */
+ isr_test_suspend_interrupt = TX_FALSE;
+ }
+
+ /* Post to the semaphore to wakeup the thread. */
+ tx_semaphore_put(&test_semaphore);
+ }
+
+ return;
+ }
+#endif
+#endif
+
+ /* Increment the ISR count. */
+ isr_count++;
+
+ /* Call sleep from ISR to check for error! */
+ status = tx_thread_sleep(100);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+
+ error = 1;
+ }
+
+ /* End the ISR. */
+ test_isr_dispatch = TX_NULL;
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_sleep_for_100ticks_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, 3, TX_AUTO_START);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Sleep for 100 Ticks Test............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+#ifdef TEST_INTERRUPT_CONDITION
+#ifndef TX_NOT_INTERRUPTABLE
+
+ status = tx_semaphore_create(&test_semaphore, "test semaphore", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Sleep for 100 Ticks Test............................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ min_loop_count = 0xFFFFFFFF;
+ max_loop_count = 0;
+ loop_count = 0xFFFFFFFF;
+ current_itterations = 0;
+#ifdef DEBUG_1
+ last_loop_count = 0x0;
+#endif
+#endif
+#endif
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+#ifdef TEST_INTERRUPT_CONDITION
+#ifndef TX_NOT_INTERRUPTABLE
+ULONG i;
+volatile ULONG value = 0;
+#endif
+#endif
+
+ /* Inform user. */
+ printf("Running Thread Sleep for 100 Ticks Test............................. ");
+
+ /* Call sleep with an expiration of 0 and test error code. */
+ status = tx_thread_sleep(0);
+
+ /* Check error code. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread Simple Sleep error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+#ifdef TEST_INTERRUPT_CONDITION
+#ifndef TX_NOT_INTERRUPTABLE
+
+
+ isr_test_suspend_interrupt = TX_TRUE;
+ isr_test_suspend_interrupted_condition = TX_FALSE;
+#endif
+#endif
+
+ /* Setup the test ISR. */
+ test_isr_dispatch = test_isr;
+
+#ifdef TEST_INTERRUPT_CONDITION
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Callibrate the loop count from thread sleep. */
+ for (i = 0; i < 180; i++)
+ {
+
+ /* Sleep to get a fresh time. */
+ tx_thread_sleep(1);
+
+ /* Set the loop count to 0 and start counting.... */
+ loop_count = 0;
+ start_time = _tx_timer_system_clock;
+ do
+ {
+
+ /* Call delay function. */
+ delay_function();
+ loop_count++;
+ } while (start_time == _tx_timer_system_clock);
+
+ /* Wait to reset the loop count. */
+ tx_thread_sleep(1);
+ }
+
+#if 1
+ /* Setup the lower and upper bounds. */
+ lower_bound = min_loop_count;
+ if (lower_bound > 5)
+ lower_bound = lower_bound - 5;
+ upper_bound = max_loop_count + 5;
+#else
+ /* Setup the lower and upper bounds. */
+ lower_bound = min_loop_count;
+ upper_bound = max_loop_count;
+#endif
+
+ current_itterations = lower_bound;
+#ifdef DEBUG
+ i = 0;
+#endif
+ while (isr_test_suspend_interrupted_condition != TX_TRUE)
+ {
+
+ /* Sleep to get a frest timer slot. */
+ tx_thread_sleep(1);
+
+ /* Loop to delay to next interrupt. */
+ loop_count = 0;
+ start_time = _tx_timer_system_clock;
+ do
+ {
+ /* Call delay function. */
+ delay_function();
+ loop_count++;
+ } while (loop_count < current_itterations);
+
+ /* Check for a timer interrupt... if so, just skip the semaphore get. */
+ if (start_time != _tx_timer_system_clock)
+ continue;
+
+ /* Suspend on the semaphore for 20 ticks... */
+ tx_semaphore_get(&test_semaphore, 20);
+
+ /* Adjust the current itterations. */
+ current_itterations++;
+ if (current_itterations > upper_bound)
+ {
+ if (lower_bound > min_loop_count)
+ lower_bound--;
+ if (upper_bound < max_loop_count)
+ upper_bound++;
+ current_itterations = lower_bound;
+ }
+
+ /* Set the tick count simply to use value. */
+ tx_time_set(value);
+#ifdef DEBUG
+ /* Debug block. */
+ i++;
+ if ((i % 180) == 0)
+ {
+ printf("*** update ***\n");
+ if (loop_count == 0xFFFFFFFF)
+ printf("loop count: NA\n");
+ else
+ printf("loop count: %lu\n", loop_count);
+ printf("current: %lu\n", current_itterations);
+ printf("last loop count: %lu\n", last_loop_count);
+ printf("minimum: %lu\n", min_loop_count);
+ printf("maximum: %lu\n", max_loop_count);
+ printf("lower bound: %lu\n", lower_bound);
+ printf("upper bound: %lu\n", upper_bound);
+ printf("count: %lu\n", i);
+ }
+#endif
+ }
+
+#ifdef DEBUG
+ /* Debug block */
+ printf("*** final ***\n");
+ if (loop_count == 0xFFFFFFFF)
+ printf("loop count: NA\n");
+ else
+ printf("loop count: %lu\n", loop_count);
+ printf("current: %lu\n", current_itterations);
+ printf("last loop count: %lu\n", last_loop_count);
+ printf("minimum: %lu\n", min_loop_count);
+ printf("maximum: %lu\n", max_loop_count);
+ printf("lower bound: %lu\n", lower_bound);
+ printf("upper bound: %lu\n", upper_bound);
+ printf("count: %lu\n", i);
+#endif
+
+ /* Clear the tick count. */
+ tx_time_set(0);
+
+ /* Sleep for 100 ticks. */
+ tx_thread_sleep(100);
+
+ /* Check for error. */
+ if (tx_time_get() < 100)
+ {
+
+ /* Thread Simple Sleep error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+#endif
+#endif
+
+ /* Clear the tick count. */
+ tx_time_set(0);
+
+
+ /* Sleep for 100 ticks. */
+ status = tx_thread_sleep(100);
+
+ /* Determine if the sleep was accurate. */
+ if ((status != TX_SUCCESS) || (tx_time_get() < 100) ||
+ (tx_time_get() > 101))
+ {
+
+ /* Thread Simple Sleep error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Check to make sure the ISR happened and the proper return value was present. */
+ if ((isr_count == 0) || (error))
+ {
+
+ /* Thread Simple Sleep error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful Simple Sleep test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
diff --git a/test/tx/regression/threadx_thread_sleep_terminate_test.c b/test/tx/regression/threadx_thread_sleep_terminate_test.c
new file mode 100644
index 00000000..871fc6e2
--- /dev/null
+++ b/test/tx/regression/threadx_thread_sleep_terminate_test.c
@@ -0,0 +1,187 @@
+/* This test is designed to test thread termination of a thread in a sleep condition. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static unsigned long thread_1_counter = 0;
+static unsigned long thread_1_enter = 0;
+static unsigned long thread_1_exit = 0;
+static TX_THREAD thread_1;
+
+extern UINT _tx_thread_preempt_disable;
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+
+static void entry_exit_notify(TX_THREAD *thread_ptr, UINT type)
+{
+
+ /* Check for the appropriate thread. */
+ if (thread_ptr != &thread_1)
+ return;
+
+ /* Check for type. */
+ if (type == TX_THREAD_ENTRY)
+ thread_1_enter++;
+ else if (type == TX_THREAD_EXIT)
+ thread_1_exit++;
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_sleep_terminate_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend Terminate Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend Terminate Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Setup the notify call to test that logic. */
+ status += tx_thread_entry_exit_notify(&thread_1, entry_exit_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Suspend Terminate Test............................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Thread Suspend Terminate Test............................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Thread Suspend Terminate Test............................... ");
+
+ /* Increment run counter. */
+ thread_0_counter++;
+
+ /* Sleep to allow lower-priority thread 1 to run. */
+ tx_thread_sleep(5);
+
+ /* Now terminate thread 1. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (_tx_thread_preempt_disable))
+ {
+
+ /* Terminate error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Now try to suspend a terminated thread. */
+ status = tx_thread_suspend(&thread_1);
+
+ /* Check status. */
+ if (status != TX_SUSPEND_ERROR)
+ {
+
+ /* Suspend error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ while(1)
+ {
+
+ /* Increment run counter. */
+ thread_1_counter++;
+
+ /* Suspend thread 1. */
+ status = tx_thread_sleep(100);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+ thread_1_counter = 0; /* Make an error! */
+ return;
+ }
+ }
+}
+
+
diff --git a/test/tx/regression/threadx_thread_stack_checking_test.c b/test/tx/regression/threadx_thread_stack_checking_test.c
new file mode 100644
index 00000000..3ffe3841
--- /dev/null
+++ b/test/tx/regression/threadx_thread_stack_checking_test.c
@@ -0,0 +1,224 @@
+/* This test is for the thread stack checking services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+
+/* Prototype for direct call. */
+
+VOID _tx_thread_stack_analyze(TX_THREAD *thread_ptr);
+
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+static CHAR *thread_2_stack_start;
+static UINT stack_error = 0;
+
+
+/* Define task prototypes. */
+
+static void thread_0_entry(ULONG task_input);
+static void thread_1_entry(ULONG task_input);
+static void thread_2_entry(ULONG task_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the stack checking error handler. */
+
+void stack_error_handler(TX_THREAD *thread_ptr)
+{
+
+ /* Check for the right thread. */
+ if (thread_ptr == &thread_2)
+ stack_error = 1;
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_stack_checking_application_define(void *first_unused_memory)
+#endif
+{
+
+INT status;
+CHAR *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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Stack Checking Test.................................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Stack Checking Test.................................. ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, TX_NO_TIME_SLICE, TX_DONT_START);
+ thread_2_stack_start = pointer;
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Stack Checking Test.................................. ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Register the stack checking handler. */
+ status = tx_thread_stack_error_notify(stack_error_handler);
+
+#ifdef TX_ENABLE_STACK_CHECKING
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+#else
+ if (status != TX_FEATURE_NOT_ENABLED)
+#endif
+
+ {
+
+ printf("Running Thread Stack Checking Test.................................. ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Inform user of success getting to this test. */
+ printf("Running Thread Stack Checking Test.................................. ");
+
+ /* Resume thread 1 to get the stack checking to take place. */
+ status = tx_thread_resume(&thread_1);
+
+ /* Suspend to allow thread 1 to run. */
+ tx_thread_suspend(&thread_0);
+
+ /* Terminate thread 1. */
+ status = tx_thread_terminate(&thread_1);
+
+ /* Check error code. */
+#ifdef TX_ENABLE_STACK_CHECKING
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) || (stack_error != 1))
+#else
+ if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) || (stack_error != 0))
+#endif
+ {
+
+ /* Thread error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Success! */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+TX_THREAD fake_thread;
+
+ /* Call stack analyze with a NULL pointer. */
+ _tx_thread_stack_analyze(TX_NULL);
+
+ /* Call the stack analyze with a fake stack just to test that path. */
+ fake_thread.tx_thread_id = 0;
+ _tx_thread_stack_analyze(&fake_thread);
+
+ /* Call the stack analyze with a NULL stack pointer. */
+ fake_thread.tx_thread_id = ((ULONG) 0x54485244);
+ fake_thread.tx_thread_stack_start = TX_NULL;
+ _tx_thread_stack_analyze(&fake_thread);
+
+ /* Call the stack analyze with a NULL highest stack pointer. */
+ fake_thread.tx_thread_id = ((ULONG) 0x54485244);
+ fake_thread.tx_thread_stack_start = (void *) 0x1000;
+ fake_thread.tx_thread_stack_highest_ptr = TX_NULL;
+ _tx_thread_stack_analyze(&fake_thread);
+
+ /* Clear the pattern in thread 2's stack. */
+ TX_MEMSET(thread_2_stack_start, (CHAR) 0x11, TEST_STACK_SIZE_PRINTF);
+
+ /* Resume thread 2, which should cause the stack error to occur. */
+ tx_thread_resume(&thread_2);
+
+ /* Suspend thread 2. */
+ tx_thread_suspend(&thread_2);
+
+ /* Increment thread 1 counter. */
+ thread_1_counter++;
+
+ /* Now, deregister the stack error handler and get into a spin condition. We will then
+ want to terminate thread 1 from thread 0 when it awakes! */
+ tx_thread_stack_error_notify(TX_NULL);
+
+ /* Now resume thread 2 again to cause the stack error! */
+ tx_thread_resume(&thread_2);
+
+ /* Now suspend thread 2 again. */
+ tx_thread_suspend(&thread_2);
+
+ /* Resume thread 0. */
+ tx_thread_resume(&thread_0);
+}
+
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Increment thread 1 counter. */
+ thread_2_counter++;
+}
diff --git a/test/tx/regression/threadx_thread_terminate_delete_test.c b/test/tx/regression/threadx_thread_terminate_delete_test.c
new file mode 100644
index 00000000..dbe919f3
--- /dev/null
+++ b/test/tx/regression/threadx_thread_terminate_delete_test.c
@@ -0,0 +1,341 @@
+/* This test is designed to test thread terminate (self, and other), thread delete,
+ and thread identify services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static unsigned long thread_1_enter = 0;
+static unsigned long thread_1_exit = 0;
+static TX_THREAD thread_1;
+
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_2;
+
+static TX_THREAD thread_3;
+static unsigned long thread_3_enter = 0;
+static unsigned long thread_3_exit = 0;
+
+
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void thread_2_entry(ULONG thread_input);
+static void thread_3_entry(ULONG thread_input);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void entry_exit_notify(TX_THREAD *thread_ptr, UINT type)
+{
+
+ /* Check for the appropriate thread. */
+ if (thread_ptr != &thread_1)
+ return;
+
+ /* Check for type. */
+ if (type == TX_THREAD_ENTRY)
+ thread_1_enter++;
+ else if (type == TX_THREAD_EXIT)
+ thread_1_exit++;
+}
+
+
+static void entry_exit_notify3(TX_THREAD *thread_ptr, UINT type)
+{
+
+ /* Check for the appropriate thread. */
+ if (thread_ptr != &thread_3)
+ return;
+
+ /* Check for type. */
+ if (type == TX_THREAD_ENTRY)
+ thread_3_enter++;
+ else if (type == TX_THREAD_EXIT)
+ thread_3_exit++;
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_terminate_delete_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Setup the notify call to test that logic. */
+ status = tx_thread_entry_exit_notify(&thread_1, entry_exit_notify);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+
+#endif
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 12, 12, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Setup the notify call to test that logic. */
+ status = tx_thread_entry_exit_notify(&thread_3, entry_exit_notify3);
+
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #7\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Check for status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #8\n");
+ test_control_return(1);
+ }
+
+#endif
+
+
+ /* Create a semaphore for thread 3 to suspend on. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Terminate and Delete Test............................ ERROR #9\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Thread Terminate and Delete Test............................ ");
+
+ /* Let other threads execute. */
+ tx_thread_relinquish();
+
+ /* Make sure thread 1 is terminated and thread 2 is suspended. */
+ if ((thread_1.tx_thread_state != TX_TERMINATED) ||
+#ifndef TX_DISABLE_NOTIFY_CALLBACKS
+ (thread_1_enter != 1) || (thread_1_exit != 1) ||
+#else
+ (thread_1_enter != 0) || (thread_1_exit != 0) ||
+#endif
+ (thread_2.tx_thread_state != TX_SUSPENDED))
+ {
+
+ /* Thread error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* At this point, terminate thread 2 which should be in a suspended state
+ right now. */
+ status = tx_thread_terminate(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Delete thread 1 (thread 1 alread terminated) and 2. */
+ status = tx_thread_delete(&thread_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_delete(&thread_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* At this point, terminate thread 3 which should be in a suspended state
+ on the semaphore right now. */
+ status = tx_thread_terminate(&thread_3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Delete thread 3. */
+ status = tx_thread_delete(&thread_3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Test identity. */
+ if (tx_thread_identify() != &thread_1)
+ return;
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Terminate self. */
+ tx_thread_terminate(&thread_1);
+}
+
+static void thread_2_entry(ULONG thread_input)
+{
+
+ /* Test identity. */
+ if (tx_thread_identify() != &thread_2)
+ return;
+
+ /* Increment thread counter. */
+ thread_2_counter++;
+
+ /* Suspend thread. */
+ tx_thread_suspend(&thread_2);
+}
+
+
+static void thread_3_entry(ULONG thread_input)
+{
+
+ /* Get the semaphore with wait forever! */
+ tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Increment thread counter. */
+ thread_2_counter++;
+}
+
diff --git a/test/tx/regression/threadx_thread_time_slice_change_test.c b/test/tx/regression/threadx_thread_time_slice_change_test.c
new file mode 100644
index 00000000..8ee7df3b
--- /dev/null
+++ b/test/tx/regression/threadx_thread_time_slice_change_test.c
@@ -0,0 +1,149 @@
+/* This test is designed to test the change time-slice service call. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+extern unsigned long _tx_timer_time_slice;
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_thread_time_slice_change_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 Thread Time-Slice Change Test............................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 22, 22, 200, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Time-Slice Change Test............................... ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG old_time_slice = 0;
+
+
+ /* Inform user. */
+ printf("Running Thread Time-Slice Change Test............................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Change the time-slice of other thread. */
+ status = tx_thread_time_slice_change(&thread_1, 33, &old_time_slice);
+
+ /* Check status and the time sice of specified thread. */
+ if ((status != TX_SUCCESS) || (old_time_slice != 200) || (thread_1.tx_thread_new_time_slice != 33))
+ {
+
+ /* Thread error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Sleep to get a fresh timer. */
+ tx_thread_sleep(1);
+
+ /* Change the time-slice of this thread. */
+ status = tx_thread_time_slice_change(&thread_0, 66, &old_time_slice);
+
+ /* Check status and the time sice of specified thread. */
+ if ((status != TX_SUCCESS) || (old_time_slice != 100) || (thread_0.tx_thread_new_time_slice != 66) ||
+ (_tx_timer_time_slice != 66))
+ {
+
+ /* Thread error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Change the time-slice of this thread. */
+ status = tx_thread_time_slice_change(&thread_1, 2, &old_time_slice);
+
+ /* Sleep for 8 ticks just to allow thread 1 to run and time-slice with no other thread ready. */
+ tx_thread_sleep(8);
+
+ if (status != TX_SUCCESS)
+ {
+
+ /* Thread error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ /* Identify. */
+ tx_thread_identify();
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+ }
+}
+
diff --git a/test/tx/regression/threadx_thread_wait_abort_and_isr_test.c b/test/tx/regression/threadx_thread_wait_abort_and_isr_test.c
new file mode 100644
index 00000000..56fef596
--- /dev/null
+++ b/test/tx/regression/threadx_thread_wait_abort_and_isr_test.c
@@ -0,0 +1,271 @@
+/* This test is designed to test for simultaneous thread suspension lifting AND thread wait abort calls. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+
+static unsigned long semaphore_put_counter = 0;
+static unsigned long condition_count = 0;
+extern UINT _tx_timer_system_clock;
+
+static TX_SEMAPHORE semaphore_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void timer_0_entry(ULONG timer_input);
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define the external reference for the preempt disable flag. */
+
+extern volatile UINT _tx_thread_preempt_disable;
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+static void isr_entry(void)
+{
+
+UINT status;
+static volatile UINT miss_count = 0;
+
+
+ /* Attempt to sleep from a timer in order to test the error logic. */
+ status = tx_thread_sleep(1);
+
+ /* Check for proper error status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Blow up the test to force an error. */
+ condition_count = 10000000;
+ semaphore_put_counter = 0xFFFF0000;
+ }
+
+ /* Determine if the interrupt occurred when the preempt disable flag was set. */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* Yes this is the condition we are looking for, increment the test condition counter. */
+ condition_count++;
+ }
+
+ /*
+ It is possible for this test to get into a resonance condition in which
+ the ISR never occurs while preemption is disabled (especially if the
+ ISR is installed in the periodic timer interrupt handler, which is
+ conveniently available). Detect this condition and break out of it by
+ perturbing the duration of this ISR a pseudo-random amount of time.
+ */
+ else if (++miss_count > 100)
+ for (miss_count = _tx_timer_system_clock % 100; miss_count != 0; --miss_count);
+
+ /* Put the semaphore to wakeup thread 0. */
+ status = tx_semaphore_put(&semaphore_0);
+
+ /* Increment the semaphore counter. */
+ if (status == TX_SUCCESS)
+ semaphore_put_counter++;
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_thread_wait_abort_and_isr_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,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Wait Abort and ISR Resume Test....................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 17, 17, 100, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Wait Abort and ISR Resume Test....................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Create semaphore - consumer producer semaphore. */
+ status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Wait Abort and ISR Resume Test....................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Create a timer to ensure a context save is called for every interrupt. */
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Wait Abort and ISR Resume Test....................... ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Clear the condition count variable. */
+ condition_count = 0;
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Setup ISR for this test. */
+ test_isr_dispatch = isr_entry;
+
+ /* Inform user. */
+ printf("Running Thread Wait Abort and ISR Resume Test....................... ");
+
+ /* Loop to exploit the probability window inside tx_thread_wait_abort. */
+ while (condition_count < 10)
+ {
+
+ /* Suspend on the semaphore that is going to be set via the ISR. */
+ status = tx_semaphore_get(&semaphore_0, (thread_0_counter % 5) + 1);
+
+ /* Determine if we have an unexpected result. */
+ if ((status != TX_SUCCESS) && (status != TX_WAIT_ABORTED))
+ {
+
+ /* Test error! */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Check for the preempt disable flag being set. */
+ if (_tx_thread_preempt_disable)
+ {
+
+ /* Test error! */
+ printf("ERROR #6\n");
+ test_control_return(2);
+ }
+
+ /* Determine if we really got the semaphore. */
+ if (status == TX_SUCCESS)
+ {
+
+ /* Increment the thread count. */
+ thread_0_counter++;
+
+#ifdef TX_NOT_INTERRUPTABLE
+
+ /* Determine if we have a non-interruptable build of ThreadX. If so, just
+ get out of this loop after 100 passes. */
+
+ if (thread_0_counter >= 100)
+ break;
+#endif
+
+ }
+ }
+
+ /* Clear ISR dispatch. */
+ test_isr_dispatch = TX_NULL;
+
+#ifdef TX_NOT_INTERRUPTABLE
+ /* At this point, check to see if we got all the semaphores! */
+ if ((thread_0_counter != (semaphore_put_counter - semaphore_0.tx_semaphore_count)) ||
+ (condition_count != 0))
+#else
+ /* At this point, check to see if we got all the semaphores! */
+ if (thread_0_counter != (semaphore_put_counter - semaphore_0.tx_semaphore_count))
+#endif
+ {
+
+ /* Test error! */
+ printf("ERROR #7\n");
+ test_control_return(3);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ /* Loop forever! */
+ while(1)
+ {
+
+
+ /* Abort the suspension on the semaphore in thread 0. */
+ tx_thread_wait_abort(&thread_0);
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Let thread 0 run again! */
+ tx_thread_relinquish();
+ }
+}
+
+
+static void timer_0_entry(ULONG input)
+{
+ timer_0_counter++;
+}
+
diff --git a/test/tx/regression/threadx_thread_wait_abort_test.c b/test/tx/regression/threadx_thread_wait_abort_test.c
new file mode 100644
index 00000000..a2e8e42d
--- /dev/null
+++ b/test/tx/regression/threadx_thread_wait_abort_test.c
@@ -0,0 +1,138 @@
+/* This test is designed to test thread wait abort. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long thread_1_counter = 0;
+static TX_THREAD thread_1;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_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_thread_wait_abort_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, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Wait Abort Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Thread Wait Abort Test...................................... ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Thread Wait Abort Test...................................... ");
+
+ /* Let other thread run. */
+ tx_thread_resume(&thread_1);
+
+ /* Make sure thread 1 is sleeping. */
+ if (thread_1.tx_thread_state != TX_SLEEP)
+ {
+
+ /* Thread error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* At this point, call tx_thread_wait_abort to abort the sleep in thread1. */
+ status = tx_thread_wait_abort(&thread_1);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_SUSPENDED))
+ {
+
+ /* Thread error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Sleep for a long long time. */
+ status = tx_thread_sleep(1000000000);
+
+ /* Check for the proper status. */
+ if (status != TX_WAIT_ABORTED)
+ {
+
+ /* Thread error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Suspend self. */
+ tx_thread_suspend(&thread_1);
+}
+
diff --git a/test/tx/regression/threadx_time_get_set_test.c b/test/tx/regression/threadx_time_get_set_test.c
new file mode 100644
index 00000000..6bc2ddc1
--- /dev/null
+++ b/test/tx/regression/threadx_time_get_set_test.c
@@ -0,0 +1,107 @@
+/* This test is designed to test simple tx_time_get and set services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+
+/* Prototype for test control return. */
+void test_control_return(UINT status);
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_time_get_set_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Time Simple Get/Set Test.................................... ERROR #1\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+ULONG current_time;
+
+
+ /* Inform user. */
+ printf("Running Time Simple Get/Set Test.................................... ");
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Sleep for 1 tick to get a fresh timer. */
+ tx_thread_sleep(1);
+
+ /* Set time to 0. */
+ tx_time_set(0);
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(35);
+
+ /* Pickup the current time. */
+ current_time = tx_time_get();
+
+ /* Check Current time. It should be 35. */
+ if (current_time != 35)
+ {
+
+ /* System time error. */
+ printf("ERROR #2\n");
+ test_control_return(1);
+ }
+
+ /* Set the new time. */
+ tx_time_set(7);
+
+ /* Check the new time. */
+ if (tx_time_get() != 7)
+ {
+
+ /* System time error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful time test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
diff --git a/test/tx/regression/threadx_timer_activate_deactivate_test.c b/test/tx/regression/threadx_timer_activate_deactivate_test.c
new file mode 100644
index 00000000..a238ea33
--- /dev/null
+++ b/test/tx/regression/threadx_timer_activate_deactivate_test.c
@@ -0,0 +1,268 @@
+/* This test is designed to test application timer activation/deactivation services
+ from threads and the activation routines. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_timer.h"
+
+
+static TX_THREAD thread_0;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+static TX_TIMER_INTERNAL test_timer;
+static TX_TIMER_INTERNAL *list_head;
+static TX_TIMER test_app_timer;
+
+static TX_TIMER timer_2;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_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_timer_activate_deactivate_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Activate/Deactivate Test.............................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 13, 23, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Activate/Deactivate Test.............................. ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
+VOID _tx_timer_system_activate(TX_TIMER_INTERNAL *timer_ptr);
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+TX_TIMER_INTERNAL **current_list_head;
+
+
+ /* Inform user. */
+ printf("Running Timer Activate/Deactivate Test.............................. ");
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+
+ /* Call the timer thread entry function with an invalid value to make sure the code simply returns. */
+ _tx_timer_thread_entry(0);
+#endif
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+
+ tx_thread_resume(&_tx_timer_thread);
+#endif
+
+ /* Call the internal timer activate function with 0 remaining time. */
+ test_timer.tx_timer_internal_remaining_ticks = 0;
+ _tx_timer_system_activate(&test_timer);
+
+ /* Call the internal timer activate function with an existing head pointer. */
+ test_timer.tx_timer_internal_remaining_ticks = 1;
+ list_head = TX_NULL;
+ test_timer.tx_timer_internal_list_head = &list_head;
+ _tx_timer_system_activate(&test_timer);
+
+ /* Call the internal timer deactivate function to ensure the list head is not updated unless valid. */
+ list_head = TX_NULL;
+ test_timer.tx_timer_internal_list_head = &list_head;
+ test_timer.tx_timer_internal_active_next = &test_timer;
+ _tx_timer_system_deactivate(&test_timer);
+
+ /* Call timer info get with a timer setup to exercise a path not possible, in order to exercise all
+ conditionals. */
+ test_app_timer.tx_timer_internal.tx_timer_internal_list_head = (_tx_timer_list_end + 1);
+ status = _tx_timer_info_get(&test_app_timer, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Deactivate and activate the timer. */
+ test_app_timer.tx_timer_internal.tx_timer_internal_active_next = &test_app_timer.tx_timer_internal;
+ status += _tx_timer_deactivate(&test_app_timer);
+
+ /* Change timer with a non-NULL list head, to cause processing to be skipped. */
+ test_app_timer.tx_timer_internal.tx_timer_internal_list_head = (_tx_timer_list_end + 1);
+ status += _tx_timer_change(&test_app_timer, 0, 0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to activate the same timer again. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_ACTIVATE_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for a 14 ticks. */
+ tx_thread_sleep(14);
+
+ /* At this point the initial expiration of the timer should have
+ happened. */
+ if (timer_0_counter != 1)
+ {
+
+ /* Application timer activate/deactivate error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for the reschedule time to make sure the timer doesn't hit
+ again! */
+ tx_thread_sleep(24);
+
+ /* At this point the timer counter should still be 1. */
+ if (timer_0_counter != 1)
+ {
+
+ /* Application timer activate/deactivate error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Clear timer 0's counter. */
+ timer_0_counter = 0;
+
+ /* Activate the timer. This should use the reschedule time. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Test timer that is in the process of expiration - on temporary "expired" list. */
+ TX_MEMSET(&timer_2, 0, (sizeof(TX_TIMER)));
+
+ /* Setup fake timer and test for reactivate condition - current timer. */
+ timer_2.tx_timer_id = TX_TIMER_ID;
+ timer_2.tx_timer_internal.tx_timer_internal_list_head = (TX_TIMER_INTERNAL **) &current_list_head;
+ current_list_head = (struct TX_TIMER_INTERNAL_STRUCT **) &(timer_2.tx_timer_internal);
+ timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = TX_TIMER_ENTRIES*2;
+ timer_2.tx_timer_internal.tx_timer_internal_active_next = &(timer_2.tx_timer_internal);
+ status = tx_timer_deactivate(&timer_2);
+
+ /* Check for error. */
+ if ((status != TX_SUCCESS) || (timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks != TX_TIMER_ENTRIES))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8a\n");
+ test_control_return(1);
+ }
+
+
+ /* Sleep for twice the expiration time to make sure the timer
+ doesn't automatically reschedule. */
+ tx_thread_sleep(47);
+
+ /* Check for an error. */
+
+ /* At this point the timer counter should still be 1. */
+ if (timer_0_counter != 1)
+ {
+
+ /* Application timer activate/deactivate error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Application Timer test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+UINT status;
+
+
+ /* Attempt to sleep from a timer in order to test the error logic. */
+ status = tx_thread_sleep(1);
+
+ /* Check for proper error status. */
+ if (status == TX_CALLER_ERROR)
+ {
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+
+ /* Deactivate the timer from the expiration routine. */
+ tx_timer_deactivate(&timer_0);
+ }
+}
+
+
diff --git a/test/tx/regression/threadx_timer_deactivate_accuracy_test.c b/test/tx/regression/threadx_timer_deactivate_accuracy_test.c
new file mode 100644
index 00000000..6af4bde4
--- /dev/null
+++ b/test/tx/regression/threadx_timer_deactivate_accuracy_test.c
@@ -0,0 +1,286 @@
+/* This test is designed to test application timer activation/deactivation services
+ from threads... Make sure the remaining ticks are being saved/restored properly. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long expected_time;
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_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_timer_deactivate_accuracy_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Activation/Deactivation Accuracy Test................. ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 29, 31, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Activation/Deactivation Accuracy Test................. ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Timer Activation/Deactivation Accuracy Test................. ");
+
+ /* Sleep so we have to handle the wrap condition. */
+ tx_thread_sleep(10);
+
+ /* Activate the timer. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(2);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(3);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(4);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(5);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(6);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(7);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) || (timer_0_counter))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(2);
+
+ /* At this point the timer should have ran! */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) || (timer_0_counter != 1))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful Re-activate test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+}
+
diff --git a/test/tx/regression/threadx_timer_information_test.c b/test/tx/regression/threadx_timer_information_test.c
new file mode 100644
index 00000000..4dbc3c9b
--- /dev/null
+++ b/test/tx/regression/threadx_timer_information_test.c
@@ -0,0 +1,538 @@
+/* This test is designed to test timer information services. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_timer.h"
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+static unsigned long timer_1_counter = 0;
+static TX_TIMER timer_1;
+
+
+static TX_TIMER timer_2;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_input);
+static void timer_1_expiration(ULONG timer_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_timer_information_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Information Test...................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Information Test...................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234,
+ 1000, 1000, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Information Test...................................... ERROR #3\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+UINT interrupt_status;
+CHAR *name;
+UINT active;
+ULONG remaining_ticks;
+ULONG reschedule_ticks;
+TX_TIMER *next_timer;
+ULONG activates;
+ULONG reactivates;
+ULONG deactivates;
+ULONG expirations;
+ULONG expiration_adjusts;
+TX_TIMER_INTERNAL **list_head;
+
+
+ /* Inform user. */
+ printf("Running Timer Information Test...................................... ");
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(19);
+
+ /* Check for an error. */
+ if (timer_0_counter != 2)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ /* Deactivate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Sleep again. */
+ tx_thread_sleep(19);
+
+ /* Check for an error. */
+ if (timer_0_counter != 2)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Modify the timer. */
+ status = tx_timer_change(&timer_0, 100, 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Clear the system time. */
+ tx_time_set(0);
+
+ /* Activate the timer. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for 120. */
+ tx_thread_sleep(120);
+
+ /* Check the counters to make sure everything is where it should be. */
+ if ((timer_0_counter != 23) || (tx_time_get() != 120))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Get the timer information. */
+ status = tx_timer_info_get(&timer_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &next_timer);
+ status += tx_timer_info_get(&timer_0, &name, &active, &remaining_ticks, &reschedule_ticks, &next_timer);
+
+ /* Check for successful completion. */
+ if ((status != TX_SUCCESS) || (active != TX_TRUE) || (remaining_ticks != 1) || (reschedule_ticks != 1) || (next_timer != &timer_1))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Now, deactivate timer 0 to get another path through the info get service. */
+ status = tx_timer_deactivate(&timer_0);
+ status += tx_timer_info_get(&timer_0, &name, &active, &remaining_ticks, &reschedule_ticks, &next_timer);
+
+ /* Check for successful completion. */
+ if ((status != TX_SUCCESS) || (active != TX_FALSE) || (remaining_ticks != 1) || (reschedule_ticks != 1) || (next_timer != &timer_1))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Change timer 0 to a large value and get the information again. */
+ status = tx_timer_change(&timer_0, 100, 200);
+ status += tx_timer_activate(&timer_0);
+
+ status += tx_timer_info_get(&timer_0, &name, &active, &remaining_ticks, &reschedule_ticks, &next_timer);
+
+ /* Check for successful completion. */
+ if ((status != TX_SUCCESS) || (active != TX_TRUE) || (remaining_ticks != 100) || (reschedule_ticks != 200) || (next_timer != &timer_1))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+#ifdef TX_TIMER_ENABLE_PERFORMANCE_INFO
+
+ /* Check for NULL pointer. */
+ status = _tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_PTR_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(&timer_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_timer_performance_info_get(&timer_0, &activates, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for successful completion. */
+ if ((status != TX_SUCCESS) || (activates != timer_0.tx_timer_performance_activate_count) || (reactivates != timer_0.tx_timer_performance_reactivate_count) ||
+ (deactivates != timer_0.tx_timer_performance_deactivate_count) || (expirations != timer_0.tx_timer_performance_expiration_count) || (expiration_adjusts != timer_0.tx_timer_performance__expiration_adjust_count))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+ status += tx_timer_performance_system_info_get(&activates, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for successful completion. */
+ if ((status != TX_SUCCESS) || (activates != _tx_timer_performance_activate_count) || (reactivates != _tx_timer_performance_reactivate_count) ||
+ (deactivates != _tx_timer_performance_deactivate_count) || (expirations != _tx_timer_performance_expiration_count) || (expiration_adjusts != _tx_timer_performance__expiration_adjust_count))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+#else
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(&timer_0, &activates, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(TX_NULL, &activates, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(TX_NULL, TX_NULL, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Now get the performance information. */
+ status = tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(&activates, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(TX_NULL, &reactivates, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, &deactivates, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &expirations, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &expiration_adjusts);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Now get the system performance information. */
+ status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check for error. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Test timer that is in the process of expiration - on temporary "expired" list. */
+ TX_MEMSET(&timer_2, 0, (sizeof(TX_TIMER)));
+
+ /* Setup fake timer and test for no-reactivate condition. */
+ timer_2.tx_timer_id = TX_TIMER_ID;
+ timer_2.tx_timer_internal.tx_timer_internal_list_head = (TX_TIMER_INTERNAL **) &list_head;
+ list_head = (struct TX_TIMER_INTERNAL_STRUCT **) &(timer_2.tx_timer_internal);
+ timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = 10;
+ status = tx_timer_info_get(&timer_2, TX_NULL, TX_NULL, &remaining_ticks, &reschedule_ticks, TX_NULL);
+
+ /* Check for error. */
+ if ((status != TX_SUCCESS) || (remaining_ticks != 0) || (reschedule_ticks != 0))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #28a\n");
+ test_control_return(1);
+ }
+
+ /* Setup fake timer and test for reactivate condition - on temporary "expired" list. */
+ timer_2.tx_timer_id = TX_TIMER_ID;
+ timer_2.tx_timer_internal.tx_timer_internal_list_head = (TX_TIMER_INTERNAL **) &list_head;
+ list_head = (struct TX_TIMER_INTERNAL_STRUCT **) &(timer_2.tx_timer_internal);
+ timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = TX_TIMER_ENTRIES * 2;
+ status = tx_timer_info_get(&timer_2, TX_NULL, TX_NULL, &remaining_ticks, &reschedule_ticks, TX_NULL);
+
+ /* Check for error. */
+ if ((status != TX_SUCCESS) || (remaining_ticks != TX_TIMER_ENTRIES) || (reschedule_ticks != 0))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #28a\n");
+ test_control_return(1);
+ }
+
+
+ /* Lockout interrupts. */
+ interrupt_status = tx_interrupt_control(TX_INT_DISABLE);
+
+ /* Setup fake timer and test for reactivate condition - current timer. */
+ timer_2.tx_timer_id = TX_TIMER_ID;
+ timer_2.tx_timer_internal.tx_timer_internal_list_head = (TX_TIMER_INTERNAL **) &list_head;
+ list_head = (struct TX_TIMER_INTERNAL_STRUCT **) &(timer_2.tx_timer_internal);
+ timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = 13;
+ _tx_timer_expired_timer_ptr = &timer_2.tx_timer_internal;
+ status = tx_timer_info_get(&timer_2, TX_NULL, TX_NULL, &remaining_ticks, &reschedule_ticks, TX_NULL);
+ _tx_timer_expired_timer_ptr = TX_NULL;
+
+ /* Restore interrupts. */
+ tx_interrupt_control(interrupt_status);
+
+ /* Check for error. */
+ if ((status != TX_SUCCESS) || (remaining_ticks != 0) || (reschedule_ticks != 0))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #28b\n");
+ test_control_return(1);
+ }
+
+
+ /* Delete the timer... that are currently active and on the same expiration
+ list! */
+ status = tx_timer_deactivate(&timer_0);
+ status += tx_timer_deactivate(&timer_1);
+ status += tx_timer_change(&timer_0, 100, 200);
+ status += tx_timer_change(&timer_1, 100, 200);
+ status += tx_timer_activate(&timer_0);
+ status += tx_timer_activate(&timer_1);
+ status += tx_timer_delete(&timer_0);
+ status += tx_timer_delete(&timer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful Multiple Sleep test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+}
+
+
+static void timer_1_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_1_counter++;
+}
diff --git a/test/tx/regression/threadx_timer_large_timer_accuracy_test.c b/test/tx/regression/threadx_timer_large_timer_accuracy_test.c
new file mode 100644
index 00000000..dde97fe4
--- /dev/null
+++ b/test/tx/regression/threadx_timer_large_timer_accuracy_test.c
@@ -0,0 +1,286 @@
+/* This test is designed to test application timer activation/deactivation services
+ from threads... To make sure large timer expirations are being saved/restored properly. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long expected_time;
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_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_timer_large_timer_accuracy_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Large Timer Activate Accuracy Test.................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 100, 31, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Large Timer Activate Accuracy Test.................... ERROR #2\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Timer Large Timer Activate Accuracy Test.................... ");
+
+ /* Sleep so we have to handle the wrap condition. */
+ tx_thread_sleep(10);
+
+ /* Activate the timer. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #3\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(20);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(35);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(2);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(1);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(2);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(5);
+
+ /* Deactivate and activate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) || (timer_0_counter))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Sleep */
+ tx_thread_sleep(35);
+
+ /* At this point the timer should have ran! */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) || (timer_0_counter != 1))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful Re-activate test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+}
+
diff --git a/test/tx/regression/threadx_timer_multiple_accuracy_test.c b/test/tx/regression/threadx_timer_multiple_accuracy_test.c
new file mode 100644
index 00000000..a7be91e2
--- /dev/null
+++ b/test/tx/regression/threadx_timer_multiple_accuracy_test.c
@@ -0,0 +1,186 @@
+/* This test is designed to test the accuracy of three free running timers. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+//static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+static unsigned long timer_1_counter = 0;
+static TX_TIMER timer_1;
+static unsigned long timer_2_counter = 0;
+static TX_TIMER timer_2;
+
+
+/* Define prototypes. */
+static void thread_0_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_input);
+static void timer_1_expiration(ULONG timer_input);
+static void timer_2_expiration(ULONG timer_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_timer_multiple_accuracy_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Accuracy Test.......................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 1, 1, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Accuracy Test.......................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234,
+ 2, 2, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Accuracy Test.......................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_2, "timer 2", timer_2_expiration, 0x1234,
+ 3, 3, TX_NO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Accuracy Test.......................... ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Timer Multiple Timer Accuracy Test.......................... ");
+
+ /* Sleep to get a fresh timer. */
+ tx_thread_sleep(1);
+
+ /* Activate all the timers. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_1);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for a some ticks. */
+ tx_thread_sleep(300);
+
+ /* Insure that each timer ran twice. */
+ if ((timer_0_counter != 300) || (timer_1_counter != 150) ||
+ (timer_2_counter != 100))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful timer test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+}
+
+static void timer_1_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_1_counter++;
+}
+
+static void timer_2_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_2_counter++;
+}
+
diff --git a/test/tx/regression/threadx_timer_multiple_test.c b/test/tx/regression/threadx_timer_multiple_test.c
new file mode 100644
index 00000000..3f02d5a7
--- /dev/null
+++ b/test/tx/regression/threadx_timer_multiple_test.c
@@ -0,0 +1,349 @@
+/* This test is designed to test a simple application timer services,
+ including create, activate, deactivate, change, and delete with multiple timers. */
+
+#include <stdio.h>
+#include "tx_api.h"
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+static unsigned long timer_1_counter = 0;
+static TX_TIMER timer_1;
+static unsigned long timer_2_counter = 0;
+static TX_TIMER timer_2;
+
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_input);
+static void timer_1_expiration(ULONG timer_input);
+static void timer_2_expiration(ULONG timer_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_timer_multiple_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Test................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 100, 200, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Test................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234,
+ 100, 200, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Test................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_2, "timer 2", timer_2_expiration, 0x1234,
+ 100, 200, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Multiple Timer Test................................... ERROR #4\n");
+ test_control_return(1);
+ }
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+ /* Inform user. */
+ printf("Running Timer Multiple Timer Test................................... ");
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(301);
+
+ /* Insure that each timer ran twice. */
+ if ((timer_0_counter != 2) || (timer_1_counter != 2) ||
+ (timer_2_counter != 2))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Deactivate the timers. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_deactivate(&timer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_deactivate(&timer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Sleep again. */
+ tx_thread_sleep(100);
+
+ /* Insure that each timer haven't run again. */
+ if ((timer_0_counter != 2) || (timer_1_counter != 2) ||
+ (timer_2_counter != 2))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Modify the timer. */
+ status = tx_timer_change(&timer_0, 100, 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_change(&timer_1, 100, 2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_change(&timer_2, 100, 3);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Activate the timer. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_activate(&timer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for 200. */
+ tx_thread_sleep(200);
+
+ /* Insure that each timer haven't run again. */
+ if ((timer_0_counter != 103) || (timer_1_counter != 53) ||
+ (timer_2_counter != 36))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Deactivate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_deactivate(&timer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_deactivate(&timer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Delete the timer. */
+ status = tx_timer_delete(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_delete(&timer_2);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_delete(&timer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Successful Multiple timer test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+}
+
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+}
+
+static void timer_1_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_1_counter++;
+}
+
+static void timer_2_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_2_counter++;
+}
+
diff --git a/test/tx/regression/threadx_timer_simple_test.c b/test/tx/regression/threadx_timer_simple_test.c
new file mode 100644
index 00000000..3df62caa
--- /dev/null
+++ b/test/tx/regression/threadx_timer_simple_test.c
@@ -0,0 +1,664 @@
+/* This test is designed to test a simple application timer services, including create,
+ activate, deactivate, change, and delete. */
+
+#include <stdio.h>
+#include "tx_api.h"
+#include "tx_timer.h"
+
+typedef struct TIMER_MEMORY_TEST_STRUCT
+{
+ ULONG first;
+ ULONG second;
+ TX_TIMER timer;
+ ULONG next_to_last;
+ ULONG last;
+
+} TIMER_MEMORY_TEST;
+
+static TIMER_MEMORY_TEST timer_memory;
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+
+/* Define external reference to status from timer create during initialization. */
+
+extern UINT test_timer_create_init;
+
+
+static unsigned long thread_0_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+
+static unsigned long timer_0_counter = 0;
+static TX_TIMER timer_0;
+
+static unsigned long timer_1_counter = 0;
+static TX_TIMER timer_1;
+
+static TX_TIMER timer_2;
+static TX_TIMER timer_3;
+
+static unsigned long error = 0;
+static unsigned long timer_executed = 0;
+static unsigned long isr_executed = 0;
+
+/* Define thread prototypes. */
+
+static void thread_0_entry(ULONG thread_input);
+static void thread_1_entry(ULONG thread_input);
+static void timer_0_expiration(ULONG timer_input);
+static void timer_1_expiration(ULONG timer_input);
+
+UINT _txe_timer_create(TX_TIMER *timer_ptr, CHAR *name_ptr,
+ VOID (*expiration_function)(ULONG), ULONG expiration_input,
+ ULONG initial_ticks, ULONG reschedule_ticks, UINT auto_activate, UINT timer_control_block_size);
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+
+
+ /* Determine if the timer was able to be created durning initialization. */
+ if (test_timer_create_init != TX_SUCCESS)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to delete a timer from a timer. */
+ status = tx_timer_delete(&timer_0);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a timer from a timer. */
+ status = tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+ /* Just to test another path, set this timer expired variable. */
+ if (timer_executed == 0)
+ _tx_timer_expired = 1;
+#endif
+
+ timer_executed = 1;
+#endif
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+UINT status;
+
+ /* Attempt to delete a timer from an ISR. */
+ status = tx_timer_delete(&timer_0);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ /* Attempt to create a timer from an ISR. */
+ status = tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE);
+
+ /* Check status. */
+ if (status != TX_CALLER_ERROR)
+ {
+
+ /* Error! */
+ error++;
+ }
+
+ isr_executed = 1;
+#endif
+}
+
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_timer_simple_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, 3, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 18, 18, 3, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Simple Test........................................... ERROR #1\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Simple Test........................................... ERROR #2\n");
+ test_control_return(1);
+ }
+
+ status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234,
+ 1000, 1000, TX_AUTO_ACTIVATE);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Timer Simple Test........................................... ERROR #3\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+
+ /* Call the timer thread entry function with a bad ID to test another path. */
+ _tx_timer_thread_entry(0);
+#endif
+
+}
+
+
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* Inform user. */
+ printf("Running Timer Simple Test........................................... ");
+
+ /* Perform timer memory test. */
+ timer_memory.first = 0x11223344;
+ timer_memory.second = 0x55667788;
+ timer_memory.next_to_last = 0x99aabbcc;
+ timer_memory.last = 0xddeeff00;
+
+ /* Create the timer. */
+ status = tx_timer_create(&timer_memory.timer, "timer memory", timer_0_expiration, 0x1234,
+ 1000000, 100000, TX_NO_ACTIVATE);
+ tx_timer_delete(&timer_memory.timer);
+
+ /* Check for status. */
+ if ((status != TX_SUCCESS) ||
+ (timer_memory.first != 0x11223344) ||
+ (timer_memory.second != 0x55667788) ||
+ (timer_memory.next_to_last != 0x99aabbcc) ||
+ (timer_memory.last != 0xddeeff00))
+ {
+
+ /* Memory overwrite error. */
+ printf("ERROR #4\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Attempt to activate a non-timer. */
+ status = tx_timer_activate(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #5\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to activate a non-created timer. */
+ timer_2.tx_timer_id = 0;
+ status = tx_timer_activate(&timer_2);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to activate a timer with a 0 expiration. */
+ timer_2.tx_timer_id = ((ULONG) 0x4154494D);
+ timer_2.tx_timer_internal.tx_timer_internal_list_head = TX_NULL;
+ timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = 0;
+ status = tx_timer_activate(&timer_2);
+
+ /* Check status. */
+ if (status != TX_ACTIVATE_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+
+ /* Attempt to activate a timer with a wait forever expiration. */
+ timer_2.tx_timer_id = ((ULONG) 0x4154494D);
+ timer_2.tx_timer_internal.tx_timer_internal_list_head = TX_NULL;
+ timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = TX_WAIT_FOREVER;
+ status = tx_timer_activate(&timer_2);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ timer_2.tx_timer_id = 0;
+
+ /* Attempt to deactivate a non-timer. */
+ status = tx_timer_deactivate(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to deactivate a non-created timer. */
+ timer_2.tx_timer_id = 0;
+ status = tx_timer_deactivate(&timer_2);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change a non-timer. */
+ status = tx_timer_change(TX_NULL, 1, 1);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change a non-created timer. */
+ timer_2.tx_timer_id = 0;
+ status = tx_timer_change(&timer_2, 1, 1);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to change a timer with a 0 initial ticks. */
+ status = tx_timer_change(&timer_0, 0, 1);
+
+ /* Check status. */
+ if (status != TX_TICK_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-time. */
+ status = tx_timer_delete(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to delete a non-created time. */
+ timer_2.tx_timer_id = 0;
+ status = tx_timer_delete(&timer_2);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get info from a non-timer. */
+ status = tx_timer_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to get info from a non-created timer. */
+ timer_2.tx_timer_id = 0;
+ status = tx_timer_info_get(&timer_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a timer with a NULL pointer. */
+ status = tx_timer_create(TX_NULL, "timer 0", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a timer with a bad control block size. */
+ status = _txe_timer_create(&timer_3, "timer 3", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE, (sizeof(TX_TIMER)+1));
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a timer that has already been created. */
+ status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE);
+
+ /* Check status. */
+ if (status != TX_TIMER_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a timer with an invalid number of initial ticks. */
+ status = tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234,
+ 0, 18, TX_AUTO_ACTIVATE);
+
+ /* Check status. */
+ if (status != TX_TICK_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to create a timer with an invalid activation. */
+ status = tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234,
+ 1, 18, TX_AUTO_ACTIVATE+3999);
+
+ /* Check status. */
+ if (status != TX_ACTIVATE_ERROR)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Sleep for a couple ticks. */
+ tx_thread_sleep(19);
+
+ /* Check for an error. */
+ if (timer_0_counter != 2)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Deactivate the timer. */
+ status = tx_timer_deactivate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Sleep again. */
+ tx_thread_sleep(19);
+
+ /* Check for an error. */
+ if (timer_0_counter != 2)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Modify the timer. */
+ status = tx_timer_change(&timer_0, 100, 1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ /* Clear the system time. */
+ tx_time_set(0);
+
+ /* Activate the timer. */
+ status = tx_timer_activate(&timer_0);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+
+ /* Sleep for 120. */
+ tx_thread_sleep(120);
+
+ /* Check the counters to make sure everything is where it should be. */
+ if ((timer_0_counter != 23) || (tx_time_get() != 120))
+ {
+
+ /* Application timer error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Delete the timer... that are currently active and on the same expiration
+ list! */
+ status = tx_timer_deactivate(&timer_0);
+ status += tx_timer_deactivate(&timer_1);
+ status += tx_timer_change(&timer_0, 100, 100);
+ status += tx_timer_change(&timer_1, 100, 100);
+ status += tx_timer_activate(&timer_0);
+ status += tx_timer_activate(&timer_1);
+ status += tx_timer_delete(&timer_0);
+ status += tx_timer_delete(&timer_1);
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Application timer error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+
+#ifndef TX_DISABLE_ERROR_CHECKING
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Resume thread 1 to take an interrupt on top of it. */
+ tx_thread_resume(&thread_1);
+
+ /* Sleep for a bit... */
+ tx_thread_sleep(3);
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Test for error. */
+ if ((error) || (timer_executed != 1) || (isr_executed != 1))
+ {
+
+ /* Thread error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ if (error)
+ {
+
+ /* Thread error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful Multiple Sleep test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+static void thread_1_entry(ULONG thread_input)
+{
+
+ while(1)
+ {
+
+ tx_thread_relinquish();
+ }
+}
+
+static void timer_0_expiration(ULONG timer_input)
+{
+
+
+ /* Process timer expiration. */
+ timer_0_counter++;
+}
+
+
+static void timer_1_expiration(ULONG timer_input)
+{
+
+ /* Process timer expiration. */
+ timer_1_counter++;
+}
diff --git a/test/tx/regression/threadx_trace_basic_test.c b/test/tx/regression/threadx_trace_basic_test.c
new file mode 100644
index 00000000..bd6ca72f
--- /dev/null
+++ b/test/tx/regression/threadx_trace_basic_test.c
@@ -0,0 +1,779 @@
+/* This test is designed to test trace functionality in ThreadX. */
+
+
+#include <stdio.h>
+#include "tx_api.h"
+#define TX_SOURCE_CODE
+#include "tx_trace.h"
+
+
+/* Define the ISR dispatch. */
+
+extern VOID (*test_isr_dispatch)(void);
+
+extern UINT _tx_trace_interrupt_control(UINT new_posture);
+extern VOID _tx_trace_object_register(UCHAR object_type, VOID *object_ptr, CHAR *object_name, ULONG parameter_1, ULONG parameter_2);
+extern VOID _tx_trace_object_unregister(VOID *object_ptr);
+
+static unsigned long thread_0_counter = 0;
+static unsigned long thread_1_counter = 0;
+static unsigned long thread_2_counter = 0;
+static TX_THREAD thread_0;
+static TX_THREAD thread_1;
+static TX_THREAD thread_2;
+
+static TX_TIMER timer_0;
+
+static TX_BLOCK_POOL block_pool_0;
+static TX_BYTE_POOL byte_pool_0;
+static TX_EVENT_FLAGS_GROUP group_0;
+static TX_MUTEX mutex_0;
+static TX_QUEUE queue_0;
+static TX_SEMAPHORE semaphore_0;
+
+/* Define a bunch of semaphores for loading up the trace buffer. */
+
+static TX_SEMAPHORE semaphore_1;
+static TX_SEMAPHORE semaphore_2;
+static TX_SEMAPHORE semaphore_3;
+static TX_SEMAPHORE semaphore_4;
+static TX_SEMAPHORE semaphore_5;
+static TX_SEMAPHORE semaphore_6;
+static TX_SEMAPHORE semaphore_7;
+static TX_SEMAPHORE semaphore_8;
+static TX_SEMAPHORE semaphore_9;
+static TX_SEMAPHORE semaphore_10;
+static TX_SEMAPHORE semaphore_11;
+static TX_SEMAPHORE semaphore_12;
+static TX_SEMAPHORE semaphore_13;
+static TX_SEMAPHORE semaphore_14;
+static TX_SEMAPHORE semaphore_15;
+static TX_SEMAPHORE semaphore_16;
+
+
+static unsigned long error = 0;
+static unsigned long full_buffer = 0;
+static void *save_pointer;
+
+#if defined(TX_WIN32_MEMORY_SIZE) || defined(TX_LINUX_MEMORY_SIZE)
+
+static FILE *trace_dump_file;
+static CHAR trace_dump_file_name[]= "tracedump000.trx";
+
+#endif
+
+
+/* Define task prototypes. */
+
+static void thread_0_entry(ULONG task_input);
+static void thread_1_entry(ULONG task_input);
+static void thread_2_entry(ULONG task_input);
+
+
+/* Define the trace buffer. */
+UCHAR trace_buffer[16384];
+
+
+
+/* Prototype for test control return. */
+
+void test_control_return(UINT status);
+UINT _tx_thread_interrupt_control(UINT new_posture);
+
+
+void trace_dump(void)
+{
+
+#if defined(TX_WIN32_MEMORY_SIZE) || defined(TX_LINUX_MEMORY_SIZE)
+
+/* Win32 automatic dump! */
+UINT old_interrupt;
+
+
+ /* Disable interrupts. */
+ old_interrupt = _tx_thread_interrupt_control(TX_INT_DISABLE);
+
+ /* If win32, we can actually dump the file! */
+ trace_dump_file = fopen(trace_dump_file_name, "wb+");
+
+ fwrite(trace_buffer, 1, sizeof(trace_buffer), trace_dump_file);
+
+ fclose(trace_dump_file);
+
+ /* Restore interrupts. */
+ _tx_thread_interrupt_control(old_interrupt);
+
+ /* Prepare for next file dump. */
+ trace_dump_file_name[11]++;
+ if (trace_dump_file_name[11] > '9')
+ {
+ trace_dump_file_name[11] = '0';
+ trace_dump_file_name[10]++;
+
+ if (trace_dump_file_name[10] > '9')
+ {
+ trace_dump_file_name[10] = '0';
+ trace_dump_file_name[9]++;
+
+ if (trace_dump_file_name[9] > '9')
+ trace_dump_file_name[9] = '0';
+ }
+ }
+
+#endif
+
+}
+
+
+/* Define the timer for this test. */
+
+static void timer_entry(ULONG i)
+{
+
+ /* Resume thread 1. */
+ tx_thread_resume(&thread_1);
+}
+
+/* Define the ISR dispatch routine. */
+
+static void test_isr(void)
+{
+
+ /* Make ISR entry event. */
+ tx_trace_isr_enter_insert(1);
+
+ /* Resume thread 2. */
+ tx_thread_resume(&thread_2);
+
+ /* Make ISR entry event. */
+ tx_trace_isr_exit_insert(1);
+}
+
+
+/* Define the trace buffer full notify function. */
+
+static VOID trace_buffer_full(void *ptr)
+{
+
+ /* Dump trace file! */
+ trace_dump();
+
+ full_buffer++;
+}
+
+/* Define what the initial system looks like. */
+
+#ifdef CTEST
+void test_application_define(void *first_unused_memory)
+#else
+void threadx_trace_basic_application_define(void *first_unused_memory)
+#endif
+{
+
+INT status;
+CHAR *pointer;
+
+
+ /* Setup a pointer. */
+ pointer = (CHAR *) first_unused_memory;
+
+ /* Adjust it forward just to make sure there is some space for the test below. */
+ pointer = pointer + 200;
+
+ /* Create a bunch of objects before being enabled. */
+
+ /* Create a timer for the test. */
+ save_pointer = (void *) pointer;
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 2, 2, TX_AUTO_ACTIVATE);
+ tx_block_pool_create(&block_pool_0, "block pool 0", 20, pointer, 100);
+ pointer = pointer + 100;
+ tx_byte_pool_create(&byte_pool_0, "byte pool 0", pointer, 1000);
+ pointer = pointer + 1000;
+ tx_event_flags_create(&group_0, "event flags group 0");
+ tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+ tx_queue_create(&queue_0, "queue 0", 16, pointer, 400);
+ pointer = pointer + 400;
+ tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
+
+ /* Enable event tracing. */
+ _tx_trace_initialize();
+ status = tx_trace_enable(trace_buffer, sizeof(trace_buffer), 16);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Trace Basic Test............................................ ERROR #1\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("Running Trace Basic Test............................................ ERROR #2\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* 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, 0,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Trace Basic Test............................................ ERROR #3\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Trace Basic Test............................................ ERROR #4\n");
+ test_control_return(1);
+ }
+
+ status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, TEST_STACK_SIZE_PRINTF,
+ 14, 14, TX_NO_TIME_SLICE, TX_DONT_START);
+ pointer = pointer + TEST_STACK_SIZE_PRINTF;
+
+ /* Check for status. */
+ if (status != TX_SUCCESS)
+ {
+
+ printf("Running Trace Basic Test............................................ ERROR #5\n");
+ test_control_return(1);
+ }
+}
+
+/* Define the test threads. */
+
+static void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+UINT old_interrupt;
+CHAR *pointer;
+TX_INTERRUPT_SAVE_AREA
+ULONG object;
+
+ /* Coverage for build without TraceX enabled. */
+ tx_saved_posture = _tx_trace_interrupt_control(TX_INT_DISABLE);
+ _tx_trace_interrupt_control(tx_saved_posture);
+#ifndef TX_ENABLE_EVENT_TRACE
+ _tx_trace_object_register(0, TX_NULL, TX_NULL, 0, 0);
+ _tx_trace_object_register(1, TX_NULL, TX_NULL, 0, 0);
+ _tx_trace_object_register(1, &object, TX_NULL, 0, 0);
+ _tx_trace_object_register(1, &object, "fake name", 0, 0);
+ _tx_trace_object_register(1, &object, "fake name", 1, 0);
+#endif
+ _tx_trace_object_register(1, &object, "fake name", 1, 1);
+ _tx_trace_object_unregister(TX_NULL);
+ _tx_trace_object_unregister(&object);
+
+ /* Increment thread 0 counter. */
+ thread_0_counter++;
+
+ /* Inform user of success getting to this test. */
+ printf("Running Trace Basic Test............................................ ");
+
+ /* Delete the additional objects. */
+ tx_timer_delete(&timer_0);
+ tx_block_pool_delete(&block_pool_0);
+ tx_byte_pool_delete(&byte_pool_0);
+ tx_event_flags_delete(&group_0);
+ tx_mutex_delete(&mutex_0);
+ tx_queue_delete(&queue_0);
+ tx_semaphore_delete(&semaphore_0);
+
+ /* Create all the semaphores. */
+ tx_semaphore_create(&semaphore_1, "semaphore 1", 1);
+ tx_semaphore_create(&semaphore_2, "semaphore 2", 1);
+ tx_semaphore_create(&semaphore_3, "semaphore 3", 1);
+ tx_semaphore_create(&semaphore_4, "semaphore 4", 1);
+ tx_semaphore_create(&semaphore_5, "semaphore 5", 1);
+ tx_semaphore_create(&semaphore_6, "semaphore 6", 1);
+ tx_semaphore_create(&semaphore_7, "semaphore 7", 1);
+ tx_semaphore_create(&semaphore_8, "semaphore 8", 1);
+ tx_semaphore_create(&semaphore_9, "semaphore 9", 1);
+ tx_semaphore_create(&semaphore_10, "semaphore 10", 1);
+ tx_semaphore_create(&semaphore_11, "semaphore 11", 1);
+ tx_semaphore_create(&semaphore_12, "semaphore 12", 1);
+ tx_semaphore_create(&semaphore_13, "semaphore 13", 1);
+ tx_semaphore_create(&semaphore_14, "semaphore 14", 1);
+ tx_semaphore_create(&semaphore_15, "semaphore 15", 1);
+ tx_semaphore_create(&semaphore_16, "semaphore 16", 1);
+
+ /* Delete them all. */
+ tx_semaphore_delete(&semaphore_1);
+ tx_semaphore_delete(&semaphore_2);
+ tx_semaphore_delete(&semaphore_3);
+ tx_semaphore_delete(&semaphore_4);
+ tx_semaphore_delete(&semaphore_5);
+ tx_semaphore_delete(&semaphore_6);
+ tx_semaphore_delete(&semaphore_7);
+ tx_semaphore_delete(&semaphore_8);
+ tx_semaphore_delete(&semaphore_9);
+ tx_semaphore_delete(&semaphore_10);
+ tx_semaphore_delete(&semaphore_11);
+ tx_semaphore_delete(&semaphore_12);
+ tx_semaphore_delete(&semaphore_13);
+ tx_semaphore_delete(&semaphore_14);
+ tx_semaphore_delete(&semaphore_15);
+ tx_semaphore_delete(&semaphore_16);
+
+ /* Create one over again. */
+ tx_semaphore_create(&semaphore_1, "semaphore 1", 1);
+
+ /* Now, create them all again. */
+ pointer = (CHAR *) save_pointer;
+ tx_block_pool_create(&block_pool_0, "block pool 0", 20, pointer, 100);
+ pointer = pointer + 100;
+ tx_byte_pool_create(&byte_pool_0, "byte pool 0", pointer, 1000);
+ pointer = pointer + 1000;
+ tx_event_flags_create(&group_0, "event flags group 0");
+ tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+ tx_queue_create(&queue_0, "queue 0", 16, pointer, 400);
+ pointer = pointer + 400;
+ tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
+
+ /* Attempt to enable event tracing again. */
+ status = tx_trace_enable(trace_buffer, sizeof(trace_buffer), 8);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_NOT_DONE)
+ {
+
+ printf("ERROR #6\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("ERROR #7\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to enable event tracing again. */
+ status = tx_trace_enable(TX_NULL, 0, 8);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("ERROR #8\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to enable event tracing again. */
+ status = tx_trace_enable(TX_NULL, 1, 0);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("ERROR #9\n");
+ test_control_return(1);
+ }
+
+ /* Attempt to enable event tracing again. */
+ status = tx_trace_enable(TX_NULL, 1, 8);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ printf("ERROR #10\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Filter all events. */
+ status = tx_trace_event_filter(TX_TRACE_ALL_EVENTS);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Trace error. */
+ printf("ERROR #11\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #12\n");
+ test_control_return(1);
+ }
+
+ /* Filter all events. */
+ status = tx_trace_event_filter(0);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #13\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Unfilter all events. */
+ status = tx_trace_event_unfilter(TX_TRACE_ALL_EVENTS);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Trace error. */
+ printf("ERROR #14\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #15\n");
+ test_control_return(1);
+ }
+
+ /* Unfilter all events. */
+ status = tx_trace_event_unfilter(0);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #16\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Register the trace buffer full notification routine. */
+ status = tx_trace_buffer_full_notify(trace_buffer_full);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Trace error. */
+ printf("ERROR #17\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #18\n");
+ test_control_return(1);
+ }
+
+ /* Check the NULL path with trace disabled. */
+ status = tx_trace_buffer_full_notify(TX_NULL);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #19\n");
+ test_control_return(1);
+ }
+
+#endif
+
+ /* Create a timer for the test. */
+ tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 2, 2, TX_AUTO_ACTIVATE);
+
+ /* Setup the ISR. */
+ test_isr_dispatch = test_isr;
+
+ while (full_buffer < 40)
+ {
+
+ if (full_buffer < 20)
+ {
+
+ /* Disable interrupts. */
+ old_interrupt = tx_interrupt_control(TX_INT_DISABLE);
+
+ /* Restore interrupts. */
+ tx_interrupt_control(old_interrupt);
+ }
+
+ /* Insert user event. */
+ status = tx_trace_user_event_insert(1027, 1, 2, 3, 4);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Trace error. */
+ printf("ERROR #20\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #21\n");
+ test_control_return(1);
+ }
+
+ /* Insert user event. */
+ status = tx_trace_user_event_insert(0, 1, 2, 3, 4);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #22\n");
+ test_control_return(1);
+ }
+
+ /* Insert user event. */
+ status = tx_trace_user_event_insert(0, 0, 2, 3, 4);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #23\n");
+ test_control_return(1);
+ }
+
+ /* Insert user event. */
+ status = tx_trace_user_event_insert(0, 0, 0, 3, 4);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #24\n");
+ test_control_return(1);
+ }
+
+ /* Insert user event. */
+ status = tx_trace_user_event_insert(0, 0, 0, 0, 4);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #25\n");
+ test_control_return(1);
+ }
+
+ /* Insert user event. */
+ status = tx_trace_user_event_insert(0, 0, 0, 0, 0);
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #26\n");
+ test_control_return(1);
+ }
+
+ break;
+#endif
+ }
+
+ /* Clear the ISR. */
+ test_isr_dispatch = TX_NULL;
+
+ /* Disable the trace buffer. */
+ status = tx_trace_disable();
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ {
+
+ /* Trace error. */
+ printf("ERROR #27\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #28\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Attempt to disable again, just to get the TX_NOT_DONE error code. */
+ status = tx_trace_disable();
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_NOT_DONE)
+ {
+
+ /* Trace error. */
+ printf("ERROR #29\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #30\n");
+ test_control_return(1);
+ }
+#endif
+
+ /* Attempt to enable event tracing with a bogus size. */
+ status = tx_trace_enable(trace_buffer, 1, 8);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_SIZE_ERROR)
+ {
+
+ /* Trace error. */
+ printf("ERROR #31\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #32\n");
+ test_control_return(1);
+ }
+#endif
+
+
+ /* Attempt to make an user event when tracing is not enabled. */
+ status = tx_trace_user_event_insert(1027, 1, 2, 3, 4);
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+ /* Check status. */
+ if (status != TX_NOT_DONE)
+ {
+
+ /* Trace error. */
+ printf("ERROR #33\n");
+ test_control_return(1);
+ }
+#else
+
+ /* Check status. */
+ if (status != TX_FEATURE_NOT_ENABLED)
+ {
+
+ /* Trace error. */
+ printf("ERROR #34\n");
+ test_control_return(1);
+ }
+#endif
+
+
+ /* Check status. */
+ if (error)
+ {
+
+ /* Trace error. */
+ printf("ERROR #35\n");
+ test_control_return(1);
+ }
+ else
+ {
+
+ /* Successful test. */
+ printf("SUCCESS!\n");
+ test_control_return(0);
+ }
+}
+
+
+static void thread_1_entry(ULONG task_input)
+{
+
+ while(1)
+ {
+
+ thread_1_counter++;
+ tx_thread_suspend(&thread_1);
+ }
+}
+
+
+
+static void thread_2_entry(ULONG task_input)
+{
+
+ while(1)
+ {
+
+ thread_2_counter++;
+ tx_thread_suspend(&thread_2);
+ }
+}