summaryrefslogtreecommitdiff
path: root/test/tx
diff options
context:
space:
mode:
authorTiejunZhou <[email protected]>2023-04-13 16:57:35 +0800
committerGitHub <[email protected]>2023-04-13 16:57:35 +0800
commit487ca45752ba350733f09ebce512c89544e190ec (patch)
treef5d38d89810821bcf049803fd5150b823fd8c664 /test/tx
parentac3b6b326cd7dac0373282c6f557d0d51764e34a (diff)
parent5f430f22e2c00f2c079c91f48c9e2a0fc0bbbf47 (diff)
Merge pull request #244 from azure-rtos/tizho/test
Release ThreadX regression system
Diffstat (limited to 'test/tx')
-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
103 files changed, 36592 insertions, 0 deletions
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);
+ }
+}