From ebeb02b95828ca100c3f24de5f9603a41049f8ff Mon Sep 17 00:00:00 2001 From: Tiejun Zhou Date: Mon, 3 Apr 2023 07:24:52 +0000 Subject: [PATCH 1/2] Release ThreadX regression system --- .devcontainer/devcontainer.json | 4 + scripts/build_smp.sh | 2 + scripts/build_tx.sh | 2 + scripts/cmake_bootstrap.sh | 120 + scripts/test_smp.sh | 3 + scripts/test_tx.sh | 3 + test/.gitignore | 2 + test/smp/cmake/CMakeLists.txt | 76 + test/smp/cmake/coverage.sh | 9 + test/smp/cmake/regression/CMakeLists.txt | 133 + .../cmake/regression/generate_test_file.sh | 10 + test/smp/cmake/run.sh | 1 + test/smp/cmake/samples/CMakeLists.txt | 15 + test/smp/cmake/samples/fake.c | 22 + test/smp/cmake/threadx_smp/CMakeLists.txt | 60 + .../threadx_smp/common_smp/CMakeLists.txt | 220 ++ .../ports_smp/linux/gnu/CMakeLists.txt | 32 + test/smp/regression/testcontrol.c | 1609 +++++++++++ .../threadx_block_memory_basic_test.c | 568 ++++ ...hreadx_block_memory_error_detection_test.c | 387 +++ .../threadx_block_memory_information_test.c | 713 +++++ .../threadx_block_memory_prioritize_test.c | 500 ++++ .../threadx_block_memory_suspension_test.c | 311 ++ ...adx_block_memory_suspension_timeout_test.c | 212 ++ ...readx_block_memory_thread_terminate_test.c | 185 ++ .../threadx_byte_memory_basic_test.c | 1064 +++++++ .../threadx_byte_memory_information_test.c | 784 ++++++ .../threadx_byte_memory_prioritize_test.c | 498 ++++ .../threadx_byte_memory_suspension_test.c | 391 +++ ...eadx_byte_memory_suspension_timeout_test.c | 196 ++ ...readx_byte_memory_thread_contention_test.c | 255 ++ ...hreadx_byte_memory_thread_terminate_test.c | 177 ++ .../threadx_event_flag_basic_test.c | 743 +++++ .../threadx_event_flag_information_test.c | 562 ++++ .../threadx_event_flag_isr_set_clear_test.c | 358 +++ .../threadx_event_flag_isr_wait_abort_test.c | 330 +++ ..._event_flag_single_thread_terminate_test.c | 331 +++ ...readx_event_flag_suspension_consume_test.c | 281 ++ ...g_suspension_different_bits_consume_test.c | 224 ++ ...vent_flag_suspension_different_bits_test.c | 230 ++ .../threadx_event_flag_suspension_test.c | 349 +++ ...readx_event_flag_suspension_timeout_test.c | 266 ++ ...threadx_event_flag_thread_terminate_test.c | 234 ++ .../threadx_initialize_kernel_setup_test.c | 83 + .../threadx_interrupt_control_test.c | 94 + .../smp/regression/threadx_mutex_basic_test.c | 767 +++++ .../regression/threadx_mutex_delete_test.c | 194 ++ .../threadx_mutex_information_test.c | 592 ++++ ...x_mutex_nested_priority_inheritance_test.c | 701 +++++ .../threadx_mutex_no_preemption_test.c | 173 ++ .../threadx_mutex_preemption_test.c | 161 ++ .../threadx_mutex_priority_inheritance_test.c | 607 ++++ .../regression/threadx_mutex_proritize_test.c | 525 ++++ .../threadx_mutex_suspension_timeout_test.c | 474 ++++ .../threadx_mutex_thread_terminate_test.c | 198 ++ .../threadx_queue_basic_eight_word_test.c | 423 +++ .../threadx_queue_basic_four_word_test.c | 423 +++ .../threadx_queue_basic_one_word_test.c | 867 ++++++ .../threadx_queue_basic_sixteen_word_test.c | 423 +++ .../threadx_queue_basic_two_word_test.c | 463 +++ .../threadx_queue_empty_suspension_test.c | 271 ++ .../threadx_queue_flush_no_suspension_test.c | 216 ++ .../smp/regression/threadx_queue_flush_test.c | 249 ++ .../threadx_queue_front_send_test.c | 686 +++++ .../threadx_queue_full_suspension_test.c | 368 +++ .../threadx_queue_information_test.c | 664 +++++ .../smp/regression/threadx_queue_prioritize.c | 534 ++++ .../threadx_queue_suspension_timeout_test.c | 254 ++ .../threadx_queue_thread_terminate_test.c | 183 ++ .../regression/threadx_semaphore_basic_test.c | 545 ++++ .../threadx_semaphore_ceiling_put_test.c | 334 +++ .../threadx_semaphore_delete_test.c | 213 ++ .../threadx_semaphore_information_test.c | 418 +++ .../threadx_semaphore_non_preemption_test.c | 271 ++ .../threadx_semaphore_preemption_test.c | 179 ++ .../regression/threadx_semaphore_prioritize.c | 525 ++++ .../threadx_semaphore_thread_terminate_test.c | 224 ++ .../threadx_semaphore_timeout_test.c | 165 ++ ...readx_smp_multiple_threads_one_core_test.c | 348 +++ .../threadx_smp_non_trivial_scheduling_test.c | 350 +++ ...dx_smp_one_thread_dynamic_exclusion_test.c | 145 + .../threadx_smp_preemption_threshold_test.c | 534 ++++ ..._random_resume_suspend_exclusion_pt_test.c | 2490 +++++++++++++++++ ...smp_random_resume_suspend_exclusion_test.c | 2373 ++++++++++++++++ .../threadx_smp_random_resume_suspend_test.c | 2329 +++++++++++++++ .../threadx_smp_rebalance_exclusion_test.c | 204 ++ .../regression/threadx_smp_relinquish_test.c | 365 +++ ..._smp_resume_suspend_accending_order_test.c | 1428 ++++++++++ ..._smp_resume_suspend_decending_order_test.c | 1427 ++++++++++ .../regression/threadx_smp_time_slice_test.c | 361 +++ .../threadx_smp_two_threads_one_core_test.c | 268 ++ .../threadx_thread_basic_execution_test.c | 863 ++++++ .../threadx_thread_basic_time_slice_test.c | 117 + .../threadx_thread_completed_test.c | 258 ++ ..._thread_create_preemption_threshold_test.c | 140 + .../threadx_thread_delayed_suspension_test.c | 390 +++ .../threadx_thread_information_test.c | 474 ++++ ...ad_multi_level_preemption_threshold_test.c | 982 +++++++ ...threadx_thread_multiple_non_current_test.c | 222 ++ .../threadx_thread_multiple_sleep_test.c | 184 ++ .../threadx_thread_multiple_suspension_test.c | 432 +++ .../threadx_thread_multiple_time_slice_test.c | 269 ++ ...readx_thread_preemptable_suspension_test.c | 416 +++ .../threadx_thread_preemption_change_test.c | 379 +++ .../threadx_thread_priority_change.c | 544 ++++ .../threadx_thread_relinquish_test.c | 459 +++ .../regression/threadx_thread_reset_test.c | 248 ++ ...readx_thread_simple_sleep_non_clear_test.c | 90 + .../threadx_thread_simple_sleep_test.c | 85 + .../threadx_thread_simple_suspend_test.c | 116 + .../threadx_thread_sleep_for_100ticks_test.c | 435 +++ .../threadx_thread_sleep_terminate_test.c | 187 ++ .../threadx_thread_stack_checking_test.c | 224 ++ .../threadx_thread_terminate_delete_test.c | 341 +++ .../threadx_thread_time_slice_change_test.c | 149 + .../threadx_thread_wait_abort_and_isr_test.c | 272 ++ .../threadx_thread_wait_abort_test.c | 138 + .../regression/threadx_time_get_set_test.c | 109 + .../threadx_timer_activate_deactivate_test.c | 268 ++ .../threadx_timer_deactivate_accuracy_test.c | 286 ++ .../threadx_timer_information_test.c | 538 ++++ .../threadx_timer_large_timer_accuracy_test.c | 286 ++ .../threadx_timer_multiple_accuracy_test.c | 186 ++ .../regression/threadx_timer_multiple_test.c | 349 +++ .../regression/threadx_timer_simple_test.c | 830 ++++++ .../smp/regression/threadx_trace_basic_test.c | 824 ++++++ test/tx/cmake/CMakeLists.txt | 73 + test/tx/cmake/coverage.sh | 8 + test/tx/cmake/regression/CMakeLists.txt | 121 + .../tx/cmake/regression/generate_test_file.sh | 10 + test/tx/cmake/run.sh | 1 + test/tx/cmake/samples/CMakeLists.txt | 15 + test/tx/cmake/samples/fake.c | 20 + test/tx/regression/testcontrol.c | 1411 ++++++++++ .../threadx_block_memory_basic_test.c | 568 ++++ ...hreadx_block_memory_error_detection_test.c | 387 +++ .../threadx_block_memory_information_test.c | 713 +++++ .../threadx_block_memory_prioritize_test.c | 500 ++++ .../threadx_block_memory_suspension_test.c | 311 ++ ...adx_block_memory_suspension_timeout_test.c | 212 ++ ...readx_block_memory_thread_terminate_test.c | 185 ++ .../threadx_byte_memory_basic_test.c | 1064 +++++++ .../threadx_byte_memory_information_test.c | 784 ++++++ .../threadx_byte_memory_prioritize_test.c | 498 ++++ .../threadx_byte_memory_suspension_test.c | 391 +++ ...eadx_byte_memory_suspension_timeout_test.c | 196 ++ ...readx_byte_memory_thread_contention_test.c | 255 ++ ...hreadx_byte_memory_thread_terminate_test.c | 177 ++ .../threadx_event_flag_basic_test.c | 743 +++++ .../threadx_event_flag_information_test.c | 562 ++++ .../threadx_event_flag_isr_set_clear_test.c | 359 +++ .../threadx_event_flag_isr_wait_abort_test.c | 331 +++ ..._event_flag_single_thread_terminate_test.c | 331 +++ ...readx_event_flag_suspension_consume_test.c | 281 ++ ...g_suspension_different_bits_consume_test.c | 224 ++ ...vent_flag_suspension_different_bits_test.c | 230 ++ .../threadx_event_flag_suspension_test.c | 349 +++ ...readx_event_flag_suspension_timeout_test.c | 266 ++ ...threadx_event_flag_thread_terminate_test.c | 234 ++ .../threadx_initialize_kernel_setup_test.c | 81 + .../threadx_interrupt_control_test.c | 94 + test/tx/regression/threadx_mutex_basic_test.c | 767 +++++ .../tx/regression/threadx_mutex_delete_test.c | 194 ++ .../threadx_mutex_information_test.c | 592 ++++ ...x_mutex_nested_priority_inheritance_test.c | 701 +++++ .../threadx_mutex_no_preemption_test.c | 173 ++ .../threadx_mutex_preemption_test.c | 161 ++ .../threadx_mutex_priority_inheritance_test.c | 573 ++++ .../regression/threadx_mutex_proritize_test.c | 525 ++++ .../threadx_mutex_suspension_timeout_test.c | 319 +++ .../threadx_mutex_thread_terminate_test.c | 198 ++ .../threadx_queue_basic_eight_word_test.c | 423 +++ .../threadx_queue_basic_four_word_test.c | 423 +++ .../threadx_queue_basic_one_word_test.c | 867 ++++++ .../threadx_queue_basic_sixteen_word_test.c | 423 +++ .../threadx_queue_basic_two_word_test.c | 463 +++ .../threadx_queue_empty_suspension_test.c | 271 ++ .../threadx_queue_flush_no_suspension_test.c | 216 ++ test/tx/regression/threadx_queue_flush_test.c | 249 ++ .../threadx_queue_front_send_test.c | 686 +++++ .../threadx_queue_full_suspension_test.c | 368 +++ .../threadx_queue_information_test.c | 664 +++++ test/tx/regression/threadx_queue_prioritize.c | 534 ++++ .../threadx_queue_suspension_timeout_test.c | 254 ++ .../threadx_queue_thread_terminate_test.c | 183 ++ .../regression/threadx_semaphore_basic_test.c | 545 ++++ .../threadx_semaphore_ceiling_put_test.c | 334 +++ .../threadx_semaphore_delete_test.c | 213 ++ .../threadx_semaphore_information_test.c | 418 +++ .../threadx_semaphore_non_preemption_test.c | 271 ++ .../threadx_semaphore_preemption_test.c | 179 ++ .../regression/threadx_semaphore_prioritize.c | 525 ++++ .../threadx_semaphore_thread_terminate_test.c | 224 ++ .../threadx_semaphore_timeout_test.c | 167 ++ .../threadx_thread_basic_execution_test.c | 979 +++++++ .../threadx_thread_basic_time_slice_test.c | 73 + .../threadx_thread_completed_test.c | 258 ++ ..._thread_create_preemption_threshold_test.c | 140 + .../threadx_thread_delayed_suspension_test.c | 390 +++ .../threadx_thread_information_test.c | 474 ++++ ...ad_multi_level_preemption_threshold_test.c | 982 +++++++ ...threadx_thread_multiple_non_current_test.c | 222 ++ .../threadx_thread_multiple_sleep_test.c | 184 ++ .../threadx_thread_multiple_suspension_test.c | 432 +++ .../threadx_thread_multiple_time_slice_test.c | 269 ++ ...readx_thread_preemptable_suspension_test.c | 416 +++ .../threadx_thread_preemption_change_test.c | 363 +++ .../threadx_thread_priority_change.c | 378 +++ .../threadx_thread_relinquish_test.c | 193 ++ .../tx/regression/threadx_thread_reset_test.c | 248 ++ ...readx_thread_simple_sleep_non_clear_test.c | 92 + .../threadx_thread_simple_sleep_test.c | 87 + .../threadx_thread_simple_suspend_test.c | 116 + .../threadx_thread_sleep_for_100ticks_test.c | 435 +++ .../threadx_thread_sleep_terminate_test.c | 187 ++ .../threadx_thread_stack_checking_test.c | 224 ++ .../threadx_thread_terminate_delete_test.c | 341 +++ .../threadx_thread_time_slice_change_test.c | 149 + .../threadx_thread_wait_abort_and_isr_test.c | 271 ++ .../threadx_thread_wait_abort_test.c | 138 + .../tx/regression/threadx_time_get_set_test.c | 107 + .../threadx_timer_activate_deactivate_test.c | 268 ++ .../threadx_timer_deactivate_accuracy_test.c | 286 ++ .../threadx_timer_information_test.c | 538 ++++ .../threadx_timer_large_timer_accuracy_test.c | 286 ++ .../threadx_timer_multiple_accuracy_test.c | 186 ++ .../regression/threadx_timer_multiple_test.c | 349 +++ .../tx/regression/threadx_timer_simple_test.c | 664 +++++ test/tx/regression/threadx_trace_basic_test.c | 779 ++++++ 229 files changed, 87243 insertions(+) create mode 100644 .devcontainer/devcontainer.json create mode 100755 scripts/build_smp.sh create mode 100755 scripts/build_tx.sh create mode 100755 scripts/cmake_bootstrap.sh create mode 100755 scripts/test_smp.sh create mode 100755 scripts/test_tx.sh create mode 100644 test/.gitignore create mode 100644 test/smp/cmake/CMakeLists.txt create mode 100755 test/smp/cmake/coverage.sh create mode 100644 test/smp/cmake/regression/CMakeLists.txt create mode 100755 test/smp/cmake/regression/generate_test_file.sh create mode 120000 test/smp/cmake/run.sh create mode 100644 test/smp/cmake/samples/CMakeLists.txt create mode 100644 test/smp/cmake/samples/fake.c create mode 100644 test/smp/cmake/threadx_smp/CMakeLists.txt create mode 100644 test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt create mode 100644 test/smp/cmake/threadx_smp/ports_smp/linux/gnu/CMakeLists.txt create mode 100644 test/smp/regression/testcontrol.c create mode 100644 test/smp/regression/threadx_block_memory_basic_test.c create mode 100644 test/smp/regression/threadx_block_memory_error_detection_test.c create mode 100644 test/smp/regression/threadx_block_memory_information_test.c create mode 100644 test/smp/regression/threadx_block_memory_prioritize_test.c create mode 100644 test/smp/regression/threadx_block_memory_suspension_test.c create mode 100644 test/smp/regression/threadx_block_memory_suspension_timeout_test.c create mode 100644 test/smp/regression/threadx_block_memory_thread_terminate_test.c create mode 100644 test/smp/regression/threadx_byte_memory_basic_test.c create mode 100644 test/smp/regression/threadx_byte_memory_information_test.c create mode 100644 test/smp/regression/threadx_byte_memory_prioritize_test.c create mode 100644 test/smp/regression/threadx_byte_memory_suspension_test.c create mode 100644 test/smp/regression/threadx_byte_memory_suspension_timeout_test.c create mode 100644 test/smp/regression/threadx_byte_memory_thread_contention_test.c create mode 100644 test/smp/regression/threadx_byte_memory_thread_terminate_test.c create mode 100644 test/smp/regression/threadx_event_flag_basic_test.c create mode 100644 test/smp/regression/threadx_event_flag_information_test.c create mode 100644 test/smp/regression/threadx_event_flag_isr_set_clear_test.c create mode 100644 test/smp/regression/threadx_event_flag_isr_wait_abort_test.c create mode 100644 test/smp/regression/threadx_event_flag_single_thread_terminate_test.c create mode 100644 test/smp/regression/threadx_event_flag_suspension_consume_test.c create mode 100644 test/smp/regression/threadx_event_flag_suspension_different_bits_consume_test.c create mode 100644 test/smp/regression/threadx_event_flag_suspension_different_bits_test.c create mode 100644 test/smp/regression/threadx_event_flag_suspension_test.c create mode 100644 test/smp/regression/threadx_event_flag_suspension_timeout_test.c create mode 100644 test/smp/regression/threadx_event_flag_thread_terminate_test.c create mode 100644 test/smp/regression/threadx_initialize_kernel_setup_test.c create mode 100644 test/smp/regression/threadx_interrupt_control_test.c create mode 100644 test/smp/regression/threadx_mutex_basic_test.c create mode 100644 test/smp/regression/threadx_mutex_delete_test.c create mode 100644 test/smp/regression/threadx_mutex_information_test.c create mode 100644 test/smp/regression/threadx_mutex_nested_priority_inheritance_test.c create mode 100644 test/smp/regression/threadx_mutex_no_preemption_test.c create mode 100644 test/smp/regression/threadx_mutex_preemption_test.c create mode 100644 test/smp/regression/threadx_mutex_priority_inheritance_test.c create mode 100644 test/smp/regression/threadx_mutex_proritize_test.c create mode 100644 test/smp/regression/threadx_mutex_suspension_timeout_test.c create mode 100644 test/smp/regression/threadx_mutex_thread_terminate_test.c create mode 100644 test/smp/regression/threadx_queue_basic_eight_word_test.c create mode 100644 test/smp/regression/threadx_queue_basic_four_word_test.c create mode 100644 test/smp/regression/threadx_queue_basic_one_word_test.c create mode 100644 test/smp/regression/threadx_queue_basic_sixteen_word_test.c create mode 100644 test/smp/regression/threadx_queue_basic_two_word_test.c create mode 100644 test/smp/regression/threadx_queue_empty_suspension_test.c create mode 100644 test/smp/regression/threadx_queue_flush_no_suspension_test.c create mode 100644 test/smp/regression/threadx_queue_flush_test.c create mode 100644 test/smp/regression/threadx_queue_front_send_test.c create mode 100644 test/smp/regression/threadx_queue_full_suspension_test.c create mode 100644 test/smp/regression/threadx_queue_information_test.c create mode 100644 test/smp/regression/threadx_queue_prioritize.c create mode 100644 test/smp/regression/threadx_queue_suspension_timeout_test.c create mode 100644 test/smp/regression/threadx_queue_thread_terminate_test.c create mode 100644 test/smp/regression/threadx_semaphore_basic_test.c create mode 100644 test/smp/regression/threadx_semaphore_ceiling_put_test.c create mode 100644 test/smp/regression/threadx_semaphore_delete_test.c create mode 100644 test/smp/regression/threadx_semaphore_information_test.c create mode 100644 test/smp/regression/threadx_semaphore_non_preemption_test.c create mode 100644 test/smp/regression/threadx_semaphore_preemption_test.c create mode 100644 test/smp/regression/threadx_semaphore_prioritize.c create mode 100644 test/smp/regression/threadx_semaphore_thread_terminate_test.c create mode 100644 test/smp/regression/threadx_semaphore_timeout_test.c create mode 100644 test/smp/regression/threadx_smp_multiple_threads_one_core_test.c create mode 100644 test/smp/regression/threadx_smp_non_trivial_scheduling_test.c create mode 100644 test/smp/regression/threadx_smp_one_thread_dynamic_exclusion_test.c create mode 100644 test/smp/regression/threadx_smp_preemption_threshold_test.c create mode 100644 test/smp/regression/threadx_smp_random_resume_suspend_exclusion_pt_test.c create mode 100644 test/smp/regression/threadx_smp_random_resume_suspend_exclusion_test.c create mode 100644 test/smp/regression/threadx_smp_random_resume_suspend_test.c create mode 100644 test/smp/regression/threadx_smp_rebalance_exclusion_test.c create mode 100644 test/smp/regression/threadx_smp_relinquish_test.c create mode 100644 test/smp/regression/threadx_smp_resume_suspend_accending_order_test.c create mode 100644 test/smp/regression/threadx_smp_resume_suspend_decending_order_test.c create mode 100644 test/smp/regression/threadx_smp_time_slice_test.c create mode 100644 test/smp/regression/threadx_smp_two_threads_one_core_test.c create mode 100644 test/smp/regression/threadx_thread_basic_execution_test.c create mode 100644 test/smp/regression/threadx_thread_basic_time_slice_test.c create mode 100644 test/smp/regression/threadx_thread_completed_test.c create mode 100644 test/smp/regression/threadx_thread_create_preemption_threshold_test.c create mode 100644 test/smp/regression/threadx_thread_delayed_suspension_test.c create mode 100644 test/smp/regression/threadx_thread_information_test.c create mode 100644 test/smp/regression/threadx_thread_multi_level_preemption_threshold_test.c create mode 100644 test/smp/regression/threadx_thread_multiple_non_current_test.c create mode 100644 test/smp/regression/threadx_thread_multiple_sleep_test.c create mode 100644 test/smp/regression/threadx_thread_multiple_suspension_test.c create mode 100644 test/smp/regression/threadx_thread_multiple_time_slice_test.c create mode 100644 test/smp/regression/threadx_thread_preemptable_suspension_test.c create mode 100644 test/smp/regression/threadx_thread_preemption_change_test.c create mode 100644 test/smp/regression/threadx_thread_priority_change.c create mode 100644 test/smp/regression/threadx_thread_relinquish_test.c create mode 100644 test/smp/regression/threadx_thread_reset_test.c create mode 100644 test/smp/regression/threadx_thread_simple_sleep_non_clear_test.c create mode 100644 test/smp/regression/threadx_thread_simple_sleep_test.c create mode 100644 test/smp/regression/threadx_thread_simple_suspend_test.c create mode 100644 test/smp/regression/threadx_thread_sleep_for_100ticks_test.c create mode 100644 test/smp/regression/threadx_thread_sleep_terminate_test.c create mode 100644 test/smp/regression/threadx_thread_stack_checking_test.c create mode 100644 test/smp/regression/threadx_thread_terminate_delete_test.c create mode 100644 test/smp/regression/threadx_thread_time_slice_change_test.c create mode 100644 test/smp/regression/threadx_thread_wait_abort_and_isr_test.c create mode 100644 test/smp/regression/threadx_thread_wait_abort_test.c create mode 100644 test/smp/regression/threadx_time_get_set_test.c create mode 100644 test/smp/regression/threadx_timer_activate_deactivate_test.c create mode 100644 test/smp/regression/threadx_timer_deactivate_accuracy_test.c create mode 100644 test/smp/regression/threadx_timer_information_test.c create mode 100644 test/smp/regression/threadx_timer_large_timer_accuracy_test.c create mode 100644 test/smp/regression/threadx_timer_multiple_accuracy_test.c create mode 100644 test/smp/regression/threadx_timer_multiple_test.c create mode 100644 test/smp/regression/threadx_timer_simple_test.c create mode 100644 test/smp/regression/threadx_trace_basic_test.c create mode 100644 test/tx/cmake/CMakeLists.txt create mode 100755 test/tx/cmake/coverage.sh create mode 100644 test/tx/cmake/regression/CMakeLists.txt create mode 100755 test/tx/cmake/regression/generate_test_file.sh create mode 120000 test/tx/cmake/run.sh create mode 100644 test/tx/cmake/samples/CMakeLists.txt create mode 100644 test/tx/cmake/samples/fake.c create mode 100644 test/tx/regression/testcontrol.c create mode 100644 test/tx/regression/threadx_block_memory_basic_test.c create mode 100644 test/tx/regression/threadx_block_memory_error_detection_test.c create mode 100644 test/tx/regression/threadx_block_memory_information_test.c create mode 100644 test/tx/regression/threadx_block_memory_prioritize_test.c create mode 100644 test/tx/regression/threadx_block_memory_suspension_test.c create mode 100644 test/tx/regression/threadx_block_memory_suspension_timeout_test.c create mode 100644 test/tx/regression/threadx_block_memory_thread_terminate_test.c create mode 100644 test/tx/regression/threadx_byte_memory_basic_test.c create mode 100644 test/tx/regression/threadx_byte_memory_information_test.c create mode 100644 test/tx/regression/threadx_byte_memory_prioritize_test.c create mode 100644 test/tx/regression/threadx_byte_memory_suspension_test.c create mode 100644 test/tx/regression/threadx_byte_memory_suspension_timeout_test.c create mode 100644 test/tx/regression/threadx_byte_memory_thread_contention_test.c create mode 100644 test/tx/regression/threadx_byte_memory_thread_terminate_test.c create mode 100644 test/tx/regression/threadx_event_flag_basic_test.c create mode 100644 test/tx/regression/threadx_event_flag_information_test.c create mode 100644 test/tx/regression/threadx_event_flag_isr_set_clear_test.c create mode 100644 test/tx/regression/threadx_event_flag_isr_wait_abort_test.c create mode 100644 test/tx/regression/threadx_event_flag_single_thread_terminate_test.c create mode 100644 test/tx/regression/threadx_event_flag_suspension_consume_test.c create mode 100644 test/tx/regression/threadx_event_flag_suspension_different_bits_consume_test.c create mode 100644 test/tx/regression/threadx_event_flag_suspension_different_bits_test.c create mode 100644 test/tx/regression/threadx_event_flag_suspension_test.c create mode 100644 test/tx/regression/threadx_event_flag_suspension_timeout_test.c create mode 100644 test/tx/regression/threadx_event_flag_thread_terminate_test.c create mode 100644 test/tx/regression/threadx_initialize_kernel_setup_test.c create mode 100644 test/tx/regression/threadx_interrupt_control_test.c create mode 100644 test/tx/regression/threadx_mutex_basic_test.c create mode 100644 test/tx/regression/threadx_mutex_delete_test.c create mode 100644 test/tx/regression/threadx_mutex_information_test.c create mode 100644 test/tx/regression/threadx_mutex_nested_priority_inheritance_test.c create mode 100644 test/tx/regression/threadx_mutex_no_preemption_test.c create mode 100644 test/tx/regression/threadx_mutex_preemption_test.c create mode 100644 test/tx/regression/threadx_mutex_priority_inheritance_test.c create mode 100644 test/tx/regression/threadx_mutex_proritize_test.c create mode 100644 test/tx/regression/threadx_mutex_suspension_timeout_test.c create mode 100644 test/tx/regression/threadx_mutex_thread_terminate_test.c create mode 100644 test/tx/regression/threadx_queue_basic_eight_word_test.c create mode 100644 test/tx/regression/threadx_queue_basic_four_word_test.c create mode 100644 test/tx/regression/threadx_queue_basic_one_word_test.c create mode 100644 test/tx/regression/threadx_queue_basic_sixteen_word_test.c create mode 100644 test/tx/regression/threadx_queue_basic_two_word_test.c create mode 100644 test/tx/regression/threadx_queue_empty_suspension_test.c create mode 100644 test/tx/regression/threadx_queue_flush_no_suspension_test.c create mode 100644 test/tx/regression/threadx_queue_flush_test.c create mode 100644 test/tx/regression/threadx_queue_front_send_test.c create mode 100644 test/tx/regression/threadx_queue_full_suspension_test.c create mode 100644 test/tx/regression/threadx_queue_information_test.c create mode 100644 test/tx/regression/threadx_queue_prioritize.c create mode 100644 test/tx/regression/threadx_queue_suspension_timeout_test.c create mode 100644 test/tx/regression/threadx_queue_thread_terminate_test.c create mode 100644 test/tx/regression/threadx_semaphore_basic_test.c create mode 100644 test/tx/regression/threadx_semaphore_ceiling_put_test.c create mode 100644 test/tx/regression/threadx_semaphore_delete_test.c create mode 100644 test/tx/regression/threadx_semaphore_information_test.c create mode 100644 test/tx/regression/threadx_semaphore_non_preemption_test.c create mode 100644 test/tx/regression/threadx_semaphore_preemption_test.c create mode 100644 test/tx/regression/threadx_semaphore_prioritize.c create mode 100644 test/tx/regression/threadx_semaphore_thread_terminate_test.c create mode 100644 test/tx/regression/threadx_semaphore_timeout_test.c create mode 100644 test/tx/regression/threadx_thread_basic_execution_test.c create mode 100644 test/tx/regression/threadx_thread_basic_time_slice_test.c create mode 100644 test/tx/regression/threadx_thread_completed_test.c create mode 100644 test/tx/regression/threadx_thread_create_preemption_threshold_test.c create mode 100644 test/tx/regression/threadx_thread_delayed_suspension_test.c create mode 100644 test/tx/regression/threadx_thread_information_test.c create mode 100644 test/tx/regression/threadx_thread_multi_level_preemption_threshold_test.c create mode 100644 test/tx/regression/threadx_thread_multiple_non_current_test.c create mode 100644 test/tx/regression/threadx_thread_multiple_sleep_test.c create mode 100644 test/tx/regression/threadx_thread_multiple_suspension_test.c create mode 100644 test/tx/regression/threadx_thread_multiple_time_slice_test.c create mode 100644 test/tx/regression/threadx_thread_preemptable_suspension_test.c create mode 100644 test/tx/regression/threadx_thread_preemption_change_test.c create mode 100644 test/tx/regression/threadx_thread_priority_change.c create mode 100644 test/tx/regression/threadx_thread_relinquish_test.c create mode 100644 test/tx/regression/threadx_thread_reset_test.c create mode 100644 test/tx/regression/threadx_thread_simple_sleep_non_clear_test.c create mode 100644 test/tx/regression/threadx_thread_simple_sleep_test.c create mode 100644 test/tx/regression/threadx_thread_simple_suspend_test.c create mode 100644 test/tx/regression/threadx_thread_sleep_for_100ticks_test.c create mode 100644 test/tx/regression/threadx_thread_sleep_terminate_test.c create mode 100644 test/tx/regression/threadx_thread_stack_checking_test.c create mode 100644 test/tx/regression/threadx_thread_terminate_delete_test.c create mode 100644 test/tx/regression/threadx_thread_time_slice_change_test.c create mode 100644 test/tx/regression/threadx_thread_wait_abort_and_isr_test.c create mode 100644 test/tx/regression/threadx_thread_wait_abort_test.c create mode 100644 test/tx/regression/threadx_time_get_set_test.c create mode 100644 test/tx/regression/threadx_timer_activate_deactivate_test.c create mode 100644 test/tx/regression/threadx_timer_deactivate_accuracy_test.c create mode 100644 test/tx/regression/threadx_timer_information_test.c create mode 100644 test/tx/regression/threadx_timer_large_timer_accuracy_test.c create mode 100644 test/tx/regression/threadx_timer_multiple_accuracy_test.c create mode 100644 test/tx/regression/threadx_timer_multiple_test.c create mode 100644 test/tx/regression/threadx_timer_simple_test.c create mode 100644 test/tx/regression/threadx_trace_basic_test.c diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..3422d61a --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,4 @@ +{ + "image": "tizho/azurertos-regression", + "runArgs": [ "--cap-add=NET_ADMIN"] +} \ No newline at end of file diff --git a/scripts/build_smp.sh b/scripts/build_smp.sh new file mode 100755 index 00000000..615a9be8 --- /dev/null +++ b/scripts/build_smp.sh @@ -0,0 +1,2 @@ +#!/bin/bash +$(dirname `realpath $0`)/../test/smp/cmake/run.sh build all diff --git a/scripts/build_tx.sh b/scripts/build_tx.sh new file mode 100755 index 00000000..a1773a1e --- /dev/null +++ b/scripts/build_tx.sh @@ -0,0 +1,2 @@ +#!/bin/bash +$(dirname `realpath $0`)/../test/tx/cmake/run.sh build all diff --git a/scripts/cmake_bootstrap.sh b/scripts/cmake_bootstrap.sh new file mode 100755 index 00000000..5cbfc9aa --- /dev/null +++ b/scripts/cmake_bootstrap.sh @@ -0,0 +1,120 @@ +#!/bin/bash + +set -e + +function help() { + echo "Usage: $0 [build|test] [all| ...]" + echo "Available build_configuration:" + for build in ${build_configurations[*]}; do + echo " $build" + done + exit 1 +} + +function validate() { + for build in ${build_configurations[*]}; do + if [ "$1" == "$build" ]; then + return + fi + done + help +} + +function generate() { + build=$1 + cmake -Bbuild/$build -GNinja -DBUILD_SHARED_LIBS=ON -DCMAKE_TOOLCHAIN_FILE=$(dirname $(realpath $0))/../cmake/linux.cmake -DCMAKE_BUILD_TYPE=$build . +} + +function build() { + cmake --build build/$1 +} + +function build_libs() { + cmake -Bbuild/libs -GNinja -DBUILD_SHARED_LIBS=ON -DCMAKE_TOOLCHAIN_FILE=$(dirname $(realpath $0))/../cmake/linux.cmake libs + cmake --build build/libs +} + +function test() { + pushd build/$1 + [ -z "${CTEST_PARALLEL_LEVEL}" ] && parallel="-j$2" + if [ -z "${CTEST_REPEAT_FAIL}" ]; + then + repeat_fail=2 + else + repeat_fail=${CTEST_REPEAT_FAIL} + fi + ctest $parallel --timeout 1000 -O $1.txt -T test --no-compress-output --test-output-size-passed 4194304 --test-output-size-failed 4194304 --output-on-failure --repeat until-pass:${repeat_fail} + popd + grep -E "^(\s*[0-9]+|Total)" build/$1/$1.txt >build/$1.txt + sed -i "s/\x1B\[[0-9;]*[JKmsu]//g" build/$1.txt + if [[ $1 = *"_coverage" ]]; then + ./coverage.sh $1 + fi +} + +cd $(dirname $0) + +result=$(sed -n "/(BUILD_CONFIGURATIONS/,/)/p" CMakeLists.txt|sed ':label;N;s/\n/ /;b label'|grep -Pzo "[a-zA-Z0-9_]*build[a-zA-Z0-9_]*\s*"| tr -d '\0') +IFS=' ' +read -ra build_configurations <<< "$result" + +if [ $# -lt 1 ]; then + help +fi + +command=$1 +shift + +if [ "$#" == "0" ]; then + builds=${build_configurations[0]} +elif [ "$*" == "all" ]; then + builds=${build_configurations[@]} +else + for item in $*; do + validate $item + done + builds=$* +fi + +if [ "$command" == "build" ]; then + for item in $builds; do + generate $item + echo "" + done + + for item in $builds; do + echo "Building $item" + build $item + echo "" + done +elif [ "$command" == "test" ]; then + cores=$(nproc) + if [ -z "${CTEST_PARALLEL_LEVEL}" ]; + then + # Run builds in parallel + build_counts=$(echo $builds | wc -w) + parallel_jobs=$(($cores / $build_counts)) + parallel_jobs=$(($parallel_jobs + 2)) + pids="" + for item in $builds; do + echo "Testing $item" + test $item $parallel_jobs & + pids+=" $!" + done + exit_code=0 + for p in $pids; do + wait $p || exit_code=$? + done + exit $exit_code + else + # Run builds in serial + for item in $builds; do + echo "Testing $item" + test $item $parallel_jobs + done + fi +elif [ "$command" == "build_libs" ]; then + build_libs +else + help +fi diff --git a/scripts/test_smp.sh b/scripts/test_smp.sh new file mode 100755 index 00000000..135f0847 --- /dev/null +++ b/scripts/test_smp.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +CTEST_PARALLEL_LEVEL=4 $(dirname `realpath $0`)/../test/smp/cmake/run.sh test all diff --git a/scripts/test_tx.sh b/scripts/test_tx.sh new file mode 100755 index 00000000..613b086c --- /dev/null +++ b/scripts/test_tx.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +CTEST_PARALLEL_LEVEL=4 $(dirname `realpath $0`)/../test/tx/cmake/run.sh test all diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 00000000..c751f6fb --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,2 @@ +tx_initialize_low_level.c +coverage_report/ \ No newline at end of file diff --git a/test/smp/cmake/CMakeLists.txt b/test/smp/cmake/CMakeLists.txt new file mode 100644 index 00000000..f50c7861 --- /dev/null +++ b/test/smp/cmake/CMakeLists.txt @@ -0,0 +1,76 @@ +cmake_minimum_required(VERSION 3.13 FATAL_ERROR) +cmake_policy(SET CMP0054 NEW) +cmake_policy(SET CMP0057 NEW) + +project(threadx_smp_test LANGUAGES C) + +# Set build configurations +set(BUILD_CONFIGURATIONS default_build_coverage + disable_notify_callbacks_build stack_checking_build + trace_build) +set(CMAKE_CONFIGURATION_TYPES + ${BUILD_CONFIGURATIONS} + CACHE STRING "list of supported configuration types" FORCE) +set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + ${CMAKE_CONFIGURATION_TYPES}) +list(GET CMAKE_CONFIGURATION_TYPES 0 BUILD_TYPE) +if((NOT CMAKE_BUILD_TYPE) OR (NOT ("${CMAKE_BUILD_TYPE}" IN_LIST + CMAKE_CONFIGURATION_TYPES))) + set(CMAKE_BUILD_TYPE + "${BUILD_TYPE}" + CACHE STRING "Build Type of the project" FORCE) +endif() + +message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") +message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.") +set(default_build_coverage "") +set(disable_notify_callbacks_build -DTX_DISABLE_NOTIFY_CALLBACKS) +set(stack_checking_build -DTX_ENABLE_STACK_CHECKING) +set(trace_build -DTX_ENABLE_EVENT_TRACE) + +add_compile_options( + -m32 + -std=c99 + -ggdb + -g3 + -gdwarf-2 + -fdiagnostics-color + # -Werror + -DTX_THREAD_SMP_ONLY_CORE_0_DEFAULT + -DTX_SMP_NOT_POSSIBLE + -DTX_REGRESSION_TEST + -DTEST_STACK_SIZE_PRINTF=4096 + ${${CMAKE_BUILD_TYPE}}) +add_link_options(-m32) + +enable_testing() + +add_subdirectory(threadx_smp) +add_subdirectory(regression) +add_subdirectory(samples) + +# Coverage +if(CMAKE_BUILD_TYPE MATCHES ".*_coverage") + target_compile_options(threadx_smp PRIVATE -fprofile-arcs -ftest-coverage) + target_link_options(threadx_smp PRIVATE -fprofile-arcs -ftest-coverage) +endif() + +target_compile_options( + threadx_smp + PRIVATE # -Werror + -Wall + -Wextra + -pedantic + -fmessage-length=0 + -fsigned-char + -ffunction-sections + -fdata-sections + -Wunused + -Wuninitialized + -Wmissing-declarations + -Wconversion + -Wpointer-arith + # -Wshadow + -Wlogical-op + -Waggregate-return + -Wfloat-equal) diff --git a/test/smp/cmake/coverage.sh b/test/smp/cmake/coverage.sh new file mode 100755 index 00000000..51b2e8ca --- /dev/null +++ b/test/smp/cmake/coverage.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -e + +cd $(dirname $0) +threadx_smp=$(realpath ../../../common_smp/src) +mkdir -p coverage_report/$1 +gcovr --object-directory=build/$1/threadx_smp/CMakeFiles/threadx_smp.dir/$threadx_smp -r build/$1 -f ../../../common_smp/src --xml-pretty --output coverage_report/$1.xml +gcovr --object-directory=build/$1/threadx_smp/CMakeFiles/threadx_smp.dir/$threadx_smp -r build/$1 -f ../../../common_smp/src --html --html-details --output coverage_report/$1/index.html diff --git a/test/smp/cmake/regression/CMakeLists.txt b/test/smp/cmake/regression/CMakeLists.txt new file mode 100644 index 00000000..ad002d18 --- /dev/null +++ b/test/smp/cmake/regression/CMakeLists.txt @@ -0,0 +1,133 @@ +cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR) +cmake_policy(SET CMP0057 NEW) + +project(regression_test LANGUAGES C) + +set(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../regression) + +set(regression_test_cases + ${SOURCE_DIR}/threadx_block_memory_basic_test.c + ${SOURCE_DIR}/threadx_block_memory_error_detection_test.c + ${SOURCE_DIR}/threadx_block_memory_information_test.c + ${SOURCE_DIR}/threadx_block_memory_prioritize_test.c + ${SOURCE_DIR}/threadx_block_memory_suspension_test.c + ${SOURCE_DIR}/threadx_block_memory_suspension_timeout_test.c + ${SOURCE_DIR}/threadx_block_memory_thread_terminate_test.c + ${SOURCE_DIR}/threadx_byte_memory_basic_test.c + ${SOURCE_DIR}/threadx_byte_memory_information_test.c + ${SOURCE_DIR}/threadx_byte_memory_prioritize_test.c + ${SOURCE_DIR}/threadx_byte_memory_suspension_test.c + ${SOURCE_DIR}/threadx_byte_memory_suspension_timeout_test.c + ${SOURCE_DIR}/threadx_byte_memory_thread_contention_test.c + ${SOURCE_DIR}/threadx_byte_memory_thread_terminate_test.c + ${SOURCE_DIR}/threadx_event_flag_basic_test.c + ${SOURCE_DIR}/threadx_event_flag_information_test.c + ${SOURCE_DIR}/threadx_event_flag_isr_set_clear_test.c + ${SOURCE_DIR}/threadx_event_flag_isr_wait_abort_test.c + ${SOURCE_DIR}/threadx_event_flag_single_thread_terminate_test.c + ${SOURCE_DIR}/threadx_event_flag_suspension_consume_test.c + ${SOURCE_DIR}/threadx_event_flag_suspension_different_bits_consume_test.c + ${SOURCE_DIR}/threadx_event_flag_suspension_different_bits_test.c + ${SOURCE_DIR}/threadx_event_flag_suspension_test.c + ${SOURCE_DIR}/threadx_event_flag_suspension_timeout_test.c + ${SOURCE_DIR}/threadx_event_flag_thread_terminate_test.c + ${SOURCE_DIR}/threadx_interrupt_control_test.c + ${SOURCE_DIR}/threadx_mutex_basic_test.c + ${SOURCE_DIR}/threadx_mutex_delete_test.c + ${SOURCE_DIR}/threadx_mutex_information_test.c + ${SOURCE_DIR}/threadx_mutex_nested_priority_inheritance_test.c + ${SOURCE_DIR}/threadx_mutex_no_preemption_test.c + ${SOURCE_DIR}/threadx_mutex_preemption_test.c + ${SOURCE_DIR}/threadx_mutex_priority_inheritance_test.c + ${SOURCE_DIR}/threadx_mutex_proritize_test.c + ${SOURCE_DIR}/threadx_mutex_suspension_timeout_test.c + ${SOURCE_DIR}/threadx_mutex_thread_terminate_test.c + ${SOURCE_DIR}/threadx_queue_basic_eight_word_test.c + ${SOURCE_DIR}/threadx_queue_basic_four_word_test.c + ${SOURCE_DIR}/threadx_queue_basic_one_word_test.c + ${SOURCE_DIR}/threadx_queue_basic_sixteen_word_test.c + ${SOURCE_DIR}/threadx_queue_basic_two_word_test.c + ${SOURCE_DIR}/threadx_queue_empty_suspension_test.c + ${SOURCE_DIR}/threadx_queue_flush_no_suspension_test.c + ${SOURCE_DIR}/threadx_queue_flush_test.c + ${SOURCE_DIR}/threadx_queue_front_send_test.c + ${SOURCE_DIR}/threadx_queue_full_suspension_test.c + ${SOURCE_DIR}/threadx_queue_information_test.c + ${SOURCE_DIR}/threadx_queue_prioritize.c + ${SOURCE_DIR}/threadx_queue_suspension_timeout_test.c + ${SOURCE_DIR}/threadx_queue_thread_terminate_test.c + ${SOURCE_DIR}/threadx_semaphore_basic_test.c + ${SOURCE_DIR}/threadx_semaphore_ceiling_put_test.c + ${SOURCE_DIR}/threadx_semaphore_delete_test.c + ${SOURCE_DIR}/threadx_semaphore_information_test.c + ${SOURCE_DIR}/threadx_semaphore_non_preemption_test.c + ${SOURCE_DIR}/threadx_semaphore_preemption_test.c + ${SOURCE_DIR}/threadx_semaphore_prioritize.c + ${SOURCE_DIR}/threadx_semaphore_thread_terminate_test.c + ${SOURCE_DIR}/threadx_semaphore_timeout_test.c + ${SOURCE_DIR}/threadx_smp_multiple_threads_one_core_test.c + ${SOURCE_DIR}/threadx_smp_non_trivial_scheduling_test.c + ${SOURCE_DIR}/threadx_smp_one_thread_dynamic_exclusion_test.c + ${SOURCE_DIR}/threadx_smp_preemption_threshold_test.c + ${SOURCE_DIR}/threadx_smp_random_resume_suspend_exclusion_pt_test.c + ${SOURCE_DIR}/threadx_smp_random_resume_suspend_exclusion_test.c + ${SOURCE_DIR}/threadx_smp_random_resume_suspend_test.c + ${SOURCE_DIR}/threadx_smp_rebalance_exclusion_test.c + ${SOURCE_DIR}/threadx_smp_relinquish_test.c + ${SOURCE_DIR}/threadx_smp_resume_suspend_accending_order_test.c + ${SOURCE_DIR}/threadx_smp_resume_suspend_decending_order_test.c + ${SOURCE_DIR}/threadx_smp_time_slice_test.c + ${SOURCE_DIR}/threadx_smp_two_threads_one_core_test.c + ${SOURCE_DIR}/threadx_thread_basic_execution_test.c + ${SOURCE_DIR}/threadx_thread_basic_time_slice_test.c + ${SOURCE_DIR}/threadx_thread_completed_test.c + ${SOURCE_DIR}/threadx_thread_create_preemption_threshold_test.c + ${SOURCE_DIR}/threadx_thread_delayed_suspension_test.c + ${SOURCE_DIR}/threadx_thread_information_test.c + ${SOURCE_DIR}/threadx_thread_multi_level_preemption_threshold_test.c + ${SOURCE_DIR}/threadx_thread_multiple_non_current_test.c + ${SOURCE_DIR}/threadx_thread_multiple_sleep_test.c + ${SOURCE_DIR}/threadx_thread_multiple_suspension_test.c + ${SOURCE_DIR}/threadx_thread_multiple_time_slice_test.c + ${SOURCE_DIR}/threadx_thread_preemptable_suspension_test.c + ${SOURCE_DIR}/threadx_thread_preemption_change_test.c + ${SOURCE_DIR}/threadx_thread_priority_change.c + ${SOURCE_DIR}/threadx_thread_relinquish_test.c + ${SOURCE_DIR}/threadx_thread_reset_test.c + ${SOURCE_DIR}/threadx_thread_simple_sleep_non_clear_test.c + ${SOURCE_DIR}/threadx_thread_simple_sleep_test.c + ${SOURCE_DIR}/threadx_thread_simple_suspend_test.c + ${SOURCE_DIR}/threadx_thread_sleep_for_100ticks_test.c + ${SOURCE_DIR}/threadx_thread_sleep_terminate_test.c + ${SOURCE_DIR}/threadx_thread_stack_checking_test.c + ${SOURCE_DIR}/threadx_thread_terminate_delete_test.c + ${SOURCE_DIR}/threadx_thread_time_slice_change_test.c + ${SOURCE_DIR}/threadx_thread_wait_abort_and_isr_test.c + ${SOURCE_DIR}/threadx_thread_wait_abort_test.c + ${SOURCE_DIR}/threadx_time_get_set_test.c + ${SOURCE_DIR}/threadx_timer_activate_deactivate_test.c + ${SOURCE_DIR}/threadx_timer_deactivate_accuracy_test.c + ${SOURCE_DIR}/threadx_timer_information_test.c + ${SOURCE_DIR}/threadx_timer_large_timer_accuracy_test.c + ${SOURCE_DIR}/threadx_timer_multiple_accuracy_test.c + ${SOURCE_DIR}/threadx_timer_multiple_test.c + ${SOURCE_DIR}/threadx_timer_simple_test.c + ${SOURCE_DIR}/threadx_trace_basic_test.c + ${SOURCE_DIR}/threadx_initialize_kernel_setup_test.c) + +add_custom_command( + OUTPUT ${SOURCE_DIR}/tx_initialize_low_level.c + COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/generate_test_file.sh + COMMENT "Generating tx_initialize_low_level.c for test") + +add_library(test_utility ${SOURCE_DIR}/tx_initialize_low_level.c + ${SOURCE_DIR}/testcontrol.c) +target_link_libraries(test_utility PUBLIC azrtos::threadx_smp) +target_compile_definitions(test_utility PUBLIC CTEST BATCH_TEST) + +foreach(test_case ${regression_test_cases}) + get_filename_component(test_name ${test_case} NAME_WE) + add_executable(${test_name} ${test_case}) + target_link_libraries(${test_name} PRIVATE test_utility) + add_test(${CMAKE_BUILD_TYPE}::${test_name} ${test_name}) +endforeach() diff --git a/test/smp/cmake/regression/generate_test_file.sh b/test/smp/cmake/regression/generate_test_file.sh new file mode 100755 index 00000000..0172469a --- /dev/null +++ b/test/smp/cmake/regression/generate_test_file.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +dst=$(dirname $0)/../../regression/tx_initialize_low_level.c +src=$(dirname $0)/../../../../ports_smp/linux/gnu/src/tx_initialize_low_level.c + +line=`sed -n '/_tx_linux_timer_interrupt/=' $src | tail -n 1` +sed "${line}iVOID test_interrupt_dispatch(VOID);" $src > tmp1 +line=`sed -n '/_tx_timer_interrupt/=' $src | tail -n 1` +sed "${line}itest_interrupt_dispatch();" tmp1 > $dst +rm tmp1 \ No newline at end of file diff --git a/test/smp/cmake/run.sh b/test/smp/cmake/run.sh new file mode 120000 index 00000000..d2f7f7df --- /dev/null +++ b/test/smp/cmake/run.sh @@ -0,0 +1 @@ +../../../tools/cmake_bootstrap.sh \ No newline at end of file diff --git a/test/smp/cmake/samples/CMakeLists.txt b/test/smp/cmake/samples/CMakeLists.txt new file mode 100644 index 00000000..4925246c --- /dev/null +++ b/test/smp/cmake/samples/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR) +cmake_policy(SET CMP0057 NEW) + +project(samples LANGUAGES C) + +set(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../../ports_smp/linux/gnu/example_build) + +set(sample_files + ${SOURCE_DIR}/sample_threadx.c) + +foreach(sample_file ${sample_files}) + get_filename_component(sample_file_name ${sample_file} NAME_WE) + add_executable(${sample_file_name} ${sample_file} ${CMAKE_CURRENT_LIST_DIR}/fake.c) + target_link_libraries(${sample_file_name} PRIVATE azrtos::threadx_smp) +endforeach() diff --git a/test/smp/cmake/samples/fake.c b/test/smp/cmake/samples/fake.c new file mode 100644 index 00000000..8159fef4 --- /dev/null +++ b/test/smp/cmake/samples/fake.c @@ -0,0 +1,22 @@ +#include "tx_api.h" + +typedef unsigned int TEST_FLAG; +TEST_FLAG threadx_byte_allocate_loop_test; +TEST_FLAG threadx_byte_release_loop_test; +TEST_FLAG threadx_mutex_suspension_put_test; +TEST_FLAG threadx_mutex_suspension_priority_test; +#ifndef TX_TIMER_PROCESS_IN_ISR +TEST_FLAG threadx_delete_timer_thread; +#endif + +void abort_and_resume_byte_allocating_thread(void){} +void abort_all_threads_suspended_on_mutex(void){} +void suspend_lowest_priority(void){} +#ifndef TX_TIMER_PROCESS_IN_ISR +void delete_timer_thread(void){} +#endif +TEST_FLAG test_stack_analyze_flag; +TEST_FLAG test_initialize_flag; +TEST_FLAG test_forced_mutex_timeout; +UINT mutex_priority_change_extension_selection; +UINT priority_change_extension_selection; \ No newline at end of file diff --git a/test/smp/cmake/threadx_smp/CMakeLists.txt b/test/smp/cmake/threadx_smp/CMakeLists.txt new file mode 100644 index 00000000..f12de984 --- /dev/null +++ b/test/smp/cmake/threadx_smp/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR) + +# Set up the project +project(threadx_smp + VERSION 6.0.0 + LANGUAGES C ASM +) + +if(NOT DEFINED THREADX_ARCH) + message(FATAL_ERROR "Error: THREADX_ARCH not defined") +endif() +if(NOT DEFINED THREADX_TOOLCHAIN) + message(FATAL_ERROR "Error: THREADX_TOOLCHAIN not defined") +endif() + +set(PROJECT_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../..) + +# Define our target library and an alias for consumers +add_library(${PROJECT_NAME}) +add_library("azrtos::${PROJECT_NAME}" ALIAS ${PROJECT_NAME}) + +# A place for generated/copied include files (no need to change) +set(CUSTOM_INC_DIR ${CMAKE_CURRENT_BINARY_DIR}/custom_inc) + +# Pick up the port specific variables and apply them +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/ports_smp/${THREADX_ARCH}/${THREADX_TOOLCHAIN}) + +# Pick up the common stuff +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/common_smp) + + + + +# If the user provided an override, copy it to the custom directory +if (NOT TX_USER_FILE) + message(STATUS "Using default tx_user.h file") + set(TX_USER_FILE ${PROJECT_DIR}/common_smp/inc/tx_user_sample.h) +else() + message(STATUS "Using custom tx_user.h file from ${TX_USER_FILE}") +endif() +configure_file(${TX_USER_FILE} ${CUSTOM_INC_DIR}/tx_user.h COPYONLY) +target_include_directories(${PROJECT_NAME} + PUBLIC + ${CUSTOM_INC_DIR} +) +target_compile_definitions(${PROJECT_NAME} PUBLIC "TX_INCLUDE_USER_DEFINE_FILE" ) + +# Enable a build target that produces a ZIP file of all sources +set(CPACK_SOURCE_GENERATOR "ZIP") +set(CPACK_SOURCE_IGNORE_FILES + \\.git/ + \\.github/ + _build/ + \\.git + \\.gitattributes + \\.gitignore + ".*~$" +) +set(CPACK_VERBATIM_VARIABLES YES) +include(CPack) \ No newline at end of file diff --git a/test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt b/test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt new file mode 100644 index 00000000..f7e35fde --- /dev/null +++ b/test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt @@ -0,0 +1,220 @@ +set(CURRENT_DIR ${PROJECT_DIR}/common_smp) + +function(target_sources_if_not_overridden filename) + list(FIND TX_SRC_OVERRIDES ${filename} OVERRIDE_FOUND) + if( OVERRIDE_FOUND EQUAL -1 ) + # message(STATUS "** Using original ${filename} from common/src **") + target_sources(${PROJECT_NAME} PRIVATE ${CURRENT_DIR}/src/${filename}) + endif() +endfunction() + +# These files can be overridden by setting them in the variable list named TX_SRC_OVERRIDES +target_sources_if_not_overridden("tx_thread_delete.c") +target_sources_if_not_overridden("tx_thread_reset.c") + +target_sources(${PROJECT_NAME} + PRIVATE + # {{BEGIN_TARGET_SOURCES}} + ${CURRENT_DIR}/src/tx_block_allocate.c + ${CURRENT_DIR}/src/tx_block_allocate.c + ${CURRENT_DIR}/src/tx_block_pool_cleanup.c + ${CURRENT_DIR}/src/tx_block_pool_create.c + ${CURRENT_DIR}/src/tx_block_pool_delete.c + ${CURRENT_DIR}/src/tx_block_pool_info_get.c + ${CURRENT_DIR}/src/tx_block_pool_initialize.c + ${CURRENT_DIR}/src/tx_block_pool_performance_info_get.c + ${CURRENT_DIR}/src/tx_block_pool_performance_system_info_get.c + ${CURRENT_DIR}/src/tx_block_pool_prioritize.c + ${CURRENT_DIR}/src/tx_block_release.c + ${CURRENT_DIR}/src/tx_byte_allocate.c + ${CURRENT_DIR}/src/tx_byte_pool_cleanup.c + ${CURRENT_DIR}/src/tx_byte_pool_create.c + ${CURRENT_DIR}/src/tx_byte_pool_delete.c + ${CURRENT_DIR}/src/tx_byte_pool_info_get.c + ${CURRENT_DIR}/src/tx_byte_pool_initialize.c + ${CURRENT_DIR}/src/tx_byte_pool_performance_info_get.c + ${CURRENT_DIR}/src/tx_byte_pool_performance_system_info_get.c + ${CURRENT_DIR}/src/tx_byte_pool_prioritize.c + ${CURRENT_DIR}/src/tx_byte_pool_search.c + ${CURRENT_DIR}/src/tx_byte_release.c + ${CURRENT_DIR}/src/txe_block_allocate.c + ${CURRENT_DIR}/src/txe_block_pool_create.c + ${CURRENT_DIR}/src/txe_block_pool_delete.c + ${CURRENT_DIR}/src/txe_block_pool_info_get.c + ${CURRENT_DIR}/src/txe_block_pool_prioritize.c + ${CURRENT_DIR}/src/txe_block_release.c + ${CURRENT_DIR}/src/txe_byte_allocate.c + ${CURRENT_DIR}/src/txe_byte_pool_create.c + ${CURRENT_DIR}/src/txe_byte_pool_delete.c + ${CURRENT_DIR}/src/txe_byte_pool_info_get.c + ${CURRENT_DIR}/src/txe_byte_pool_prioritize.c + ${CURRENT_DIR}/src/txe_byte_release.c + ${CURRENT_DIR}/src/txe_event_flags_create.c + ${CURRENT_DIR}/src/txe_event_flags_delete.c + ${CURRENT_DIR}/src/txe_event_flags_get.c + ${CURRENT_DIR}/src/txe_event_flags_info_get.c + ${CURRENT_DIR}/src/txe_event_flags_set.c + ${CURRENT_DIR}/src/txe_event_flags_set_notify.c + ${CURRENT_DIR}/src/txe_mutex_create.c + ${CURRENT_DIR}/src/txe_mutex_delete.c + ${CURRENT_DIR}/src/txe_mutex_get.c + ${CURRENT_DIR}/src/txe_mutex_info_get.c + ${CURRENT_DIR}/src/txe_mutex_prioritize.c + ${CURRENT_DIR}/src/txe_mutex_put.c + ${CURRENT_DIR}/src/txe_queue_create.c + ${CURRENT_DIR}/src/txe_queue_delete.c + ${CURRENT_DIR}/src/txe_queue_flush.c + ${CURRENT_DIR}/src/txe_queue_front_send.c + ${CURRENT_DIR}/src/txe_queue_info_get.c + ${CURRENT_DIR}/src/txe_queue_prioritize.c + ${CURRENT_DIR}/src/txe_queue_receive.c + ${CURRENT_DIR}/src/txe_queue_send.c + ${CURRENT_DIR}/src/txe_queue_send_notify.c + ${CURRENT_DIR}/src/txe_semaphore_ceiling_put.c + ${CURRENT_DIR}/src/txe_semaphore_create.c + ${CURRENT_DIR}/src/txe_semaphore_delete.c + ${CURRENT_DIR}/src/txe_semaphore_get.c + ${CURRENT_DIR}/src/txe_semaphore_info_get.c + ${CURRENT_DIR}/src/txe_semaphore_prioritize.c + ${CURRENT_DIR}/src/txe_semaphore_put.c + ${CURRENT_DIR}/src/txe_semaphore_put_notify.c + ${CURRENT_DIR}/src/txe_thread_create.c + ${CURRENT_DIR}/src/txe_thread_delete.c + ${CURRENT_DIR}/src/txe_thread_entry_exit_notify.c + ${CURRENT_DIR}/src/txe_thread_info_get.c + ${CURRENT_DIR}/src/txe_thread_preemption_change.c + ${CURRENT_DIR}/src/txe_thread_priority_change.c + ${CURRENT_DIR}/src/txe_thread_relinquish.c + ${CURRENT_DIR}/src/txe_thread_reset.c + ${CURRENT_DIR}/src/txe_thread_resume.c + ${CURRENT_DIR}/src/txe_thread_suspend.c + ${CURRENT_DIR}/src/txe_thread_terminate.c + ${CURRENT_DIR}/src/txe_thread_time_slice_change.c + ${CURRENT_DIR}/src/txe_thread_wait_abort.c + ${CURRENT_DIR}/src/txe_timer_activate.c + ${CURRENT_DIR}/src/txe_timer_change.c + ${CURRENT_DIR}/src/txe_timer_create.c + ${CURRENT_DIR}/src/txe_timer_deactivate.c + ${CURRENT_DIR}/src/txe_timer_delete.c + ${CURRENT_DIR}/src/txe_timer_info_get.c + ${CURRENT_DIR}/src/tx_event_flags_cleanup.c + ${CURRENT_DIR}/src/tx_event_flags_create.c + ${CURRENT_DIR}/src/tx_event_flags_delete.c + ${CURRENT_DIR}/src/tx_event_flags_get.c + ${CURRENT_DIR}/src/tx_event_flags_info_get.c + ${CURRENT_DIR}/src/tx_event_flags_initialize.c + ${CURRENT_DIR}/src/tx_event_flags_performance_info_get.c + ${CURRENT_DIR}/src/tx_event_flags_performance_system_info_get.c + ${CURRENT_DIR}/src/tx_event_flags_set.c + ${CURRENT_DIR}/src/tx_event_flags_set_notify.c + ${CURRENT_DIR}/src/tx_initialize_high_level.c + ${CURRENT_DIR}/src/tx_initialize_kernel_enter.c + ${CURRENT_DIR}/src/tx_initialize_kernel_setup.c + ${CURRENT_DIR}/src/tx_misra.c + ${CURRENT_DIR}/src/tx_mutex_cleanup.c + ${CURRENT_DIR}/src/tx_mutex_create.c + ${CURRENT_DIR}/src/tx_mutex_delete.c + ${CURRENT_DIR}/src/tx_mutex_get.c + ${CURRENT_DIR}/src/tx_mutex_info_get.c + ${CURRENT_DIR}/src/tx_mutex_initialize.c + ${CURRENT_DIR}/src/tx_mutex_performance_info_get.c + ${CURRENT_DIR}/src/tx_mutex_performance_system_info_get.c + ${CURRENT_DIR}/src/tx_mutex_prioritize.c + ${CURRENT_DIR}/src/tx_mutex_priority_change.c + ${CURRENT_DIR}/src/tx_mutex_put.c + ${CURRENT_DIR}/src/tx_queue_cleanup.c + ${CURRENT_DIR}/src/tx_queue_create.c + ${CURRENT_DIR}/src/tx_queue_delete.c + ${CURRENT_DIR}/src/tx_queue_flush.c + ${CURRENT_DIR}/src/tx_queue_front_send.c + ${CURRENT_DIR}/src/tx_queue_info_get.c + ${CURRENT_DIR}/src/tx_queue_initialize.c + ${CURRENT_DIR}/src/tx_queue_performance_info_get.c + ${CURRENT_DIR}/src/tx_queue_performance_system_info_get.c + ${CURRENT_DIR}/src/tx_queue_prioritize.c + ${CURRENT_DIR}/src/tx_queue_receive.c + ${CURRENT_DIR}/src/tx_queue_send.c + ${CURRENT_DIR}/src/tx_queue_send_notify.c + ${CURRENT_DIR}/src/tx_semaphore_ceiling_put.c + ${CURRENT_DIR}/src/tx_semaphore_cleanup.c + ${CURRENT_DIR}/src/tx_semaphore_create.c + ${CURRENT_DIR}/src/tx_semaphore_delete.c + ${CURRENT_DIR}/src/tx_semaphore_get.c + ${CURRENT_DIR}/src/tx_semaphore_info_get.c + ${CURRENT_DIR}/src/tx_semaphore_initialize.c + ${CURRENT_DIR}/src/tx_semaphore_performance_info_get.c + ${CURRENT_DIR}/src/tx_semaphore_performance_system_info_get.c + ${CURRENT_DIR}/src/tx_semaphore_prioritize.c + ${CURRENT_DIR}/src/tx_semaphore_put.c + ${CURRENT_DIR}/src/tx_semaphore_put_notify.c + ${CURRENT_DIR}/src/tx_thread_create.c + ${CURRENT_DIR}/src/tx_thread_entry_exit_notify.c + ${CURRENT_DIR}/src/tx_thread_identify.c + ${CURRENT_DIR}/src/tx_thread_info_get.c + ${CURRENT_DIR}/src/tx_thread_initialize.c + ${CURRENT_DIR}/src/tx_thread_performance_info_get.c + ${CURRENT_DIR}/src/tx_thread_performance_system_info_get.c + ${CURRENT_DIR}/src/tx_thread_preemption_change.c + ${CURRENT_DIR}/src/tx_thread_priority_change.c + ${CURRENT_DIR}/src/tx_thread_relinquish.c + ${CURRENT_DIR}/src/tx_thread_resume.c + ${CURRENT_DIR}/src/tx_thread_shell_entry.c + ${CURRENT_DIR}/src/tx_thread_sleep.c + ${CURRENT_DIR}/src/tx_thread_smp_utilities.c + ${CURRENT_DIR}/src/tx_thread_stack_analyze.c + ${CURRENT_DIR}/src/tx_thread_stack_error_handler.c + ${CURRENT_DIR}/src/tx_thread_stack_error_notify.c + ${CURRENT_DIR}/src/tx_thread_suspend.c + ${CURRENT_DIR}/src/tx_thread_system_preempt_check.c + ${CURRENT_DIR}/src/tx_thread_system_resume.c + ${CURRENT_DIR}/src/tx_thread_system_suspend.c + ${CURRENT_DIR}/src/tx_thread_terminate.c + ${CURRENT_DIR}/src/tx_thread_timeout.c + ${CURRENT_DIR}/src/tx_thread_time_slice.c + ${CURRENT_DIR}/src/tx_thread_time_slice_change.c + ${CURRENT_DIR}/src/tx_thread_wait_abort.c + ${CURRENT_DIR}/src/tx_time_get.c + ${CURRENT_DIR}/src/tx_timer_activate.c + ${CURRENT_DIR}/src/tx_timer_change.c + ${CURRENT_DIR}/src/tx_timer_create.c + ${CURRENT_DIR}/src/tx_timer_deactivate.c + ${CURRENT_DIR}/src/tx_timer_delete.c + ${CURRENT_DIR}/src/tx_timer_expiration_process.c + ${CURRENT_DIR}/src/tx_timer_info_get.c + ${CURRENT_DIR}/src/tx_timer_initialize.c + ${CURRENT_DIR}/src/tx_timer_performance_info_get.c + ${CURRENT_DIR}/src/tx_timer_performance_system_info_get.c + ${CURRENT_DIR}/src/tx_timer_system_activate.c + ${CURRENT_DIR}/src/tx_timer_system_deactivate.c + ${CURRENT_DIR}/src/tx_timer_thread_entry.c + ${CURRENT_DIR}/src/tx_time_set.c + ${CURRENT_DIR}/src/tx_trace_buffer_full_notify.c + ${CURRENT_DIR}/src/tx_trace_disable.c + ${CURRENT_DIR}/src/tx_trace_enable.c + ${CURRENT_DIR}/src/tx_trace_event_filter.c + ${CURRENT_DIR}/src/tx_trace_event_unfilter.c + ${CURRENT_DIR}/src/tx_trace_initialize.c + ${CURRENT_DIR}/src/tx_trace_interrupt_control.c + ${CURRENT_DIR}/src/tx_trace_isr_enter_insert.c + ${CURRENT_DIR}/src/tx_trace_isr_exit_insert.c + ${CURRENT_DIR}/src/tx_trace_object_register.c + ${CURRENT_DIR}/src/tx_trace_object_unregister.c + ${CURRENT_DIR}/src/tx_trace_user_event_insert.c + ${CURRENT_DIR}/src/tx_thread_smp_core_exclude.c + ${CURRENT_DIR}/src/tx_thread_smp_core_exclude_get.c + ${CURRENT_DIR}/src/tx_thread_smp_current_state_set.c + ${CURRENT_DIR}/src/tx_thread_smp_debug_entry_insert.c + ${CURRENT_DIR}/src/tx_thread_smp_high_level_initialize.c + ${CURRENT_DIR}/src/tx_thread_smp_rebalance_execute_list.c + ${CURRENT_DIR}/src/tx_timer_smp_core_exclude.c + ${CURRENT_DIR}/src/tx_timer_smp_core_exclude_get.c + + # {{END_TARGET_SOURCES}} +) + +# Add the Common/inc directory to the project include list +target_include_directories(${PROJECT_NAME} + PUBLIC + ${CURRENT_DIR}/inc +) + diff --git a/test/smp/cmake/threadx_smp/ports_smp/linux/gnu/CMakeLists.txt b/test/smp/cmake/threadx_smp/ports_smp/linux/gnu/CMakeLists.txt new file mode 100644 index 00000000..9c51522c --- /dev/null +++ b/test/smp/cmake/threadx_smp/ports_smp/linux/gnu/CMakeLists.txt @@ -0,0 +1,32 @@ + +set(CURRENT_DIR ${PROJECT_DIR}/ports_smp/linux/gnu) +target_sources(${PROJECT_NAME} + PRIVATE + # {{BEGIN_TARGET_SOURCES}} + ${CURRENT_DIR}/src/tx_initialize_low_level.c + ${CURRENT_DIR}/src/tx_thread_context_restore.c + ${CURRENT_DIR}/src/tx_thread_context_save.c + ${CURRENT_DIR}/src/tx_thread_interrupt_control.c + ${CURRENT_DIR}/src/tx_thread_schedule.c + ${CURRENT_DIR}/src/tx_thread_smp_core_get.c + ${CURRENT_DIR}/src/tx_thread_smp_core_preempt.c + ${CURRENT_DIR}/src/tx_thread_smp_current_state_get.c + ${CURRENT_DIR}/src/tx_thread_smp_current_thread_get.c + ${CURRENT_DIR}/src/tx_thread_smp_initialize_wait.c + ${CURRENT_DIR}/src/tx_thread_smp_low_level_initialize.c + ${CURRENT_DIR}/src/tx_thread_smp_protect.c + ${CURRENT_DIR}/src/tx_thread_smp_time_get.c + ${CURRENT_DIR}/src/tx_thread_smp_unprotect.c + ${CURRENT_DIR}/src/tx_thread_stack_build.c + ${CURRENT_DIR}/src/tx_thread_system_return.c + ${CURRENT_DIR}/src/tx_timer_interrupt.c + + # {{END_TARGET_SOURCES}} +) + +target_include_directories(${PROJECT_NAME} + PUBLIC + ${CURRENT_DIR}/inc +) + +target_compile_definitions(${PROJECT_NAME} PUBLIC "-D_GNU_SOURCE -DTX_LINUX_DEBUG_ENABLE") \ No newline at end of file diff --git a/test/smp/regression/testcontrol.c b/test/smp/regression/testcontrol.c new file mode 100644 index 00000000..1813d42f --- /dev/null +++ b/test/smp/regression/testcontrol.c @@ -0,0 +1,1609 @@ +/* This is the test control routine of the ThreadX kernel. All tests are dispatched from this routine. */ + +#define TX_THREAD_SMP_SOURCE_CODE + +#include "tx_api.h" +#include +#include "tx_initialize.h" +#include "tx_timer.h" +#include "tx_thread.h" +#include "tx_semaphore.h" +#include "tx_queue.h" +#include "tx_mutex.h" +#include "tx_block_pool.h" +#include "tx_byte_pool.h" +#include "tx_event_flags.h" + + +#define TEST_STACK_SIZE 6144 + + +/* Define the test control ThreadX objects... */ + +TX_THREAD test_control_thread; +TX_THREAD test_thread; +TX_THREAD test_thread1; +TX_THREAD test_thread2; +TX_THREAD test_thread3; +ULONG test_thread3_stack[256]; +TX_QUEUE test_queue; +ULONG test_thread2_stack[256]; +TX_TIMER test_timer; +TX_MUTEX init_mutex; +TX_MUTEX init_mutex_inherit; +TX_MUTEX cleanup_mutex; +TX_EVENT_FLAGS_GROUP cleanup_event_flags; +TX_BLOCK_POOL cleanup_block_pool; +TX_BYTE_POOL cleanup_byte_pool; +TX_QUEUE cleanup_queue; +TX_SEMAPHORE cleanup_semaphore; +TX_SEMAPHORE init_semaphore; +ULONG init_queue_area[20]; +TX_QUEUE init_queue; +TX_BYTE_POOL init_byte_pool; +ULONG init_byte_pool_area[50]; +TX_BLOCK_POOL init_block_pool; +ULONG init_block_pool_area[50]; +TX_EVENT_FLAGS_GROUP init_event_flags; +TX_TIMER init_timer; +TX_THREAD init_test_thread; +TX_THREAD second_test_thread; +#ifndef TX_TIMER_PROCESS_IN_ISR +TEST_FLAG threadx_delete_timer_thread; +#endif +TX_TIMER_INTERNAL **_timer_list_start_backup; +TEST_FLAG test_stack_analyze_flag; +TEST_FLAG test_initialize_flag; +TX_BLOCK_POOL fake_block_pool; +TX_BYTE_POOL fake_byte_pool; +TX_EVENT_FLAGS_GROUP fake_event_flags; +TX_MUTEX fake_mutex; +TX_QUEUE fake_queue; +TX_SEMAPHORE fake_semaphore; +TX_THREAD test_thread4; +TX_THREAD test_thread5; +TX_THREAD test_thread6; +TX_THREAD test_thread7; +TX_THREAD test_thread8; +TX_THREAD test_thread9; +TX_THREAD test_thread10; +TX_THREAD test_thread11; +TX_THREAD test_thread12; +TX_THREAD test_thread13; +TX_THREAD test_thread14; +ULONG test_thread4_stack[256]; +ULONG test_thread5_stack[256]; +ULONG test_thread6_stack[256]; +ULONG test_thread7_stack[256]; +ULONG test_thread8_stack[256]; +ULONG test_thread9_stack[256]; +ULONG test_thread10_stack[256]; +ULONG test_thread11_stack[256]; +ULONG test_thread12_stack[256]; +ULONG test_thread13_stack[256]; +ULONG test_thread14_stack[256]; + + +/* Define the test control global variables. */ + +ULONG test_control_return_status; +ULONG test_control_successful_tests; +ULONG test_control_failed_tests; +ULONG test_control_system_errors; + +UINT test_mutex_from_init; +UINT test_semaphore_from_init; +UINT test_queue_from_init; +UINT test_event_flags_from_init; +UINT test_byte_pool_create_init; +UINT test_block_pool_create_init; +UINT test_timer_create_init; + + +/* Remember the start of free memory. */ + +UCHAR *test_free_memory_ptr; + + +/* Define the function pointer for ISR dispatch. */ + +VOID (*test_isr_dispatch)(void); + + +UCHAR test_control_memory[0x60000]; +UCHAR tests_memory[0x60000]; + +UINT mutex_priority_change_extension_selection; +UINT priority_change_extension_selection; +TEST_FLAG test_forced_mutex_timeout; +TEST_FLAG threadx_byte_allocate_loop_test; +TEST_FLAG threadx_byte_release_loop_test; +TEST_FLAG threadx_mutex_suspension_put_test; +TEST_FLAG threadx_mutex_suspension_priority_test; + + +/* Define the external reference for the preempt disable flag. */ + +extern volatile UINT _tx_thread_preempt_disable; +extern volatile ULONG _tx_thread_system_state[TX_THREAD_SMP_MAX_CORES]; + + +/* Define test entry pointer type. */ + +typedef struct TEST_ENTRY_STRUCT +{ + +VOID (*test_entry)(void *); +} TEST_ENTRY; + + +/* Define the prototypes for the test entry points. */ + +void threadx_block_memory_basic_application_define(void *); +void threadx_block_memory_error_detection_application_define(void *); +void threadx_block_memory_suspension_application_define(void *); +void threadx_block_memory_suspension_timeout_application_define(void *); +void threadx_block_memory_thread_terminate_application_define(void *); +void threadx_block_memory_prioritize_application_define(void *); +void threadx_block_memory_information_application_define(void *); + +void threadx_byte_memory_basic_application_define(void *); +void threadx_byte_memory_thread_contention_application_define(void *); +void threadx_byte_memory_suspension_application_define(void *); +void threadx_byte_memory_suspension_timeout_application_define(void *); +void threadx_byte_memory_thread_terminate_application_define(void *); +void threadx_byte_memory_prioritize_application_define(void *); +void threadx_byte_memory_information_application_define(void *); + +void threadx_event_flag_basic_application_define(void *); +void threadx_event_flag_suspension_application_define(void *); +void threadx_event_flag_suspension_consume_application_define(void *); +void threadx_event_flag_suspension_different_bits_application_define(void *); +void threadx_event_flag_suspension_different_bits_consume_application_define(void *); +void threadx_event_flag_suspension_timeout_application_define(void *); +void threadx_event_flag_thread_terminate_application_define(void *); +void threadx_event_flag_single_thread_terminate_application_define(void *); +void threadx_event_flag_isr_set_clear_application_define(void *); +void threadx_event_flag_isr_wait_abort_application_define(void *); +void threadx_event_flag_information_application_define(void *); + +void threadx_interrupt_control_application_define(void *); + +void threadx_mutex_basic_application_define(void *); +void threadx_mutex_delete_application_define(void *); +void threadx_mutex_preemption_application_define(void *); +void threadx_mutext_no_preemption_application_define(void *); +void threadx_mutex_suspension_timeout_application_define(void *); +void threadx_mutex_thread_terminate_application_define(void *); +void threadx_mutex_priority_inheritance_application_define(void *); +void threadx_mutex_nested_priority_inheritance_application_define(void *); +void threadx_mutex_prioritize_application_define(void *); +void threadx_mutex_information_application_define(void *); + +void threadx_queue_basic_application_define(void *); +void threadx_queue_basic_two_word_application_define(void *); +void threadx_queue_basic_four_word_application_define(void *); +void threadx_queue_basic_eight_word_application_define(void *); +void threadx_queue_basic_sixteen_word_application_define(void *); +void threadx_queue_empty_suspension_application_define(void *); +void threadx_queue_full_suspension_application_define(void *); +void threadx_queue_suspension_timeout_application_define(void *); +void threadx_queue_thread_terminate_application_define(void *); +void threadx_queue_flush_application_define(void *); +void threadx_queue_flush_no_suspension_application_define(void *); +void threadx_queue_front_send_application_define(void *); +void threadx_queue_prioritize_application_define(void *); +void threadx_queue_information_application_define(void *); + +void threadx_semaphore_basic_application_define(void *); +void threadx_semaphore_delete_application_define(void *); +void threadx_semaphore_preemption_application_define(void *); +void threadx_semaphore_non_preemption_application_define(void *); +void threadx_semaphore_timeout_application_define(void *); +void threadx_semaphore_thread_terminate_application_define(void *); +void threadx_semaphore_prioritize_application_define(void *); +void threadx_semaphore_ceiling_put_application_define(void *); +void threadx_semaphore_information_application_define(void *); + +void threadx_thread_basic_execution_application_define(void *); +void threadx_thread_completed_application_define(void *); +void threadx_thread_relinquish_application_define(void *); +void threadx_thread_simple_supsend_application_define(void *); +void threadx_thread_multiple_suspension_application_define(void *); +void threadx_thread_multiple_non_current_suspension_application_define(void *); +void threadx_thread_multi_level_preemption_threshold_application_define(void *); +void threadx_thread_preemptable_suspension_application_define(void *); +void threadx_thread_basic_time_slice_application_define(void *); +void threadx_thread_multiple_time_slice_application_define(void *); +void threadx_thread_simple_sleep_application_define(void *); +void threadx_thread_simple_sleep_non_clear_application_define(void *); +void threadx_thread_sleep_for_100ticks_application_define(void *); +void threadx_thread_multiple_sleep_application_define(void *); +void threadx_thread_terminate_delete_application_define(void *); +void threadx_thread_preemption_change_application_define(void *); +void threadx_thread_priority_change_application_define(void *); +void threadx_thread_time_slice_change_application_define(void *); +void threadx_thread_sleep_terminate_application_define(void *); +void threadx_thread_delayed_suspension_application_define(void *); +void threadx_thread_wait_abort_application_define(void *); +void threadx_thread_wait_abort_and_isr_application_define(void *); +void threadx_thread_create_preemption_threshold_application_define(void *); +void threadx_thread_information_application_define(void *); +void threadx_thread_reset_application_define(void *); +void threadx_thread_stack_checking_application_define(void *); + +void threadx_time_get_set_application_define(void *); + +void threadx_timer_simple_application_define(void *); +void threadx_timer_activate_deactivate_application_define(void *); +void threadx_timer_deactivate_accuracy_application_define(void *); +void threadx_timer_large_timer_accuracy_application_define(void *); +void threadx_timer_multiple_application_define(void *); +void threadx_timer_multiple_accuracy_application_define(void *); +void threadx_timer_information_application_define(void *); + +void threadx_trace_basic_application_define(void *); + +void threadx_smp_rebalance_exclustion_test(void *first_unused_memory); +void threadx_smp_two_threads_one_core_test(void *first_unused_memory); +void threadx_smp_multiple_threads_one_core_test(void *first_unused_memory); +void threadx_smp_one_thread_dynamic_exclusion_test(void *first_unused_memory); +void threadx_smp_non_trivial_scheduling_test(void *first_unused_memory); +void threadx_smp_resume_suspend_accending_order_test(void *first_unused_memory); +void threadx_smp_resume_suspend_decending_order_test(void *first_unused_memory); +void threadx_smp_preemption_threshold_test(void *first_unused_memory); +void threadx_smp_relinquish_test(void *first_unused_memory); +void threadx_smp_time_slice_test(void *first_unused_memory); +void threadx_smp_random_resume_suspend_test(void *first_unused_memory); +void threadx_smp_random_resume_suspend_exclusion_test(void *first_unused_memory); +void threadx_smp_random_resume_suspend_exclusion_pt_test(void *first_unused_memory); +void test_application_define(void *first_unused_memory); + + +/* Define the array of test entry points. */ + +TEST_ENTRY test_control_tests[] = +{ +#if CTEST + test_application_define, +#else + + threadx_smp_rebalance_exclustion_test, + threadx_smp_two_threads_one_core_test, + threadx_smp_multiple_threads_one_core_test, + threadx_smp_one_thread_dynamic_exclusion_test, + threadx_smp_non_trivial_scheduling_test, + threadx_smp_resume_suspend_accending_order_test, + threadx_smp_resume_suspend_decending_order_test, + threadx_smp_preemption_threshold_test, + threadx_smp_relinquish_test, + threadx_smp_time_slice_test, + threadx_smp_random_resume_suspend_test, + threadx_smp_random_resume_suspend_exclusion_test, + threadx_smp_random_resume_suspend_exclusion_pt_test, + + threadx_block_memory_basic_application_define, + threadx_block_memory_error_detection_application_define, + threadx_block_memory_prioritize_application_define, + threadx_block_memory_suspension_application_define, + threadx_block_memory_suspension_timeout_application_define, + threadx_block_memory_thread_terminate_application_define, + threadx_block_memory_information_application_define, + + threadx_byte_memory_basic_application_define, + threadx_byte_memory_suspension_application_define, + threadx_byte_memory_suspension_timeout_application_define, + threadx_byte_memory_thread_terminate_application_define, + threadx_byte_memory_prioritize_application_define, + threadx_byte_memory_thread_contention_application_define, + threadx_byte_memory_information_application_define, + + threadx_event_flag_basic_application_define, + threadx_event_flag_suspension_application_define, + threadx_event_flag_suspension_consume_application_define, + threadx_event_flag_suspension_different_bits_application_define, + threadx_event_flag_suspension_different_bits_consume_application_define, + threadx_event_flag_suspension_timeout_application_define, + threadx_event_flag_thread_terminate_application_define, + threadx_event_flag_single_thread_terminate_application_define, + threadx_event_flag_isr_set_clear_application_define, + threadx_event_flag_isr_wait_abort_application_define, + threadx_event_flag_information_application_define, + + threadx_interrupt_control_application_define, + + threadx_mutex_basic_application_define, + threadx_mutex_delete_application_define, + threadx_mutex_preemption_application_define, + threadx_mutext_no_preemption_application_define, + threadx_mutex_suspension_timeout_application_define, + threadx_mutex_thread_terminate_application_define, + threadx_mutex_priority_inheritance_application_define, + threadx_mutex_prioritize_application_define, + threadx_mutex_nested_priority_inheritance_application_define, + threadx_mutex_information_application_define, + + threadx_queue_basic_application_define, + threadx_queue_basic_two_word_application_define, + threadx_queue_basic_four_word_application_define, + threadx_queue_basic_eight_word_application_define, + threadx_queue_basic_sixteen_word_application_define, + threadx_queue_empty_suspension_application_define, + threadx_queue_full_suspension_application_define, + threadx_queue_suspension_timeout_application_define, + threadx_queue_thread_terminate_application_define, + threadx_queue_flush_application_define, + threadx_queue_flush_no_suspension_application_define, + threadx_queue_front_send_application_define, + threadx_queue_prioritize_application_define, + threadx_queue_information_application_define, + + threadx_semaphore_basic_application_define, + threadx_semaphore_delete_application_define, + threadx_semaphore_preemption_application_define, + threadx_semaphore_non_preemption_application_define, + threadx_semaphore_timeout_application_define, + threadx_semaphore_thread_terminate_application_define, + threadx_semaphore_prioritize_application_define, + threadx_semaphore_ceiling_put_application_define, + threadx_semaphore_information_application_define, + + threadx_thread_basic_execution_application_define, + threadx_thread_completed_application_define, + threadx_thread_relinquish_application_define, + threadx_thread_simple_supsend_application_define, + threadx_thread_multiple_suspension_application_define, + threadx_thread_multiple_non_current_suspension_application_define, + threadx_thread_multi_level_preemption_threshold_application_define, + threadx_thread_preemptable_suspension_application_define, + threadx_thread_basic_time_slice_application_define, + threadx_thread_multiple_time_slice_application_define, + threadx_thread_simple_sleep_application_define, + threadx_thread_simple_sleep_non_clear_application_define, + threadx_thread_sleep_for_100ticks_application_define, + threadx_thread_multiple_sleep_application_define, + threadx_thread_terminate_delete_application_define, + + threadx_thread_priority_change_application_define, + + threadx_thread_time_slice_change_application_define, + threadx_thread_sleep_terminate_application_define, + threadx_thread_delayed_suspension_application_define, + threadx_thread_wait_abort_application_define, + threadx_thread_wait_abort_and_isr_application_define, + threadx_thread_create_preemption_threshold_application_define, + threadx_thread_preemption_change_application_define, + threadx_thread_information_application_define, + threadx_thread_reset_application_define, + threadx_thread_stack_checking_application_define, + + threadx_time_get_set_application_define, + + threadx_timer_simple_application_define, + threadx_timer_activate_deactivate_application_define, + threadx_timer_deactivate_accuracy_application_define, + threadx_timer_large_timer_accuracy_application_define, + threadx_timer_multiple_application_define, + threadx_timer_multiple_accuracy_application_define, + threadx_timer_information_application_define, + + threadx_trace_basic_application_define, +#endif + + TX_NULL, +}; + +/* Define thread prototypes. */ + +void test_control_thread_entry(ULONG thread_input); +void test_thread_entry(ULONG thread_input); +void test_thread_entry1(ULONG thread_input); +void test_control_return(UINT status); +void test_control_cleanup(void); +void test_exit_notify(TX_THREAD *thread_ptr, UINT type); + + +/* Define necessary exernal references. */ + +#ifdef __ghs +extern TX_MUTEX __ghLockMutex; +#endif + +extern TX_TIMER *_tx_timer_created_ptr; +extern ULONG _tx_timer_created_count; +#ifndef TX_TIMER_PROCESS_IN_ISR +extern TX_THREAD _tx_timer_thread; +#endif +extern TX_THREAD *_tx_thread_created_ptr; +extern ULONG _tx_thread_created_count; +extern TX_SEMAPHORE *_tx_semaphore_created_ptr; +extern ULONG _tx_semaphore_created_count; +extern TX_QUEUE *_tx_queue_created_ptr; +extern ULONG _tx_queue_created_count; +extern TX_MUTEX *_tx_mutex_created_ptr; +extern ULONG _tx_mutex_created_count; +extern TX_EVENT_FLAGS_GROUP *_tx_event_flags_created_ptr; +extern ULONG _tx_event_flags_created_count; +extern TX_BYTE_POOL *_tx_byte_pool_created_ptr; +extern ULONG _tx_byte_pool_created_count; +extern TX_BLOCK_POOL *_tx_block_pool_created_ptr; +extern ULONG _tx_block_pool_created_count; + +#ifdef EXTERNAL_EXIT +void external_exit(UINT code); +#endif + + +/* Define the interrupt processing dispatcher. The individual tests will set this up when they desire + asynchrouns processing for testing purposes. */ + +void test_interrupt_dispatch(void) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Test calling tx_thread_relinquish from ISR to see if the error checking throws it out. */ + tx_thread_relinquish(); +#endif + + /* Check for something to run... */ + if (test_isr_dispatch) + { + + (test_isr_dispatch)(); + } +} + + +/* Define init timer entry. */ + +static void init_timer_entry(ULONG timer_input) +{ + +} + + +#ifndef TX_TIMER_PROCESS_IN_ISR + +/* Define the deletion of the system timer thread. */ + +void delete_timer_thread(void) +{ + + _tx_thread_terminate(&_tx_timer_thread); + _tx_thread_delete(&_tx_timer_thread); +} + +#endif + + +/* Define main entry point. */ +#ifndef EXTERNAL_MAIN +void main() +{ + +#ifndef TX_MISRA_ENABLE +#ifndef TX_MANUAL_TEST + + /* Test the pre-initialize path through _tx_initialize_kernel_enter. */ + _tx_thread_system_state[0] = TX_INITIALIZE_ALMOST_DONE; + test_initialize_flag = 1; + + /* Call the internal kernel enter function to exercise two paths. */ + _tx_initialize_kernel_enter(); + _tx_thread_system_state[0] = 0; + +#ifndef TX_TIMER_PROCESS_IN_ISR + threadx_delete_timer_thread = 1; +#endif +#endif +#endif + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} +#endif + + +/* Define what the initial system looks like. */ + +void tx_application_define(void *first_unused_memory) +{ + +UCHAR *pointer; +VOID (*temp_mutex_release)(TX_THREAD *thread_ptr); +TX_THREAD *temp_thread; +UINT old_preemption; +ULONG old_time_slice; +UINT status; +ULONG flags; +ULONG temp; +UINT i, j; + + + /* Initialize the test error/success counters. */ + test_control_successful_tests = 0; + test_control_failed_tests = 0; + test_control_system_errors = 0; + + /* Create two equal priority threads. */ + status = tx_thread_create(&test_thread4, "test thread 4", test_thread_entry1, 4, + test_thread4_stack, sizeof(test_thread4_stack), 15, 15, TX_NO_TIME_SLICE, TX_DONT_START); + status += tx_thread_create(&test_thread5, "test thread 5", test_thread_entry1, 5, + test_thread5_stack, sizeof(test_thread5_stack), 15, 15, TX_NO_TIME_SLICE, TX_DONT_START); + status += tx_thread_create(&test_thread6, "test thread 6", test_thread_entry1, 6, + test_thread6_stack, sizeof(test_thread6_stack), 16, 16, TX_NO_TIME_SLICE, TX_DONT_START); + status += tx_thread_create(&test_thread7, "test thread 7", test_thread_entry1, 7, + test_thread7_stack, sizeof(test_thread7_stack), 17, 17, TX_NO_TIME_SLICE, TX_DONT_START); + status += tx_thread_create(&test_thread8, "test thread 8", test_thread_entry1, 8, + test_thread8_stack, sizeof(test_thread8_stack), 18, 18, TX_NO_TIME_SLICE, TX_DONT_START); + status += tx_thread_create(&test_thread9, "test thread 9", test_thread_entry1, 9, + test_thread9_stack, sizeof(test_thread9_stack), 19, 19, TX_NO_TIME_SLICE, TX_DONT_START); + status += tx_thread_create(&test_thread10, "test thread 10", test_thread_entry1, 10, + test_thread10_stack, sizeof(test_thread10_stack), 20, 20, TX_NO_TIME_SLICE, TX_DONT_START); + status += tx_thread_create(&test_thread11, "test thread 11", test_thread_entry1, 11, + test_thread11_stack, sizeof(test_thread11_stack), 20, 20, TX_NO_TIME_SLICE, TX_DONT_START); + status += tx_thread_create(&test_thread12, "test thread 12", test_thread_entry1, 12, + test_thread12_stack, sizeof(test_thread12_stack), 20, 20, TX_NO_TIME_SLICE, TX_DONT_START); + status += tx_thread_create(&test_thread13, "test thread 13", test_thread_entry1, 13, + test_thread13_stack, sizeof(test_thread13_stack), 20, 20, TX_NO_TIME_SLICE, TX_DONT_START); + status += tx_thread_create(&test_thread14, "test thread 14", test_thread_entry1, 14, + test_thread14_stack, sizeof(test_thread14_stack), 20, 20, TX_NO_TIME_SLICE, TX_DONT_START); + status += tx_thread_smp_core_exclude(&test_thread4, 0xD); + status += tx_thread_smp_core_exclude(&test_thread5, 0xD); + status += tx_thread_resume(&test_thread4); + status += tx_thread_suspend(&test_thread4); + status += tx_thread_resume(&test_thread4); + status += tx_thread_resume(&test_thread5); + status += tx_thread_suspend(&test_thread4); + status += tx_thread_suspend(&test_thread5); + + /* Test the fringe cases in tx_thread_system_resume to make sure the behave properly. */ + status += tx_thread_smp_core_exclude(&test_thread14, 0); + status += tx_thread_smp_core_exclude(&test_thread13, 0); + status += tx_thread_smp_core_exclude(&test_thread12, 0); + status += tx_thread_smp_core_exclude(&test_thread11, 0); + status += tx_thread_smp_core_exclude(&test_thread10, 0); + status += tx_thread_smp_core_exclude(&test_thread9, 0xC); + status += tx_thread_smp_core_exclude(&test_thread8, 0x3); + status += tx_thread_smp_core_exclude(&test_thread7, 0xE); + status += tx_thread_smp_core_exclude(&test_thread6, 0xD); + status += tx_thread_smp_core_exclude(&test_thread5, 0xB); + status += tx_thread_smp_core_exclude(&test_thread4, 0x7); + test_thread13.tx_thread_timer.tx_timer_internal_active_next = &test_thread13.tx_thread_timer; + test_thread13.tx_thread_timer.tx_timer_internal_list_head = (TX_TIMER_INTERNAL **) &test_thread13.tx_thread_timer; + status += tx_thread_resume(&test_thread14); + status += tx_thread_resume(&test_thread13); + status += tx_thread_resume(&test_thread12); + status += tx_thread_resume(&test_thread11); + status += tx_thread_resume(&test_thread10); + status += tx_thread_resume(&test_thread9); + status += tx_thread_resume(&test_thread8); + status += tx_thread_resume(&test_thread7); + status += tx_thread_resume(&test_thread6); + status += tx_thread_resume(&test_thread5); + status += tx_thread_resume(&test_thread4); + status += tx_thread_suspend(&test_thread14); + status += tx_thread_suspend(&test_thread13); + status += tx_thread_suspend(&test_thread12); + status += tx_thread_suspend(&test_thread11); + status += tx_thread_suspend(&test_thread10); + status += tx_thread_suspend(&test_thread9); + status += tx_thread_suspend(&test_thread8); + status += _tx_thread_preemption_change(&test_thread8, 17, &old_preemption); + status += tx_thread_resume(&test_thread8); + status += tx_thread_suspend(&test_thread8); + status += tx_thread_suspend(&test_thread7); + status += tx_thread_suspend(&test_thread6); + status += tx_thread_suspend(&test_thread5); + status += tx_thread_suspend(&test_thread4); + + /* Setup a pointer to the first unused memory. */ + pointer = (UCHAR *) &test_control_memory[0]; //first_unused_memory; + + /* Create the test control thread. */ + tx_thread_create(&test_control_thread, "test control thread", test_control_thread_entry, 0, + pointer, TEST_STACK_SIZE, + 17, 15, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE; + + /* Create the test thread. */ + tx_thread_create(&test_thread, "test thread", test_thread_entry, 0, + pointer, TEST_STACK_SIZE, + 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE; + + /* Create the second test thread. */ + tx_thread_create(&test_thread1, "test thread 1", test_thread_entry1, 0, + pointer, TEST_STACK_SIZE, + 15, 15, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE; + + /* Suspend the test thread temporarily. */ + tx_thread_suspend(&test_thread); + + /* Resume the test thread again to exercise the resume code fully. */ + tx_thread_resume(&test_thread); + + /* Timer change just to exercise the code... an error from initialization! */ + test_timer.tx_timer_id = TX_TIMER_ID; + tx_timer_change(&test_timer, 1, 1); + + /* Test mutex created and used in initialization. */ + test_mutex_from_init = tx_mutex_create(&init_mutex, "init mutex", TX_INHERIT); + test_mutex_from_init += tx_mutex_get(&init_mutex, TX_NO_WAIT); + test_mutex_from_init += tx_mutex_get(&init_mutex, TX_NO_WAIT); + test_mutex_from_init += tx_mutex_put(&init_mutex); + test_mutex_from_init += tx_mutex_put(&init_mutex); + test_mutex_from_init = tx_mutex_create(&init_mutex_inherit, "init mutex", TX_INHERIT); + test_mutex_from_init += tx_mutex_get(&init_mutex_inherit, TX_NO_WAIT); + test_mutex_from_init += tx_mutex_get(&init_mutex_inherit, TX_NO_WAIT); + test_mutex_from_init += tx_mutex_put(&init_mutex_inherit); + test_mutex_from_init += tx_mutex_put(&init_mutex_inherit); + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Test timer create from initialization. */ + test_block_pool_create_init = tx_block_pool_create(&init_block_pool, "init block pool", 10, init_block_pool_area, sizeof(init_block_pool_area)); + + /* Test byte pool create from initialization. */ + test_byte_pool_create_init = tx_byte_pool_create(&init_byte_pool, "init byte pool", init_byte_pool_area, sizeof(init_byte_pool_area)); + test_byte_pool_create_init += tx_byte_allocate(&init_byte_pool, (VOID **) &pointer, 20, TX_NO_WAIT); + test_byte_pool_create_init += tx_byte_release(pointer); + + /* Test event flag create from initialization. */ + test_event_flags_from_init = tx_event_flags_create(&init_event_flags, "init events"); + + /* Test queue create from initialization. */ + test_queue_from_init = tx_queue_create(&init_queue, "init queue", TX_1_ULONG, init_queue_area, sizeof(init_queue_area)); + + /* Test semaphore create from initialization. */ + test_semaphore_from_init = tx_semaphore_create(&init_semaphore, "init semaphore", 0); + + /* Test timer creat from initialization. */ + test_timer_create_init = tx_timer_create(&init_timer, "init timer", init_timer_entry, 0x5678, + 100, 200, TX_AUTO_ACTIVATE); + + /* Test calling tx_thread_relinquish to see if the error checking throws it out. */ + tx_thread_relinquish(); +#endif + + /* Remember the free memory pointer. */ + test_free_memory_ptr = &tests_memory[0]; //pointer; + + /* Clear the ISR dispatch. */ + test_isr_dispatch = TX_NULL; + + /* Ensure that _tx_thread_time_slice can handle NULL thread, note that current thread pointer is NULL at this point. */ + _tx_thread_time_slice(); + + /* Test to make sure _tx_thread_time_slice can handle a none-ready thread. */ + init_test_thread.tx_thread_state = TX_IO_DRIVER; + init_test_thread.tx_thread_new_time_slice = 0; + init_test_thread.tx_thread_suspend_cleanup = TX_NULL; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_suspending = TX_TRUE; + _tx_thread_current_ptr[0] = &init_test_thread; + _tx_thread_time_slice(); + + /* Test to make sure _tx_thread_time_slice can handle preemption-threshold set. */ + init_test_thread.tx_thread_state = TX_READY; + init_test_thread.tx_thread_new_time_slice = 0; + init_test_thread.tx_thread_priority = 10; + init_test_thread.tx_thread_preempt_threshold = 9; + init_test_thread.tx_thread_ready_next = &init_test_thread; + init_test_thread.tx_thread_ready_previous = &init_test_thread; + _tx_thread_time_slice(); + _tx_thread_current_ptr[0] = TX_NULL; + + /* Test to make sure _tx_thread_shell_entry can handle a NULL mutex release function pointer. */ + temp_mutex_release = _tx_thread_mutex_release; + temp_thread = _tx_thread_execute_ptr[0]; + _tx_thread_mutex_release = TX_NULL; + init_test_thread.tx_thread_state = TX_READY; + init_test_thread.tx_thread_suspend_cleanup = TX_NULL; + init_test_thread.tx_thread_new_time_slice = 0; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_suspending = TX_FALSE; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_entry = test_thread_entry1; + _tx_thread_current_ptr[0] = &init_test_thread; + _tx_thread_execute_ptr[0] = &init_test_thread; + _tx_thread_entry_exit_notify(&init_test_thread, test_exit_notify); + _tx_thread_shell_entry(); + _tx_thread_current_ptr[0] = TX_NULL; + _tx_thread_execute_ptr[0] = temp_thread; + _tx_thread_mutex_release = temp_mutex_release; /* Recover Mutex release pointer. */ + + /* Test _tx_thread_system_suspend when not current, preemption is needed but disabled. */ + temp_thread = _tx_thread_execute_ptr[0]; + init_test_thread.tx_thread_state = TX_READY; + init_test_thread.tx_thread_suspend_cleanup = TX_NULL; + init_test_thread.tx_thread_new_time_slice = 0; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_suspending = TX_FALSE; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_entry = test_thread_entry1; + _tx_thread_execute_ptr[0] = &init_test_thread; +#ifndef TX_NOT_INTERRUPTABLE + _tx_thread_preempt_disable++; +#endif + _tx_thread_system_suspend(&init_test_thread); + _tx_thread_execute_ptr[0] = temp_thread; + + /* Test _tx_thread_system_resume when not current, suspending and in a COMPLETED state. */ + temp_thread = _tx_thread_execute_ptr[0]; + init_test_thread.tx_thread_state = TX_COMPLETED; + init_test_thread.tx_thread_suspend_cleanup = TX_NULL; + init_test_thread.tx_thread_new_time_slice = 0; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_suspending = TX_TRUE; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_entry = test_thread_entry1; +#ifndef TX_NOT_INTERRUPTABLE + _tx_thread_preempt_disable++; +#endif + _tx_thread_execute_ptr[0] = &init_test_thread; + _tx_thread_system_resume(&init_test_thread); + _tx_thread_execute_ptr[0] = temp_thread; + + + /* Test _tx_thread_system_resume when not current, not suspending and already in a TX_READY state. */ + temp_thread = _tx_thread_execute_ptr[0]; + init_test_thread.tx_thread_state = TX_READY; + init_test_thread.tx_thread_suspend_cleanup = TX_NULL; + init_test_thread.tx_thread_new_time_slice = 0; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_suspending = TX_FALSE; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_entry = test_thread_entry1; +#ifndef TX_NOT_INTERRUPTABLE + _tx_thread_preempt_disable++; +#endif + _tx_thread_execute_ptr[0] = &init_test_thread; + _tx_thread_system_resume(&init_test_thread); + _tx_thread_execute_ptr[0] = temp_thread; + + /* Test _tx_thread_system_resume when not current, suspending and in a TERMINATED state. */ + temp_thread = _tx_thread_execute_ptr[0]; + init_test_thread.tx_thread_state = TX_TERMINATED; + init_test_thread.tx_thread_suspend_cleanup = TX_NULL; + init_test_thread.tx_thread_new_time_slice = 0; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_suspending = TX_TRUE; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_entry = test_thread_entry1; +#ifndef TX_NOT_INTERRUPTABLE + _tx_thread_preempt_disable++; +#endif + _tx_thread_execute_ptr[0] = &init_test_thread; + _tx_thread_system_resume(&init_test_thread); + _tx_thread_execute_ptr[0] = temp_thread; + + /* Test tx_thread_resume to test the saved_thread_ptr being NULL. */ + temp_thread = _tx_thread_execute_ptr[0]; + _tx_thread_execute_ptr[0] = TX_NULL; + tx_thread_resume(&test_thread1); + tx_thread_suspend(&test_thread1); + _tx_thread_execute_ptr[0] = temp_thread; + + /* Test preemption change when the new priority is the same as the threshold. */ + init_test_thread.tx_thread_state = TX_SUSPENDED; + init_test_thread.tx_thread_suspend_cleanup = TX_NULL; + init_test_thread.tx_thread_new_time_slice = 0; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_suspending = TX_FALSE; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_user_priority = 10; + init_test_thread.tx_thread_user_preempt_threshold = 10; + init_test_thread.tx_thread_priority = 10; + init_test_thread.tx_thread_preempt_threshold = 10; + init_test_thread.tx_thread_entry = test_thread_entry1; + _tx_thread_preemption_change(&init_test_thread, 10, &old_preemption); + +#ifndef TX_NOT_INTERRUPTABLE + + /* Test semaphore cleanup with an invalid semaphore ID. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_semaphore; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup); + cleanup_semaphore.tx_semaphore_id = 0; + cleanup_semaphore.tx_semaphore_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_semaphore_cleanup(&init_test_thread, 0); + + /* Test semaphore cleanup with an invalid suspension sequence. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_semaphore; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup); + cleanup_semaphore.tx_semaphore_id = 0; + cleanup_semaphore.tx_semaphore_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_semaphore_cleanup(&init_test_thread, 1); + + /* Test semaphore cleanup with a NULL semaphore pointer. */ + init_test_thread.tx_thread_suspend_control_block = TX_NULL; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup); + cleanup_semaphore.tx_semaphore_id = TX_SEMAPHORE_ID; + cleanup_semaphore.tx_semaphore_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_semaphore_cleanup(&init_test_thread, 0); + + /* Test semaphore cleanup with an valid semaphore ID but a suspension count of 0. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_semaphore; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_semaphore_cleanup); + cleanup_semaphore.tx_semaphore_id = TX_SEMAPHORE_ID; + cleanup_semaphore.tx_semaphore_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_semaphore_cleanup(&init_test_thread, 0); + + /* Test queue cleanup with a NULL cleanup pointer. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue; + init_test_thread.tx_thread_suspend_cleanup = TX_NULL; + cleanup_queue.tx_queue_id = 0; + cleanup_queue.tx_queue_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_queue_cleanup(&init_test_thread, 0); + + /* Test queue cleanup with a NULL queue pointer. */ + init_test_thread.tx_thread_suspend_control_block = TX_NULL; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup); + cleanup_queue.tx_queue_id = 0; + cleanup_queue.tx_queue_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_queue_cleanup(&init_test_thread, 0); + + /* Test queue cleanup with an invalid queue ID. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup); + cleanup_queue.tx_queue_id = 0; + cleanup_queue.tx_queue_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_queue_cleanup(&init_test_thread, 0); + + /* Test queue cleanup with an invalid suspension sequence. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup); + cleanup_queue.tx_queue_id = 0; + cleanup_queue.tx_queue_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_queue_cleanup(&init_test_thread, 1); + + /* Test queue cleanup with an valid queue ID but a suspension count of 0. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_queue; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_queue_cleanup); + cleanup_queue.tx_queue_id = TX_QUEUE_ID; + cleanup_queue.tx_queue_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_queue_cleanup(&init_test_thread, 0); + + /* Test mutex cleanup with a NULL cleanup pointer. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex; + init_test_thread.tx_thread_suspend_cleanup = TX_NULL; + cleanup_mutex.tx_mutex_id = 0; + cleanup_mutex.tx_mutex_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_mutex_cleanup(&init_test_thread, 0); + + /* Test mutex cleanup with a NULL mutex pointer. */ + init_test_thread.tx_thread_suspend_control_block = TX_NULL; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup); + cleanup_mutex.tx_mutex_id = 0; + cleanup_mutex.tx_mutex_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_mutex_cleanup(&init_test_thread, 0); + + /* Test mutex cleanup with an invalid mutex ID. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup); + cleanup_mutex.tx_mutex_id = 0; + cleanup_mutex.tx_mutex_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_mutex_cleanup(&init_test_thread, 0); + + /* Test mutex cleanup with an invalid suspension sequence. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup); + cleanup_mutex.tx_mutex_id = 0; + cleanup_mutex.tx_mutex_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_mutex_cleanup(&init_test_thread, 1); + + /* Test mutex cleanup with an valid mutex ID but a suspension count of 0. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_mutex; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_mutex_cleanup); + cleanup_mutex.tx_mutex_id = TX_MUTEX_ID; + cleanup_mutex.tx_mutex_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_mutex_cleanup(&init_test_thread, 0); + + /* Test event flag cleanup with a NULL cleanup pointer. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags; + init_test_thread.tx_thread_suspend_cleanup = TX_NULL; + cleanup_event_flags.tx_event_flags_group_id = 0; + cleanup_event_flags.tx_event_flags_group_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_event_flags_cleanup(&init_test_thread, 0); + + /* Test event flag cleanup with a NULL event flag pointer. */ + init_test_thread.tx_thread_suspend_control_block = TX_NULL; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup); + cleanup_event_flags.tx_event_flags_group_id = 0; + cleanup_event_flags.tx_event_flags_group_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_event_flags_cleanup(&init_test_thread, 0); + + /* Test event flag cleanup with an invalid ID. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup); + cleanup_event_flags.tx_event_flags_group_id = 0; + cleanup_event_flags.tx_event_flags_group_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_event_flags_cleanup(&init_test_thread, 0); + + /* Test event flag cleanup with an invalid suspension sequence. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup); + cleanup_event_flags.tx_event_flags_group_id = 0; + cleanup_event_flags.tx_event_flags_group_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_event_flags_cleanup(&init_test_thread, 1); + + /* Test event flag cleanup with an valid ID but a suspension count of 0. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_event_flags; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup); + cleanup_event_flags.tx_event_flags_group_id = TX_EVENT_FLAGS_ID; + cleanup_event_flags.tx_event_flags_group_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_event_flags_cleanup(&init_test_thread, 0); + + /* Test block pool cleanup with a NULL cleanup pointer. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool; + init_test_thread.tx_thread_suspend_cleanup = TX_NULL; + cleanup_block_pool.tx_block_pool_id = 0; + cleanup_block_pool.tx_block_pool_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_block_pool_cleanup(&init_test_thread, 0); + + /* Test block pool cleanup with a NULL block pool pointer. */ + init_test_thread.tx_thread_suspend_control_block = TX_NULL; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup); + cleanup_block_pool.tx_block_pool_id = 0; + cleanup_block_pool.tx_block_pool_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_block_pool_cleanup(&init_test_thread, 0); + + /* Test block pool cleanup with an invalid ID. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup); + cleanup_block_pool.tx_block_pool_id = 0; + cleanup_block_pool.tx_block_pool_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_block_pool_cleanup(&init_test_thread, 0); + + /* Test block pool cleanup with an invalid suspension sequence. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup); + cleanup_block_pool.tx_block_pool_id = 0; + cleanup_block_pool.tx_block_pool_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_block_pool_cleanup(&init_test_thread, 1); + + /* Test block pool cleanup with an valid ID but a suspension count of 0. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_block_pool; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup); + cleanup_block_pool.tx_block_pool_id = TX_BLOCK_POOL_ID; + cleanup_block_pool.tx_block_pool_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_block_pool_cleanup(&init_test_thread, 0); + + /* Test byte pool cleanup with a NULL cleanup pointer. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool; + init_test_thread.tx_thread_suspend_cleanup = TX_NULL; + cleanup_byte_pool.tx_byte_pool_id = 0; + cleanup_byte_pool.tx_byte_pool_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_byte_pool_cleanup(&init_test_thread, 0); + + /* Test byte pool cleanup with a NULL byte pool pointer. */ + init_test_thread.tx_thread_suspend_control_block = TX_NULL; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup); + cleanup_byte_pool.tx_byte_pool_id = 0; + cleanup_byte_pool.tx_byte_pool_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_byte_pool_cleanup(&init_test_thread, 0); + + /* Test byte pool cleanup with an invalid ID. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup); + cleanup_byte_pool.tx_byte_pool_id = 0; + cleanup_byte_pool.tx_byte_pool_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_byte_pool_cleanup(&init_test_thread, 0); + + /* Test byte pool cleanup with an invalid suspension sequence. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup); + cleanup_byte_pool.tx_byte_pool_id = 0; + cleanup_byte_pool.tx_byte_pool_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_byte_pool_cleanup(&init_test_thread, 1); + + /* Test byte pool cleanup with an valid ID but a suspension count of 0. */ + init_test_thread.tx_thread_suspend_control_block = (VOID *) &cleanup_byte_pool; + init_test_thread.tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup); + cleanup_byte_pool.tx_byte_pool_id = TX_BYTE_POOL_ID; + cleanup_byte_pool.tx_byte_pool_suspended_count = 0; + init_test_thread.tx_thread_suspension_sequence = 0; + _tx_byte_pool_cleanup(&init_test_thread, 0); +#endif + +#ifndef TX_ENABLE_EVENT_TRACE + + /* Call ISR trace events when trace is not enabled. */ + + /* Call trace ISR enter event insert. */ + tx_trace_isr_enter_insert(1); + + /* Call trace ISR exit event insert. */ + tx_trace_isr_exit_insert(1); + + /* Call trace ISR enter event insert. */ + tx_trace_isr_enter_insert(0); + + /* Call trace ISR exit event insert. */ + tx_trace_isr_exit_insert(0); + +#endif + + /* Test the list start path in timer info get and timer deactivate. */ + test_timer.tx_timer_id = 0; + _tx_timer_create(&test_timer, "init timer", init_timer_entry, 0x5678, 100, 200, TX_AUTO_ACTIVATE); + _timer_list_start_backup = _tx_timer_list_start; + _tx_timer_list_start = _tx_timer_list_end; + _tx_timer_info_get(&test_timer, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + _tx_timer_deactivate(&test_timer); + _tx_timer_list_start = _timer_list_start_backup; + _tx_timer_deactivate(&test_timer); + _tx_timer_delete(&test_timer); + + /* Test the stack analyze function with a dummy thread. */ + + /* Clear the test stack analyze flag. */ + test_stack_analyze_flag = 0; + + /* Make a fake thread with a fake stack. */ + test_thread2.tx_thread_id = TX_THREAD_ID; + for (i = 0; i < (sizeof(test_thread2_stack)/sizeof(ULONG)); i++) + { + /* Set the fake thread stack to the fill pattern. */ + test_thread2_stack[i] = TX_STACK_FILL; + } + + /* Setup index to last point. */ + i = (sizeof(test_thread2_stack)/sizeof(ULONG)) - 1; + + /* Setup the stack start and end pointers. */ + test_thread2.tx_thread_stack_start = &(test_thread2_stack[0]); + test_thread2.tx_thread_stack_end = &(test_thread2_stack[i]); + test_thread2.tx_thread_stack_size = sizeof(test_thread2_stack); + test_thread2.tx_thread_stack_highest_ptr = test_thread2.tx_thread_stack_end; + test_thread2.tx_thread_stack_ptr = test_thread2.tx_thread_stack_start; + + /* Fill 20 words of stack. */ + for (j = 0; j < 20; j++) + { + /* Fill the stack with 0s. */ + test_thread2_stack[i--] = 0; + } + + /* Call the analyze stack function. */ + _tx_thread_stack_analyze(&test_thread2); + + /* Call it again for no change coverage. */ + _tx_thread_stack_analyze(&test_thread2); + + /* Fill 99 words of stack. */ + for (j = 0; j < 99; j++) + { + /* Fill the stack with 1s. */ + test_thread2_stack[i--] = 1; + } + + /* Call the analyze stack function. */ + _tx_thread_stack_analyze(&test_thread2); + + /* Call it again for no change coverage. */ + _tx_thread_stack_analyze(&test_thread2); + +#ifndef TX_MANUAL_TEST + + /* Now set the flag to 1 to cause the thread ID to be cleared. */ + test_stack_analyze_flag = 1; + + /* Call stack analyze with an ID that is cleared in the middle. */ + _tx_thread_stack_analyze(&test_thread2); + + /* Restore the ID. */ + test_thread2.tx_thread_id = TX_THREAD_ID; + + /* Now set the flag to 2 to cause the stack ptr to be equal to the start of the stack. */ + test_stack_analyze_flag = 2; + + /* Call stack analyze with an ID that is cleared in the middle. */ + _tx_thread_stack_analyze(&test_thread2); + test_thread2.tx_thread_stack_highest_ptr = test_thread2.tx_thread_stack_end; + + /* Now set the flag to 3 to cause the stack pointer to not have the fill pattern. */ + test_stack_analyze_flag = 3; + + /* Call stack analyze with an ID that is cleared in the middle. */ + _tx_thread_stack_analyze(&test_thread2); +#endif + + /* Test error condition on _tx_queue_flush. */ + test_queue.tx_queue_enqueued = 1; + test_queue.tx_queue_suspended_count = 1; + test_queue.tx_queue_suspension_list = TX_NULL; + + /* Call _tx_queue_flush to test the thread NULL check. */ + _tx_queue_flush(&test_queue); + +#ifndef TX_NOT_INTERRUPTABLE + + /* Make sure the suspension cancelled path is exercised in tx_thread_system_resume... This normally happens, + however, sometimes on less real-time platforms the timing is not guaranteed. */ + + /* Increment the preempt disable flag. */ + _tx_thread_preempt_disable++; + + /* Build a thread control block with fake info. */ + test_thread3.tx_thread_suspending = TX_TRUE; + test_thread3.tx_thread_state = TX_SUSPENDED; + test_thread3.tx_thread_delayed_suspend = TX_FALSE; + test_thread3.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + test_thread3.tx_thread_stack_start = (VOID *) &test_thread2_stack[0]; + test_thread3.tx_thread_stack_end = (VOID *) &test_thread2_stack[255]; + test_thread3.tx_thread_stack_ptr = (VOID *) &test_thread2_stack[255]; + + /* Call the system resume function directly to insure the suspension cancel works properly. */ + _tx_thread_system_resume(&test_thread3); +#endif + + /* Test preempt-disable safeguard. */ + + /* Increment the preempt disable flag. */ + _tx_thread_preempt_disable++; + + /* Test block pool suspenson safeguard. */ + fake_block_pool.tx_block_pool_available = 0; + status = _tx_block_allocate(&fake_block_pool, (VOID **) &pointer, TX_WAIT_FOREVER); + if (status != TX_NO_MEMORY) + test_control_system_errors++; + + /* Test byte pool suspension safeguard. */ + fake_byte_pool.tx_byte_pool_fragments = 2; + fake_byte_pool.tx_byte_pool_available = 0; + status = _tx_byte_allocate(&fake_byte_pool, (VOID **) &pointer, 1000, TX_WAIT_FOREVER); + if (status != TX_NO_MEMORY) + test_control_system_errors++; + + /* Test event flags suspension safeguard. */ + fake_event_flags.tx_event_flags_group_current = 0; + status = _tx_event_flags_get(&fake_event_flags, 1, TX_AND, &flags, TX_WAIT_FOREVER); + if (status != TX_NO_EVENTS) + test_control_system_errors++; + + /* Test mutex suspension safeguard. */ + fake_mutex.tx_mutex_ownership_count = 1; + fake_mutex.tx_mutex_inherit = 0; + fake_mutex.tx_mutex_owner = &init_test_thread; + status = _tx_mutex_get(&fake_mutex, TX_WAIT_FOREVER); + if (status != TX_NOT_AVAILABLE) + test_control_system_errors++; + + /* Test queue front send suspension safeguard. */ + fake_queue.tx_queue_available_storage = 0; + status = _tx_queue_front_send(&fake_queue, (VOID *) pointer, TX_WAIT_FOREVER); + if (status != TX_QUEUE_FULL) + test_control_system_errors++; + + /* Test queue receive suspension safeguard. */ + fake_queue.tx_queue_enqueued = 0; + status = _tx_queue_receive(&fake_queue, (VOID **) &pointer, TX_WAIT_FOREVER); + if (status != TX_QUEUE_EMPTY) + test_control_system_errors++; + + /* Test queue send suspension safeguard. */ + fake_queue.tx_queue_available_storage = 0; + status = _tx_queue_send(&fake_queue, (VOID *) pointer, TX_WAIT_FOREVER); + if (status != TX_QUEUE_FULL) + test_control_system_errors++; + + /* Test semaphore suspension safeguard. */ + fake_semaphore.tx_semaphore_count = 0; + status = _tx_semaphore_get(&fake_semaphore, TX_WAIT_FOREVER); + if (status != TX_NO_INSTANCE) + test_control_system_errors++; + + /* Test thread sleep suspension safeguard. */ + _tx_thread_current_ptr[0] = &init_test_thread; + temp = _tx_thread_system_state[0]; + _tx_thread_system_state[0] = 0; + status = _tx_thread_sleep(10); + if (status != TX_CALLER_ERROR) + test_control_system_errors++; + + /* Test thread suspend suspension safeguard. */ + init_test_thread.tx_thread_state = TX_READY; + status = _tx_thread_suspend(&init_test_thread); + if (status != TX_SUSPEND_ERROR) + test_control_system_errors++; + _tx_thread_system_state[0] = temp; + _tx_thread_current_ptr[0] = TX_NULL; + + + /* Pickup the current core exclusion. */ + tx_thread_smp_core_exclude_get(&test_thread, &temp); + + /* Move the test thread form core 0. */ + tx_thread_smp_core_exclude(&test_thread, 0x1); + + /* Restore the core exclusion for the test thread. */ + tx_thread_smp_core_exclude(&test_thread, temp); + + /* Test some code paths in the tx_thread_smp_utilities file. */ + temp_thread = _tx_thread_current_ptr[3]; + _tx_thread_current_ptr[3] = &init_test_thread; + _tx_thread_smp_core_interrupt(&test_thread, 0, 3); + _tx_thread_current_ptr[3] = temp_thread; + temp_thread = _tx_thread_execute_ptr[0]; + _tx_thread_execute_ptr[0] = TX_NULL; + _tx_thread_smp_lowest_priority_get(); + _tx_thread_execute_ptr[0] = temp_thread; + _tx_thread_smp_schedule_list[0] = TX_NULL; + _tx_thread_smp_remap_solution_find(&init_test_thread, 1, 1, 1); + + /* Test a corner case in time-slice change. */ + init_test_thread.tx_thread_smp_core_mapped = TX_THREAD_SMP_MAX_CORES; + _tx_thread_time_slice_change(&init_test_thread, 3, &old_time_slice); + + /* Test time-slice paths. */ + _tx_timer_time_slice[0] = 0; + _tx_timer_time_slice[1] = 1; + _tx_timer_time_slice[2] = 0; + _tx_timer_time_slice[3] = 0; + _tx_thread_time_slice(); + + _tx_timer_time_slice[0] = 0; + _tx_timer_time_slice[1] = 0; + _tx_timer_time_slice[2] = 1; + _tx_timer_time_slice[3] = 0; + _tx_thread_time_slice(); + + _tx_timer_time_slice[0] = 0; + _tx_timer_time_slice[1] = 0; + _tx_timer_time_slice[2] = 0; + _tx_timer_time_slice[3] = 1; + _tx_thread_time_slice(); + + _tx_timer_time_slice[0] = 1; + _tx_timer_time_slice[1] = 0; + _tx_timer_time_slice[2] = 0; + _tx_timer_time_slice[3] = 0; + temp_thread -> tx_thread_state = TX_COMPLETED; + _tx_thread_current_ptr[0] = temp_thread; + _tx_thread_time_slice(); + temp_thread -> tx_thread_state = TX_READY; + _tx_thread_current_ptr[0] = TX_NULL; + + _tx_timer_time_slice[0] = 1; + _tx_timer_time_slice[1] = 0; + _tx_timer_time_slice[2] = 0; + _tx_timer_time_slice[3] = 0; + temp_thread -> tx_thread_time_slice = 0; + _tx_thread_current_ptr[0] = temp_thread; + _tx_thread_time_slice(); + _tx_thread_current_ptr[0] = TX_NULL; + + /* Decrement the preempt disable flag. */ + _tx_thread_preempt_disable--; +} + + + +/* Define the test control thread. This thread is responsible for dispatching all of the + tests in the ThreadX test suite. */ + +void test_control_thread_entry(ULONG thread_input) +{ + +UINT i; + + /* Raise the priority of the control thread to 0. */ + tx_thread_priority_change(&test_control_thread, 0, &i); +#ifdef CTEST + test_control_cleanup(); +#endif + + /* Print out banner. */ + printf("********************** ThreadX Validation/Regression Test Suite *********************************\n\n"); + + /* Print version id. */ + printf("Version: %s\n\n", _tx_version_id); + + /* Print out the tests... */ + printf("Running validation/regression test:\n\n"); + + /* Loop to process all tests... */ + i = 0; + while (test_control_tests[i].test_entry != TX_NULL) + { + + /* Clear the ISR dispatch. */ + test_isr_dispatch = TX_NULL; + + /* Dispatch the test. */ + (test_control_tests[i++].test_entry)(test_free_memory_ptr); + + /* Clear the ISR dispatch. */ + test_isr_dispatch = TX_NULL; + + /* Suspend control test to allow test to run. */ + tx_thread_suspend(&test_control_thread); + + /* Test finished, cleanup in preparation for the next test. */ + test_control_cleanup(); + } + + /* Finished with all tests, print results and return! */ + printf("**** Testing Complete ****\n"); + printf("**** Test Summary: Tests Passed: %lu Tests Failed: %lu System Errors: %lu\n", test_control_successful_tests, test_control_failed_tests, test_control_system_errors); +#ifndef EXTERNAL_EXIT + exit(test_control_failed_tests + test_control_system_errors); +#else + external_exit(test_control_failed_tests + test_control_system_errors); +#endif +} + + +void test_control_return(UINT status) +{ + +TX_INTERRUPT_SAVE_AREA + +UINT old_posture = TX_INT_ENABLE; + + fflush(stdout); + + /* Save the status in a global. */ + test_control_return_status = status; + + /* Ensure interrupts are enabled. */ + old_posture = tx_interrupt_control(TX_INT_ENABLE); + + /* Determine if it was successful or not. */ + if (status) + test_control_failed_tests++; + else + test_control_successful_tests++; + + /* Now check for system errors. */ + + /* Get protection for examination of preempt disable and system state variables. */ + TX_DISABLE + + /* Is preempt disable flag set? */ + if (_tx_thread_preempt_disable) + { + + /* System error - preempt disable should never be set inside of a thread! */ + printf(" ***** SYSTEM ERROR ***** _tx_thread_preempt_disable is non-zero!\n"); + test_control_system_errors++; + } + + /* Is system state set? */ + if (_tx_thread_system_state[0]) + { + + /* System error - system state should never be set inside of a thread! */ + printf(" ***** SYSTEM ERROR ***** _tx_thread_system_state is non-zero!\n"); + test_control_system_errors++; + } + + /* Release protection. */ + TX_RESTORE + + /* Are interrupts disabled? */ + if (old_posture == TX_INT_DISABLE) + { + + /* System error - interrupts should alwasy be enabled in our test threads! */ + printf(" ***** SYSTEM ERROR ***** test returned with interrupts disabled!\n"); + test_control_system_errors++; + } + + /* Resume the control thread to fully exit the test. */ + tx_thread_resume(&test_control_thread); +} + + +void test_control_cleanup(void) +{ + +TX_MUTEX *mutex_ptr; +TX_THREAD *thread_ptr; + + + /* Delete all queues. */ + while(_tx_queue_created_ptr) + { + + /* Delete queue. */ + tx_queue_delete(_tx_queue_created_ptr); + } + + /* Delete all semaphores. */ + while(_tx_semaphore_created_ptr) + { + + /* Delete semaphore. */ + tx_semaphore_delete(_tx_semaphore_created_ptr); + } + + /* Delete all event flag groups. */ + while(_tx_event_flags_created_ptr) + { + + /* Delete event flag group. */ + tx_event_flags_delete(_tx_event_flags_created_ptr); + } + + /* Delete all byte pools. */ + while(_tx_byte_pool_created_ptr) + { + + /* Delete byte pool. */ + tx_byte_pool_delete(_tx_byte_pool_created_ptr); + } + + /* Delete all block pools. */ + while(_tx_block_pool_created_ptr) + { + + /* Delete block pool. */ + tx_block_pool_delete(_tx_block_pool_created_ptr); + } + + /* Delete all timers. */ + while(_tx_timer_created_ptr) + { + + /* Deactivate timer. */ + tx_timer_deactivate(_tx_timer_created_ptr); + + /* Delete timer. */ + tx_timer_delete(_tx_timer_created_ptr); + } + + /* Delete all mutexes (except for system mutex). */ + while(_tx_mutex_created_ptr) + { + + /* Setup working mutex pointer. */ + mutex_ptr = _tx_mutex_created_ptr; + +#ifdef __ghs + + /* Determine if the mutex is the GHS system mutex. If so, don't delete! */ + if (mutex_ptr == &__ghLockMutex) + { + + /* Move to next mutex. */ + mutex_ptr = mutex_ptr -> tx_mutex_created_next; + } + + /* Determine if there are no more mutexes to delete. */ + if (_tx_mutex_created_count == 1) + break; +#endif + + /* Delete mutex. */ + tx_mutex_delete(mutex_ptr); + } + + /* Delete all threads, except for timer thread, and test control thread. */ + while (_tx_thread_created_ptr) + { + + /* Setup working pointer. */ + thread_ptr = _tx_thread_created_ptr; + + +#ifdef TX_TIMER_PROCESS_IN_ISR + + /* Determine if there are more threads to delete. */ + if (_tx_thread_created_count == 1) + break; + + /* Determine if this thread is the test control thread. */ + if (thread_ptr == &test_control_thread) + { + + /* Move to the next thread pointer. */ + thread_ptr = thread_ptr -> tx_thread_created_next; + } +#else + + /* Determine if there are more threads to delete. */ + if (_tx_thread_created_count == 2) + break; + + /* Move to the thread not protected. */ + while ((thread_ptr == &_tx_timer_thread) || (thread_ptr == &test_control_thread)) + { + + /* Yes, move to the next thread. */ + thread_ptr = thread_ptr -> tx_thread_created_next; + } +#endif + + /* First terminate the thread to ensure it is ready for deletion. */ + tx_thread_terminate(thread_ptr); + + /* Delete the thread. */ + tx_thread_delete(thread_ptr); + } + + /* At this point, only the test control thread and the system timer thread and/or mutex should still be + in the system. */ +} + +void test_thread_entry(ULONG thread_input) +{ + + /* Resume the next test thread. */ + tx_thread_resume(&test_thread1); + + /* Suspend this thread but with preemption disabled, so we will actually return. */ + _tx_thread_preempt_disable++; + tx_thread_suspend(&test_thread); + + /* Now perform a fake thread resume to cause preemption and exercise the path in _tx_thread_system_resume that returns to the scheduler. */ + init_test_thread.tx_thread_state = TX_TERMINATED; + init_test_thread.tx_thread_suspend_cleanup = TX_NULL; + init_test_thread.tx_thread_new_time_slice = 0; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_suspending = TX_TRUE; + init_test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + init_test_thread.tx_thread_entry = test_thread_entry1; + _tx_thread_system_resume(&init_test_thread); +#ifdef TX_NOT_INTERRUPTABLE + _tx_thread_preempt_disable--; +#endif +} + + +void test_thread_entry1(ULONG thread_input) +{ + + /* Do nothing, just return! */ +} + + +void test_exit_notify(TX_THREAD *thread_ptr, UINT type) +{ + + /* Clear the suspending flag to short-circuit the suspension. */ + thread_ptr -> tx_thread_suspending = TX_FALSE; +} + +__attribute__((weak)) void abort_all_threads_suspended_on_mutex(void) +{ +} + +__attribute__((weak)) void suspend_lowest_priority(void) +{ +} + +__attribute__((weak)) void abort_and_resume_byte_allocating_thread(void) +{ +} diff --git a/test/smp/regression/threadx_block_memory_basic_test.c b/test/smp/regression/threadx_block_memory_basic_test.c new file mode 100644 index 00000000..5f2afa01 --- /dev/null +++ b/test/smp/regression/threadx_block_memory_basic_test.c @@ -0,0 +1,568 @@ +/* This test is designed to test simple memory block pool creation, deletion, and + allocates and releases. */ + +#include +#include "tx_api.h" + +typedef struct BLOCK_MEMORY_TEST_STRUCT +{ + ULONG first; + ULONG second; + TX_BLOCK_POOL pool; + ULONG first_middle; + ULONG second_middle; + ULONG pool_area[2048/sizeof(ULONG)]; + ULONG next_to_last; + ULONG last; + +} BLOCK_MEMORY_TEST; + +static BLOCK_MEMORY_TEST block_memory; + + +/* Define external reference for status of block pool create from initialization. */ + +extern UINT test_block_pool_create_init; + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + + +static TX_BLOCK_POOL pool_0; +static TX_BLOCK_POOL pool_1; +static TX_BLOCK_POOL pool_2; +static TX_BLOCK_POOL pool_3; + +static TX_TIMER timer_0; + + +static unsigned long error = 0; +static unsigned long timer_executed = 0; +static unsigned long isr_executed = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Prototype direct call to block pool core service. */ + +UINT _tx_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size, + VOID *pool_start, ULONG pool_size); + + + +/* Define the timer for this test. */ + +static void timer_entry(ULONG i) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +UINT status; +CHAR *pointer; + + + /* Determine if calling block pool create from initialization was successful. */ + if (test_block_pool_create_init != TX_SUCCESS) + { + + /* Error! */ + error++; + } + + /* Attempt to create a block pool from a timer. */ + pointer = (CHAR *) 0x30000; + status = tx_block_pool_create(&pool_3, "pool 3", 100, pointer, 320); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to delete a block pool. */ + status = tx_block_pool_delete(&pool_0); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + timer_executed = 1; + + /* Attempt to allocate a block with suspension from a timer. */ + status = tx_block_allocate(&pool_0, (void **) &pointer, 10); + + /* Check status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + +#endif +} + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +CHAR *pointer; +UINT status; + + + /* Attempt to Allocate block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to create a block pool from an ISR. */ + status = tx_block_pool_create(&pool_3, "pool 3", 100, (void *) 0x100000, 320); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to delete a pool from an ISR. */ + status = tx_block_pool_delete(&pool_0); + + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + isr_executed = 1; +#endif +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_block_memory_basic_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Basic Functionality Test....................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Basic Functionality Test....................... ERROR #2\n"); + test_control_return(1); + } + + /* Create block pools 0 and 1. */ + status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320); + pointer = pointer + 320; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Basic Functionality Test....................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_block_pool_create(&pool_1, "pool 1", 100, pointer, 320); + pointer = pointer + 320; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Basic Functionality Test....................... ERROR #4\n"); + test_control_return(1); + } + + /* Check the no-blocks path. */ + status = _tx_block_pool_create(&pool_2, "pool 2", 100, pointer, 50); + pointer = pointer + 320; + + /* Check status. */ + if (status != TX_SIZE_ERROR) + { + + printf("Running Block Memory Basic Functionality Test....................... ERROR #5\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer_1; +CHAR *pointer_2; +CHAR *pointer_3; +CHAR *pointer_4; +INT i; +unsigned long fake_block[20]; + + + /* Inform user. */ + printf("Running Block Memory Basic Functionality Test....................... "); + + /* Perform block memory test. */ + block_memory.first = 0x11223344; + block_memory.second = 0x55667788; + block_memory.first_middle = 0x21314151; + block_memory.second_middle= 0x61718191; + block_memory.next_to_last = 0x99aabbcc; + block_memory.last = 0xddeeff00; + + /* Create the block pool. */ + status = tx_block_pool_create(&block_memory.pool, "pool memory", 16, &block_memory.pool_area[0], (2048*sizeof(ULONG))/sizeof(ULONG)); + tx_block_pool_delete(&block_memory.pool); + + /* Check for status. */ + if ((status != TX_SUCCESS) || + (block_memory.first != 0x11223344) || + (block_memory.second != 0x55667788) || + (block_memory.first_middle != 0x21314151) || + (block_memory.second_middle != 0x61718191) || + (block_memory.next_to_last != 0x99aabbcc) || + (block_memory.last != 0xddeeff00)) + { + + /* Block memory error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Try to release a non-block. */ + fake_block[0] = 0; + fake_block[1] = 0; + status = tx_block_release(&fake_block[2]); + + /* Check status. */ + if (status != TX_PTR_ERROR) + { + + /* Block memory error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Try to release a block that points to a non-pool. */ + fake_block[0] = 0; + fake_block[1] = (unsigned long) &fake_block[0]; + status = tx_block_release(&fake_block[2]); + + /* Check status. */ + if (status != TX_PTR_ERROR) + { + + /* Block memory error. */ + printf("ERROR #8\n"); + test_control_return(1); + } +#endif + + /* Allocate first block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_1, (CHAR) 0xEF, 100); + + /* Allocate second block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_2, (CHAR) 0xEF, 100); + + /* Allocate third block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_3, (CHAR) 0xEF, 100); + + /* Attempt to allocate fourth block from the pool. This should fail because + there should be no more blocks in the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_MEMORY) + { + + /* Block memory error. */ + printf("ERROR ##12\n"); + test_control_return(1); + } + + /* Set the memory of all of the allocated blocks. */ + for (i =0; i < 100; i++) + { + pointer_1[i] = (CHAR) 0xFF; + pointer_2[i] = (CHAR) 0xFF; + pointer_3[i] = (CHAR) 0xFF; + } + + /* Now release each of the blocks. */ + status = tx_block_release(pointer_1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Release the second block. */ + status = tx_block_release(pointer_2); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Release the third block. */ + status = tx_block_release(pointer_3); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Allocate each block again to make sure everything still + works. The block addresses should come out in reverse + order, because a released block is placed at the head of + the list. */ + + /* Allocate first block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_1, (CHAR) 0xEF, 100); + + /* Allocate second block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_2, (CHAR) 0xEF, 100); + + /* Allocate third block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_3, (CHAR) 0xEF, 100); + + /* Attempt to allocate fourth block from the pool. This should fail because + there should be no more blocks in the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_MEMORY) + { + + /* Block memory error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Create a timer for the test. */ + tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE); + + /* Setup the ISR. */ + test_isr_dispatch = test_isr; + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Now resume the background thread. */ + tx_thread_resume(&thread_1); + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Clear the ISR. */ + test_isr_dispatch = TX_NULL; + + /* Test for error. */ + if ((error) || (timer_executed != 1) || (isr_executed != 1)) + { + + /* Block memory error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + +#endif + + /* Delete both block pools. */ + status = tx_block_pool_delete(&pool_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + status = tx_block_pool_delete(&pool_1); + + /* Check status. */ + if ((status != TX_SUCCESS) || (error)) + { + + /* Block memory error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + } +} diff --git a/test/smp/regression/threadx_block_memory_error_detection_test.c b/test/smp/regression/threadx_block_memory_error_detection_test.c new file mode 100644 index 00000000..de28012f --- /dev/null +++ b/test/smp/regression/threadx_block_memory_error_detection_test.c @@ -0,0 +1,387 @@ +/* This test is designed to test error detection for simple memory block operations. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + + +static TX_BLOCK_POOL pool_0; +static TX_BLOCK_POOL pool_1; +static TX_BLOCK_POOL pool_2; +static CHAR *pointer; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + +UINT _txe_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size, + VOID *pool_start, ULONG pool_size, UINT pool_control_block_size); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_block_memory_error_detection_application_define(void *first_unused_memory) +#endif +{ + +INT status; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Create block pool 0. */ + status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320); + pointer = pointer + 320; + +#ifndef TX_DISABLE_ERROR_CHECKING /* skip this test and pretend it passed */ + + /* Create block pool again to get pool_ptr error. */ + status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320); + if (status != TX_POOL_ERROR) + return; + + /* Create block pool with NULL pointer. */ + status = tx_block_pool_create(TX_NULL, "pool 0", 100, pointer, 320); + if (status != TX_POOL_ERROR) + { + + printf("Running Block Memory Error Detection Test........................... ERROR #1\n"); + test_control_return(1); + } + + /* Create block pool pointer if NULL start. */ + status = tx_block_pool_create(&pool_1, "pool 0", 100, NULL, 320); + if (status != TX_PTR_ERROR) + { + + printf("Running Block Memory Error Detection Test........................... ERROR #2\n"); + test_control_return(1); + } + + /* Create block pool pointer with invalid size. */ + status = tx_block_pool_create(&pool_1, "pool 0", 100, pointer, 100); + if (status != TX_SIZE_ERROR) + { + + printf("Running Block Memory Error Detection Test........................... ERROR #3\n"); + test_control_return(1); + } + + /* Attempt of allocate block with NULL dest. */ + status = tx_block_allocate(&pool_0, (VOID **) TX_NULL, TX_NO_WAIT); + if (status != TX_PTR_ERROR) + { + + printf("Running Block Memory Error Detection Test........................... ERROR #4\n"); + test_control_return(1); + } + + /* Delete null pointer. */ + status = tx_block_pool_delete(TX_NULL); + if (status != TX_POOL_ERROR) + { + + printf("Running Block Memory Error Detection Test........................... ERROR #5\n"); + test_control_return(1); + } + +#endif /* TX_DISABLE_ERROR_CHECKING */ +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING +UINT status; +CHAR *pointer_1; +CHAR *pointer_2; +CHAR *pointer_3; +CHAR *pointer_4; +INT i; +#endif + + /* Inform user. */ + printf("Running Block Memory Error Detection Test........................... "); + +#ifndef TX_DISABLE_ERROR_CHECKING /* skip this test and pretend it passed */ + + status = tx_block_pool_create(&pool_1, "pool 1", 100, pointer, 320); + pointer = pointer + 320; + + /* Attempt to create a pool with an invalid size. */ + status = _txe_block_pool_create(&pool_2, "pool 2", 100, pointer, 320, 777777); + if (status != TX_POOL_ERROR) + { + + /* Error! */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Allocate with a NULL destination pointer. */ + status = tx_block_allocate(&pool_0, (VOID **) TX_NULL, TX_NO_WAIT); + if (status != TX_PTR_ERROR) + { + + /* Error! */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Allocate with a NULL pool pointer. */ + status = tx_block_allocate(TX_NULL, (VOID **) TX_NULL, TX_NO_WAIT); + if (status != TX_POOL_ERROR) + { + + /* Error! */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Allocate with bad pool pointer. */ + pool_2.tx_block_pool_id = 0; + status = tx_block_allocate(&pool_2, (VOID **) TX_NULL, TX_NO_WAIT); + if (status != TX_POOL_ERROR) + { + + /* Error! */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Release bad pool ptr. */ + status = tx_block_release(TX_NULL); + if (status != TX_PTR_ERROR) + { + + /* Error! */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Allocate first block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Error! */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_1, (CHAR) 0xEF, 100); + + /* Allocate second block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Error! */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_2, (CHAR) 0xEF, 100); + + /* Allocate third block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Error! */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_3, (CHAR) 0xEF, 100); + + /* Attempt to allocate fourth block from the pool. This should fail because + there should be no more blocks in the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_MEMORY) + { + + /* Error! */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Set the memory of all of the allocated blocks. */ + for (i =0; i < 100; i++) + { + pointer_1[i] = (CHAR) 0xFF; + pointer_2[i] = (CHAR) 0xFF; + pointer_3[i] = (CHAR) 0xFF; + } + + /* Now release each of the blocks. */ + status = tx_block_release(pointer_1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Error! */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Release the second block. */ + status = tx_block_release(pointer_2); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Error! */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Release the third block. */ + status = tx_block_release(pointer_3); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Error! */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Allocate each block again to make sure everything still + works. The block addresses should come out in reverse + order, because a released block is placed at the head of + the list. */ + + /* Allocate first block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Error! */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_1, (CHAR) 0xEF, 100); + + /* Allocate second block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Error! */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_2, (CHAR) 0xEF, 100); + + /* Allocate third block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Error! */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_3, (CHAR) 0xEF, 100); + + /* Attempt to allocate fourth block from the pool. This should fail because + there should be no more blocks in the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_MEMORY) + { + + /* Error! */ + printf("ERROR #21\n"); + test_control_return(1); + } + + /* Delete both block pools. */ + status = tx_block_pool_delete(&pool_0); + if (status != TX_SUCCESS) + { + + /* Error! */ + printf("ERROR #22\n"); + test_control_return(1); + } + + status = tx_block_pool_delete(&pool_1); + if (status != TX_SUCCESS) + { + + /* Error! */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Attempt to delete again. */ + status = tx_block_pool_delete(&pool_1); + if (status != TX_POOL_ERROR) + { + + /* Error! */ + printf("ERROR #24\n"); + test_control_return(1); + } + + thread_0_counter++; + +#endif /* TX_DISABLE_ERROR_CHECKING */ + + /* All is good! */ + printf("SUCCESS!\n"); + test_control_return(0); +} + diff --git a/test/smp/regression/threadx_block_memory_information_test.c b/test/smp/regression/threadx_block_memory_information_test.c new file mode 100644 index 00000000..d6416bc2 --- /dev/null +++ b/test/smp/regression/threadx_block_memory_information_test.c @@ -0,0 +1,713 @@ +/* This test is designed to test block memory information services. */ + +#include +#include "tx_api.h" +#include "tx_block_pool.h" + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Define the external reference for the preempt disable flag. */ + +extern volatile UINT _tx_thread_preempt_disable; + + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + +static unsigned long thread_5_counter = 0; +static TX_THREAD thread_5; + +static unsigned long thread_6_counter = 0; +static TX_THREAD thread_6; + +static TX_BLOCK_POOL block_pool_0; +static TX_BLOCK_POOL block_pool_2; +#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO +static TX_BLOCK_POOL block_pool_1; +#endif + +static int test_status; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); +static void thread_6_entry(ULONG thread_input); + +/* Direct core function to bypass the error checking shell. */ +UINT _tx_block_pool_info_get(TX_BLOCK_POOL *pool_ptr, CHAR **name, ULONG *available_blocks, + ULONG *total_blocks, TX_THREAD **first_suspended, + ULONG *suspended_count, TX_BLOCK_POOL **next_pool); + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + + /* Determine if the test case we are looking for is present. */ + if ((_tx_thread_preempt_disable) && (test_status == 1)) + { + + /* Abort the wait of thread 3. */ + tx_thread_wait_abort(&thread_3); + + /* End the ISR processing. */ + test_status = 2; + test_isr_dispatch = TX_NULL; + } +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_block_memory_information_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Information Test............................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Information Test............................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Information Test............................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 3, 3, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Information Test............................... ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 4, 4, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Information Test............................... ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, TEST_STACK_SIZE_PRINTF, + 5, 5, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Information Test............................... ERROR #6\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6, + pointer, TEST_STACK_SIZE_PRINTF, + 6, 6, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Information Test............................... ERROR #7\n"); + test_control_return(1); + } + + /* Create the block_pool with one block. */ + status = tx_block_pool_create(&block_pool_0, "block_pool 0", 30, pointer, 40); + pointer = pointer + 40; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Information Test............................... ERROR #8\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; +CHAR *name; +ULONG available; +ULONG total_blocks; +TX_THREAD *first_suspended; +ULONG suspended_count; +TX_BLOCK_POOL *next_pool; +ULONG allocates; +ULONG releases; +ULONG suspensions; +ULONG timeouts; + + + /* Inform user. */ + printf("Running Block Memory Information Test............................... "); + + /* Allocate the one block. */ + tx_block_allocate(&block_pool_0, &pointer, TX_NO_WAIT); + + /* Nothing to do here, but check prioritization with no suspended threads. */ + status = tx_block_pool_prioritize(&block_pool_0); + + /* Check for an error condition. */ + if (status != TX_SUCCESS) + { + + /* Block Pool error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Get both threads suspended. */ + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Make sure thread 1 and 2 are suspended on the block_pool. */ + if ((thread_1.tx_thread_state != TX_BLOCK_MEMORY) || (thread_2.tx_thread_state != TX_BLOCK_MEMORY) || + (block_pool_0.tx_block_pool_suspension_list != &thread_1)) + { + + /* Block Pool error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Prioritize the block pool suspension list. */ + status = tx_block_pool_prioritize(&block_pool_0); + + /* Check status and make sure thread 1 is terminated. */ + if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_2)) + { + + /* Block Pool error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* At this point we are going to get more than 2 threads suspended. */ + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + tx_thread_resume(&thread_3); + tx_thread_resume(&thread_4); + tx_thread_resume(&thread_5); + tx_thread_resume(&thread_6); + + /* Prioritize the block pool suspension list. */ + status = tx_block_pool_prioritize(&block_pool_0); + + /* Check status and make sure thread 3 is at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_3)) + { + + /* Block Pool error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Now loop to test the interrupt of the prioritize loop logic. */ + test_status = 1; + test_isr_dispatch = test_isr; + do + { + + /* Prioritize the block pool suspension list. */ + status = tx_block_pool_prioritize(&block_pool_0); + + /* Check status and make sure thread 1 is terminated. */ + if (status != TX_SUCCESS) + { + + /* Block Pool error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + } while (test_status == 1); + + /* Now determine if thread 4 is at the front of the list... It should be! */ + if (block_pool_0.tx_block_pool_suspension_list != &thread_4) + { + + /* Block Pool error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Test the NULL pointer on the info get call. */ + status = tx_block_pool_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for the proper error code. */ + if (status != TX_POOL_ERROR) + { + + /* Block Pool error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Test the non-thread pointer on the info get call. */ + block_pool_2.tx_block_pool_id = 0; + status = tx_block_pool_info_get(&block_pool_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for the proper error code. */ + if (status != TX_POOL_ERROR) + { + + /* Block Pool error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + +#endif + + /* Now use the information services in order to test them. */ + status = tx_block_pool_info_get(&block_pool_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_block_pool_info_get(&block_pool_0, &name, &available, &total_blocks, &first_suspended, &suspended_count, &next_pool); + + /* Check for an error condition. */ + if ((status) || (available != block_pool_0.tx_block_pool_available) || (total_blocks != block_pool_0.tx_block_pool_total) || + (first_suspended != &thread_4) || (suspended_count != block_pool_0.tx_block_pool_suspended_count) || (next_pool != &block_pool_0)) + { + + /* Block Pool error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + +#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO + + /* Call the core block pool info get function with a NULL pointer. */ + status = _tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for the proper error code. */ + if (status != TX_PTR_ERROR) + { + + /* Block Pool error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Call the core block pool info get function with a non-initialized pool. */ + status = _tx_block_pool_performance_info_get(&block_pool_1, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for the proper error code. */ + if (status != TX_PTR_ERROR) + { + + /* Block Pool error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Now get the pool performance information. */ + status = tx_block_pool_performance_info_get(&block_pool_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_block_pool_performance_info_get(&block_pool_0, &allocates, &releases, &suspensions, &timeouts); + + /* Check for an error condition. */ + if ((status) || (allocates != block_pool_0.tx_block_pool_performance_allocate_count) || + (releases != block_pool_0.tx_block_pool_performance_release_count) || + (suspensions != block_pool_0.tx_block_pool_performance_suspension_count) || + (timeouts != block_pool_0.tx_block_pool_performance_timeout_count)) + { + + /* Block Pool error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Now get the system pool performance information. */ + status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_block_pool_performance_system_info_get(&allocates, &releases, &suspensions, &timeouts); + + /* Check for an error condition. */ + if ((status) || (allocates != _tx_block_pool_performance_allocate_count) || (releases != _tx_block_pool_performance_release_count) || + (suspensions != _tx_block_pool_performance_suspension_count) || (timeouts != _tx_block_pool_performance_timeout_count)) + { + + /* Block Pool error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +#else + + /* Call the block pool performance info get function. */ + status = tx_block_pool_performance_info_get(&block_pool_0, &allocates, &releases, &suspensions, &timeouts); + + /* Check for the proper error code. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Block Pool error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Call the block pool performance info get function. */ + status = tx_block_pool_performance_info_get(TX_NULL, &allocates, &releases, &suspensions, &timeouts); + + /* Check for the proper error code. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Block Pool error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Call the block pool performance info get function. */ + status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, &releases, &suspensions, &timeouts); + + /* Check for the proper error code. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Block Pool error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Call the block pool performance info get function. */ + status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts); + + /* Check for the proper error code. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Block Pool error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + + /* Call the block pool performance info get function. */ + status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts); + + /* Check for the proper error code. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Block Pool error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Call the block pool performance info get function. */ + status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for the proper error code. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Block Pool error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Now get the system pool performance information. */ + status = tx_block_pool_performance_system_info_get(&allocates, &releases, &suspensions, &timeouts); + + /* Check for the proper error code. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Block Pool error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + + /* Now get the system pool performance information. */ + status = tx_block_pool_performance_system_info_get(TX_NULL, &releases, &suspensions, &timeouts); + + /* Check for the proper error code. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Block Pool error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + + /* Now get the system pool performance information. */ + status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts); + + /* Check for the proper error code. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Block Pool error. */ + printf("ERROR #30\n"); + test_control_return(1); + } + + /* Now get the system pool performance information. */ + status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts); + + /* Check for the proper error code. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Block Pool error. */ + printf("ERROR #31\n"); + test_control_return(1); + } + + /* Now get the system pool performance information. */ + status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for the proper error code. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Block Pool error. */ + printf("ERROR #32\n"); + test_control_return(1); + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +#endif +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +VOID *pointer; + + /* Loop forever! */ + while(1) + { + + + /* Get block from pool. */ + status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get block from pool. */ + status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_2_counter++; + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get block from pool. */ + status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_3_counter++; + } +} + + +static void thread_4_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get block from pool. */ + status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_4_counter++; + } +} + + +static void thread_5_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get block from pool. */ + status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_5_counter++; + } +} + + +static void thread_6_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get block from pool. */ + status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_6_counter++; + } +} + diff --git a/test/smp/regression/threadx_block_memory_prioritize_test.c b/test/smp/regression/threadx_block_memory_prioritize_test.c new file mode 100644 index 00000000..274daa01 --- /dev/null +++ b/test/smp/regression/threadx_block_memory_prioritize_test.c @@ -0,0 +1,500 @@ +/* This test is designed to test block memory pool prioritize. */ + +#include +#include "tx_api.h" + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Define the external reference for the preempt disable flag. */ + +extern volatile UINT _tx_thread_preempt_disable; + + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + +static unsigned long thread_5_counter = 0; +static TX_THREAD thread_5; + +static unsigned long thread_6_counter = 0; +static TX_THREAD thread_6; + +static TX_BLOCK_POOL block_pool_0; +static TX_BLOCK_POOL block_pool_1; + + +static int test_status; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); +static void thread_6_entry(ULONG thread_input); + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + + /* Determine if the test case we are looking for is present. */ + if ((_tx_thread_preempt_disable) && (test_status == 1)) + { + + /* Determine if thread 3 is at the front of the suspension list. */ + if (block_pool_0.tx_block_pool_suspension_list == &thread_3) + { + + /* Abort the wait of thread 3. */ + tx_thread_wait_abort(&thread_3); + } + else + { + + /* Abort the wait of thread 5. */ + tx_thread_wait_abort(&thread_5); + + /* End the ISR processing. */ + test_status = 2; + test_isr_dispatch = TX_NULL; + } + } +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_block_memory_prioritize_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Prioritize Test................................ ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Prioritize Test................................ ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Prioritize Test................................ ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 3, 3, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Prioritize Test................................ ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 4, 4, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Prioritize Test................................ ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, TEST_STACK_SIZE_PRINTF, + 5, 5, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Prioritize Test................................ ERROR #6\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6, + pointer, TEST_STACK_SIZE_PRINTF, + 6, 6, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Prioritize Test................................ ERROR #7\n"); + test_control_return(1); + } + + /* Create the block_pool with one block. */ + status = tx_block_pool_create(&block_pool_0, "block_pool 0", 30, pointer, 40); + pointer = pointer + 40; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Prioritize Test................................ ERROR #8\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Inform user. */ + printf("Running Block Memory Prioritize Test................................ "); + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Attempt to prioritize with a NULL pointer. */ + status = tx_block_pool_prioritize(TX_NULL); + + /* Check for an error condition. */ + if (status != TX_POOL_ERROR) + { + + /* Block Pool error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to prioritize with a bad pool pointer. */ + block_pool_1.tx_block_pool_id = 0; + status = tx_block_pool_prioritize(&block_pool_1); + + /* Check for an error condition. */ + if (status != TX_POOL_ERROR) + { + + /* Block Pool error. */ + printf("ERROR #10\n"); + test_control_return(1); + } +#endif + + /* Allocate the one block. */ + tx_block_allocate(&block_pool_0, &pointer, TX_NO_WAIT); + + /* Nothing to do here, but check prioritization with no suspended threads. */ + status = tx_block_pool_prioritize(&block_pool_0); + + /* Check for an error condition. */ + if (status != TX_SUCCESS) + { + + /* Block Pool error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Get both threads suspended. */ + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Make sure thread 1 and 2 are suspended on the block_pool. */ + if ((thread_1.tx_thread_state != TX_BLOCK_MEMORY) || (thread_2.tx_thread_state != TX_BLOCK_MEMORY) || + (block_pool_0.tx_block_pool_suspension_list != &thread_1)) + { + + /* Block Pool error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Prioritize the block pool suspension list. */ + status = tx_block_pool_prioritize(&block_pool_0); + + /* Check status and make sure thread 2 is at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_2)) + { + + /* Block Pool error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Call block pool prioritize again to test the don't-do-anything path in tx_block_pool_prioritize. */ + status += tx_block_pool_prioritize(&block_pool_0); + + /* At this point we are going to get more than 2 threads suspended. */ + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + tx_thread_resume(&thread_3); + tx_thread_resume(&thread_4); + tx_thread_resume(&thread_5); + tx_thread_resume(&thread_6); + + /* Prioritize the block pool suspension list. */ + status = tx_block_pool_prioritize(&block_pool_0); + + /* Check status and make sure thread 3 is at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_3)) + { + + /* Block Pool error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Now loop to test the interrupt of the prioritize loop logic. */ + test_status = 1; + test_isr_dispatch = test_isr; + do + { + + /* Prioritize the block pool suspension list. */ + status = tx_block_pool_prioritize(&block_pool_0); + + /* Check status and make sure thread 1 is terminated. */ + if (status != TX_SUCCESS) + { + + /* Block Pool error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + } while (test_status == 1); + + /* Now determine if thread 4 is at the front of the list... It should be! */ + if (block_pool_0.tx_block_pool_suspension_list != &thread_4) + { + + /* Block Pool error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +VOID *pointer; + + /* Loop forever! */ + while(1) + { + + + /* Get block from pool. */ + status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get block from pool. */ + status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_2_counter++; + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get block from pool. */ + status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_3_counter++; + } +} + + +static void thread_4_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get block from pool. */ + status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_4_counter++; + } +} + + +static void thread_5_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get block from pool. */ + status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_5_counter++; + } +} + + +static void thread_6_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get block from pool. */ + status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_6_counter++; + } +} diff --git a/test/smp/regression/threadx_block_memory_suspension_test.c b/test/smp/regression/threadx_block_memory_suspension_test.c new file mode 100644 index 00000000..6f2d635c --- /dev/null +++ b/test/smp/regression/threadx_block_memory_suspension_test.c @@ -0,0 +1,311 @@ +/* This test is designed to test suspension on memory block pools. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static TX_BLOCK_POOL pool_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_block_memory_suspension_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Suspension Test................................ ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Suspension Test................................ ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Suspension Test................................ ERROR #3\n"); + test_control_return(1); + } + + /* Create block pool. */ + status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320); + pointer = pointer + 320; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Suspension Test................................ ERROR #4\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer_1; +CHAR *pointer_2; +CHAR *pointer_3; + + + /* Inform user. */ + printf("Running Block Memory Suspension Test................................ "); + + /* Increment the run counter. */ + thread_0_counter++; + + /* Allocate all blocks from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_1, (CHAR) 0xEF, 100); + + status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_2, (CHAR) 0xEF, 100); + + /* Get the last block. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_3, (CHAR) 0xEF, 100); + + /* Let the other thread suspend on the pool. */ + tx_thread_relinquish(); + + /* Now release the block to lift the suspension on the other thread. */ + status = tx_block_release(pointer_3); + + /* Check status and run counter. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 0)) + { + + /* Block memory error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Let the other thread run again. */ + tx_thread_relinquish(); + + /* Check the run counter of the other thread. */ + if (thread_1_counter != 1) + { + + /* Block memory error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* At this point the other thread has run and there is one block free. */ + + /* Get the last block again. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_3, (CHAR) 0xEF, 100); + + /* Resume the second thread. */ + tx_thread_resume(&thread_2); + + /* Let both threads suspend on the block pool via relinquish. */ + tx_thread_relinquish(); + + /* Now release the block. */ + status = tx_block_release(pointer_3); + + /* Check status and run counter. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0)) + { + + /* Block memory error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Let thread 1 release the block. */ + tx_thread_relinquish(); + + /* Let thread 2 get the block and release the block. */ + tx_thread_relinquish(); + + /* Check status and run counter. */ + if ((thread_1_counter != 3) || (thread_2_counter != 1)) + { + + /* Block memory error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + else + { + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer_1; + + + /* Attempt to get a block from the pool. */ + while(1) + { + + /* Allocate a block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_WAIT_FOREVER); + + /* Determine if the allocate was successful. */ + if (status != TX_SUCCESS) + return; + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_1, (CHAR) 0xEF, 100); + + /* Increment the thread counter. */ + thread_1_counter++; + + /* Release the block. */ + tx_block_release(pointer_1); + + /* Switch back to other thread. */ + tx_thread_relinquish(); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer_1; + + + /* Attempt to get a block from the pool. */ + while(1) + { + + /* Allocate a block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_WAIT_FOREVER); + + /* Determine if the allocate was successful. */ + if (status != TX_SUCCESS) + return; + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_1, (CHAR) 0xEF, 100); + + /* Increment the thread counter. */ + thread_2_counter++; + + /* Release the block. */ + tx_block_release(pointer_1); + + /* Switch back to other thread. */ + tx_thread_relinquish(); + } +} + + diff --git a/test/smp/regression/threadx_block_memory_suspension_timeout_test.c b/test/smp/regression/threadx_block_memory_suspension_timeout_test.c new file mode 100644 index 00000000..f290f01a --- /dev/null +++ b/test/smp/regression/threadx_block_memory_suspension_timeout_test.c @@ -0,0 +1,212 @@ +/* This test is designed to test timeouts on suspension on memory block pools. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + + +static TX_BLOCK_POOL pool_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_block_memory_suspension_timeout_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Suspension Timeout Test........................ ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Suspension Timeout Test........................ ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Suspension Timeout Test........................ ERROR #3\n"); + test_control_return(1); + } + + /* Create block pool. */ + status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320); + pointer = pointer + 320; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Suspension Timeout Test........................ ERROR #4\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer_1; +CHAR *pointer_2; +CHAR *pointer_3; + + + /* Inform user. */ + printf("Running Block Memory Suspension Timeout Test........................ "); + + /* Allocate all blocks from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT); + status += tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT); + status += tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_1, (CHAR) 0xEF, 100); + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_2, (CHAR) 0xEF, 100); + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_3, (CHAR) 0xEF, 100); + + /* Sleep for 64 ticks to allow the other thread 6 timeouts on the block + pool. */ + tx_thread_sleep(64); + + /* Incrment the run counter. */ + thread_0_counter++; + + /* Check the counter of the other thread. */ + if ((thread_1_counter != 6) || (thread_2_counter != 3)) + { + + /* Block memory error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer_1; + + + /* Attempt to get a block from the pool. */ + while(1) + { + + /* Allocate a block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, 10); + + /* Determine if the allocate was successful. */ + if (status != TX_NO_MEMORY) + return; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer_1; + + + /* Delay so we get some single suspension timeouts as well. */ + tx_thread_sleep(32); + + /* Attempt to get a block from the pool. */ + while(1) + { + + /* Allocate a block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, 10); + + /* Determine if the allocate was successful. */ + if (status != TX_NO_MEMORY) + return; + + /* Increment the thread counter. */ + thread_2_counter++; + } +} + diff --git a/test/smp/regression/threadx_block_memory_thread_terminate_test.c b/test/smp/regression/threadx_block_memory_thread_terminate_test.c new file mode 100644 index 00000000..c9221af9 --- /dev/null +++ b/test/smp/regression/threadx_block_memory_thread_terminate_test.c @@ -0,0 +1,185 @@ +/* This test is designed to test thread termination on a thread suspended on a block + memory pool. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + + +static TX_BLOCK_POOL pool_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_block_memory_thread_terminate_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Thread Terminate Test.......................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Thread Terminate Test.......................... ERROR #2\n"); + test_control_return(1); + } + + /* Create block pool. */ + status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320); + pointer = pointer + 320; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Block Memory Thread Terminate Test.......................... ERROR #3\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer_1; +CHAR *pointer_2; +CHAR *pointer_3; + + + /* Inform user. */ + printf("Running Block Memory Thread Terminate Test.......................... "); + + /* Allocate all blocks from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT); + status += tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT); + status += tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT); + + /* Increment the run counter. */ + thread_0_counter++; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Block memory error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_1, (CHAR) 0xEF, 100); + TX_MEMSET(pointer_2, (CHAR) 0xEF, 100); + TX_MEMSET(pointer_3, (CHAR) 0xEF, 100); + + + /* Let other thread suspend on block pool. */ + tx_thread_relinquish(); + + /* Terminate the other thread. */ + status = tx_thread_terminate(&thread_1); + + /* Check status. */ + if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_TERMINATED) || + (thread_1_counter != 0)) + { + + /* Block memory error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Release all the blocks. */ + status = tx_block_release(pointer_1); + status += tx_block_release(pointer_2); + status += tx_block_release(pointer_3); + + /* Check status. */ + if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_TERMINATED) || + (thread_1_counter != 0)) + { + + /* Block memory error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer_1; + + + /* Attempt to get a block from the pool. */ + while(1) + { + + /* Allocate a block from the pool. */ + status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, 10); + + /* Determine if the allocate was successful. */ + if (status != TX_NO_MEMORY) + return; + + /* Set all the memory of the blocks. */ + TX_MEMSET(pointer_1, (CHAR) 0xEF, 100); + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + diff --git a/test/smp/regression/threadx_byte_memory_basic_test.c b/test/smp/regression/threadx_byte_memory_basic_test.c new file mode 100644 index 00000000..9fffc840 --- /dev/null +++ b/test/smp/regression/threadx_byte_memory_basic_test.c @@ -0,0 +1,1064 @@ +/* This test is designed to test simple memory byte pool creation, deletion, and + allocates and releases. */ + +#include +#include "tx_api.h" + +typedef struct BYTE_MEMORY_TEST_STRUCT +{ + ULONG first; + ULONG second; + TX_BYTE_POOL pool; + ULONG first_middle; + ULONG second_middle; + ULONG pool_area[2048/sizeof(ULONG)]; + ULONG next_to_last; + ULONG last; + +} BYTE_MEMORY_TEST; + +static BYTE_MEMORY_TEST byte_memory; + + +/* Define external reference to byte pool creation status. */ + +extern UINT test_byte_pool_create_init; + + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + +UINT _txe_byte_pool_create(TX_BYTE_POOL *pool_ptr, CHAR *name_ptr, VOID *pool_start, + ULONG pool_size, UINT pool_control_block_size); + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + + +static TX_BYTE_POOL pool_0; +static TX_BYTE_POOL pool_1; +static TX_BYTE_POOL pool_2; +static TX_BYTE_POOL pool_3; + +static TX_BYTE_POOL pool_4; +static UCHAR *search_ptr_1; +static UCHAR *block_0; +static UCHAR *block_1; +static UCHAR *block_2; +static UCHAR *block_3; +static UCHAR *block_4; +static CHAR *pool_4_memory; +static TX_TIMER timer_0; + + +static unsigned long error = 0; +static unsigned long timer_executed = 0; +static unsigned long isr_executed = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +UINT _tx_byte_release(VOID *memory_ptr); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define the timer for this test. */ + +static void timer_entry(ULONG i) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +UINT status; +CHAR *pointer; + + + /* Determine if calling byte pool create from initialization was successful. */ + if (test_byte_pool_create_init != TX_SUCCESS) + { + + /* Error! */ + error++; + } + + /* Attempt to create a byte pool from a timer. */ + pointer = (CHAR *) 0x30000; + status = tx_byte_pool_create(&pool_2, "pool 2", pointer, 108); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to create a byte pool with an invalid size. */ + status = _txe_byte_pool_create(&pool_3, "pool 3", pointer, + 108, (sizeof(TX_BYTE_POOL)+1)); + + /* Check status. */ + if (status != TX_POOL_ERROR) + { + + /* Error! */ + error++; + } + + /* Allocate memory from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Try to delete a byte pool from a timer. */ + status = tx_byte_pool_delete(&pool_0); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to release byte memory from timer. */ + pointer = (CHAR *) 0x30000; + status = tx_byte_release(pointer); + + /* Check for error status! */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + timer_executed = 1; +#endif +} + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +CHAR *pointer; +UINT status; + + + /* Allocate memory from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 24, 100); + + /* Check status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + /* Allocate memory from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + + /* Attempt to create a byte pool from an ISR. */ + status = tx_byte_pool_create(&pool_2, "pool 0", (void *) 0x100000, 108); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to deleate a pool from an ISR. */ + status = tx_byte_pool_delete(&pool_0); + + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to release byte memory from ISR. */ + pointer = (CHAR *) 0x30000; + status = tx_byte_release(pointer); + + /* Check for error status! */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + isr_executed = 1; +#endif +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_byte_memory_basic_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Basic Test...................................... ERROR #1\n"); + test_control_return(1); + } + + /* Create byte pools 0 and 1. */ + status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108); + pointer = pointer + 108; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Basic Test...................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_byte_pool_create(&pool_1, "pool 1", pointer, 200); + pointer = pointer + 200; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Basic Test...................................... ERROR #3\n"); + test_control_return(1); + } + + /* Test for search pointer issue on wrapped seach with prior block to search pointer merged. */ + status = tx_byte_pool_create(&pool_4, "pool 4", pointer, 300); + pool_4_memory = pointer; + pointer = pointer + 300; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Basic Test...................................... ERROR #3a\n"); + test_control_return(1); + } + + /* Allocate first block. */ + status += tx_byte_allocate(&pool_4, (VOID **) &block_0, 80, TX_NO_WAIT); + + /* Save next search pointer. */ + search_ptr_1 = pool_4.tx_byte_pool_search; + + /* Clear the allocatged memory. */ + TX_MEMSET(block_0, 0, 80); + + /* Allocate another block. */ + status += tx_byte_allocate(&pool_4, (VOID **) &block_1, 80, TX_NO_WAIT); + + /* Clear the allocated block. */ + TX_MEMSET(block_1, 0, 80); + + /* Allocate the third and final block. */ + status += tx_byte_allocate(&pool_4, (VOID **) &block_2, 80, TX_NO_WAIT); + + /* Clear the allocated block. */ + TX_MEMSET(block_2, 0, 80); + + /* Release the first block. */ + status += tx_byte_release(block_0); + + /* Release the second block. */ + status += tx_byte_release(block_1); + + /* Manually move the search pointer to create the case where the search wraps and a merge happens on the search pointer + necessitating its update. */ + pool_4.tx_byte_pool_search = search_ptr_1; /* Point to the middle block. */ + + /* Allocate a larger block that will wrap the search and require moving as well as an update of the search pointer. */ + status += tx_byte_allocate(&pool_4, (VOID **) &block_3, 120, TX_NO_WAIT); + + /* Clear the newly allocated block. */ + TX_MEMSET(block_3, 0, 120); + + /* At this point, verify the search pointer was properly updated in the previous allocation. */ + status += tx_byte_allocate(&pool_4, (VOID **) &block_4, 40, TX_NO_WAIT); /* Should fail since search pointer is now invalid! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Basic Test...................................... ERROR #3b\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer_1; +CHAR *pointer_2; +CHAR *pointer_3; +CHAR *pointer_4; +INT i; +ULONG array[20]; +UCHAR *save_search; + + + /* Inform user. */ + printf("Running Byte Memory Basic Test...................................... "); + + /* Perform byte memory test. */ + byte_memory.first = 0x11223344; + byte_memory.second = 0x55667788; + byte_memory.first_middle = 0x21314151; + byte_memory.second_middle= 0x61718191; + byte_memory.next_to_last = 0x99aabbcc; + byte_memory.last = 0xddeeff00; + + /* Create the byte pool. */ + status = tx_byte_pool_create(&byte_memory.pool, "pool memory", &byte_memory.pool_area[0], (2048*sizeof(ULONG))/sizeof(ULONG)); + tx_byte_pool_delete(&byte_memory.pool); + + /* Check for status. */ + if ((status != TX_SUCCESS) || + (byte_memory.first != 0x11223344) || + (byte_memory.second != 0x55667788) || + (byte_memory.first_middle != 0x21314151) || + (byte_memory.second_middle != 0x61718191) || + (byte_memory.next_to_last != 0x99aabbcc) || + (byte_memory.last != 0xddeeff00)) + { + + /* Byte memory error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Increment the run counter. */ + thread_0_counter++; + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Try to create a NULL pool. */ + pointer_1 = (CHAR *) 0x30000; + status = tx_byte_pool_create(TX_NULL, "pool 0", pointer_1, 108); + + /* Check status. */ + if (status != TX_POOL_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Try to create the same pool. */ + status = tx_byte_pool_create(&pool_0, "pool 0", pointer_1, 108); + + /* Check status. */ + if (status != TX_POOL_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Try to create a pool with a NULL start address. */ + status = tx_byte_pool_create(&pool_2, "pool 2", TX_NULL, 108); + + /* Check status. */ + if (status != TX_PTR_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Try to create a pool with a a bad size. */ + status = tx_byte_pool_create(&pool_2, "pool 2", pointer_1, 1); + + /* Check status. */ + if (status != TX_SIZE_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Try to delete a byte pool with a NULL pointer. */ + status = tx_byte_pool_delete(TX_NULL); + + /* Check status. */ + if (status != TX_POOL_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Try to delete a byte pool that hasn't been created. */ + pool_2.tx_byte_pool_id = 0; + status = tx_byte_pool_delete(&pool_2); + + /* Check status. */ + if (status != TX_POOL_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Test NULL pool pointer. */ + status = tx_byte_allocate(TX_NULL, (VOID **) &pointer_1, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_POOL_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Test non-created pool pointer. */ + pool_2.tx_byte_pool_id = 0; + status = tx_byte_allocate(&pool_2, (VOID **) &pointer_1, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_POOL_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Test NULL memory pointer. */ + status = tx_byte_allocate(&pool_0, (VOID **) TX_NULL, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_PTR_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Test extreme size. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 240000, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SIZE_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Test size of 0. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 0, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SIZE_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #15\n"); + test_control_return(1); + } +#endif + + /* Test NULL pointer release. */ + status = tx_byte_release(TX_NULL); + + /* Check for error status! */ + if (status != TX_PTR_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Allocate memory from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Allocate memory from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_2, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Allocate memory from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Attempt to allocate fourth area from the pool. This should fail because + there should be not enough bytes in the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_4, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_MEMORY) + { + + /* Byte memory error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Set the memory of all of the allocated memory. */ + for (i =0; i < 24; i++) + { + pointer_1[i] = (CHAR) 0xFF; + pointer_2[i] = (CHAR) 0xFF; + pointer_3[i] = (CHAR) 0xFF; + } + + /* Test the byte release with a bad block pointer. */ + status = _tx_byte_release(TX_NULL); + + /* Check for error status! */ + if (status != TX_PTR_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + /* Test another bad block release... no pool pointer! */ + array[0] = 0; + array[1] = 0; + array[2] = 0; + status = _tx_byte_release(&array[2]); + + /* Check for error status! */ + if (status != TX_PTR_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Test another bad block release.... pool pointer is not a valid pool! */ + array[0] = 0; + array[1] = (ULONG) &array[3]; + array[2] = 0; + array[3] = 0; + status = _tx_byte_release(&array[2]); + + /* Check for error status! */ + if (status != TX_PTR_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Now release each of the blocks. */ + status = tx_byte_release(pointer_1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Now release the same block again. */ + status = tx_byte_release(pointer_1); + + /* Check for status. */ + if (status != TX_PTR_ERROR) + { + + /* Byte memory error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Release the second memory area. */ + status = tx_byte_release(pointer_2); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + + /* Release the third memory area. */ + status = tx_byte_release(pointer_3); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Allocate each block again to make sure everything still + works. */ + + /* Allocate memory from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Allocate second memory area from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_2, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + + /* Allocate third memory area from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + + /* Attempt to allocate fourth memory area from the pool. This should fail because + there should be not enough bytes in the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_4, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_MEMORY) + { + + /* Byte memory error. */ + printf("ERROR #30\n"); + test_control_return(1); + } + + /* Now release each of the blocks. */ + status = tx_byte_release(pointer_1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #31\n"); + test_control_return(1); + } + + /* Release the second memory area. */ + status = tx_byte_release(pointer_2); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #32\n"); + test_control_return(1); + } + + /* Release the third memory area. */ + status = tx_byte_release(pointer_3); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #33\n"); + test_control_return(1); + } + + /* Now allocate a block that should cause all of the blocks to merge + together. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 88, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #34\n"); + test_control_return(1); + } + + /* Attempt to allocate fourth memory area from the pool. This should fail because + there should be not enough bytes in the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_4, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_MEMORY) + { + + /* Byte memory error. */ + printf("ERROR #35\n"); + test_control_return(1); + } + + /* Release the block. */ + status = tx_byte_release(pointer_3); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #36\n"); + test_control_return(1); + } + + /* Now ensure the search pointer update in the byte search algorithm is updated. */ + + /* Allocate memory from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_1, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #37\n"); + test_control_return(1); + } + + /* Allocate second memory area from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_2, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #38\n"); + test_control_return(1); + } + + /* Allocate third memory area from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #39\n"); + test_control_return(1); + } + + /* Release the middle block. */ + status = tx_byte_release(pointer_2); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #40\n"); + test_control_return(1); + } + + /* Move the search pointer to the third block to exercise that code in the byte search algorithm. */ + pool_0.tx_byte_pool_search = (UCHAR *) pointer_3-8; + + /* Now allocate the block again. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_2, 24, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #41\n"); + test_control_return(1); + } + + /* Now release the blocks are test the merge with the update of the search pointer. */ + status = tx_byte_release(pointer_3); + status += tx_byte_release(pointer_2); + status += tx_byte_release(pointer_1); + + /* Move the search pointer to the third block to exercise that code in the byte search algorithm. */ + pool_0.tx_byte_pool_search = (UCHAR *) pointer_3-8; + + /* Allocate a large block to force the search pointer update. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer_3, 88, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #42\n"); + test_control_return(1); + } + + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Create a timer for the test. */ + tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE); + + /* Setup the ISR. */ + test_isr_dispatch = test_isr; + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Clear the ISR. */ + test_isr_dispatch = TX_NULL; + + /* Test for error. */ + if ((error) || (timer_executed != 1) || (isr_executed != 1)) + { + + /* Byte memory error. */ + printf("ERROR #43\n"); + test_control_return(1); + } + +#endif + + /* Delete both byte pools. */ + status = tx_byte_pool_delete(&pool_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #44\n"); + test_control_return(1); + } + + status = tx_byte_pool_delete(&pool_1); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #45\n"); + test_control_return(1); + } + + /* Delete pool 4. */ + status = tx_byte_pool_delete(&pool_4); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #46\n"); + test_control_return(1); + } + + /* Create pool 4. */ + status = tx_byte_pool_create(&pool_4, "pool 4", pool_4_memory, 300); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #47\n"); + test_control_return(1); + } + + /* Allocate three blocks... */ + status = tx_byte_allocate(&pool_4, (VOID **) &pointer_1, 84, TX_NO_WAIT); + status += tx_byte_allocate(&pool_4, (VOID **) &pointer_2, 84, TX_NO_WAIT); + status += tx_byte_allocate(&pool_4, (VOID **) &pointer_3, 84, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #48\n"); + test_control_return(1); + } + + /* At this point, there should be three allocated blocks and the reserved block at the end. */ + + /* Now release all the blocks in reverse order. This should leave the search pointer at the last block. */ + status = tx_byte_release(pointer_3); + save_search = pool_4.tx_byte_pool_search; + status += tx_byte_release(pointer_2); + status += tx_byte_release(pointer_1); + + /* Move the search pointer back to the last block. */ + pool_4.tx_byte_pool_search = save_search; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #49\n"); + test_control_return(1); + } + + /* Now attempt to allocate a block that requires a merge, which should exercise the branch in byte search that does not + result in a search pointer change. */ + status = tx_byte_allocate(&pool_4, (VOID **) &pointer_1, 168, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #50\n"); + test_control_return(1); + } + + /* Release the last block. */ + status = tx_byte_release(pointer_1); + + /* Allocate all the blocks. */ + status = tx_byte_allocate(&pool_4, (VOID **) &pointer_1, 84, TX_NO_WAIT); + status += tx_byte_allocate(&pool_4, (VOID **) &pointer_2, 84, TX_NO_WAIT); + status += tx_byte_allocate(&pool_4, (VOID **) &pointer_3, 84, TX_NO_WAIT); + + /* Release all of the blocks in order. */ + status += tx_byte_release(pointer_1); + status += tx_byte_release(pointer_2); + status += tx_byte_release(pointer_3); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #50\n"); + test_control_return(1); + } + + /* Now setup a special test to exercise the examine blocks equal to 0 path in the byte pool search. */ + pool_4.tx_byte_pool_search = save_search; + pool_4.tx_byte_pool_fragments = (UINT) (-1); + + /* Call byte allocate to execise the examine blocks equal to 0 path on non-merge block condition. */ + status = tx_byte_allocate(&pool_4, (VOID **) &pointer_1, 168, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_MEMORY) + { + + /* Byte memory error. */ + printf("ERROR #51\n"); + test_control_return(1); + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + diff --git a/test/smp/regression/threadx_byte_memory_information_test.c b/test/smp/regression/threadx_byte_memory_information_test.c new file mode 100644 index 00000000..2d1c20bc --- /dev/null +++ b/test/smp/regression/threadx_byte_memory_information_test.c @@ -0,0 +1,784 @@ +/* This test is designed to test byte memory information. */ + +#include +#include "tx_api.h" +#include "tx_byte_pool.h" + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Define the external reference for the preempt disable flag. */ + +extern volatile UINT _tx_thread_preempt_disable; + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + +static unsigned long thread_5_counter = 0; +static TX_THREAD thread_5; + +static unsigned long thread_6_counter = 0; +static TX_THREAD thread_6; + +static TX_BYTE_POOL byte_pool_0; +#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO +static TX_BYTE_POOL byte_pool_1; +#endif +static TX_BYTE_POOL byte_pool_2; + +static int test_status; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); +static void thread_6_entry(ULONG thread_input); + +UINT _tx_byte_pool_performance_info_get(TX_BYTE_POOL *pool_ptr, ULONG *allocates, ULONG *releases, + ULONG *fragments_searched, ULONG *merges, ULONG *splits, ULONG *suspensions, ULONG *timeouts); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + + /* Determine if the test case we are looking for is present. */ + if ((_tx_thread_preempt_disable) && (test_status == 1)) + { + + /* Abort the wait of thread 3. */ + tx_thread_wait_abort(&thread_3); + + /* End the ISR processing. */ + test_status = 2; + test_isr_dispatch = TX_NULL; + } +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_byte_memory_information_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Information Test................................ ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Information Test................................ ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Information Test................................ ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 3, 3, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Information Test................................ ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 4, 4, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Information Test................................ ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, TEST_STACK_SIZE_PRINTF, + 5, 5, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Information Test................................ ERROR #6\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6, + pointer, TEST_STACK_SIZE_PRINTF, + 6, 6, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Information Test................................ ERROR #7\n"); + test_control_return(1); + } + + /* Create the byte_pool with one byte. */ + status = tx_byte_pool_create(&byte_pool_0, "byte_pool 0", pointer, 100); + pointer = pointer + 100; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Information Test................................ ERROR #8\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; +CHAR *name; +ULONG available; +ULONG fragments; +TX_THREAD *first_suspended; +ULONG suspended_count; +TX_BYTE_POOL *next_pool; +ULONG allocates; +ULONG releases; +ULONG fragments_searched; +ULONG merges; +ULONG splits; +ULONG suspensions; +ULONG timeouts; + + + /* Inform user. */ + printf("Running Byte Memory Information Test................................ "); + + /* Allocate the one byte. */ + tx_byte_allocate(&byte_pool_0, &pointer, 80, TX_NO_WAIT); + + /* Nothing to do here, but check prioritization with no suspended threads. */ + status = tx_byte_pool_prioritize(&byte_pool_0); + + /* Check status and make sure thread 1 is terminated. */ + if (status != TX_SUCCESS) + { + + /* Byte Pool error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Make sure thread 1 and 2 are suspended on the byte_pool. */ + if ((thread_1.tx_thread_state != TX_BYTE_MEMORY) || (thread_2.tx_thread_state != TX_BYTE_MEMORY) || + (byte_pool_0.tx_byte_pool_suspension_list != &thread_1)) + { + + /* Byte Pool error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Prioritize the byte pool suspension list. */ + status = tx_byte_pool_prioritize(&byte_pool_0); + + /* Check status and make sure thread 2 is now at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_2)) + { + + /* Byte Pool error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* At this point we are going to get more than 2 threads suspended. */ + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + tx_thread_resume(&thread_3); + tx_thread_resume(&thread_4); + tx_thread_resume(&thread_5); + tx_thread_resume(&thread_6); + + /* Prioritize the byte pool suspension list. */ + status = tx_byte_pool_prioritize(&byte_pool_0); + + /* Check status and make sure thread 3 is now at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_3)) + { + + /* Byte Pool error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Now loop to test the interrupt of the prioritize loop logic. */ + test_status = 1; + test_isr_dispatch = test_isr; + do + { + + /* Prioritize the byte pool suspension list. */ + status = tx_byte_pool_prioritize(&byte_pool_0); + + /* Check status and make sure thread 1 is terminated. */ + if (status != TX_SUCCESS) + { + + /* Byte Pool error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + } while (test_status == 1); + + /* Check status and make sure thread 3 is now at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_4)) + { + + /* Byte Pool error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Call byte pool info with a NULL pointer. */ + status = tx_byte_pool_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for error. */ + if (status != TX_POOL_ERROR) + { + + /* Byte Pool error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Call byte pool info with an non-created pool pointer. */ + byte_pool_2.tx_byte_pool_id = 0; + status = tx_byte_pool_info_get(&byte_pool_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for error. */ + if (status != TX_POOL_ERROR) + { + + /* Byte Pool error. */ + printf("ERROR #16\n"); + test_control_return(1); + } +#endif + + /* Get the byte pool information. */ + status = tx_byte_pool_info_get(&byte_pool_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_byte_pool_info_get(&byte_pool_0, &name, &available, &fragments, &first_suspended, &suspended_count, &next_pool); + + /* Check the status. */ + if ((status != TX_SUCCESS) || (available != byte_pool_0.tx_byte_pool_available) || (fragments != byte_pool_0.tx_byte_pool_fragments) || + (first_suspended != &thread_4) || (suspended_count != byte_pool_0.tx_byte_pool_suspended_count) || (next_pool != &byte_pool_0)) + { + + /* Byte Pool error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + +#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO + + /* Get the byte pool performance information. */ + status = tx_byte_pool_performance_info_get(TX_NULL, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_PTR_ERROR) + { + + /* Byte Pool error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Get the byte pool performance information. */ + status = tx_byte_pool_performance_info_get(&byte_pool_1, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_PTR_ERROR) + { + + /* Byte Pool error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Get the byte pool performance information. */ + status = tx_byte_pool_performance_info_get(&byte_pool_0, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if ((status != TX_SUCCESS) || (allocates != byte_pool_0.tx_byte_pool_performance_allocate_count) || (releases != byte_pool_0.tx_byte_pool_performance_release_count) || + (fragments_searched != byte_pool_0.tx_byte_pool_performance_search_count) || (merges != byte_pool_0.tx_byte_pool_performance_merge_count) || + (splits != byte_pool_0.tx_byte_pool_performance_split_count) || (suspensions != byte_pool_0.tx_byte_pool_performance_suspension_count) || + (timeouts != byte_pool_0.tx_byte_pool_performance_timeout_count)) + { + + /* Byte Pool error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Get the byte pool system performance information. */ + status = tx_byte_pool_performance_system_info_get(&allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if ((status != TX_SUCCESS) || (allocates != _tx_byte_pool_performance_allocate_count) || (releases != _tx_byte_pool_performance_release_count) || + (fragments_searched != _tx_byte_pool_performance_search_count) || (merges != _tx_byte_pool_performance_merge_count) || + (splits != _tx_byte_pool_performance_split_count) || (suspensions != _tx_byte_pool_performance_suspension_count) || + (timeouts != _tx_byte_pool_performance_timeout_count)) + { + + /* Byte Pool error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +#else + + /* Get the byte pool performance information. */ + status = tx_byte_pool_performance_info_get(&byte_pool_0, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Get the byte pool performance information. */ + status = tx_byte_pool_performance_info_get(TX_NULL, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Get the byte pool performance information. */ + status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Get the byte pool performance information. */ + status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &fragments_searched, &merges, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + + /* Get the byte pool performance information. */ + status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &merges, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Get the byte pool performance information. */ + status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Get the byte pool performance information. */ + status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + + /* Get the byte pool performance information. */ + status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + + /* Get the byte pool performance information. */ + status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #30\n"); + test_control_return(1); + } + + /* Get the byte pool system performance information. */ + status = tx_byte_pool_performance_system_info_get(&allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #31\n"); + test_control_return(1); + } + + /* Get the byte pool system performance information. */ + status = tx_byte_pool_performance_system_info_get(TX_NULL, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #32\n"); + test_control_return(1); + } + + /* Get the byte pool system performance information. */ + status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, &fragments_searched, &merges, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #33\n"); + test_control_return(1); + } + + /* Get the byte pool system performance information. */ + status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &merges, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #34\n"); + test_control_return(1); + } + + /* Get the byte pool system performance information. */ + status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &splits, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #35\n"); + test_control_return(1); + } + + /* Get the byte pool system performance information. */ + status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #36\n"); + test_control_return(1); + } + + /* Get the byte pool system performance information. */ + status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #37\n"); + test_control_return(1); + } + + /* Get the byte pool system performance information. */ + status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Byte Pool error. */ + printf("ERROR #38\n"); + test_control_return(1); + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +#endif +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +VOID *pointer; + + /* Loop forever! */ + while(1) + { + + + /* Get byte from pool. */ + status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get byte from pool. */ + status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_2_counter++; + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get byte from pool. */ + status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_3_counter++; + } +} + + +static void thread_4_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get byte from pool. */ + status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_4_counter++; + } +} + + +static void thread_5_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get byte from pool. */ + status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_5_counter++; + } +} + + +static void thread_6_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get byte from pool. */ + status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_6_counter++; + } +} diff --git a/test/smp/regression/threadx_byte_memory_prioritize_test.c b/test/smp/regression/threadx_byte_memory_prioritize_test.c new file mode 100644 index 00000000..f06d5cd3 --- /dev/null +++ b/test/smp/regression/threadx_byte_memory_prioritize_test.c @@ -0,0 +1,498 @@ +/* This test is designed to test byte memory prioritize. */ + +#include +#include "tx_api.h" + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Define the external reference for the preempt disable flag. */ + +extern volatile UINT _tx_thread_preempt_disable; + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + +static unsigned long thread_5_counter = 0; +static TX_THREAD thread_5; + +static unsigned long thread_6_counter = 0; +static TX_THREAD thread_6; + +static TX_BYTE_POOL byte_pool_0; +static TX_BYTE_POOL byte_pool_1; + +static int test_status; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); +static void thread_6_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + + /* Determine if the test case we are looking for is present. */ + if ((_tx_thread_preempt_disable) && (test_status == 1)) + { + + /* Determine if thread 3 is at the front of the suspension list. */ + if (byte_pool_0.tx_byte_pool_suspension_list == &thread_3) + { + + /* Abort the wait of thread 3. */ + tx_thread_wait_abort(&thread_3); + } + else + { + + /* Abort the wait of thread 5. */ + tx_thread_wait_abort(&thread_5); + + /* End the ISR processing. */ + test_status = 2; + test_isr_dispatch = TX_NULL; + } + } +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_byte_memory_prioritize_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Prioritize Test................................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Prioritize Test................................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Prioritize Test................................. ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 3, 3, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Prioritize Test................................. ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 4, 4, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Prioritize Test................................. ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, TEST_STACK_SIZE_PRINTF, + 5, 5, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Prioritize Test................................. ERROR #6\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6, + pointer, TEST_STACK_SIZE_PRINTF, + 6, 6, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Prioritize Test................................. ERROR #7\n"); + test_control_return(1); + } + + /* Create the byte_pool with one byte. */ + status = tx_byte_pool_create(&byte_pool_0, "byte_pool 0", pointer, 100); + pointer = pointer + 100; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Prioritize Test................................. ERROR #8\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Inform user. */ + printf("Running Byte Memory Prioritize Test................................. "); + + /* Allocate the one byte. */ + tx_byte_allocate(&byte_pool_0, &pointer, 80, TX_NO_WAIT); + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Call byte pool prioritize with a NULL pointer. */ + status = tx_byte_pool_prioritize(TX_NULL); + + /* Check for error. */ + if (status != TX_POOL_ERROR) + { + + /* Byte Pool error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Call byte pool info with an non-created pool pointer. */ + byte_pool_1.tx_byte_pool_id = 0; + status = tx_byte_pool_prioritize(&byte_pool_1); + + /* Check for error. */ + if (status != TX_POOL_ERROR) + { + + /* Byte Pool error. */ + printf("ERROR #10\n"); + test_control_return(1); + } +#endif + + /* Nothing to do here, but check prioritization with no suspended threads. */ + status = tx_byte_pool_prioritize(&byte_pool_0); + + /* Check status and make sure thread 1 is terminated. */ + if (status != TX_SUCCESS) + { + + /* Byte Pool error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Make sure thread 1 and 2 are suspended on the byte_pool. */ + if ((thread_1.tx_thread_state != TX_BYTE_MEMORY) || (thread_2.tx_thread_state != TX_BYTE_MEMORY) || + (byte_pool_0.tx_byte_pool_suspension_list != &thread_1)) + { + + /* Byte Pool error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Prioritize the byte pool suspension list. */ + status = tx_byte_pool_prioritize(&byte_pool_0); + + /* Check status and make sure thread 2 is now at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_2)) + { + + /* Byte Pool error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Call byte pool prioritize again to test the don't-do-anything path in tx_byte_pool_prioritize. */ + status += tx_byte_pool_prioritize(&byte_pool_0); + + /* At this point we are going to get more than 2 threads suspended. */ + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + tx_thread_resume(&thread_3); + tx_thread_resume(&thread_4); + tx_thread_resume(&thread_5); + tx_thread_resume(&thread_6); + + /* Prioritize the byte pool suspension list. */ + status = tx_byte_pool_prioritize(&byte_pool_0); + + /* Check status and make sure thread 3 is now at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_3)) + { + + /* Byte Pool error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Now loop to test the interrupt of the prioritize loop logic. */ + test_status = 1; + test_isr_dispatch = test_isr; + do + { + + /* Prioritize the byte pool suspension list. */ + status = tx_byte_pool_prioritize(&byte_pool_0); + + /* Check status and make sure thread 1 is terminated. */ + if (status != TX_SUCCESS) + { + + /* Block Pool error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + } while (test_status == 1); + + /* Check status and make sure thread 3 is now at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_4)) + { + + /* Byte Pool error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +VOID *pointer; + + /* Loop forever! */ + while(1) + { + + + /* Get byte from pool. */ + status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get byte from pool. */ + status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_2_counter++; + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get byte from pool. */ + status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_3_counter++; + } +} + + +static void thread_4_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get byte from pool. */ + status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_4_counter++; + } +} + + +static void thread_5_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get byte from pool. */ + status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_5_counter++; + } +} + + +static void thread_6_entry(ULONG thread_input) +{ + +UINT status; +VOID *pointer; + + + /* Loop forever! */ + while(1) + { + + + /* Get byte from pool. */ + status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_6_counter++; + } +} + diff --git a/test/smp/regression/threadx_byte_memory_suspension_test.c b/test/smp/regression/threadx_byte_memory_suspension_test.c new file mode 100644 index 00000000..069410c5 --- /dev/null +++ b/test/smp/regression/threadx_byte_memory_suspension_test.c @@ -0,0 +1,391 @@ +/* This test is designed to test suspension on a memory byte pool. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + + +static TX_BYTE_POOL pool_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); + + + +#ifndef TX_MANUAL_TEST + +/* Define test flags for automated test. */ + +extern TEST_FLAG threadx_byte_allocate_loop_test; +extern TEST_FLAG threadx_byte_release_loop_test; + +#endif + + +void abort_and_resume_byte_allocating_thread(void) +{ + +UCHAR *search_ptr; + + /* Adjust the search pointer to avoid the search pointer change for this test. */ + search_ptr = pool_0.tx_byte_pool_search; + while (search_ptr >= pool_0.tx_byte_pool_search) + + { + search_ptr = *((UCHAR **) ((VOID *) search_ptr)); + } + pool_0.tx_byte_pool_search = search_ptr; + + tx_thread_wait_abort(&thread_3); + tx_thread_resume(&thread_3); +} + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_byte_memory_suspension_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Suspension Test................................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Suspension Test................................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Suspension Test................................. ERROR #3\n"); + test_control_return(1); + } + + /* Create byte pool 0. */ + status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108); + pointer = pointer + 108; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Suspension Test................................. ERROR #4\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer; + + + /* Inform user. */ + printf("Running Byte Memory Suspension Test................................. "); + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Allocate memory from the pool. Only one block of this size will fit. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Let other thread suspend on byte pool. */ + tx_thread_relinquish(); + + /* Now release the blocks. */ + status = tx_byte_release(pointer); + + /* Check status. */ + if ((status != TX_SUCCESS) && (thread_1_counter == 0)) + { + + /* Byte memory error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Let other thread run again. */ + tx_thread_relinquish(); + + /* Check to make sure thread 1 has now run. */ + if (thread_1_counter != 1) + { + + /* Byte memory error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Now allocate the memory again. Only one block of this size will fit. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Resume the second thread. */ + tx_thread_resume(&thread_2); + + /* Now relinquish to let both thread 1 and 2 suspend. */ + tx_thread_relinquish(); + + /* At this point both threads should be suspended on the byte pool. */ + + /* Release the memory again. */ + status = tx_byte_release(pointer); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Now relinquish to get the other threads to run once. */ + tx_thread_relinquish(); + tx_thread_relinquish(); + + /* At this point both threads 1 and 2 are suspended on the byte pool again. */ + if ((thread_1_counter != 3) && (thread_2_counter != 1)) + { + + /* Byte memory error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Now allocate the memory again. Only one block of this size will fit. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #10a\n"); + test_control_return(1); + } + + /* Resume thread 3 to get it suspended on the the pool. */ + tx_thread_resume(&thread_3); + +#ifdef TX_MANUAL_TEST + + /* Set BP hear. Now release the memory and step into the code. After byte search issue IRQ2 mannually, which will + make thread 3 abort the first request and make another request of a different size. This is the path we are trying + to generate in the test. */ + status = tx_byte_release(pointer); +#else + + /* Set the flag that will make thread 3 abort the first request and make another request of a different size. This tests the memory size change path + in the byte release loop logic. */ + threadx_byte_release_loop_test = 1; + status = tx_byte_release(pointer); + +#endif + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #10b\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer; + + while(1) + { + + /* Allocate memory from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + return; + + /* Increment the thread counter. */ + thread_1_counter++; + + /* Now release each of the blocks. */ + status = tx_byte_release(pointer); + + /* Check for status. */ + if (status != TX_SUCCESS) + return; + + /* Let thread 0 run again. */ + tx_thread_relinquish(); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer; + + while(1) + { + + /* Allocate memory from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + return; + + /* Increment the thread counter. */ + thread_2_counter++; + + /* Now release each of the blocks. */ + status = tx_byte_release(pointer); + + /* Check for status. */ + if (status != TX_SUCCESS) + return; + + /* Let thread 0 run again. */ + tx_thread_relinquish(); + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer; + + while (1) + { + + /* Allocate memory from the pool. */ + tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER); + +#ifdef TX_MANUAL_TEST + + /* Set BP here and manually clear the owner after one failed byte search just to test the loop + construct in tx_byte_allocate.c. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 90, TX_WAIT_FOREVER); +#else + + /* Set the flag that clears the pool owner after one failed byte search to test the loop + construct processing in tx_byte_allocate.c. */ + threadx_byte_allocate_loop_test = 1; + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 90, TX_WAIT_FOREVER); +#endif + + /* Check for status. */ + if (status != TX_SUCCESS) + return; + + /* Increment the thread counter. */ + thread_3_counter++; + + /* Now release the block. */ + status = tx_byte_release(pointer); + + /* Check for status. */ + if (status != TX_SUCCESS) + return; + + /* suspend this thread. */ + tx_thread_suspend(&thread_3); + } +} diff --git a/test/smp/regression/threadx_byte_memory_suspension_timeout_test.c b/test/smp/regression/threadx_byte_memory_suspension_timeout_test.c new file mode 100644 index 00000000..ed122dab --- /dev/null +++ b/test/smp/regression/threadx_byte_memory_suspension_timeout_test.c @@ -0,0 +1,196 @@ +/* This test is designed to test suspension timeout on a memory byte pool. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + + +static TX_BYTE_POOL pool_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_byte_memory_suspension_timeout_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Suspension Timeout Test......................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Suspension Timeout Test......................... ERROR #2\n"); + test_control_return(1); + } + + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Suspension Timeout Test......................... ERROR #3\n"); + test_control_return(1); + } + + /* Create byte pool 0. */ + status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108); + pointer = pointer + 108; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Suspension Timeout Test......................... ERROR #4\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer; + + + /* Inform user. */ + printf("Running Byte Memory Suspension Timeout Test......................... "); + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Allocate memory from the pool. Only one block of this size will fit. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT); + + /* Check status. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 0)) + { + + /* Byte memory error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Sleep to allow the other thread to suspend and timeout on the memory + pool once. */ + tx_thread_sleep(64); + + /* Check the counter of the other thread. */ + if ((thread_1_counter != 6) || (thread_2_counter != 3)) + { + + /* Block memory error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer; + + while(1) + { + + /* Allocate memory from the pool - with timeout. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, 10); + + /* Check status. */ + if (status != TX_NO_MEMORY) + return; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer; + + + /* Delay so we get some single suspension timeouts as well. */ + tx_thread_sleep(32); + + while(1) + { + + /* Allocate memory from the pool - with timeout. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, 10); + + /* Check status. */ + if (status != TX_NO_MEMORY) + return; + + /* Increment the thread counter. */ + thread_2_counter++; + } +} diff --git a/test/smp/regression/threadx_byte_memory_thread_contention_test.c b/test/smp/regression/threadx_byte_memory_thread_contention_test.c new file mode 100644 index 00000000..55f7f4f3 --- /dev/null +++ b/test/smp/regression/threadx_byte_memory_thread_contention_test.c @@ -0,0 +1,255 @@ +/* This test is designed to test contention of two threads on a single + memory byte pool. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; +static unsigned long initial_pool_size; + + +static TX_BYTE_POOL pool_0; + + +static int test_done; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_byte_memory_thread_contention_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 1, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Thread Contention Test.......................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 1, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Thread Contention Test.......................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 1, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Thread Contention Test.......................... ERROR #3\n"); + test_control_return(1); + } + + /* Create byte pool 0. */ + status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108); + pointer = pointer + 108; + + /* Save off the intial pool size. */ + initial_pool_size = pool_0.tx_byte_pool_available; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Thread Contention Test.......................... ERROR #4\n"); + test_control_return(1); + } + + /* Set the test done flag to false. */ + test_done = TX_FALSE; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer; + + + /* Inform user. */ + printf("Running Byte Memory Thread Contention Test.......................... "); + + /* Set time to 0. */ + tx_time_set(0); + + while(1) + { + + /* Allocate memory from the pool. This size will cause merge activity + because the search pointer will sit in this large block about half + the time. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Fill the memory. */ + TX_MEMSET(pointer, (CHAR) 0xEF, 60); + + /* Now release the block. */ + status = tx_byte_release(pointer); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Check the time. */ + if (tx_time_get() > 1280) + break; + + /* Increment the thread counter. */ + thread_0_counter++; + } + + /* Set the done flag. */ + test_done = TX_TRUE; + + /* Sleep to let the other threads finish up! */ + tx_thread_sleep(2); + + /* Determine if we all all the original memory and that thread 1 + is in the proper place. */ + if (pool_0.tx_byte_pool_available != initial_pool_size) + { + + /* Byte memory error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer; + + + while(test_done == TX_FALSE) + { + + /* Allocate memory from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 30, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + return; + + /* Fill the memory. */ + TX_MEMSET(pointer, (CHAR) 0xEF, 30); + + /* Now release the block. */ + status = tx_byte_release(pointer); + + /* Check for status. */ + if (status != TX_SUCCESS) + return; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer; + + + while(test_done == TX_FALSE) + { + + /* Allocate memory from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 12, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + return; + + /* Fill the memory. */ + TX_MEMSET(pointer, (CHAR) 0xEF, 12); + + /* Now release the block. */ + status = tx_byte_release(pointer); + + /* Check for status. */ + if (status != TX_SUCCESS) + return; + + /* Increment the thread counter. */ + thread_2_counter++; + } +} diff --git a/test/smp/regression/threadx_byte_memory_thread_terminate_test.c b/test/smp/regression/threadx_byte_memory_thread_terminate_test.c new file mode 100644 index 00000000..29fec0c0 --- /dev/null +++ b/test/smp/regression/threadx_byte_memory_thread_terminate_test.c @@ -0,0 +1,177 @@ +/* This test is designed to test termination on thread suspended on memory byte pool. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + + +static TX_BYTE_POOL pool_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_byte_memory_thread_terminate_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Thread Terminate Test........................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Thread Terminate Test........................... ERROR #2\n"); + test_control_return(1); + } + + /* Create byte pools 0 and 1. */ + status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108); + pointer = pointer + 108; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Byte Memory Thread Terminate Test........................... ERROR #3\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer; + + + /* Inform user. */ + printf("Running Byte Memory Thread Terminate Test........................... "); + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Allocate memory from the pool. Only one block of this size will fit. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Let other thread suspend on byte pool. */ + tx_thread_relinquish(); + + /* Terminate the other thread. */ + status = tx_thread_terminate(&thread_1); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Release block back. */ + status = tx_byte_release(pointer); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Byte memory error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Allocate memory from the pool. Only one block of this size will fit. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT); + + /* Check status. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 0)) + { + + /* Byte memory error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +CHAR *pointer; + + while(1) + { + + /* Allocate memory from the pool. */ + status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER); + + /* Should never get here! */ + if (status != TX_NO_MEMORY) + return; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + diff --git a/test/smp/regression/threadx_event_flag_basic_test.c b/test/smp/regression/threadx_event_flag_basic_test.c new file mode 100644 index 00000000..9c19f9bd --- /dev/null +++ b/test/smp/regression/threadx_event_flag_basic_test.c @@ -0,0 +1,743 @@ +/* This test is designed to test simple event flag group creation, deletion, gets and + sets. */ + +#include +#include "tx_api.h" + + +typedef struct EVENT_FLAG_MEMORY_TEST_STRUCT +{ + ULONG first; + ULONG second; + TX_EVENT_FLAGS_GROUP event_flags; + ULONG next_to_last; + ULONG last; + +} EVENT_FLAG_MEMORY_TEST; + +static EVENT_FLAG_MEMORY_TEST event_flag_memory; + + +/* Define external reference to the event flag create call from initialization. */ + +extern UINT test_event_flags_from_init; + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_TIMER timer_0; + +static unsigned long error = 0; +static unsigned long timer_executed = 0; +static unsigned long isr_executed = 0; + +static TX_EVENT_FLAGS_GROUP group_0; +static TX_EVENT_FLAGS_GROUP group_1; +static TX_EVENT_FLAGS_GROUP group_2; +static TX_EVENT_FLAGS_GROUP group_3; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +UINT _txe_event_flags_create(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name_ptr, UINT event_control_block_size); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void event_set_notify(TX_EVENT_FLAGS_GROUP *group) +{ + + /* Not necessary to do anything in this function. */ +} + + +/* Define the timer for this test. */ + +static void timer_entry(ULONG i) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +UINT status; +ULONG actual_events; + + + /* Determine if calling event flag create from initialization was successful. */ + if (test_event_flags_from_init != TX_SUCCESS) + { + + /* Error! */ + error++; + } + + /* Attempt to create an event flag group from a timer. */ + status = tx_event_flags_create(&group_2, "group 2"); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Try to delete an event flags group from a timer. */ + status = tx_event_flags_delete(&group_0); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Get events with suspendsion from a timer. */ + status = tx_event_flags_get(&group_0, 0x80008000, 14, &actual_events, 100); + + /* Check status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + timer_executed = 1; +#endif +} + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +UINT status; +ULONG actual_events; + + + /* Attempt to create an event flag group from an ISR. */ + status = tx_event_flags_create(&group_2, "group 2"); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to delete an event flags group from an ISR. */ + status = tx_event_flags_delete(&group_0); + + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Get events with suspendsion from an ISR. */ + status = tx_event_flags_get(&group_0, 0x80008000, 14, &actual_events, 100); + + /* Check status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + + isr_executed = 1; +#endif +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_event_flag_basic_application_define(void *first_unused_memory) +#endif +{ + +INT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Basic Test....................................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Basic Test....................................... ERROR #2\n"); + test_control_return(1); + } + + /* Create event flag group 0 and 1. */ + status = tx_event_flags_create(&group_0, "group 0"); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Basic Test....................................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_event_flags_create(&group_1, "group 1"); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Basic Test....................................... ERROR #4\n"); + test_control_return(1); + } + + /* Register the event set notify function. */ + status = tx_event_flags_set_notify(&group_0, event_set_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Basic Test....................................... ERROR #5\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Event Flag Basic Test....................................... ERROR #6\n"); + test_control_return(1); + } + +#endif + + /* Un-register the event set notify function. */ + status = tx_event_flags_set_notify(&group_0, TX_NULL); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Basic Test....................................... ERROR #5a\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Event Flag Basic Test....................................... ERROR #6a\n"); + test_control_return(1); + } +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_events; + + + /* Inform user. */ + printf("Running Event Flag Basic Test....................................... "); + + /* Perform event flag memory test. */ + event_flag_memory.first = 0x11223344; + event_flag_memory.second = 0x55667788; + event_flag_memory.next_to_last = 0x99aabbcc; + event_flag_memory.last = 0xddeeff00; + + /* Create the event flag group. */ + status = tx_event_flags_create(&event_flag_memory.event_flags, "group memory"); + tx_event_flags_delete(&event_flag_memory.event_flags); + + /* Check for status. */ + if ((status != TX_SUCCESS) || + (event_flag_memory.first != 0x11223344) || + (event_flag_memory.second != 0x55667788) || + (event_flag_memory.next_to_last != 0x99aabbcc) || + (event_flag_memory.last != 0xddeeff00)) + { + + /* Event flag error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Event flags should be created now. */ + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Try to create with a NULL pointer. */ + status = tx_event_flags_create(TX_NULL, "group 0"); + + /* Check status. */ + if (status != TX_GROUP_ERROR) + { + + /* Event flag error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Try to create with a bad size. */ + status = _txe_event_flags_create(&group_3, "group 3", (sizeof(TX_EVENT_FLAGS_GROUP)+1)); + + /* Check status. */ + if (status != TX_GROUP_ERROR) + { + + /* Event flag error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Try to create an already created group. */ + status = tx_event_flags_create(&group_0, "group 0"); + + /* Check status. */ + if (status != TX_GROUP_ERROR) + { + + /* Event flag error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Delete with a NULL pointer. */ + status = tx_event_flags_delete(TX_NULL); + + /* Check the status. */ + if (status != TX_GROUP_ERROR) + { + + /* Event flag error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Delete with a non-created pointer. */ + group_2.tx_event_flags_group_id = 0; + status = tx_event_flags_delete(&group_2); + + /* Check the status. */ + if (status != TX_GROUP_ERROR) + { + + /* Event flag error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Get events with a null group pointer. */ + status = tx_event_flags_get(TX_NULL, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_GROUP_ERROR) + { + + /* Event flag error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Get events with a non-created group pointer. */ + group_2.tx_event_flags_group_id = 0; + status = tx_event_flags_get(&group_2, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_GROUP_ERROR) + { + + /* Event flag error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Get events with a null flags retun pointer. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, TX_NULL, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_PTR_ERROR) + { + + /* Event flag error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Get events with a bad option. */ + status = tx_event_flags_get(&group_0, 0x80008000, 14, &actual_events, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_OPTION_ERROR) + { + + /* Event flag error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Set evetns with a NULL group pointer. */ + status = tx_event_flags_set(TX_NULL, 0x80008000, TX_OR); + + /* Check status. */ + if (status != TX_GROUP_ERROR) + { + + /* Event flag error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Set events with a non-created group pointer. */ + group_2.tx_event_flags_group_id = 0; + status = tx_event_flags_set(&group_2, 0x80008000, TX_OR); + + /* Check status. */ + if (status != TX_GROUP_ERROR) + { + + /* Event flag error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Set events with a bad option. */ + status = tx_event_flags_set(&group_0, 0x80008000, 14); + + /* Check status. */ + if (status != TX_OPTION_ERROR) + { + + /* Event flag error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Attempt to register the event set notify function with a NULL group pointer. */ + status = tx_event_flags_set_notify(TX_NULL, event_set_notify); + + /* Check status. */ + if (status != TX_GROUP_ERROR) + { + + /* Event flag error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Attempt to register the event set notify function with a non-created group pointer. */ + group_2.tx_event_flags_group_id = 0; + status = tx_event_flags_set_notify(&group_2, event_set_notify); + + /* Check status. */ + if (status != TX_GROUP_ERROR) + { + + /* Event flag error. */ + printf("ERROR #21\n"); + test_control_return(1); + } +#endif + + /* Attempt to get events from an empty event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_EVENTS) + { + + /* Event flag error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Attempt to get events from an empty event flag group. OR option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_EVENTS) + { + + /* Event flag error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Attempt to get events from an empty event flag group. AND CLEAR option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_EVENTS) + { + + /* Event flag error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Attempt to get events from an empty event flag group. OR CLEAR option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_EVENTS) + { + + /* Event flag error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + + /* Set the necessary events. */ + status = tx_event_flags_set(&group_0, 0x80008000, TX_OR); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Just for fun, clear bit 15. */ + status = tx_event_flags_set(&group_0, 0x80000000, TX_AND); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Set bit 15 again. */ + status = tx_event_flags_set(&group_0, 0x00008000, TX_OR); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + + /* Now attemp to retrieve events... */ + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL)) + { + + /* Event flag error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + + /* Attempt to get events from event flag group. OR option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL)) + { + + /* Event flag error. */ + printf("ERROR #30\n"); + test_control_return(1); + } + + /* Attempt to get events from event flag group. AND CLEAR option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL)) + { + + /* Event flag error. */ + printf("ERROR #31\n"); + test_control_return(1); + } + + /* Attempt to get events from an empty event flag group. OR CLEAR option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_EVENTS) + { + + /* Event flag error. */ + printf("ERROR #32\n"); + test_control_return(1); + } + + /* Put event flags back in the group. */ + + /* Set the necessary events. */ + status = tx_event_flags_set(&group_0, 0x80008000, TX_OR); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #33\n"); + test_control_return(1); + } + + /* Attempt to get events from event flag group. OR CLEAR option. */ + status = tx_event_flags_get(&group_0, 0x00008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL)) + { + + /* Event flag error. */ + printf("ERROR #34\n"); + test_control_return(1); + } + + /* Attempt to get events from event flag group. OR CLEAR option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL)) + { + + /* Event flag error. */ + printf("ERROR #35\n"); + test_control_return(1); + } + + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Create a timer for the test. */ + tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE); + + /* Setup the ISR. */ + test_isr_dispatch = test_isr; + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Now resume thread 1. */ + tx_thread_resume(&thread_1); + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Clear the ISR. */ + test_isr_dispatch = TX_NULL; + + /* Test for error. */ + if ((error) || (timer_executed != 1) || (isr_executed != 1)) + { + + /* Block memory error. */ + printf("ERROR #36\n"); + test_control_return(1); + } + +#endif + + /* Delete both event flag groups. */ + status = tx_event_flags_delete(&group_0); + + /* Check the status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #37\n"); + test_control_return(1); + } + + status = tx_event_flags_delete(&group_1); + + /* Check the status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #38\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + } +} + diff --git a/test/smp/regression/threadx_event_flag_information_test.c b/test/smp/regression/threadx_event_flag_information_test.c new file mode 100644 index 00000000..1f03fdf3 --- /dev/null +++ b/test/smp/regression/threadx_event_flag_information_test.c @@ -0,0 +1,562 @@ +/* This test is designed to test the event flag group information gathering services. */ + +#include +#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, ¤t_flags, &first_suspended, &suspended_count, &next_group); + + /* Check the status. */ + if ((status != TX_SUCCESS) || (current_flags != group_0.tx_event_flags_group_current) || (first_suspended != TX_NULL) || (suspended_count != 0) || (next_group != &group_1)) + { + + /* Event flag error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + +#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO + + /* Get performance information with NULL pointer. */ + status = _tx_event_flags_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check the status. */ + if (status != TX_PTR_ERROR) + { + + /* Event flag error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Get performance information on the event flag group. */ + status = tx_event_flags_performance_info_get(&group_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_event_flags_performance_info_get(&group_0, &sets, &gets, &suspensions, &timeouts); + + /* Check the status. */ + if ((status != TX_SUCCESS) || (sets != group_0.tx_event_flags_group_performance_set_count) || (gets != group_0.tx_event_flags_group__performance_get_count) || + (suspensions != group_0.tx_event_flags_group___performance_suspension_count) || (timeouts != group_0.tx_event_flags_group____performance_timeout_count)) + { + + /* Event flag error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Get system performance information on all event flags groups. */ + status = tx_event_flags_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_event_flags_performance_system_info_get(&sets, &gets, &suspensions, &timeouts); + + /* Check the status. */ + if ((status != TX_SUCCESS) || (sets != _tx_event_flags_performance_set_count) || (gets != _tx_event_flags_performance_get_count) || + (suspensions != _tx_event_flags_performance_suspension_count) || (timeouts != _tx_event_flags_performance_timeout_count)) + { + + /* Event flag error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + +#else + + /* Get performance information on the event flag group. */ + status = tx_event_flags_performance_info_get(&group_0, &sets, &gets, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Event flag error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Get performance information on the event flag group. */ + status = tx_event_flags_performance_info_get(TX_NULL, &sets, &gets, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Event flag error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Get performance information on the event flag group. */ + status = tx_event_flags_performance_info_get(TX_NULL, TX_NULL, &gets, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Event flag error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + + /* Get performance information on the event flag group. */ + status = tx_event_flags_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Event flag error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + + /* Get performance information on the event flag group. */ + status = tx_event_flags_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Event flag error. */ + printf("ERROR #30\n"); + test_control_return(1); + } + + /* Get performance information on the event flag group. */ + status = tx_event_flags_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Event flag error. */ + printf("ERROR #31\n"); + test_control_return(1); + } + + /* Get system performance information on all event flags groups. */ + status = tx_event_flags_performance_system_info_get(&sets, &gets, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Event flag error. */ + printf("ERROR #32\n"); + test_control_return(1); + } + + /* Get system performance information on all event flags groups. */ + status = tx_event_flags_performance_system_info_get(TX_NULL, &gets, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Event flag error. */ + printf("ERROR #33\n"); + test_control_return(1); + } + + /* Get system performance information on all event flags groups. */ + status = tx_event_flags_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Event flag error. */ + printf("ERROR #34\n"); + test_control_return(1); + } + + /* Get system performance information on all event flags groups. */ + status = tx_event_flags_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Event flag error. */ + printf("ERROR #35\n"); + test_control_return(1); + } + + /* Get system performance information on all event flags groups. */ + status = tx_event_flags_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check the status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Event flag error. */ + printf("ERROR #36\n"); + test_control_return(1); + } +#endif + + /* Delete both event flag groups. */ + status = tx_event_flags_delete(&group_0); + + /* Check the status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #37\n"); + test_control_return(1); + } + + status = tx_event_flags_delete(&group_1); + + /* Check the status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #38\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} diff --git a/test/smp/regression/threadx_event_flag_isr_set_clear_test.c b/test/smp/regression/threadx_event_flag_isr_set_clear_test.c new file mode 100644 index 00000000..394bd601 --- /dev/null +++ b/test/smp/regression/threadx_event_flag_isr_set_clear_test.c @@ -0,0 +1,358 @@ +/* This test is designed to test for simultaneous thread event flag set AND ISR event flag set and clear. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" +#include "tx_timer.h" + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static unsigned long timer_0_counter = 0; +static TX_TIMER timer_0; + +static unsigned long event_flags_set_counter = 0; +static unsigned long condition_count = 0; + +static TX_EVENT_FLAGS_GROUP event_flags_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void timer_0_entry(ULONG timer_input); + + +static void event_set_notify(TX_EVENT_FLAGS_GROUP *group) +{ + + /* Not necessary to do anything in this function. */ +} + + +static void test_isr(void) +{ + +UINT status; +ULONG actual; +static volatile UINT miss_count = 0; + + + /* Determine if the interrupt occurred when the preempt disable flag was set. */ + if (_tx_thread_preempt_disable) + { + + /* Yes this is the condition we are looking for, increment the test condition counter. */ + condition_count++; + } + + /* + It is possible for this test to get into a resonance condition in which + the ISR never occurs while preemption is disabled (especially if the + ISR is installed in the periodic timer interrupt handler, which is + conveniently available). Detect this condition and break out of it by + perturbing the duration of this ISR a pseudo-random amount of time. + */ + else if (++miss_count > 100) + { + for (miss_count = _tx_timer_system_clock % 100; miss_count != 0; --miss_count); + } + + if (((event_flags_0.tx_event_flags_group_current & 0x3) == 0) && + (event_flags_0.tx_event_flags_group_suspended_count == 2)) + { + + /* Put the event_flags to wakeup thread 0. */ + status = tx_event_flags_set(&event_flags_0, 0x3, TX_OR); + + /* Clear the same flags immediately. */ + status += tx_event_flags_set(&event_flags_0, 0xFFFFFFFC, TX_AND); + + /* Setup some event flags just so we can clear them. */ + status += tx_event_flags_set(&event_flags_0, 0x30000, TX_OR); + + /* Clear the same flags immediately. */ + status += tx_event_flags_set(&event_flags_0, 0xFFFEFFFF, TX_AND); + + /* Clear the same flags immediately. */ + status += tx_event_flags_set(&event_flags_0, 0xFFFDFFFC, TX_AND); + + /* Check for an error. */ + if (status) + return; + + /* Get the events from an ISR. */ + status = tx_event_flags_get(&event_flags_0, 0x30000, TX_OR, &actual, TX_NO_WAIT); + + /* Check to make sure this results in an error. */ + if (status != TX_NO_EVENTS) + return; + + /* Do a set and a get consume from an ISR. */ + status = tx_event_flags_set(&event_flags_0, 0x000000C0, TX_OR); + + status += tx_event_flags_get(&event_flags_0, 0x00000080, TX_OR, &actual, TX_NO_WAIT); + + status += tx_event_flags_get(&event_flags_0, 0x000000C0, TX_OR_CLEAR, &actual, TX_NO_WAIT); + + /* Increment the event_flags counter. */ + if ((status == TX_SUCCESS) && (actual == 0xC4)) + { + event_flags_set_counter++; + } + } +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_event_flag_isr_set_clear_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #3\n"); + test_control_return(1); + } + + /* Create event flags group. */ + status = tx_event_flags_create(&event_flags_0, "event_flags 0"); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #4\n"); + test_control_return(1); + } + + /* Create a timer to ensure a context save is called for every interrupt. */ + status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 1, TX_AUTO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #5\n"); + test_control_return(1); + } + + /* Register the event set notify function. */ + status = tx_event_flags_set_notify(&event_flags_0, event_set_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #6\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #7\n"); + test_control_return(1); + } + +#endif +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual; + + + /* Inform user. */ + printf("Running Event Flag Set/Clear from ISR Test.......................... "); + + /* Setup the test ISR. */ + test_isr_dispatch = test_isr; + + /* Loop to exploit the probability window inside tx_event_flags_set call. */ + while (condition_count < 40) + { + + /* Suspend on the event_flags that is going to be set via the ISR. */ + status = tx_event_flags_get(&event_flags_0, 2, TX_OR_CLEAR, &actual, 4); + + /* Determine if we have an unexpected result. */ + if (status != TX_SUCCESS) + { + + /* Test error! */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Check for the preempt disable flag being set. */ + if (_tx_thread_preempt_disable) + { + + /* Test error! */ + printf("ERROR #9\n"); + test_control_return(2); + } + + /* Determine if we really got the event_flags. */ + if (status == TX_SUCCESS) + { + + /* Increment the thread count. */ + thread_0_counter++; + } + } + + /* Setup the test ISR. */ + test_isr_dispatch = TX_NULL; + + /* Let the other threads run once more... */ + tx_thread_relinquish(); + + /* At this point, check to see if we got all the event_flagss! */ + if ((thread_0_counter != event_flags_set_counter) || + (thread_1_counter != event_flags_set_counter)) + { + + /* Test error! */ + printf("ERROR #10\n"); + test_control_return(3); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual; + + + /* Loop to exploit the probability window inside tx_event_flags_set call. */ + while (1) + { + + /* Suspend on the event_flags that is going to be set via the ISR. */ + status = tx_event_flags_get(&event_flags_0, 1, TX_OR_CLEAR, &actual, 4); + + /* Determine if we have an unexpected result. */ + if (status != TX_SUCCESS) + { + + break; + } + + /* Increment this thread's counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + + /* Loop forever! */ + while(1) + { + + + /* Set event flags - not the one needed by threads 0 and 1. */ + tx_event_flags_set(&event_flags_0, 0x4, TX_OR); + + /* Increment the thread counter. */ + thread_2_counter++; + + /* Let thread 0 run again! */ + tx_thread_relinquish(); + } +} + + +static void timer_0_entry(ULONG input) +{ + timer_0_counter++; +} + + diff --git a/test/smp/regression/threadx_event_flag_isr_wait_abort_test.c b/test/smp/regression/threadx_event_flag_isr_wait_abort_test.c new file mode 100644 index 00000000..1382ea29 --- /dev/null +++ b/test/smp/regression/threadx_event_flag_isr_wait_abort_test.c @@ -0,0 +1,330 @@ +/* This test is designed to test for wait abort from an ISR. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" +#include "tx_timer.h" + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static unsigned long timer_0_counter = 0; +static TX_TIMER timer_0; + +static unsigned long event_flags_wait_abort_counter = 0; +static unsigned long condition_count = 0; + +static TX_EVENT_FLAGS_GROUP event_flags_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void timer_0_entry(ULONG timer_input); + + +static void event_set_notify(TX_EVENT_FLAGS_GROUP *group) +{ + + /* Not necessary to do anything in this function. */ +} + + +static void test_isr(void) +{ + +UINT status; +static volatile UINT miss_count = 0; + + + /* Determine if the interrupt occurred when the preempt disable flag was set. */ + if (_tx_thread_preempt_disable) + { + + /* Yes this is the condition we are looking for, increment the test condition counter. */ + condition_count++; + } + + /* + It is possible for this test to get into a resonance condition in which + the ISR never occurs while preemption is disabled (especially if the + ISR is installed in the periodic timer interrupt handler, which is + conveniently available). Detect this condition and break out of it by + perturbing the duration of this ISR a pseudo-random amount of time. + */ + else if (++miss_count > 100) + { + for (miss_count = _tx_timer_system_clock % 100; miss_count != 0; --miss_count); + } + + if (((event_flags_0.tx_event_flags_group_current & 0x3) == 0) && + (event_flags_0.tx_event_flags_group_suspended_count == 2)) + { + + /* Set event flags - not the one needed by threads 0 and 1. */ + status = tx_event_flags_set(&event_flags_0, 0x4, TX_OR); + + /* Abort the threads 1 and 2. */ + status += tx_thread_wait_abort(&thread_0); + status += tx_thread_wait_abort(&thread_1); + + if (status == TX_SUCCESS) + { + + event_flags_wait_abort_counter++; + } + } +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_event_flag_isr_wait_abort_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #3\n"); + test_control_return(1); + } + + /* Create event flags group. */ + status = tx_event_flags_create(&event_flags_0, "event_flags 0"); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #4\n"); + test_control_return(1); + } + + /* Create a timer to ensure a context save is called for every interrupt. */ + status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 1, TX_AUTO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #5\n"); + test_control_return(1); + } + + /* Register the event set notify function. */ + status = tx_event_flags_set_notify(&event_flags_0, event_set_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #6\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #7\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual; + + + /* Inform user. */ + printf("Running Event Flag Wait Abort from ISR Test......................... "); + + /* Setup the test ISR. */ + test_isr_dispatch = test_isr; + + /* Loop to exploit the probability window inside tx_event_flags_set call. */ + while (condition_count < 40) + { + + /* Suspend on the event_flags that is going to be set via the ISR. */ + status = tx_event_flags_get(&event_flags_0, 2, TX_OR_CLEAR, &actual, 4); + + /* Determine if we have an unexpected result. */ + if (status != TX_WAIT_ABORTED) + { + + /* Test error! */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Check for the preempt disable flag being set. */ + if (_tx_thread_preempt_disable) + { + + /* Test error! */ + printf("ERROR #9\n"); + test_control_return(2); + } + + /* Determine if we really got the event_flags. */ + if (status == TX_WAIT_ABORTED) + { + + /* Increment the thread count. */ + thread_0_counter++; + } + } + + /* Setup the test ISR. */ + test_isr_dispatch = TX_NULL; + + /* Let the other threads run once more... */ + tx_thread_relinquish(); + + /* At this point, check to see if we got all the event_flagss! */ + if ((thread_0_counter != event_flags_wait_abort_counter) || + (thread_1_counter != event_flags_wait_abort_counter)) + { + + /* Test error! */ + printf("ERROR #10\n"); + test_control_return(3); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual; + + + /* Loop to exploit the probability window inside tx_event_flags_set call. */ + while (1) + { + + /* Suspend on the event_flags that is going to be set via the ISR. */ + status = tx_event_flags_get(&event_flags_0, 1, TX_OR_CLEAR, &actual, 4); + + /* Determine if we have an unexpected result. */ + if (status != TX_WAIT_ABORTED) + { + + break; + } + + /* Increment this thread's counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + + /* Loop forever! */ + while(1) + { + + + /* Set event flags - not the one needed by threads 0 and 1. */ + tx_event_flags_set(&event_flags_0, 0x4, TX_OR); + + /* Increment the thread counter. */ + thread_2_counter++; + + /* Let thread 0 run again! */ + tx_thread_relinquish(); + } +} + + +static void timer_0_entry(ULONG input) +{ + timer_0_counter++; +} diff --git a/test/smp/regression/threadx_event_flag_single_thread_terminate_test.c b/test/smp/regression/threadx_event_flag_single_thread_terminate_test.c new file mode 100644 index 00000000..a5db6e41 --- /dev/null +++ b/test/smp/regression/threadx_event_flag_single_thread_terminate_test.c @@ -0,0 +1,331 @@ +/* This test is designed to test event flag suspension with a single suspended thread + being terminated at the same priority level. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + + +extern UINT _tx_thread_preempt_disable; + +static TX_EVENT_FLAGS_GROUP group_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +static void event_set_notify(TX_EVENT_FLAGS_GROUP *group) +{ + + /* Not necessary to do anything in this function. */ +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_event_flag_single_thread_terminate_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Single Thread Terminate Test..................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Single Thread Terminate Test..................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Single Thread Terminate Test..................... ERROR #3\n"); + test_control_return(1); + } + + /* Create event flag group 0. */ + status = tx_event_flags_create(&group_0, "group 0"); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Single Thread Terminate Test..................... ERROR #4\n"); + test_control_return(1); + } + + /* Register the event set notify function. */ + status = tx_event_flags_set_notify(&group_0, event_set_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Single Thread Terminate Test..................... ERROR #5\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Event Flag Single Thread Terminate Test..................... ERROR #6\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Event Flag Single Thread Terminate Test..................... "); + + /* Increment run counter. */ + thread_0_counter++; + + /* Sleep to allow lower-priority thread 1 to run. */ + tx_thread_sleep(5); + + /* Resume Thread 2. */ + status = tx_thread_resume(&thread_2); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Now terminate thread 1. */ + status = tx_thread_terminate(&thread_1); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Now sleep to allow Thread 2 to run. */ + tx_thread_sleep(5); + + /* Set only one of the event flags needed. */ + status = tx_event_flags_set(&group_0, 0x00080000, TX_OR); + + /* Now sleep to allow thread 2 to run. */ + tx_thread_sleep(5); + + /* Check status. */ + if ((status != TX_SUCCESS) && (thread_2_counter != 1)) + { + + /* Event flag error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Set the other event flag needed. */ + status = tx_event_flags_set(&group_0, 0x00800000, TX_OR); + + /* Now sleep to allow thread 2 to run. */ + tx_thread_sleep(5); + + /* Check status. */ + if ((status != TX_SUCCESS) && (thread_2_counter != 2)) + { + + /* Event flag error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* At this point, thread 2 is suspended on the flags again. Or some flags that are + not needed. */ + + /* Set an event flag that is not needed. */ + status = tx_event_flags_set(&group_0, 0x00000001, TX_OR); + + /* Now sleep to allow thread 2 to run. */ + tx_thread_sleep(5); + + /* Check status. */ + if ((status != TX_SUCCESS) && (thread_2_counter != 2)) + { + + /* Event flag error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Set an event flag that is needed. */ + status = tx_event_flags_set(&group_0, 0x00080001, TX_OR); + + /* Now sleep to allow thread 2 to run. */ + tx_thread_sleep(5); + + /* Check status and run counters. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 3) || + (_tx_thread_preempt_disable)) + { + + /* Event flag error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Terminate thread 2. */ + status = tx_thread_terminate(&thread_2); + + /* Check status. */ + if ((status != TX_SUCCESS) || (thread_2_counter != 3)) + { + + /* Event flag error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_1_counter++; + + /* Self suspend thread. */ + status = tx_thread_suspend(&thread_1); + + /* Check status. */ + if (status != TX_SUCCESS) + { + thread_1_counter = 0; /* Make an error! */ + return; + } + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_2_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x000880000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + return; + + /* Increment run counter. */ + thread_2_counter++; + + /* Attempt to get events from event flag group. OR option. */ + status = tx_event_flags_get(&group_0, 0x000880000, TX_OR_CLEAR, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + return; + + /* Increment run counter. */ + thread_2_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x000880000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_NO_EVENTS) + return; + } +} + diff --git a/test/smp/regression/threadx_event_flag_suspension_consume_test.c b/test/smp/regression/threadx_event_flag_suspension_consume_test.c new file mode 100644 index 00000000..b83a8123 --- /dev/null +++ b/test/smp/regression/threadx_event_flag_suspension_consume_test.c @@ -0,0 +1,281 @@ +/* This test is designed to test event flag suspension and resumption of two threads + waiting on the same event flag set with the consumption. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + + +static TX_EVENT_FLAGS_GROUP group_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +static void event_set_notify(TX_EVENT_FLAGS_GROUP *group) +{ + + /* Not necessary to do anything in this function. */ +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_event_flag_suspension_consume_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension/Consumption Test...................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension/Consumption Test...................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension/Consumption Test...................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension/Consumption Test...................... ERROR #4\n"); + test_control_return(1); + } + + /* Create event flag group 0. */ + status = tx_event_flags_create(&group_0, "group 0"); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension/Consumption Test...................... ERROR #5\n"); + test_control_return(1); + } + + /* Register the event set notify function. */ + status = tx_event_flags_set_notify(&group_0, event_set_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension/Consumption Test...................... ERROR #6\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Event Flag Suspension/Consumption Test...................... ERROR #7\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG event_flag = 1; +int i; + + + /* Inform user. */ + printf("Running Event Flag Suspension/Consumption Test...................... "); + + /* Set all event flags. */ + for (i = 0; i < 32; i++) + { + + /* Increment run counter. */ + thread_0_counter++; + + /* Set event flag. */ + status = tx_event_flags_set(&group_0, event_flag, TX_OR); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Check the thread counters... */ + if ((i < 31) && ((thread_1_counter != 1) || (thread_2_counter != 1) || (thread_3_counter != 1))) + { + + /* Event flag error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + if ((i == 31) && ((thread_1_counter != 2) || (thread_2_counter != 2) || (thread_3_counter != 2))) + { + + /* Event flag error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Shift event flag up one bit. */ + event_flag = event_flag << 1; + + /* Check for 0. */ + if (event_flag == 0) + event_flag = 1; + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +//ULONG event_flag = 1; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_1_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL)) + return; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +//ULONG event_flag = 1; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_2_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL)) + return; + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + +UINT status; +//ULONG event_flag = 1; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_3_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL)) + return; + } +} + diff --git a/test/smp/regression/threadx_event_flag_suspension_different_bits_consume_test.c b/test/smp/regression/threadx_event_flag_suspension_different_bits_consume_test.c new file mode 100644 index 00000000..fa4a985a --- /dev/null +++ b/test/smp/regression/threadx_event_flag_suspension_different_bits_consume_test.c @@ -0,0 +1,224 @@ +/* This test is designed to test event flag suspension and resumption of two threads + waiting on different event flags with consumption. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + + +static TX_EVENT_FLAGS_GROUP group_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +static void event_set_notify(TX_EVENT_FLAGS_GROUP *group) +{ + + /* Not necessary to do anything in this function. */ +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_event_flag_suspension_different_bits_consume_application_define(void *first_unused_memory) +#endif +{ + +INT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #2\n"); + test_control_return(1); + } + + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #3\n"); + test_control_return(1); + } + + /* Create event flag group 0. */ + status = tx_event_flags_create(&group_0, "group 0"); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #4\n"); + test_control_return(1); + } + + /* Register the event set notify function. */ + status = tx_event_flags_set_notify(&group_0, event_set_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #5\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #6\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Event Flag Suspension/Consumption Unique Bit Test........... "); + + /* Increment run counter. */ + thread_0_counter++; + + /* Set event flag. */ + status = tx_event_flags_set(&group_0, 0x80000000, TX_OR); + + /* Check status and run counters. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 2) || + (thread_2_counter != 1)) + { + + /* Event flag error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Set event flag. */ + status = tx_event_flags_set(&group_0, 0x00008000, TX_OR); + + /* Check status. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 2) || + (thread_2_counter != 2)) + { + + /* Event flag error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_1_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x80000000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL)) + return; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +//ULONG event_flag = 1; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_2_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x00008000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0x00008000UL)) + return; + } +} + diff --git a/test/smp/regression/threadx_event_flag_suspension_different_bits_test.c b/test/smp/regression/threadx_event_flag_suspension_different_bits_test.c new file mode 100644 index 00000000..92505744 --- /dev/null +++ b/test/smp/regression/threadx_event_flag_suspension_different_bits_test.c @@ -0,0 +1,230 @@ +/* This test is designed to test event flag suspension and resumption of two threads + waiting on different event flags. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + + +static TX_EVENT_FLAGS_GROUP group_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +static void event_set_notify(TX_EVENT_FLAGS_GROUP *group) +{ + + /* Not necessary to do anything in this function. */ +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_event_flag_suspension_different_bits_application_define(void *first_unused_memory) +#endif +{ + +INT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #2\n"); + test_control_return(1); + } + + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #3\n"); + test_control_return(1); + } + + /* Create event flag group 0. */ + status = tx_event_flags_create(&group_0, "group 0"); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #4\n"); + test_control_return(1); + } + + /* Register the event set notify function. */ + status = tx_event_flags_set_notify(&group_0, event_set_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #5\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #6\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Event Flag Suspension Unique Bit Test....................... "); + + /* Increment run counter. */ + thread_0_counter++; + + /* Set event flag. */ + status = tx_event_flags_set(&group_0, 0x80000000, TX_OR); + + /* Check status and run counters. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 2) || + (thread_2_counter != 1)) + { + + /* Event flag error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Set event flag. */ + status = tx_event_flags_set(&group_0, 0x00008000, TX_OR); + + /* Check status. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 2) || + (thread_2_counter != 2)) + { + + /* Event flag error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_1_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x80000000, TX_AND, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL)) + return; + + /* Clear the event flags. */ + tx_event_flags_set(&group_0, 0x7FFFFFFF, TX_AND); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +//ULONG event_flag = 1; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_2_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x00008000, TX_AND, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0x00008000UL)) + return; + + /* Clear the event flags. */ + tx_event_flags_set(&group_0, 0xFFFF7FFF, TX_AND); + } +} + diff --git a/test/smp/regression/threadx_event_flag_suspension_test.c b/test/smp/regression/threadx_event_flag_suspension_test.c new file mode 100644 index 00000000..3587fadd --- /dev/null +++ b/test/smp/regression/threadx_event_flag_suspension_test.c @@ -0,0 +1,349 @@ +/* This test is designed to test event flag suspension and resumption of three threads + waiting on the same event flag set. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + + +static TX_EVENT_FLAGS_GROUP group_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +static void event_set_notify(TX_EVENT_FLAGS_GROUP *group) +{ + + /* Not necessary to do anything in this function. */ +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_event_flag_suspension_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Same Bit Test......................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Same Bit Test......................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Same Bit Test......................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Same Bit Test......................... ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Same Bit Test......................... ERROR #5\n"); + test_control_return(1); + } + + /* Create event flag group 0. */ + status = tx_event_flags_create(&group_0, "group 0"); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Same Bit Test......................... ERROR #6\n"); + test_control_return(1); + } + + /* Register the event set notify function. */ + status = tx_event_flags_set_notify(&group_0, event_set_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Same Bit Test......................... ERROR #7\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Event Flag Suspension Same Bit Test......................... ERROR #8\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG event_flag = 1; +int i; + + + /* Inform user. */ + printf("Running Event Flag Suspension Same Bit Test......................... "); + + /* Set all event flags. */ + for (i = 0; i < 32; i++) + { + + /* Increment run counter. */ + thread_0_counter++; + + /* Set event flag. */ + status = tx_event_flags_set(&group_0, event_flag, TX_OR); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Check the thread counters... */ + if ((i < 31) && ((thread_1_counter != 1) || (thread_2_counter != 1) || (thread_3_counter != 1))) + { + + /* Event flag error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + if ((i == 31) && ((thread_1_counter != 2) || (thread_2_counter != 2) || (thread_3_counter != 2))) + { + + /* Event flag error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Shift event flag up one bit. */ + event_flag = event_flag << 1; + + /* Check for 0. */ + if (event_flag == 0) + event_flag = 1; + } + + /* Set the event flags to 0. */ + status = tx_event_flags_set(&group_0, 0x0, TX_AND); + + /* Resume thread 4 so it can suspend on the event flag group too. */ + status += tx_thread_resume(&thread_4); + + /* Determine if there was an error. */ + if ((status != TX_SUCCESS) || (thread_4_counter != 1)) + { + + /* Event flag error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Now set the event flag that only thread 4 is waiting on to ensure that we are not satisfying the first thread on the list. */ + status = tx_event_flags_set(&group_0, 0x1, TX_OR); + + /* Determine if there was an error. */ + if ((status != TX_SUCCESS) || (thread_4_counter != 2)) + { + + /* Event flag error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +//ULONG event_flag = 1; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_1_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL)) + return; + + /* Clear the event flags. */ + tx_event_flags_set(&group_0, 0, TX_AND); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +//ULONG event_flag = 1; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_2_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL)) + return; + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + +UINT status; +//ULONG event_flag = 1; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_3_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL)) + return; + } +} + + +static void thread_4_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_4_counter++; + + /* Attempt to get events from event flag group. OR option. */ + status = tx_event_flags_get(&group_0, 0x00000001, TX_OR_CLEAR, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_events != 0x1UL)) + return; + } +} diff --git a/test/smp/regression/threadx_event_flag_suspension_timeout_test.c b/test/smp/regression/threadx_event_flag_suspension_timeout_test.c new file mode 100644 index 00000000..2fed61c0 --- /dev/null +++ b/test/smp/regression/threadx_event_flag_suspension_timeout_test.c @@ -0,0 +1,266 @@ +/* This test is designed to test event flag suspension timeout processing. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + + +static TX_EVENT_FLAGS_GROUP group_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +static void event_set_notify(TX_EVENT_FLAGS_GROUP *group) +{ + + /* Not necessary to do anything in this function. */ +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_event_flag_suspension_timeout_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Timeout Test.......................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Timeout Test.......................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Timeout Test.......................... ERROR #3\n"); + test_control_return(1); + } + + /* Create event flag group 0. */ + status = tx_event_flags_create(&group_0, "group 0"); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Timeout Test.......................... ERROR #4\n"); + test_control_return(1); + } + + /* Register the event set notify function. */ + status = tx_event_flags_set_notify(&group_0, event_set_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Suspension Timeout Test.......................... ERROR #5\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Event Flag Suspension Timeout Test.......................... ERROR #6\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG actual_events; +UINT status; + + + /* Inform user. */ + printf("Running Event Flag Suspension Timeout Test.......................... "); + + /* Increment run counter. */ + thread_0_counter++; + + /* Set event flag 0. */ + tx_event_flags_set(&group_0, 0x00000001, TX_OR); + + /* Resume thread 3. */ + tx_thread_resume(&thread_3); + tx_thread_sleep(1); /* Thread 3 should now be suspended on group 0. */ + tx_event_flags_set(&group_0, 0x00000002, TX_OR); + + /* Start everything on a new timer. */ + tx_thread_sleep(2); + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + tx_thread_sleep(1); + status = tx_event_flags_get(&group_0, 0x00000001, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER); + + /* Check the status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #6a\n"); + test_control_return(1); + } + + /* Sleep for 63 ticks. */ + tx_thread_sleep(63); + + /* Check the run counters. */ + if ((thread_1_counter != 33) || (thread_2_counter != 13)) + { + + /* Event flag error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_events; + + + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_1_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x80000000, TX_AND_CLEAR, &actual_events, 2); + + /* Check status. */ + if (status != TX_NO_EVENTS) + return; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +//ULONG event_flag = 1; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_2_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x00008000, TX_AND_CLEAR, &actual_events, 5); + + /* Check status. */ + if (status != TX_NO_EVENTS) + return; + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + +UINT status; +//ULONG event_flag = 1; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_3_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x00000002, TX_AND, &actual_events, 5); + + /* Check status. */ + if (status != TX_NO_EVENTS) + return; + } +} diff --git a/test/smp/regression/threadx_event_flag_thread_terminate_test.c b/test/smp/regression/threadx_event_flag_thread_terminate_test.c new file mode 100644 index 00000000..eecb76e6 --- /dev/null +++ b/test/smp/regression/threadx_event_flag_thread_terminate_test.c @@ -0,0 +1,234 @@ +/* This test is designed to test event flag suspension with the suspended threads + being terminated. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + + +static TX_EVENT_FLAGS_GROUP group_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +static void event_set_notify(TX_EVENT_FLAGS_GROUP *group) +{ + + /* Not necessary to do anything in this function. */ +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_event_flag_thread_terminate_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Thread Terminate Test............................ ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Thread Terminate Test............................ ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Thread Terminate Test............................ ERROR #3\n"); + test_control_return(1); + } + + /* Create event flag group 0. */ + status = tx_event_flags_create(&group_0, "group 0"); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Thread Terminate Test............................ ERROR #4\n"); + test_control_return(1); + } + + /* Register the event set notify function. */ + status = tx_event_flags_set_notify(&group_0, event_set_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Event Flag Thread Terminate Test............................ ERROR #5\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Event Flag Thread Terminate Test............................ ERROR #6\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Event Flag Thread Terminate Test............................ "); + + /* Increment run counter. */ + thread_0_counter++; + + /* Terminate thread 2. */ + status = tx_thread_terminate(&thread_2); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Terminate thread 1. */ + status = tx_thread_terminate(&thread_1); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Event flag error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Set event flags to make sure no threads are suspended. */ + status = tx_event_flags_set(&group_0, 0xFFFFFFFF, TX_OR); + + /* Check status and run counters. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1)) + { + + /* Event flag error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_1_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x80000000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_NO_EVENTS) + return; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +//ULONG event_flag = 1; +ULONG actual_events; + + /* Wait for event flags. */ + while(1) + { + + /* Increment run counter. */ + thread_2_counter++; + + /* Attempt to get events from event flag group. AND option. */ + status = tx_event_flags_get(&group_0, 0x00008000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_NO_EVENTS) + return; + } +} + diff --git a/test/smp/regression/threadx_initialize_kernel_setup_test.c b/test/smp/regression/threadx_initialize_kernel_setup_test.c new file mode 100644 index 00000000..fbdee6fe --- /dev/null +++ b/test/smp/regression/threadx_initialize_kernel_setup_test.c @@ -0,0 +1,83 @@ +/* This test is designed to test kernel setup functionality in ThreadX. */ + +#include +#include "tx_api.h" +#include "tx_initialize.h" +#include "tx_thread.h" + + +TEST_FLAG test_forced_mutex_timeout; +TEST_FLAG threadx_mutex_suspension_put_test; +TEST_FLAG threadx_mutex_suspension_priority_test; +TEST_FLAG threadx_byte_allocate_loop_test; +TEST_FLAG test_initialize_flag; +TEST_FLAG threadx_byte_release_loop_test; +TEST_FLAG test_stack_analyze_flag; + + +/* Define the test control global variables. */ + +ULONG test_control_return_status; +ULONG test_control_successful_tests; +ULONG test_control_failed_tests; +ULONG test_control_system_errors; + +UINT test_mutex_from_init; +UINT test_semaphore_from_init; +UINT test_queue_from_init; +UINT test_event_flags_from_init; +UINT test_byte_pool_create_init; +UINT test_block_pool_create_init; +UINT test_timer_create_init; +UINT mutex_priority_change_extension_selection; +UINT priority_change_extension_selection; + + +__attribute__((weak)) void abort_all_threads_suspended_on_mutex(void) +{ +} + +__attribute__((weak)) void suspend_lowest_priority(void) +{ +} + +__attribute__((weak)) void abort_and_resume_byte_allocating_thread(void) +{ +} + +void main() +{ + + /* Setup the ThreadX kernel. */ + _tx_initialize_kernel_setup(); + + if (_tx_thread_system_state == TX_INITIALIZE_ALMOST_DONE) + { + printf("Running Initialize Kernel Setup Test................................ SUCCESS!\n"); + exit(0); + } + else + { + printf("Running Initialize Kernel Setup Test................................ ERROR!\n"); + exit(1); + } +} + +void test_application_define(void *first_unused_memory){} +void tx_application_define(void *first_unused_memory){} + + +#ifndef TX_TIMER_PROCESS_IN_ISR + +/* Define the deletion of the system timer thread. */ + +extern TX_THREAD _tx_timer_thread; +TEST_FLAG threadx_delete_timer_thread; +void delete_timer_thread(void) +{ + + _tx_thread_terminate(&_tx_timer_thread); + _tx_thread_delete(&_tx_timer_thread); +} + +#endif \ No newline at end of file diff --git a/test/smp/regression/threadx_interrupt_control_test.c b/test/smp/regression/threadx_interrupt_control_test.c new file mode 100644 index 00000000..d58ceba3 --- /dev/null +++ b/test/smp/regression/threadx_interrupt_control_test.c @@ -0,0 +1,94 @@ +/* This test is designed to test the interrupt control service call avaialbe to the + application. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_interrupt_control_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Interrupt Control Test...................................... ERROR #1\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT saved_interrupt_posture; + + + /* Inform user. */ + printf("Running Interrupt Control Test...................................... "); + + /* Lockout interrupts. */ + saved_interrupt_posture = tx_interrupt_control(TX_INT_DISABLE); + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Restore interrupts. */ + saved_interrupt_posture = tx_interrupt_control(saved_interrupt_posture); + + /* Sleep to make sure interrupts now work. */ + tx_thread_sleep(2); + + /* Check to make sure the returned interrupt type works. */ + if (saved_interrupt_posture != TX_INT_DISABLE) + { + + /* Interrupt control error. */ + printf("ERROR #2\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + diff --git a/test/smp/regression/threadx_mutex_basic_test.c b/test/smp/regression/threadx_mutex_basic_test.c new file mode 100644 index 00000000..2e784961 --- /dev/null +++ b/test/smp/regression/threadx_mutex_basic_test.c @@ -0,0 +1,767 @@ +/* This test is designed to test the mutex create/delete and immediate + return gets and puts. */ + +#include +#include "tx_api.h" +#include "tx_mutex.h" + + +typedef struct MUTEX_MEMORY_TEST_STRUCT +{ + ULONG first; + ULONG second; + TX_MUTEX mutex; + ULONG next_to_last; + ULONG last; + +} MUTEX_MEMORY_TEST; + +static MUTEX_MEMORY_TEST mutex_memory; + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +static unsigned long thread_0_counter = 0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; +static TX_THREAD thread_4; + +static TX_MUTEX mutex_0; +static TX_MUTEX mutex_1; +static TX_MUTEX mutex_2; +static TX_MUTEX mutex_3; +static TX_MUTEX mutex_4; +static TX_MUTEX mutex_5; +static TX_MUTEX mutex_6; +static TX_MUTEX mutex_7; +static TX_MUTEX mutex_8; + +static TX_TIMER timer_0; + + +static unsigned long error = 0; +static unsigned long timer_executed = 0; +static unsigned long isr_executed = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); + +UINT _txe_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit, UINT mutex_control_block_size); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define the timer for this test. */ + +static void timer_entry(ULONG i) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +UINT status; + + /* Attempt to create a mutex from a timer. */ + status = tx_mutex_create(&mutex_4, "mutex 4", TX_NO_INHERIT); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to delete a mutex from a timer. */ + status = tx_mutex_delete(&mutex_2); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to get from mutex from a timer with suspension. */ + status = tx_mutex_get(&mutex_2, 100); + + /* Check status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + timer_executed = 1; +#endif +} + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +UINT status; + + + /* Attempt to create a mutex from an ISR. */ + status = tx_mutex_create(&mutex_4, "mutex 4", TX_NO_INHERIT); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to delete a mutex from an ISR. */ + status = tx_mutex_delete(&mutex_2); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to get from mutex from an ISR with suspension. */ + status = tx_mutex_get(&mutex_2, 100); + + /* Check status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to get from mutex from an ISR without suspension. */ + status = tx_mutex_get(&mutex_2, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to put a mutex from an ISR. */ + status = tx_mutex_put(&mutex_2); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + isr_executed = 1; +#endif +} + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_mutex_basic_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + + status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + status += tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + status += tx_thread_create(&thread_4, "thread 4", thread_4_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Basic Test............................................ ERROR #1\n"); + test_control_return(1); + } + + /* Create a mutex. */ + status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Basic Test............................................ ERROR #2\n"); + test_control_return(1); + } + + /* Create another mutex. */ + status = tx_mutex_create(&mutex_1, "mutex 1", TX_NO_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Basic Test............................................ ERROR #3\n"); + test_control_return(1); + } + + /* Create another mutex. */ + status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Basic Test............................................ ERROR #4\n"); + test_control_return(1); + } + + /* Create another mutex. */ + status = tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Basic Test............................................ ERROR #5\n"); + test_control_return(1); + } + + /* Create another mutex. */ + status = tx_mutex_create(&mutex_8, "mutex 8", TX_NO_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Basic Test............................................ ERROR #5a\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Mutex Basic Test............................................ "); + + /* Perform mutex memory test. */ + mutex_memory.first = 0x11223344; + mutex_memory.second = 0x55667788; + mutex_memory.next_to_last = 0x99aabbcc; + mutex_memory.last = 0xddeeff00; + + /* Create the semaphore. */ + status = tx_mutex_create(&mutex_memory.mutex, "mutex memory", TX_INHERIT); + tx_mutex_delete(&mutex_memory.mutex); + + /* Check for status. */ + if ((status != TX_SUCCESS) || + (mutex_memory.first != 0x11223344) || + (mutex_memory.second != 0x55667788) || + (mutex_memory.next_to_last != 0x99aabbcc) || + (mutex_memory.last != 0xddeeff00)) + { + + /* Mutex error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Increment thread 0 counter. */ + thread_0_counter++; + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Attempt to create a mutex with a NULL pointer. */ + status = tx_mutex_create(TX_NULL, "mutex 2", TX_INHERIT); + + /* Check status. */ + if (status != TX_MUTEX_ERROR) + { + + /* Mutex error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Attempt to create a mutex with a bad size. */ + status = _txe_mutex_create(&mutex_5, "mutex 5", TX_INHERIT, (sizeof(TX_MUTEX)+1)); + + /* Check status. */ + if (status != TX_MUTEX_ERROR) + { + + /* Mutex error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Attempt to create a mutex that has already been created. */ + status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT); + + /* Check status. */ + if (status != TX_MUTEX_ERROR) + { + + /* Mutex error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to create a mutex with a bad inheritance option. */ + status = tx_mutex_create(&mutex_4, "mutex 4", 14); + + /* Check status. */ + if (status != TX_INHERIT_ERROR) + { + + /* Mutex error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Attempt to delete a mutex with a NULL pointer. */ + status = tx_mutex_delete(TX_NULL); + + /* Check status. */ + if (status != TX_MUTEX_ERROR) + { + + /* Mutex error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Attempt to delete a non-created mutex. */ + mutex_4.tx_mutex_id = 0; + status = tx_mutex_delete(&mutex_4); + + /* Check status. */ + if (status != TX_MUTEX_ERROR) + { + + /* Mutex error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Attempt to get a mutex with a NULL pointer. */ + status = tx_mutex_get(TX_NULL, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_MUTEX_ERROR) + { + + /* Mutex error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Attempt to get a non-created mutex. */ + mutex_4.tx_mutex_id = 0; + status = tx_mutex_get(&mutex_4, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_MUTEX_ERROR) + { + + /* Mutex error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Attempt to put a NULL mutex. */ + status = tx_mutex_put(TX_NULL); + + /* Check status. */ + if (status != TX_MUTEX_ERROR) + { + + /* Mutex error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Attempt to put a non-created mutex. */ + mutex_4.tx_mutex_id = 0; + status = tx_mutex_put(&mutex_4); + + /* Check status. */ + if (status != TX_MUTEX_ERROR) + { + + /* Mutex error. */ + printf("ERROR #16\n"); + test_control_return(1); + } +#endif + + /* Attempt to get from mutex that is available. Should be successful! */ + status = tx_mutex_get(&mutex_0, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Attempt to get the same mutex again. Should be successful! */ + status = tx_mutex_get(&mutex_0, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Put the mutex. */ + status = tx_mutex_put(&mutex_0); + + /* Check status. */ + if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_ownership_count != 1)) + { + + /* Mutex error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Put the mutex again. Should be successful! */ + status = tx_mutex_put(&mutex_0); + + /* Check status. */ + if ((status != TX_SUCCESS) != (mutex_0.tx_mutex_owner != TX_NULL)) + { + + /* Mutex error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Relinquish to allow other thread to get the mutex. */ + tx_thread_relinquish(); + + /* Attempt to get the mutex. Should be unsuccessful. */ + status = tx_mutex_get(&mutex_1, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NOT_AVAILABLE) + { + + /* Mutex error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + /* Relinquish again so that the other thread can release it. */ + tx_thread_relinquish(); + + /* Delete mutex. */ + status = tx_mutex_delete(&mutex_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + status = tx_mutex_delete(&mutex_1); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Attempt to get a priority inheritance mutex. */ + status = tx_mutex_get(&mutex_2, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Attempt to get another priority inheritance mutex. */ + status = tx_mutex_get(&mutex_3, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Create a timer for the test. */ + tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE); + + /* Setup the ISR. */ + test_isr_dispatch = test_isr; + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Wakeup thread 2 to get the ISR to take place on top of the thread. */ + tx_thread_resume(&thread_2); + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Clear the ISR. */ + test_isr_dispatch = TX_NULL; + + /* Test for error. */ + if ((error) || (timer_executed != 1) || (isr_executed != 1)) + { + + /* Block memory error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + +#endif + + /* Release mutex multiple times. */ + status = tx_mutex_put(&mutex_2); + status += tx_mutex_put(&mutex_2); + + /* Check status. */ + if (status != TX_NOT_OWNED) + { + + /* Mutex error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Attempt to release a mutex that is not owned. */ + status = _tx_mutex_put(&mutex_2); + + /* Check status. */ + if (status != TX_NOT_OWNED) + { + + /* Mutex error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + + /* Delete mutex. */ + status = tx_mutex_delete(&mutex_2); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + + /* Get mutex 8. */ + status = tx_mutex_get(&mutex_8, TX_WAIT_FOREVER); + + /* Start thread 3 and 4. */ + status += tx_thread_resume(&thread_3); + status += tx_thread_resume(&thread_4); + + /* Sleep to let thread 3 suspend on the mutex. */ + tx_thread_sleep(2); + + /* Now, put the mutex to give it to thread 3. */ + status += tx_mutex_put(&mutex_8); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #29a\n"); + test_control_return(1); + } + + status = tx_mutex_delete(&mutex_3); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #30\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Increment thread 1 counter. */ + thread_1_counter++; + + /* Attempt to get from mutex that is available. Should be successful! */ + status = tx_mutex_get(&mutex_1, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #31\n"); + test_control_return(1); + } + + /* Let other thread run again. */ + tx_thread_relinquish(); + + /* Release mutex! */ + status = tx_mutex_put(&mutex_1); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #32\n"); + test_control_return(1); + } + + /* Create and obtain a couple mutexes so the thread completion can release them. */ + status = tx_mutex_create(&mutex_6, "mutex 6", TX_NO_INHERIT); + status += tx_mutex_create(&mutex_7, "mutex 7", TX_NO_INHERIT); + status += tx_mutex_get(&mutex_6, TX_NO_WAIT); + status += tx_mutex_get(&mutex_7, TX_NO_WAIT); + status += tx_mutex_get(&mutex_6, TX_NO_WAIT); + status += tx_mutex_get(&mutex_7, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #33\n"); + test_control_return(1); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + + while(1) + { + + tx_mutex_get(&mutex_8, TX_WAIT_FOREVER); + tx_mutex_put(&mutex_8); + } +} + + +static void thread_4_entry(ULONG thread_input) +{ + + while(1) + { + + tx_mutex_get(&mutex_8, TX_WAIT_FOREVER); + tx_mutex_put(&mutex_8); + } +} diff --git a/test/smp/regression/threadx_mutex_delete_test.c b/test/smp/regression/threadx_mutex_delete_test.c new file mode 100644 index 00000000..28676f4b --- /dev/null +++ b/test/smp/regression/threadx_mutex_delete_test.c @@ -0,0 +1,194 @@ +/* This test is designed to test the mutex suspension and mutex delete with + suspended threads. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + + +static TX_MUTEX mutex_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_mutex_delete_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Delete Test........................................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Delete Test........................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Delete Test........................................... ERROR #3\n"); + test_control_return(1); + } + + /* Create a mutex. */ + status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Delete Test........................................... ERROR #4\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Mutex Delete Test........................................... "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Grab the mutex so it is owned by this thread. */ + status = tx_mutex_get(&mutex_0, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Relinquish to let other threads run. */ + tx_thread_relinquish(); + + /* Other threads should now be suspended on the mutex. */ + + /* Delete the mutex to test it out! */ + status = tx_mutex_delete(&mutex_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Relinquish to allow other threads to run again before we return. */ + tx_thread_relinquish(); + + /* Now check the run counter of each thread. */ + if ((thread_1_counter != 1) || (thread_2_counter != 1)) + { + + /* Mutex error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + + /* Suspend on the mutex. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Did we get the right status? */ + if (status == TX_DELETED) + thread_1_counter++; +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; + + + /* Suspend on the mutex. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Did we get the right status? */ + if (status == TX_DELETED) + thread_2_counter++; +} diff --git a/test/smp/regression/threadx_mutex_information_test.c b/test/smp/regression/threadx_mutex_information_test.c new file mode 100644 index 00000000..e95c16c6 --- /dev/null +++ b/test/smp/regression/threadx_mutex_information_test.c @@ -0,0 +1,592 @@ +/* This test is designed to test the mutex information services. */ + +#include +#include "tx_api.h" +#include "tx_mutex.h" + + +static unsigned long thread_0_counter = 0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static TX_MUTEX mutex_0; +static TX_MUTEX mutex_1; +static TX_MUTEX mutex_2; +static TX_MUTEX mutex_3; +static TX_MUTEX mutex_4; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +UINT _tx_mutex_performance_info_get(TX_MUTEX *mutex_ptr, ULONG *puts, ULONG *gets, + ULONG *suspensions, ULONG *timeouts, ULONG *inversions, ULONG *inheritances); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_mutex_information_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Information Test...................................... ERROR #1\n"); + test_control_return(1); + } + + /* Create a mutex. */ + status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Information Test...................................... ERROR #2\n"); + test_control_return(1); + } + + /* Create another mutex. */ + status = tx_mutex_create(&mutex_1, "mutex 1", TX_NO_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Information Test...................................... ERROR #3\n"); + test_control_return(1); + } + + /* Create another mutex. */ + status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Information Test...................................... ERROR #4\n"); + test_control_return(1); + } + + /* Create another mutex. */ + status = tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Information Test...................................... ERROR #5\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR *name; +ULONG count; +TX_THREAD *owner; +TX_THREAD *first_suspended; +ULONG suspended_count; +TX_MUTEX *next_mutex; +ULONG puts; +ULONG gets; +ULONG suspensions; +ULONG timeouts; +ULONG inversions; +ULONG inheritances; + + + /* Inform user. */ + printf("Running Mutex Information Test...................................... "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Attempt to get from mutex that is available. Should be successful! */ + status = tx_mutex_get(&mutex_0, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Attempt to get the same mutex again. Should be successful! */ + status = tx_mutex_get(&mutex_0, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Put the mutex. */ + status = tx_mutex_put(&mutex_0); + + /* Check status. */ + if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_ownership_count != 1)) + { + + /* Mutex error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Put the mutex again. Should be successful! */ + status = tx_mutex_put(&mutex_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Relinquish to allow other thread to get the mutex. */ + tx_thread_relinquish(); + + /* Attempt to get the mutex. Should be unsuccessful. */ + status = tx_mutex_get(&mutex_1, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NOT_AVAILABLE) + { + + /* Mutex error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Relinquish again so that the other thread can release it. */ + tx_thread_relinquish(); + + /* Delete mutex. */ + status = tx_mutex_delete(&mutex_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + status = tx_mutex_delete(&mutex_1); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Attempt to get a priority inheritance mutex. */ + status = tx_mutex_get(&mutex_2, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Attempt to get another priority inheritance mutex. */ + status = tx_mutex_get(&mutex_3, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Attempt to get mutex info with a NULL pointer. */ + status = tx_mutex_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check status. */ + if (status != TX_MUTEX_ERROR) + { + + /* Mutex error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Attempt to get mutex info from a non-created mutex. */ + mutex_4.tx_mutex_id = 0; + status = tx_mutex_info_get(&mutex_4, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check status. */ + if (status != TX_MUTEX_ERROR) + { + + /* Mutex error. */ + printf("ERROR #16\n"); + test_control_return(1); + } +#endif + + /* Get mutex information. */ + status = tx_mutex_info_get(&mutex_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_mutex_info_get(&mutex_2, &name, &count, &owner, &first_suspended, &suspended_count, &next_mutex); + + /* Check status. */ + if ((status != TX_SUCCESS) || (count != mutex_2.tx_mutex_ownership_count) || (owner != mutex_2.tx_mutex_owner) || + (first_suspended != mutex_2.tx_mutex_suspension_list) || (suspended_count != mutex_2.tx_mutex_suspended_count) || (next_mutex != mutex_2.tx_mutex_created_next)) + { + + /* Mutex error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + +#ifdef TX_MUTEX_ENABLE_PERFORMANCE_INFO + + /* Call with NULL pointer. */ + status = _tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check status. */ + if (status != TX_PTR_ERROR) + { + + /* Mutex error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Now get the performance inforamtion. */ + status = tx_mutex_performance_info_get(&mutex_2, &puts, &gets, &suspensions, &timeouts, &inversions, &inheritances); + + /* Check status. */ + if ((status != TX_SUCCESS) || (puts != mutex_2.tx_mutex_performance_put_count) || (gets != mutex_2.tx_mutex_performance_get_count) || + (suspensions != mutex_2.tx_mutex_performance_suspension_count) || (timeouts != mutex_2.tx_mutex_performance_timeout_count) || + (inversions != mutex_2.tx_mutex_performance_priority_inversion_count) || (inheritances != mutex_2.tx_mutex_performance__priority_inheritance_count)) + { + + /* Mutex error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Now get the system performance inforamtion. */ + status = tx_mutex_performance_system_info_get(&puts, &gets, &suspensions, &timeouts, &inversions, &inheritances); + + /* Check status. */ + if ((status != TX_SUCCESS) || (puts != _tx_mutex_performance_put_count) || (gets != _tx_mutex_performance_get_count) || + (suspensions != _tx_mutex_performance_suspension_count) || (timeouts != _tx_mutex_performance_timeout_count) || + (inversions != _tx_mutex_performance_priority_inversion_count) || (inheritances != _tx_mutex_performance__priority_inheritance_count)) + { + + /* Mutex error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + +#else + + /* Now get the performance inforamtion. */ + status = tx_mutex_performance_info_get(&mutex_2, &puts, &gets, &suspensions, &timeouts, &inversions, &inheritances); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + /* Now get the performance inforamtion. */ + status = tx_mutex_performance_info_get(TX_NULL, &puts, &gets, &suspensions, &timeouts, &inversions, &inheritances); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Now get the performance inforamtion. */ + status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, &gets, &suspensions, &timeouts, &inversions, &inheritances); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Now get the performance inforamtion. */ + status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts, &inversions, &inheritances); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Now get the performance inforamtion. */ + status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts, &inversions, &inheritances); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + + /* Now get the performance inforamtion. */ + status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inversions, &inheritances); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Now get the performance inforamtion. */ + status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inheritances); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Now get the performance inforamtion. */ + status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + + /* Now get the system performance inforamtion. */ + status = tx_mutex_performance_system_info_get(&puts, &gets, &suspensions, &timeouts, &inversions, &inheritances); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + + /* Now get the system performance inforamtion. */ + status = tx_mutex_performance_system_info_get(TX_NULL, &gets, &suspensions, &timeouts, &inversions, &inheritances); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #30\n"); + test_control_return(1); + } + + /* Now get the system performance inforamtion. */ + status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts, &inversions, &inheritances); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #31\n"); + test_control_return(1); + } + + /* Now get the system performance inforamtion. */ + status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts, &inversions, &inheritances); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #32\n"); + test_control_return(1); + } + + /* Now get the system performance inforamtion. */ + status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inversions, &inheritances); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #33\n"); + test_control_return(1); + } + + /* Now get the system performance inforamtion. */ + status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inheritances); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #34\n"); + test_control_return(1); + } + + /* Now get the system performance inforamtion. */ + status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Mutex error. */ + printf("ERROR #35\n"); + test_control_return(1); + } + +#endif + + /* Delete mutex. */ + status = tx_mutex_delete(&mutex_2); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #36\n"); + test_control_return(1); + } + + status = tx_mutex_delete(&mutex_3); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #37\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Increment thread 1 counter. */ + thread_1_counter++; + + /* Attempt to get from mutex that is available. Should be successful! */ + status = tx_mutex_get(&mutex_1, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #38\n"); + test_control_return(1); + } + + /* Let other thread run again. */ + tx_thread_relinquish(); + + /* Release mutex! */ + status = tx_mutex_put(&mutex_1); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #39\n"); + test_control_return(1); + } +} diff --git a/test/smp/regression/threadx_mutex_nested_priority_inheritance_test.c b/test/smp/regression/threadx_mutex_nested_priority_inheritance_test.c new file mode 100644 index 00000000..7397b4e2 --- /dev/null +++ b/test/smp/regression/threadx_mutex_nested_priority_inheritance_test.c @@ -0,0 +1,701 @@ +/* This test is designed to test multiple mutex priority inheritance situations. */ + +#include +#include "tx_api.h" + +#define DEMO_STACK_SIZE TEST_STACK_SIZE_PRINTF + + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD thread_0; +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; +static TX_THREAD thread_4; +static TX_THREAD thread_5; +static TX_THREAD thread_6; + +static TX_MUTEX mutex_0; +static TX_MUTEX mutex_1; +static TX_MUTEX mutex_2; +static TX_MUTEX mutex_3; + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG thread_2_counter; +static ULONG thread_3_counter; +static ULONG thread_4_counter; +static ULONG thread_5_counter; +static ULONG thread_6_counter; +#endif + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); +static void thread_6_entry(ULONG thread_input); +#endif + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_mutex_nested_priority_inheritance_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + pointer = (CHAR *) first_unused_memory; + + /* Create thread. */ + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 16, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #1\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD + + /* Create thread. */ + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #2\n"); + test_control_return(1); + } + + /* Create thread. */ + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #3\n"); + test_control_return(1); + } + + /* Create thread. */ + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, DEMO_STACK_SIZE, + 30, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4\n"); + test_control_return(1); + } + + /* Create thread. */ + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4a\n"); + test_control_return(1); + } + + /* Create thread. */ + status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, DEMO_STACK_SIZE, + 2, 2, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4b\n"); + test_control_return(1); + } + + /* Create thread. */ + status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6, + pointer, DEMO_STACK_SIZE, + 30, 30, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4c\n"); + test_control_return(1); + } + + /* Create the mutexes. */ + status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + status += tx_mutex_create(&mutex_1, "mutex 1", TX_INHERIT); + status += tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT); + status += tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #5\n"); + test_control_return(1); + } +#endif +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +#ifdef TX_DISABLE_PREEMPTION_THRESHOLD + + /* Preemption threshold is not enabled, skip this test. */ + + /* Inform user. */ + printf("Running Mutex Nested Priority Inheritance Test...................... SUCCESS!\n"); + test_control_return(0); + +#else + +UINT test_case = 0; +UINT loop_count = 0; +UINT priority; +UINT status; + + + /* Inform user. */ + printf("Running Mutex Nested Priority Inheritance Test...................... "); + + /* Get the mutex that will be owned always.... */ + tx_mutex_get(&mutex_3, TX_WAIT_FOREVER); + + while(loop_count++ < 50) + { + + /* Increment the thread counter. */ + thread_0_counter++; + + tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + tx_mutex_get(&mutex_1, TX_WAIT_FOREVER); + tx_mutex_get(&mutex_2, TX_WAIT_FOREVER); + + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + + /* Suspend this thread. */ + tx_thread_suspend(&thread_0); + + /* Resume thread thread 3. */ + tx_thread_resume(&thread_3); + + /* Thread priority should be 4. */ + if (thread_0.tx_thread_priority != 4) + { + + /* Test error! */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Release the mutexes... Depending on the order they are released should dictate + the thread's returned to priority. */ + if (test_case == 0) + { + + + tx_mutex_put(&mutex_2); + + /* Priority should now be returned to priority 8. */ + if (thread_0.tx_thread_priority != 8) + { + + /* Test error! */ + printf("ERROR #7\n"); + test_control_return(2); + } + + tx_mutex_put(&mutex_1); + + /* Priority should now be returned to priority 15. */ + if (thread_0.tx_thread_priority != 15) + { + + /* Test error! */ + printf("ERROR #8\n"); + test_control_return(3); + } + + tx_mutex_put(&mutex_0); + + /* No change. */ + if (thread_0.tx_thread_priority != 15) + { + + /* Test error! */ + printf("ERROR #9\n"); + test_control_return(4); + } + } + else if (test_case == 1) + { + + priority = thread_0.tx_thread_priority; + tx_mutex_put(&mutex_0); + + /* Should have no change in priority since nothing was inherited for this mutex. */ + if (thread_0.tx_thread_priority != priority) + { + + /* Test error! */ + printf("ERROR #10\n"); + test_control_return(4); + } + + tx_mutex_put(&mutex_1); + + /* Should not do anything since mutex 2 elevated to a higher priority. */ + if (thread_0.tx_thread_priority != priority) + { + + /* Test error! */ + printf("ERROR #11\n"); + test_control_return(5); + } + + tx_mutex_put(&mutex_2); + + /* Should go back to priority 15. */ + if (thread_0.tx_thread_priority != 15) + { + + /* Test error! */ + printf("ERROR #12\n"); + test_control_return(6); + } + } + else if (test_case == 2) + { + + tx_mutex_put(&mutex_2); + + /* Should go back to priority 8. */ + if (thread_0.tx_thread_priority != 8) + { + + /* Test error! */ + printf("ERROR #13\n"); + test_control_return(7); + } + + tx_mutex_put(&mutex_0); + + /* Should not do anything. */ + if (thread_0.tx_thread_priority != 8) + { + + /* Test error! */ + printf("ERROR #14\n"); + test_control_return(8); + } + + tx_mutex_put(&mutex_1); + + /* Should go back to priority 15. */ + if (thread_0.tx_thread_priority != 15) + { + + /* Test error! */ + printf("ERROR #15\n"); + test_control_return(9); + } + } + else if (test_case == 3) + { + + priority = thread_0.tx_thread_priority; + tx_mutex_put(&mutex_1); + + /* Should not do anything since mutex 2 is still owned. */ + if (thread_0.tx_thread_priority != priority) + { + + /* Test error! */ + printf("ERROR #16\n"); + test_control_return(10); + } + + tx_mutex_put(&mutex_0); + + /* Should not do anything. */ + if (thread_0.tx_thread_priority != priority) + { + + /* Test error! */ + printf("ERROR #17\n"); + test_control_return(11); + } + + tx_mutex_put(&mutex_2); + + /* Should finally go back to priority 15. */ + if (thread_0.tx_thread_priority != 15) + { + + /* Test error! */ + printf("ERROR #18\n"); + test_control_return(12); + } + } + else if (test_case == 4) + { + + priority = thread_0.tx_thread_priority; + tx_mutex_put(&mutex_1); + + /* Should not do anything since mutex 2 is still owned. */ + if (thread_0.tx_thread_priority != priority) + { + + /* Test error! */ + printf("ERROR #19\n"); + test_control_return(13); + } + + tx_mutex_put(&mutex_2); + + /* Should reurn us back to priority 15. */ + if (thread_0.tx_thread_priority != 15) + { + + /* Test error! */ + printf("ERROR #20\n"); + test_control_return(14); + } + + tx_mutex_put(&mutex_0); + + /* Should not do anything. */ + if (thread_0.tx_thread_priority != 15) + { + + /* Test error! */ + printf("ERROR #21\n"); + test_control_return(15); + } + } + else if (test_case == 5) + { + + priority = thread_0.tx_thread_priority; + tx_mutex_put(&mutex_0); + + /* Should not do anything since mutex 2 is still owned. */ + if (thread_0.tx_thread_priority != priority) + { + + /* Test error! */ + printf("ERROR #22\n"); + test_control_return(16); + } + + tx_mutex_put(&mutex_2); + + /* Should reurn us back to priority 8. */ + if (thread_0.tx_thread_priority != 8) + { + + /* Test error! */ + printf("ERROR #23\n"); + test_control_return(17); + } + + tx_mutex_put(&mutex_1); + + /* Should return us back to priority 15. */ + if (thread_0.tx_thread_priority != 15) + { + + /* Test error! */ + printf("ERROR #24\n"); + test_control_return(18); + } + } + + test_case++; + if (test_case > 5) + test_case = 0; + } + + /* Check for thread 3 running... this should not happen! */ + if (thread_3_counter != 50) + { + + printf("ERROR #25\n"); + test_control_return(19); + } + + /* At this point, mutex 3 owned by this thread. */ + + /* Resume thread 6, lowest priority thread. */ + status = tx_thread_resume(&thread_6); + + /* Check for an error. */ + if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 15) || (thread_6_counter != 0)) + { + + printf("ERROR #27\n"); + test_control_return(19); + } + + /* Now resume thread 4. */ + status = tx_thread_resume(&thread_4); + + /* Check for an error. */ + if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 4) || (thread_6_counter != 0)) + { + + printf("ERROR #28\n"); + test_control_return(19); + } + + /* Now resume thread 5. */ + status = tx_thread_resume(&thread_5); + + /* Check for an error. */ + if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 2) || (thread_6_counter != 0)) + { + + printf("ERROR #29\n"); + test_control_return(19); + } + + /* Sleep to let thread 6 run, which is lower priority. */ + tx_thread_sleep(1); + + /* Now release the mutex. */ + status = tx_mutex_put(&mutex_3); + + /* Check for an error. */ + if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 15) || (thread_6_counter != 0) || (thread_4_counter != 1) || (thread_5_counter != 1)) + { + + printf("ERROR #30\n"); + test_control_return(19); + } + + /* Sleep to let thread 6 run and release the mutex. */ + tx_thread_sleep(2); + + + /* If we get here the test was successful! */ + printf("SUCCESS!\n"); + test_control_return(0); +#endif +} + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD + +static void thread_1_entry(ULONG thread_input) +{ + +UINT old_priority; +UINT old_threshold; + + + while(1) + { + + /* Increment the thread counter. */ + thread_1_counter++; + + /* Update the thread priority and thread preemption-threshold of thread 0. */ + tx_thread_priority_change(&thread_0, 15, &old_priority); + tx_thread_preemption_change(&thread_0, 14, &old_threshold); + + /* Get mutex. */ + tx_mutex_get(&mutex_1, TX_WAIT_FOREVER); + tx_mutex_put(&mutex_1); + + tx_thread_suspend(&thread_1); + + /* Increment the thread counter. */ + thread_1_counter++; + + /* Update the thread priority and thread preemption-threshold of thread 0. */ + tx_thread_priority_change(&thread_0, 15, &old_priority); + tx_thread_preemption_change(&thread_0, 8, &old_threshold); + + /* Get mutex. */ + tx_mutex_get(&mutex_1, TX_WAIT_FOREVER); + tx_mutex_put(&mutex_1); + + tx_thread_suspend(&thread_1); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT old_priority; +UINT old_threshold; + + while(1) + { + + /* Increment the thread counter. */ + thread_2_counter++; + + /* Update the thread priority and thread preemption-threshold of thread 0. */ + tx_thread_priority_change(&thread_0, 15, &old_priority); + tx_thread_preemption_change(&thread_0, 14, &old_threshold); + + /* Get mutex. */ + tx_mutex_get(&mutex_2, TX_WAIT_FOREVER); + tx_mutex_put(&mutex_2); + + tx_thread_suspend(&thread_2); + + /* Increment the thread counter. */ + thread_2_counter++; + + /* Update the thread priority and thread preemption-threshold of thread 0. */ + tx_thread_priority_change(&thread_0, 15, &old_priority); + tx_thread_preemption_change(&thread_0, 8, &old_threshold); + + /* Get mutex. */ + tx_mutex_get(&mutex_2, TX_WAIT_FOREVER); + tx_mutex_put(&mutex_2); + + tx_thread_suspend(&thread_2); + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + + + while(1) + { + + /* Resume thread 0. */ + tx_thread_resume(&thread_0); + + /* Increment the thread counter. */ + thread_3_counter++; + + /* Suspend this thread. */ + tx_thread_suspend(&thread_3); + } +} + + +static void thread_4_entry(ULONG thread_input) +{ + + + while(1) + { + + /* Get priority inherit mutex. */ + tx_mutex_get(&mutex_3, TX_WAIT_FOREVER); + + /* Increment the thread counter. */ + thread_4_counter++; + + /* Release the priority inherit mutex. */ + tx_mutex_put(&mutex_3); + + /* Suspend this thread. */ + tx_thread_suspend(&thread_4); + } +} + + +static void thread_5_entry(ULONG thread_input) +{ + + + while(1) + { + + /* Get priority inherit mutex. */ + tx_mutex_get(&mutex_3, TX_WAIT_FOREVER); + + /* Increment the thread counter. */ + thread_5_counter++; + + /* Release the priority inherit mutex. */ + tx_mutex_put(&mutex_3); + + /* Suspend this thread. */ + tx_thread_suspend(&thread_5); + } +} + + +static void thread_6_entry(ULONG thread_input) +{ + + + while(1) + { + + /* Get priority inherit mutex. */ + tx_mutex_get(&mutex_3, TX_WAIT_FOREVER); + + /* Increment the thread counter. */ + thread_6_counter++; + + /* Release the priority inherit mutex. */ + tx_mutex_put(&mutex_3); + + /* Suspend this thread. */ + tx_thread_suspend(&thread_6); + } +} +#endif + + diff --git a/test/smp/regression/threadx_mutex_no_preemption_test.c b/test/smp/regression/threadx_mutex_no_preemption_test.c new file mode 100644 index 00000000..c26c3651 --- /dev/null +++ b/test/smp/regression/threadx_mutex_no_preemption_test.c @@ -0,0 +1,173 @@ +/* This test is designed to test the mutex suspension and another thread resuming the + same priority thread by doing a mutex put. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + + +static TX_MUTEX mutex_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_mutext_no_preemption_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Put with No Preemption Test........................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Put with No Preemption Test........................... ERROR #2\n"); + test_control_return(1); + } + + /* Create a mutex. */ + status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Put with No Preemption Test........................... ERROR #3\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Mutex Put with No Preemption Test........................... "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Get the mutex. */ + status = tx_mutex_get(&mutex_0, TX_NO_WAIT); + + /* Should be successful. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Relinquish to make the other thread suspend on the mutex. */ + tx_thread_relinquish(); + + /* Make sure the other thread has run. */ + if (thread_1_counter != 1) + { + + /* Mutex error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Put the mutex, this should resume the other thread + but not preempt this thread. */ + status = tx_mutex_put(&mutex_0); + + /* Check the status and the run counter of the other thread. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1)) + { + + /* Mutex error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Relinquish to allow the other thread to run. */ + tx_thread_relinquish(); + + /* Make sure the other thread has run. */ + if (thread_1_counter != 2) + { + + /* Mutex error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Increment thread run counter. */ + thread_1_counter++; + + /* Suspend on the mutex. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_1_counter++; +} + diff --git a/test/smp/regression/threadx_mutex_preemption_test.c b/test/smp/regression/threadx_mutex_preemption_test.c new file mode 100644 index 00000000..238dda03 --- /dev/null +++ b/test/smp/regression/threadx_mutex_preemption_test.c @@ -0,0 +1,161 @@ +/* This test is designed to test the mutex suspension and another thread resuming the + higher priority thread by doing a mutex put. Higher-priority thread should preempt. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + + +static TX_MUTEX mutex_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_mutex_preemption_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Put with Preemption Test.............................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Put with Preemption Test.............................. ERROR #2\n"); + test_control_return(1); + } + + /* Create a mutex. */ + status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Put with Preemption Test.............................. ERROR #3\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Mutex Put with Preemption Test.............................. "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Get the mutex. */ + status = tx_mutex_get(&mutex_0, TX_NO_WAIT); + + /* Should be successful. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Now resume the higher priority thread to cause suspension. */ + tx_thread_resume(&thread_1); + + /* The other thread should now be suspended on the mutex. */ + if (thread_1_counter != 1) + { + + /* Mutex error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Release the mutex, this should cause the other thread + to preempt. */ + status = tx_mutex_put(&mutex_0); + + /* Check status and run counter of other thread. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 2)) + { + + /* Mutex error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Increment thread run counter. */ + thread_1_counter++; + + /* Suspend on the mutex. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_1_counter++; +} + diff --git a/test/smp/regression/threadx_mutex_priority_inheritance_test.c b/test/smp/regression/threadx_mutex_priority_inheritance_test.c new file mode 100644 index 00000000..7a82206f --- /dev/null +++ b/test/smp/regression/threadx_mutex_priority_inheritance_test.c @@ -0,0 +1,607 @@ +/* This test is designed to test the mutex suspension and priority inheritance with another + thread resuming the higher priority thread by doing a mutex put. Higher-priority thread should preempt. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; +static TX_THREAD thread_3; + +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + +static unsigned long thread_5_counter = 0; +static TX_THREAD thread_5; + +static unsigned long thread_6_counter = 0; +static TX_THREAD thread_6; + +static unsigned long thread_7_counter = 0; +static TX_THREAD thread_7; + +static TX_MUTEX mutex_0; +static TX_MUTEX mutex_1; +static TX_MUTEX mutex_2; +static TX_MUTEX mutex_3; + + +extern UINT test_mutex_from_init; +extern TEST_FLAG test_forced_mutex_timeout; + + +VOID _tx_mutex_priority_change(TX_THREAD *thread_ptr, UINT priority, UINT threshold); + + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); +static void thread_6_entry(ULONG thread_input); +static void thread_7_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_mutex_priority_inheritance_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Test for an error creating/using a mutex from initialization. */ + if (test_mutex_from_init != TX_SUCCESS) + { + + printf("Running Mutex Priority Inheritance Test............................. ERROR #0\n"); + test_control_return(1); + } + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Priority Inheritance Test............................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Priority Inheritance Test............................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 14, 14, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Priority Inheritance Test............................. ERROR #3\n"); + test_control_return(1); + } + + /* Create a high-priority thread that will get all the priority inheritance mutexes and return from + it's entry function in order to test the auto delete feature. */ + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 10, 10, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Priority Inheritance Test............................. ERROR #4\n"); + test_control_return(1); + } + + /* Create a higher-priority thread that is used to get thread 4 into a priority inheritance state. */ + status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, TEST_STACK_SIZE_PRINTF, + 8, 8, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Priority Inheritance Test............................. ERROR #5\n"); + test_control_return(1); + } + + + /* Create a higher-priority thread that is used to suspend on priority inheritance mutex 3. */ + status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6, + pointer, TEST_STACK_SIZE_PRINTF, + 6, 6, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Priority Inheritance Test............................. ERROR #6\n"); + test_control_return(1); + } + + + /* Create a higher-priority thread that is used to suspend on priority inheritance mutex 3. */ + status = tx_thread_create(&thread_7, "thread 7", thread_7_entry, 7, + pointer, TEST_STACK_SIZE_PRINTF, + 7, 7, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Priority Inheritance Test............................. ERROR #7\n"); + test_control_return(1); + } + + /* Create a mutex. */ + status = tx_mutex_create(&mutex_0, "mutex 0", TX_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Priority Inheritance Test............................. ERROR #8\n"); + test_control_return(1); + } + + /* Create another mutex. */ + status = tx_mutex_create(&mutex_1, "mutex 1", TX_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Priority Inheritance Test............................. ERROR #9\n"); + test_control_return(1); + } + + /* Create another mutex. */ + status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Priority Inheritance Test............................. ERROR #10\n"); + test_control_return(1); + } + + /* Create another mutex. */ + status = tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Priority Inheritance Test............................. ERROR #11\n"); + test_control_return(1); + } + + /* Drive one path of the internal mutex priority change routine directly for code coverage. */ + thread_3.tx_thread_user_priority = 1; + thread_3.tx_thread_user_preempt_threshold = 1; + thread_3.tx_thread_state = 4; + _tx_mutex_priority_change(&thread_3, 3, 3); +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Mutex Priority Inheritance Test............................. "); + + /* Resume thread 4 to test the automatic release of the mutexes. */ + tx_thread_resume(&thread_4); + + /* Determine if thread 4 was able to get the mutexes before completion... and + have its original priority restored after the priority inheritance. */ + if ((thread_4_counter != 1) || (thread_5_counter != 1) || (thread_4.tx_thread_priority != 10) || + (thread_4.tx_thread_inherit_priority != TX_MAX_PRIORITIES)) + { + + /* Mutex error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Get all the mutexex. */ + status = tx_mutex_get(&mutex_0, TX_NO_WAIT); + status += tx_mutex_get(&mutex_1, TX_NO_WAIT); + status += tx_mutex_get(&mutex_2, TX_NO_WAIT); + + /* Should be successful. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Release mutex 2 to be compatible with original test. */ + tx_mutex_put(&mutex_2); + + /* Now resume the higher priority thread to cause suspension. */ + tx_thread_resume(&thread_1); + + /* The other thread should now be suspended on the mutex. */ + if ((thread_1_counter != 1) || (thread_0.tx_thread_priority != 15)) + { + + /* Mutex error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Release the mutex, this should cause the other thread + to preempt. */ + status = tx_mutex_put(&mutex_0); + + /* Check status and run counter of other thread. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 2) || (thread_0.tx_thread_priority != 16)) + { + + /* Mutex error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* At this point, get the mutex again. */ + status = tx_mutex_get(&mutex_0, TX_NO_WAIT); + + /* Should be successful. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Now sleep for 20 ticks in order to test the priority inheritance change of a + non-ready thread. */ + tx_thread_sleep(20); + + /* The other thread should now be suspended on the mutex. */ + if ((thread_1_counter != 3) || (thread_0.tx_thread_priority != 15)) + { + + /* Mutex error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Resume thread 2 in order to get two threads suspended on the mutex. */ + tx_thread_resume(&thread_2); + + /* Now do a mutex put to release both threads suspended on this mutex. */ + status = tx_mutex_put(&mutex_0); + + /* The other thread should now be suspended on the mutex. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 4) || (thread_2_counter != 2) || (thread_0.tx_thread_priority != 16)) + { + + /* Mutex error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* At this point, get the mutex again. */ + status = tx_mutex_get(&mutex_0, TX_NO_WAIT); + + /* Should be successful. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Abort the sleep. */ + tx_thread_wait_abort(&thread_1); + tx_thread_wait_abort(&thread_2); + + /* Now both threads are suspended again on mutex... and then terminate them. */ + tx_thread_terminate(&thread_1); + tx_thread_terminate(&thread_2); + + /* Now do a mutex put to release both threads suspended on this mutex. */ + status = tx_mutex_put(&mutex_0); + + /* The other thread should now be suspended on the mutex. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 3) || (thread_0.tx_thread_priority != 16)) + { + + /* Mutex error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Now test the timeout on the suspension list of a priority inheritance mutex. */ + + /* First, obtain priority inheritance mutex 3. */ + status = tx_mutex_get(&mutex_3, TX_WAIT_FOREVER); + + /* Next resume threads 6 and 7 so they will block on trying to get this mutex forever. */ + status += tx_thread_resume(&thread_7); + status += tx_thread_resume(&thread_6); + + /* Now set the flag which will cause the last thread in the suspension list to timeout (abort) + resulting in a NULL suspension list and covering that branch condition in tx_mutex_put */ + test_forced_mutex_timeout = 1; + + /* Perform a mutex put to release the mutex. */ + status += tx_mutex_put(&mutex_3); + + /* Now check for errors. */ +#ifndef TX_MISRA_ENABLE +#ifndef TX_MANUAL_TEST +#ifndef TX_NOT_INTERRUPTABLE + if ((status != TX_SUCCESS) || (thread_6_counter != 1) || (thread_7_counter != 0)) +#else + if ((status != TX_SUCCESS) || (thread_6_counter != 1)) +#endif +#else + if ((status != TX_SUCCESS) || (thread_6_counter != 1)) +#endif +#else + if ((status != TX_SUCCESS) || (thread_6_counter != 1)) +#endif + { + + /* Mutex error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + + while(1) + { + + /* Increment thread run counter. */ + thread_1_counter++; + + /* Suspend on the mutex. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + status += tx_mutex_put(&mutex_0); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_1_counter++; + + /* Sleep for 10 ticks... to delay. */ + tx_thread_sleep(10); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; + + + /* Get mutex to cause additional ownership linked-list processing. */ + tx_mutex_get(&mutex_2, TX_WAIT_FOREVER); + + while(1) + { + + /* Increment thread run counter. */ + thread_2_counter++; + + /* Suspend on the mutex. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + status += tx_mutex_put(&mutex_0); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_2_counter++; + + /* Sleep for 10 ticks... to delay. */ + tx_thread_sleep(10); + } +} + + +static void thread_4_entry(ULONG thread_input) +{ + +UINT status; +UINT old_priority; + + + /* Get mutex to cause additional ownership linked-list processing. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + status += tx_mutex_get(&mutex_1, TX_WAIT_FOREVER); + status += tx_mutex_get(&mutex_1, TX_WAIT_FOREVER); + status += tx_mutex_get(&mutex_1, TX_WAIT_FOREVER); + status += tx_mutex_get(&mutex_2, TX_WAIT_FOREVER); + + /* Resume thread 5 to get into priority inheritance. */ + tx_thread_resume(&thread_5); + + /* Determine if all the mutex gets were successful... and we have + inherited priority 8. */ + if ((status == TX_SUCCESS) && (thread_4.tx_thread_priority == 8)) + { + + /* Yes, increment the thread counter. */ + thread_4_counter++; + } + + /* Now, attempt to manually set this thread's priority to the same priority. */ + status = tx_thread_priority_change(&thread_4, 8, &old_priority); + + /* Determine if there is an error. */ + if ((status != TX_SUCCESS) || (thread_4.tx_thread_user_priority != 8) || (old_priority != 10)) + { + + /* Clear the counter, which will signal an error to the thread above. */ + thread_4_counter = 0; + } + + /* Now attempt to manually set the same thread priority. */ + status = tx_thread_priority_change(&thread_4, 8, &old_priority); + + /* Determine if there is an error. */ + if ((status != TX_SUCCESS) || (thread_4.tx_thread_user_priority != 8) || (old_priority != 8)) + { + + /* Clear the counter, which will signal an error to the thread above. */ + thread_4_counter = 0; + } + + /* Now restore the original user priority of 10. */ + status = tx_thread_priority_change(&thread_4, 10, &old_priority); + + /* Determine if there is an error. */ + if ((status != TX_SUCCESS) || (thread_4.tx_thread_user_priority != 10) || (old_priority != 8)) + { + + /* Clear the counter, which will signal an error to the thread above. */ + thread_4_counter = 0; + } + + /* Now fall through and make sure the mutex cleanup function + releases all the mutexes. */ +} + + +static void thread_5_entry(ULONG thread_input) +{ + +UINT status; + + + /* Get mutex to cause priority inheritance in thread 4. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Determine if all the mutex gets were successful. */ + if (status == TX_SUCCESS) + { + + /* Yes, increment the thread counter. */ + thread_5_counter++; + } + + /* Now fall through and make sure the mutex cleanup function + releases all the mutexes. */ +} + + +static void thread_6_entry(ULONG thread_input) +{ + +UINT status; + + + /* Get mutex to cause priority inheritance in thread 0. */ + status = tx_mutex_get(&mutex_3, TX_WAIT_FOREVER); + + /* Determine if all the mutex gets were successful. */ + if (status == TX_SUCCESS) + { + + /* Yes, increment the thread counter. */ + thread_6_counter++; + } + + /* Now fall through and make sure the mutex cleanup function + releases all the mutexes. */ +} + + +static void thread_7_entry(ULONG thread_input) +{ + +UINT status; + + + /* Get mutex to cause priority inheritance in thread 0. */ + status = tx_mutex_get(&mutex_3, TX_WAIT_FOREVER); + + /* Determine if all the mutex gets were successful. */ + if (status == TX_SUCCESS) + { + + /* Yes, increment the thread counter. */ + thread_7_counter++; + } + + /* Now fall through and make sure the mutex cleanup function + releases all the mutexes. */ +} + diff --git a/test/smp/regression/threadx_mutex_proritize_test.c b/test/smp/regression/threadx_mutex_proritize_test.c new file mode 100644 index 00000000..4e25673f --- /dev/null +++ b/test/smp/regression/threadx_mutex_proritize_test.c @@ -0,0 +1,525 @@ +/* This test is designed to test the mutex suspension prioritization. */ + +#include +#include "tx_api.h" + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Define the external reference for the preempt disable flag. */ + +extern volatile UINT _tx_thread_preempt_disable; + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + +static unsigned long thread_5_counter = 0; +static TX_THREAD thread_5; + +static unsigned long thread_6_counter = 0; +static TX_THREAD thread_6; + + +static TX_MUTEX mutex_0; +static TX_MUTEX mutex_1; + +static int test_status; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); +static void thread_6_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + + /* Determine if the test case we are looking for is present. */ + if ((_tx_thread_preempt_disable) && (test_status == 1)) + { + + /* Determine if thread 3 is at the front of the suspension list. */ + if (mutex_0.tx_mutex_suspension_list == &thread_3) + { + + /* Abort the wait of thread 3. */ + tx_thread_wait_abort(&thread_3); + } + else + { + + /* Abort the wait of thread 5. */ + tx_thread_wait_abort(&thread_5); + + /* End the ISR processing. */ + test_status = 2; + test_isr_dispatch = TX_NULL; + } + } +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_mutex_prioritize_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Prioritize Test....................................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Prioritize Test....................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 14, 14, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Prioritize Test....................................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 3, 3, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Prioritize Test....................................... ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 4, 4, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Prioritize Test....................................... ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, TEST_STACK_SIZE_PRINTF, + 5, 5, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Prioritize Test....................................... ERROR #6\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6, + pointer, TEST_STACK_SIZE_PRINTF, + 6, 6, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Prioritize Test....................................... ERROR #7\n"); + test_control_return(1); + } + + /* Create a mutex. */ + status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Prioritize Test....................................... ERROR #8\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Mutex Prioritize Test....................................... "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Attempt to prioritize a NULL mutex. */ + status = tx_mutex_prioritize(TX_NULL); + + /* Check status. */ + if (status != TX_MUTEX_ERROR) + { + + /* Mutex error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to prioritize a non-created mutex. */ + mutex_1.tx_mutex_id = 0; + status = tx_mutex_prioritize(&mutex_1); + + /* Check status. */ + if (status != TX_MUTEX_ERROR) + { + + /* Mutex error. */ + printf("ERROR #10\n"); + test_control_return(1); + } +#endif + + /* Prioritize the mutex with no suspended threads! */ + status = tx_mutex_prioritize(&mutex_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Grab the mutex so it is owned by this thread. */ + status = tx_mutex_get(&mutex_0, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Resume other threads run. */ + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + + /* Other threads should now be suspended on the mutex. Thread 1 should be + in front of thread 2 since it was suspended first. */ + if (mutex_0.tx_mutex_suspension_list != &thread_1) + { + + /* Mutex error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Prioritize the mutex to test it out! */ + status = tx_mutex_prioritize(&mutex_0); + + /* Check status and make sure thread 2 is now at the front of the list. */ + if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_2)) + { + + /* Mutex error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Prioritize the mutex again to make sure nothing has changed! */ + status = tx_mutex_prioritize(&mutex_0); + + /* Check status and make sure thread 2 is now at the front of the list. */ + if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_2)) + { + + /* Mutex error. */ + printf("ERROR #14a\n"); + test_control_return(1); + } + + /* At this point we are going to get more than 2 threads suspended. */ + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + tx_thread_resume(&thread_3); + tx_thread_resume(&thread_4); + tx_thread_resume(&thread_5); + tx_thread_resume(&thread_6); + + /* Prioritize the block pool suspension list. */ + status = tx_mutex_prioritize(&mutex_0); + + /* Check status and make sure thread 3 is at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_3)) + { + + /* Mutex error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Now loop to test the interrupt of the prioritize loop logic. */ + test_status = 1; + test_isr_dispatch = test_isr; + do + { + + /* Prioritize the mutex suspension list. */ + status = tx_mutex_prioritize(&mutex_0); + + /* Check status and make sure thread 1 is terminated. */ + if (status != TX_SUCCESS) + { + + /* Mutex error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + } while (test_status == 1); + + /* Now determine if thread 4 is at the front of the list... It should be! */ + if (mutex_0.tx_mutex_suspension_list != &thread_4) + { + + /* Mutex error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + + while (1) + { + + /* Suspend on the mutex. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Release the mutex. */ + status += tx_mutex_put(&mutex_0); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_1_counter++; + + /* Self suspend. */ + tx_thread_suspend(&thread_1); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; + + + while (1) + { + + /* Suspend on the mutex. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Release the mutex. */ + status += tx_mutex_put(&mutex_0); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_2_counter++; + + /* Self suspend. */ + tx_thread_suspend(&thread_2); + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + +UINT status; + + + while (1) + { + + /* Suspend on the mutex. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Release the mutex. */ + status += tx_mutex_put(&mutex_0); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_3_counter++; + + /* Self suspend. */ + tx_thread_suspend(&thread_3); + } +} + + +static void thread_4_entry(ULONG thread_input) +{ + +UINT status; + + + while (1) + { + + /* Suspend on the mutex. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Release the mutex. */ + status += tx_mutex_put(&mutex_0); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_4_counter++; + + /* Self suspend. */ + tx_thread_suspend(&thread_4); + } +} + + +static void thread_5_entry(ULONG thread_input) +{ + +UINT status; + + + while (1) + { + + /* Suspend on the mutex. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Release the mutex. */ + status += tx_mutex_put(&mutex_0); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_5_counter++; + + /* Self suspend. */ + tx_thread_suspend(&thread_5); + } +} + + +static void thread_6_entry(ULONG thread_input) +{ + +UINT status; + + + while (1) + { + + /* Suspend on the mutex. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Release the mutex. */ + status += tx_mutex_put(&mutex_0); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_6_counter++; + + /* Self suspend. */ + tx_thread_suspend(&thread_6); + } +} + diff --git a/test/smp/regression/threadx_mutex_suspension_timeout_test.c b/test/smp/regression/threadx_mutex_suspension_timeout_test.c new file mode 100644 index 00000000..8e1b79ea --- /dev/null +++ b/test/smp/regression/threadx_mutex_suspension_timeout_test.c @@ -0,0 +1,474 @@ +/* This test is designed to test the mutex suspension and timeout functionality. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" +#include "tx_mutex.h" + + +//static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; +static TX_THREAD thread_4; +static TX_THREAD low_priority; + + +static TX_MUTEX mutex_0; +static TX_MUTEX mutex_1; +extern UINT mutex_priority_change_extension_selection; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void low_priority_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +extern void test_control_return(UINT status); + + +#ifndef TX_MANUAL_TEST + +/* Define test flags for automated test. */ + +extern TEST_FLAG threadx_mutex_suspension_put_test; +extern TEST_FLAG threadx_mutex_suspension_priority_test; + +#endif + + +/* This test routine is used to get NULL suspension lists in various parts of tx_mutex_put. This is hooked up to IRQ 0 on this simulation and is entered manually at the + correct time. */ +void abort_all_threads_suspended_on_mutex(void) +{ + +TX_THREAD *thread_ptr; + + thread_ptr = _tx_thread_created_ptr; + while (thread_ptr) + { + if (thread_ptr -> tx_thread_state == TX_MUTEX_SUSP) + tx_thread_wait_abort(thread_ptr); + + thread_ptr = thread_ptr -> tx_thread_created_next; + if (thread_ptr == _tx_thread_created_ptr) + break; + } +} + + +/* This test routine is used to get a thread of a non ready state into _tx_mutex_change, called froim _tx_mutex_put. This is hooked up to IRQ 1 on this simulation and is entered manually at the + correct time. */ +void suspend_lowest_priority(void) +{ + +TX_INTERRUPT_SAVE_AREA + +TX_THREAD *thread_ptr; + + + /* Determine which extension to perform... to get to the different error checks in _tx_mutex_priority_change. */ + if (mutex_priority_change_extension_selection == 0) + { + + /* Setup the thread pointer. */ + thread_ptr = &thread_0; + + /* Disable interrupts. */ + TX_DISABLE + + /* Set the state to suspended. */ + thread_ptr -> tx_thread_state = TX_SUSPENDED; + +#ifdef TX_NOT_INTERRUPTABLE + + /* Call actual non-interruptable thread suspension routine. */ + _tx_thread_system_ni_suspend(thread_ptr, ((ULONG) 0)); + + /* Restore interrupts. */ + TX_RESTORE +#else + + /* Set the suspending flag. */ + thread_ptr -> tx_thread_suspending = TX_TRUE; + + /* Setup for no timeout period. */ + thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks = ((ULONG) 0); + + /* Temporarily disable preemption. */ + _tx_thread_preempt_disable++; + + /* Restore interrupts. */ + TX_RESTORE + + /* Call actual thread suspension routine. */ + _tx_thread_system_suspend(thread_ptr); +#endif + } + else if (mutex_priority_change_extension_selection == 1) + { + + /* Make the mapped core field to be invalid to exercise the error checking branch for core_index. */ + thread_0.tx_thread_smp_core_mapped = TX_THREAD_SMP_MAX_CORES; + } +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_mutex_suspension_timeout_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 1, 1, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 2, 2, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 3, 3, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 4, 4, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_create(&low_priority, "low priority", low_priority_entry, 30, + pointer, TEST_STACK_SIZE_PRINTF, + 30, 30, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Suspension Timeout Test............................... ERROR #1\n"); + test_control_return(1); + } + + /* Create mutexes. */ + status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + status += tx_mutex_create(&mutex_1, "mutex 1", TX_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Suspension Timeout Test............................... ERROR #2\n"); + test_control_return(1); + } + + /* Get the mutex to prevent thread from getting it. */ + tx_mutex_get(&mutex_0, TX_NO_WAIT); +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +TX_INTERRUPT_SAVE_AREA + +TX_THREAD *temp_thread; +UINT status; + + + /* Inform user. */ + printf("Running Mutex Suspension Timeout Test............................... "); + + /* Sleep for 2 ticks for fresh timer. */ + tx_thread_sleep(2); + + /* Set clock to 0. */ + tx_time_set(0); + + /* Suspend on the mutex. */ + status = tx_mutex_get(&mutex_0, 33); + + /* Did we get the right status at the right time? */ + if ((status != TX_NOT_AVAILABLE) || (tx_time_get() != 33)) + { + + /* Mutex error. */ + printf("ERROR #3\n"); + test_control_return(1); + } + + /* Get the mutex. */ + status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER); + + /* Make sure the three higher priority threads suspend on the mutex. */ + tx_thread_resume(&thread_4); + tx_thread_resume(&thread_3); + tx_thread_resume(&thread_2); + tx_thread_resume(&thread_1); + + +#ifdef TX_MANUAL_TEST + + /* Set BP hear and step into code and generate appropriate interrupt IRQ 0 by hand right after the prioritize function with interrupts enabled. This is to achieve the empty list branch coverage after the prioritize function. */ + tx_mutex_put(&mutex_1); +#else + + /* Set the flag such that generate the condition wehre the empty list condition is satisfied in the branch coverage. */ + threadx_mutex_suspension_put_test = 1; + tx_mutex_put(&mutex_1); +#endif + + /* Now some hand testing for tx_mutex_priority_change. */ + + /* Resume the low priority thread. */ + tx_thread_resume(&low_priority); + + /* Disable interrupts. */ + TX_DISABLE + + /* Simulate a call from inside of mutex put, but doing it here makes life easier. */ + _tx_thread_preempt_disable++; + + /* Move the current thread to a lower priority. */ + _tx_mutex_priority_change(&thread_0, 15); + _tx_mutex_priority_change(&thread_0, 16); + + /* Move the lower priority thread to a higher priority. */ + _tx_mutex_priority_change(&low_priority, 28); + _tx_mutex_priority_change(&low_priority, 29); + _tx_mutex_priority_change(&low_priority, 30); + + /* Change the priority of the current thread, such that we should have reverse the preemption-threshold issue. */ + thread_0.tx_thread_user_priority = 30; + thread_0.tx_thread_user_preempt_threshold = 30; + _tx_mutex_priority_change(&thread_0, 30); + + /* Change to an even lower priority. */ + thread_0.tx_thread_user_priority = 31; + thread_0.tx_thread_user_preempt_threshold = 31; + _tx_mutex_priority_change(&thread_0, 31); + + /* Move back to a higher-priority. */ + thread_0.tx_thread_user_priority = 30; + thread_0.tx_thread_user_preempt_threshold = 30; + _tx_mutex_priority_change(&thread_0, 16); + +#ifdef TX_MANUAL_TEST + + /* Set BP here and step into code and step through the code until the internal thread resume function returns, then issue an IRQ 1 to cause an ISR to suspend the thread and test the first condition. */ + _tx_mutex_priority_change(&thread_0, 30); +#else + + /* Set the flag to suspend the thread and test the first condition after internal resume is called. */ + mutex_priority_change_extension_selection = 0; + threadx_mutex_suspension_priority_test = 1; + _tx_mutex_priority_change(&thread_0, 30); +#endif + + /* Resume this thread. */ + tx_thread_resume(&thread_0); + _tx_mutex_priority_change(&thread_0, 16); + + /* Change to an even lower priority. */ + thread_0.tx_thread_user_priority = 27; + thread_0.tx_thread_user_preempt_threshold = 27; + _tx_mutex_priority_change(&thread_0, 28); + + /* Setup the low priority thread infromation. */ + low_priority.tx_thread_user_priority = 30; + low_priority.tx_thread_user_preempt_threshold = 29; + _tx_mutex_priority_change(&low_priority, 31); + + /* Change to an even lower priority. */ + thread_0.tx_thread_user_priority = 30; + thread_0.tx_thread_user_preempt_threshold = 29; + _tx_mutex_priority_change(&thread_0, 26); + +#ifdef TX_MANUAL_TEST + + /* Set BP here and step into code and step through the code until the internal thread resume function returns, and then issue the IRQ that modifies the core mapped. */ + mutex_priority_change_extension_selection = 1; + _tx_mutex_priority_change(&thread_0, 30); + thread_0.tx_thread_smp_core_mapped = 0; +#else + + /* Set the flag to suspend the thread and test the first condition after internal resume is called. */ + mutex_priority_change_extension_selection = 1; + threadx_mutex_suspension_priority_test = 1; + _tx_mutex_priority_change(&thread_0, 30); + thread_0.tx_thread_smp_core_mapped = 0; +#endif + + /* Move the thread back to priority 28. */ + _tx_mutex_priority_change(&thread_0, 28); + +#ifdef TX_MANUAL_TEST + + /* Set BP here and step into code and step through the code until the internal thread resume function returns, and then issue the IRQ that modifies the original priority. */ + mutex_priority_change_extension_selection = 2; + _tx_mutex_priority_change(&thread_0, 29); +#else + + /* Set the flag to suspend the thread and test the first condition after internal resume is called. */ + mutex_priority_change_extension_selection = 2; + threadx_mutex_suspension_priority_test = 1; + _tx_mutex_priority_change(&thread_0, 29); + _tx_thread_execute_ptr[0] = &thread_0; +#endif + +#ifdef TX_MANUAL_TEST + + /* Set BP here and step into code and step through the code until the internal thread resume function returns, and then issue the IRQ that sets the original_pt_thread to NULL. */ + mutex_priority_change_extension_selection = 3; + _tx_mutex_priority_change(&thread_0, 30); +#else + + /* Set the flag to suspend the thread and test the first condition after internal resume is called. */ + mutex_priority_change_extension_selection = 3; + threadx_mutex_suspension_priority_test = 1; + _tx_mutex_priority_change(&thread_0, 30); +#endif + +#ifdef TX_MANUAL_TEST + + /* Set BP here and step into code and step through the code until the internal thread resume function returns, and then issue the IRQ that sets the _tx_thread_preemption__threshold_scheduled to NULL. */ + temp_thread = _tx_thread_preemption__threshold_scheduled; + mutex_priority_change_extension_selection = 4; + _tx_mutex_priority_change(&thread_0, 31); + _tx_thread_preemption__threshold_scheduled = temp_thread; +#else + + /* Set the flag to suspend the thread and test the first condition after internal resume is called. */ + temp_thread = _tx_thread_preemption__threshold_scheduled; + mutex_priority_change_extension_selection = 4; + threadx_mutex_suspension_priority_test = 1; + _tx_mutex_priority_change(&thread_0, 31); + _tx_thread_preemption__threshold_scheduled = temp_thread; +#endif + + /* Just change to same priority to ensure that path is executed. */ + mutex_priority_change_extension_selection = 0; + suspend_lowest_priority(); + thread_0.tx_thread_user_priority = 31; + thread_0.tx_thread_user_preempt_threshold = 30; + thread_0.tx_thread_priority = 31; + thread_0.tx_thread_preempt_threshold = 30; + _tx_mutex_priority_change(&thread_0, 31); + thread_0.tx_thread_user_priority = 31; + thread_0.tx_thread_user_preempt_threshold = 31; + thread_0.tx_thread_priority = 31; + thread_0.tx_thread_preempt_threshold = 31; + _tx_mutex_priority_change(&thread_0, 31); + tx_thread_resume(&thread_0); + + /* Restore the preempt disable flag. */ + _tx_thread_preempt_disable--; + + /* Restore interrupts. */ + TX_RESTORE + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; + + /* Loop to get the mutex. */ + while(1) + { + + /* Get and release the mutex. */ + status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER); + if (status == TX_SUCCESS) + tx_mutex_put(&mutex_1); + tx_thread_suspend(&thread_1); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; + + /* Loop to get the mutex. */ + while(1) + { + + /* Get and release the mutex. */ + status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER); + if (status == TX_SUCCESS) + tx_mutex_put(&mutex_1); + tx_thread_suspend(&thread_2); + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + +UINT status; + + /* Loop to get the mutex. */ + while(1) + { + + /* Get and release the mutex. */ + status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER); + if (status == TX_SUCCESS) + tx_mutex_put(&mutex_1); + tx_thread_suspend(&thread_3); + } +} + +static void thread_4_entry(ULONG thread_input) +{ + +UINT status; + + /* Loop to get the mutex. */ + while(1) + { + + /* Get and release the mutex. */ + status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER); + if (status == TX_SUCCESS) + tx_mutex_put(&mutex_1); + tx_thread_suspend(&thread_4); + } +} + + +static void low_priority_entry(ULONG thread_input) +{ +} diff --git a/test/smp/regression/threadx_mutex_thread_terminate_test.c b/test/smp/regression/threadx_mutex_thread_terminate_test.c new file mode 100644 index 00000000..9b552f54 --- /dev/null +++ b/test/smp/regression/threadx_mutex_thread_terminate_test.c @@ -0,0 +1,198 @@ +/* This test is designed to test thread terminate calls when threads are suspended on + a mutex. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + + +static TX_MUTEX mutex_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_mutex_thread_terminate_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Thread Terminate Test................................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Thread Terminate Test................................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Thread Terminate Test................................. ERROR #3\n"); + test_control_return(1); + } + + /* Create a mutex. */ + status = tx_mutex_create(&mutex_0, "mutex 0", 0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Mutex Thread Terminate Test................................. ERROR #4\n"); + test_control_return(1); + } + + /* Get the mutex. */ + tx_mutex_get(&mutex_0, TX_NO_WAIT); +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Mutex Thread Terminate Test................................. "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Relinquish to let other threads run. */ + tx_thread_relinquish(); + + /* Other threads should now be suspended on the mutex. */ + if ((thread_1_counter != 1) || (thread_2_counter != 1)) + { + + /* Mutex error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Terminate the other threads to make sure the mutex gets + cleaned up. */ + status = tx_thread_terminate(&thread_1); + + /* Check status and run counters of other threads. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1)) + { + + /* Mutex error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Terminate the other thread. */ + status = tx_thread_terminate(&thread_2); + + /* Relinquish just to make sure. */ + tx_thread_relinquish(); + + /* Check status and run counters of other threads. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1)) + { + + /* Mutex error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +//UINT status; + + /* Increment thread run counter. */ + thread_1_counter++; + + /* Suspend on the mutex. */ + tx_mutex_get(&mutex_0, 33); + + /* Should never get here! */ + thread_1_counter++; +} + + +static void thread_2_entry(ULONG thread_input) +{ + +//UINT status; + + /* Increment thread run counter. */ + thread_2_counter++; + + /* Suspend on the mutex. */ + tx_mutex_get(&mutex_0, 44); + + /* Should never get here! */ + thread_2_counter++; +} diff --git a/test/smp/regression/threadx_queue_basic_eight_word_test.c b/test/smp/regression/threadx_queue_basic_eight_word_test.c new file mode 100644 index 00000000..c201fdee --- /dev/null +++ b/test/smp/regression/threadx_queue_basic_eight_word_test.c @@ -0,0 +1,423 @@ +/* This test is designed to test immediate response queue services including create + and delete. This test is for queue sizes of 8 ULONG. Two queues are used one with + a capacity of 1 message and another with a capacity of 3 messages. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static TX_QUEUE queue_0; +static TX_QUEUE queue_1; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_basic_eight_word_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Eight Word Queue Test................................. ERROR #1\n"); + test_control_return(1); + } + + /* Create the queues. */ + status = tx_queue_create(&queue_0, "queue 0", TX_8_ULONG, pointer, 8*sizeof(ULONG)); + pointer = pointer + (8*sizeof(ULONG)); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Eight Word Queue Test................................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_queue_create(&queue_1, "queue 1", TX_8_ULONG, pointer, 8*3*sizeof(ULONG)); + pointer = pointer + 8*3*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Eight Word Queue Test................................. ERROR #3\n"); + test_control_return(1); + } +} + + + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG source_message[8]; +ULONG dest_message[8]; +ULONG expected_message[8]; + + + /* Inform user. */ + printf("Running Queue Eight Word Queue Test................................. "); + + source_message[0] = 0x01234567; + source_message[7] = 0x89ABCDEF; + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) || + (source_message[7] != dest_message[7])) + { + + /* Queue error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + source_message[0]++; + source_message[7]++; + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) || + (source_message[7] != dest_message[7])) + { + + /* Queue error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Now we need to do the same thing with the queue with three entries. */ + + source_message[0]++; + source_message[7]++; + expected_message[0] = source_message[0]; + expected_message[7] = source_message[7]; + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[7]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[7]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[7]++; + + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[7] != dest_message[7])) + { + + /* Queue error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[7]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[7] != dest_message[7])) + { + + /* Queue error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[7]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[7] != dest_message[7])) + { + + /* Queue error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[7]++; + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[7]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[7]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[7]++; + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[7] != dest_message[7])) + { + + /* Queue error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[7]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[7] != dest_message[7])) + { + + /* Queue error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[7]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[7] != dest_message[7])) + { + + /* Queue error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[7]++; + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Delete the queues. */ + status = tx_queue_delete(&queue_1); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + status = tx_queue_delete(&queue_0); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + diff --git a/test/smp/regression/threadx_queue_basic_four_word_test.c b/test/smp/regression/threadx_queue_basic_four_word_test.c new file mode 100644 index 00000000..5e01bc5b --- /dev/null +++ b/test/smp/regression/threadx_queue_basic_four_word_test.c @@ -0,0 +1,423 @@ +/* This test is designed to test immediate response queue services including create + and delete. This test is for queue sizes of 4 ULONG. Two queues are used one with + a capacity of 1 message and another with a capacity of 3 messages. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static TX_QUEUE queue_0; +static TX_QUEUE queue_1; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_basic_four_word_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Four Word Test........................................ ERROR #1\n"); + test_control_return(1); + } + + /* Create the queues. */ + status = tx_queue_create(&queue_0, "queue 0", TX_4_ULONG, pointer, 4*sizeof(ULONG)); + pointer = pointer + (4*sizeof(ULONG)); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Four Word Test........................................ ERROR #2\n"); + test_control_return(1); + } + + status = tx_queue_create(&queue_1, "queue 1", TX_4_ULONG, pointer, 4*3*sizeof(ULONG)); + pointer = pointer + 4*3*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Four Word Test........................................ ERROR #3\n"); + test_control_return(1); + } +} + + + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG source_message[4]; +ULONG dest_message[4]; +ULONG expected_message[4]; + + + /* Inform user. */ + printf("Running Queue Four Word Test........................................ "); + + source_message[0] = 0x01234567; + source_message[3] = 0x89ABCDEF; + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) || + (source_message[3] != dest_message[3])) + { + + /* Queue error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + source_message[0]++; + source_message[3]++; + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) || + (source_message[3] != dest_message[3])) + { + + /* Queue error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Now we need to do the same thing with the queue with three entries. */ + + source_message[0]++; + source_message[3]++; + expected_message[0] = source_message[0]; + expected_message[3] = source_message[3]; + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[3]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[3]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[3]++; + + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[3] != dest_message[3])) + { + + /* Queue error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[3]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[3] != dest_message[3])) + { + + /* Queue error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[3]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[3] != dest_message[3])) + { + + /* Queue error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[3]++; + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[3]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[3]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[3]++; + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[3] != dest_message[3])) + { + + /* Queue error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[3]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[3] != dest_message[3])) + { + + /* Queue error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[3]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[3] != dest_message[3])) + { + + /* Queue error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[3]++; + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Delete the queues. */ + status = tx_queue_delete(&queue_1); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + status = tx_queue_delete(&queue_0); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + diff --git a/test/smp/regression/threadx_queue_basic_one_word_test.c b/test/smp/regression/threadx_queue_basic_one_word_test.c new file mode 100644 index 00000000..142a9b60 --- /dev/null +++ b/test/smp/regression/threadx_queue_basic_one_word_test.c @@ -0,0 +1,867 @@ +/* This test is designed to test immediate response queue services including create + and delete. This test is for queue sizes of 1 ULONG. Two queues are used one with + a capacity of 1 message and another with a capacity of 3 messages. */ + +#include +#include "tx_api.h" + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static TX_THREAD thread_1; + + +static TX_TIMER timer_0; + + +static unsigned long error = 0; +static unsigned long timer_executed = 0; +static unsigned long isr_executed = 0; + +static TX_QUEUE queue_0; +static TX_QUEUE queue_1; +static TX_QUEUE queue_2; +static TX_QUEUE queue_3; + + +/* Define the external reference to the status for queue create from initialization. */ + +extern UINT test_queue_from_init; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +UINT _txe_queue_create(TX_QUEUE *queue_ptr, CHAR *name_ptr, UINT message_size, + VOID *queue_start, ULONG queue_size, UINT queue_control_block_size); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define the timer for this test. */ + +static void timer_entry(ULONG i) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +UINT status; +CHAR *pointer; +ULONG source = 1234; +ULONG destination; + + + /* Determine if calling queue create from initialization was successful. */ + if (test_queue_from_init != TX_SUCCESS) + { + + /* Error! */ + error++; + } + + /* Attempt to create a queue from a timer. */ + pointer = (CHAR *) 0x3000; + status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, pointer, 3*sizeof(ULONG)); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to delete a queue from a timer. */ + status = tx_queue_delete(&queue_0); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to send something with suspension from a timer. */ + status = tx_queue_front_send(&queue_0, &source, 100); + + /* Check for status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to send something with suspension from a timer. */ + status = tx_queue_send(&queue_0, &source, 100); + + /* Check for status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to receive something with suspension from a timer. */ + status = tx_queue_receive(&queue_0, &destination, 100); + + /* Check for status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + + timer_executed = 1; +#endif +} + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +CHAR *pointer; +UINT status; +ULONG source = 1234; +ULONG destination; + + + /* Attempt to create a queue from an ISR. */ + pointer = (CHAR *) 0x3000; + status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, pointer, 3*sizeof(ULONG)); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to delete a queue from an ISR. */ + status = tx_queue_delete(&queue_0); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to send something with suspension from an ISR. */ + status = tx_queue_front_send(&queue_0, &source, 100); + + /* Check for status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to send something with suspension from an ISR. */ + status = tx_queue_send(&queue_0, &source, 100); + + /* Check for status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to receive something with suspension from an ISR. */ + status = tx_queue_receive(&queue_0, &destination, 100); + + /* Check for status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + isr_executed = 1; +#endif +} + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_basic_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue One Word Queue Test................................... ERROR #1\n"); + test_control_return(1); + } + + /* Create the queues. */ + status = tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, sizeof(ULONG)); + pointer = pointer + sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue One Word Queue Test................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_queue_create(&queue_1, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG)); + pointer = pointer + 3*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue One Word Queue Test................................... ERROR #3\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG source_message = 0x12345678UL; +ULONG dest_message; +ULONG expected_message; +#ifndef TX_DISABLE_ERROR_CHECKING +CHAR *pointer; +#endif + + /* Inform user. */ + printf("Running Queue One Word Queue Test................................... "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Attempt to create with NULL queue. */ + pointer = (CHAR *) 0x3000; + status = tx_queue_create(TX_NULL, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG)); + + /* Check for status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Attempt to create with bad sized queue control block. */ + status = _txe_queue_create(&queue_3, "queue 3", TX_1_ULONG, pointer, 3*sizeof(ULONG), (sizeof(TX_QUEUE)+1)); + + /* Check for status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Attempt to create with bad sized message. */ + status = tx_queue_create(&queue_3, "queue 3", 0, pointer, 3*sizeof(ULONG)); + + /* Check for status. */ + if (status != TX_SIZE_ERROR) + { + + /* Queue error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Attempt to create a queue that has already been created. */ + pointer = (CHAR *) 0x3000; + status = tx_queue_create(&queue_0, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG)); + + /* Check for status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Attempt to create a queue with an invalid message size. */ + pointer = (CHAR *) 0x3000; + status = tx_queue_create(&queue_2, "queue 2", 47, pointer, 3*sizeof(ULONG)); + + /* Check for status. */ + if (status != TX_SIZE_ERROR) + { + + /* Queue error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Attempt to create a queue with a NULL queue area. */ + status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, TX_NULL, 3*sizeof(ULONG)); + + /* Check for status. */ + if (status != TX_PTR_ERROR) + { + + /* Queue error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to create a queue with a too small queue area. */ + pointer = (CHAR *) 0x3000; + status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, pointer, 1); + + /* Check for status. */ + if (status != TX_SIZE_ERROR) + { + + /* Queue error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Attempt to delete a NULL pointer. */ + status = tx_queue_delete(TX_NULL); + + /* Check for status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Attempt to delete a non-created queue. */ + queue_2.tx_queue_id = 0; + status = tx_queue_delete(&queue_2); + + /* Check for status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Attempt to flush a NULL pointer. */ + status = tx_queue_flush(TX_NULL); + + /* Check for status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Attempt to flush a non-created queue. */ + queue_2.tx_queue_id = 0; + status = tx_queue_flush(&queue_2); + + /* Check for status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Attempt to send something to the front of a non-queue. */ + status = tx_queue_front_send(TX_NULL, &source_message, TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Attempt to send something to the front of a non-created queue. */ + queue_2.tx_queue_id = 0; + status = tx_queue_front_send(&queue_2, &source_message, TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Attempt to send something with a NULL source pointer. */ + status = tx_queue_front_send(&queue_0, TX_NULL, TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_PTR_ERROR) + { + + /* Queue error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Attempt to send something to a non-queue. */ + status = tx_queue_send(TX_NULL, &source_message, TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Attempt to send something to a non-created queue. */ + queue_2.tx_queue_id = 0; + status = tx_queue_send(&queue_2, &source_message, TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Attempt to send something with a NULL source pointer. */ + status = tx_queue_send(&queue_0, TX_NULL, TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_PTR_ERROR) + { + + /* Queue error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Attempt to receive something from a non-queue. */ + status = tx_queue_receive(TX_NULL, &dest_message, TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + /* Attempt to receive something from a non-created queue. */ + queue_2.tx_queue_id = 0; + status = tx_queue_receive(&queue_2, &dest_message, TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Attempt to receive something to a NULL destination. */ + status = tx_queue_receive(&queue_0, TX_NULL, TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_PTR_ERROR) + { + + /* Queue error. */ + printf("ERROR #23\n"); + test_control_return(1); + } +#endif + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message != dest_message)) + { + + /* Queue error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + source_message++; + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message != dest_message)) + { + + /* Queue error. */ + printf("ERROR #30\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #31\n"); + test_control_return(1); + } + + /* Now we need to do the same thing with the queue with three entries. */ + + source_message++; + expected_message = source_message; + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + source_message++; + status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + source_message++; + status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + source_message++; + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #32\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #33\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message++ != dest_message)) + { + + /* Queue error. */ + printf("ERROR #34\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message++ != dest_message)) + { + + /* Queue error. */ + printf("ERROR #35\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message++ != dest_message)) + { + + /* Queue error. */ + printf("ERROR #36\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #37\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + source_message++; + status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + source_message++; + status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + source_message++; + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #38\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #39\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message++ != dest_message)) + { + + /* Queue error. */ + printf("ERROR #40\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message++ != dest_message)) + { + + /* Queue error. */ + printf("ERROR #41\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message++ != dest_message)) + { + + /* Queue error. */ + printf("ERROR #42\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #43\n"); + test_control_return(1); + } + + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Create a timer for the test. */ + tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE); + + /* Setup the ISR. */ + test_isr_dispatch = test_isr; + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Resume thread 1 so that we can take an interrupt on top of it. */ + tx_thread_resume(&thread_1); + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Clear the ISR. */ + test_isr_dispatch = TX_NULL; + + /* Test for error. */ + if ((error) || (timer_executed != 1) || (isr_executed != 1)) + { + + /* Queue error. */ + printf("ERROR #44\n"); + test_control_return(1); + } + +#endif + + /* Delete the queues. */ + status = tx_queue_delete(&queue_1); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #45\n"); + test_control_return(1); + } + + status = tx_queue_delete(&queue_0); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #46\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + } +} + diff --git a/test/smp/regression/threadx_queue_basic_sixteen_word_test.c b/test/smp/regression/threadx_queue_basic_sixteen_word_test.c new file mode 100644 index 00000000..703a1cf4 --- /dev/null +++ b/test/smp/regression/threadx_queue_basic_sixteen_word_test.c @@ -0,0 +1,423 @@ +/* This test is designed to test immediate response queue services including create + and delete. This test is for queue sizes of 16 ULONG. Two queues are used one with + a capacity of 1 message and another with a capacity of 3 messages. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static TX_QUEUE queue_0; +static TX_QUEUE queue_1; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_basic_sixteen_word_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Sixteen Word Test..................................... ERROR #1\n"); + test_control_return(1); + } + + /* Create the queues. */ + status = tx_queue_create(&queue_0, "queue 0", TX_16_ULONG, pointer, 16*sizeof(ULONG)); + pointer = pointer + (16*sizeof(ULONG)); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Sixteen Word Test..................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_queue_create(&queue_1, "queue 1", TX_16_ULONG, pointer, 16*3*sizeof(ULONG)); + pointer = pointer + 16*3*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Sixteen Word Test..................................... ERROR #3\n"); + test_control_return(1); + } +} + + + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG source_message[16]; +ULONG dest_message[16]; +ULONG expected_message[16]; + + + /* Inform user. */ + printf("Running Queue Sixteen Word Test..................................... "); + + source_message[0] = 0x01234567; + source_message[15] = 0x89ABCDEF; + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) || + (source_message[15] != dest_message[15])) + { + + /* Queue error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + source_message[0]++; + source_message[15]++; + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) || + (source_message[15] != dest_message[15])) + { + + /* Queue error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Now we need to do the same thing with the queue with three entries. */ + + source_message[0]++; + source_message[15]++; + expected_message[0] = source_message[0]; + expected_message[15] = source_message[15]; + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[15]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[15]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[15]++; + + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[15] != dest_message[15])) + { + + /* Queue error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[15]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[15] != dest_message[15])) + { + + /* Queue error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[15]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[15] != dest_message[15])) + { + + /* Queue error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[15]++; + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[15]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[15]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[15]++; + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[15] != dest_message[15])) + { + + /* Queue error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[15]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[15] != dest_message[15])) + { + + /* Queue error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[15]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[15] != dest_message[15])) + { + + /* Queue error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[15]++; + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Delete the queues. */ + status = tx_queue_delete(&queue_1); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + status = tx_queue_delete(&queue_0); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + diff --git a/test/smp/regression/threadx_queue_basic_two_word_test.c b/test/smp/regression/threadx_queue_basic_two_word_test.c new file mode 100644 index 00000000..ab24d08e --- /dev/null +++ b/test/smp/regression/threadx_queue_basic_two_word_test.c @@ -0,0 +1,463 @@ +/* This test is designed to test immediate response queue services including create + and delete. This test is for queue sizes of 2 ULONG. Two queues are used one with + a capacity of 1 message and another with a capacity of 3 messages. */ + +#include +#include "tx_api.h" + +typedef struct QUEUE_MEMORY_TEST_STRUCT +{ + ULONG first; + ULONG second; + TX_QUEUE queue; + ULONG first_middle; + ULONG second_middle; + ULONG queue_area[2048/sizeof(ULONG)]; + ULONG next_to_last; + ULONG last; + +} QUEUE_MEMORY_TEST; + +static QUEUE_MEMORY_TEST queue_memory; + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static TX_QUEUE queue_0; +static TX_QUEUE queue_1; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_basic_two_word_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Two Word Test......................................... ERROR #1\n"); + test_control_return(1); + } + + /* Create the queues. */ + status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 2*sizeof(ULONG)); + pointer = pointer + (2*sizeof(ULONG)); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Two Word Test......................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_queue_create(&queue_1, "queue 1", TX_2_ULONG, pointer, 2*3*sizeof(ULONG)); + pointer = pointer + 2*3*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Two Word Test......................................... ERROR #3\n"); + test_control_return(1); + } +} + + + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG source_message[2]; +ULONG dest_message[2]; +ULONG expected_message[2]; + + + /* Inform user. */ + printf("Running Queue Two Word Test......................................... "); + + /* Perform queue memory test. */ + queue_memory.first = 0x11223344; + queue_memory.second = 0x55667788; + queue_memory.first_middle = 0x21314151; + queue_memory.second_middle= 0x61718191; + queue_memory.next_to_last = 0x99aabbcc; + queue_memory.last = 0xddeeff00; + + /* Create the queue. */ + status = tx_queue_create(&queue_memory.queue, "queue memory", TX_2_ULONG, &queue_memory.queue_area[0], (2048*sizeof(ULONG))/sizeof(ULONG)); + tx_queue_delete(&queue_memory.queue); + + /* Check for status. */ + if ((status != TX_SUCCESS) || + (queue_memory.first != 0x11223344) || + (queue_memory.second != 0x55667788) || + (queue_memory.first_middle != 0x21314151) || + (queue_memory.second_middle != 0x61718191) || + (queue_memory.next_to_last != 0x99aabbcc) || + (queue_memory.last != 0xddeeff00)) + { + /* Queue error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + source_message[0] = 0x01234567; + source_message[1] = 0x89ABCDEF; + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) || + (source_message[1] != dest_message[1])) + { + + /* Queue error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + source_message[0]++; + source_message[1]++; + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) || + (source_message[1] != dest_message[1])) + { + + /* Queue error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Now we need to do the same thing with the queue with three entries. */ + + source_message[0]++; + source_message[1]++; + expected_message[0] = source_message[0]; + expected_message[1] = source_message[1]; + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[1]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[1]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[1]++; + + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[1] != dest_message[1])) + { + + /* Queue error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[1]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[1] != dest_message[1])) + { + + /* Queue error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[1]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[1] != dest_message[1])) + { + + /* Queue error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[1]++; + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[1]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[1]++; + status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + source_message[0]++; + source_message[1]++; + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[1] != dest_message[1])) + { + + /* Queue error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[1]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[1] != dest_message[1])) + { + + /* Queue error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[1]++; + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) || + (expected_message[1] != dest_message[1])) + { + + /* Queue error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + expected_message[0]++; + expected_message[1]++; + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Delete the queues. */ + status = tx_queue_delete(&queue_1); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + + status = tx_queue_delete(&queue_0); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + diff --git a/test/smp/regression/threadx_queue_empty_suspension_test.c b/test/smp/regression/threadx_queue_empty_suspension_test.c new file mode 100644 index 00000000..59d53e70 --- /dev/null +++ b/test/smp/regression/threadx_queue_empty_suspension_test.c @@ -0,0 +1,271 @@ +/* This test is designed to test empty queue suspension of queue that supports 3 messages + that are each 2 ULONG in size. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static TX_QUEUE queue_0; +static TX_QUEUE queue_1; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void queue_notify(TX_QUEUE *queue_ptr) +{ + +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_empty_suspension_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Empty Suspension Test................................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Empty Suspension Test................................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Empty Suspension Test................................. ERROR #3\n"); + test_control_return(1); + } + + /* Create the queue. */ + status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG)); + pointer = pointer + 3*2*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Empty Suspension Test................................. ERROR #4\n"); + test_control_return(1); + } + + /* Setup queue send notification. */ + status = tx_queue_send_notify(&queue_0, queue_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Empty Suspension Test................................. ERROR #5\n"); + test_control_return(1); + } + +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Queue Empty Suspension Test................................. ERROR #6\n"); + test_control_return(1); + } + +#endif +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG source_message[2] = {0x12345678, 0}; + + + /* Inform user. */ + printf("Running Queue Empty Suspension Test................................. "); + + /* Increment the thread counter. */ + thread_0_counter++; + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Attempt to setup notify on a non-queue. */ + status = tx_queue_send_notify(TX_NULL, queue_notify); + + /* Check status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Attempt to setup notify on a non-created queue. */ + queue_1.tx_queue_id = 0; + status = tx_queue_send_notify(&queue_1, queue_notify); + + /* Check status. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #8\n"); + test_control_return(1); + } +#endif + + /* Send message that should go directly into the the other thread's + destination area! We should also preempt and the queue should + be empty by the next time we get around! */ + status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT); + + /* Check status and run count of other thread - it should have got the + message already. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1)) + { + + /* Queue error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Now resume thread 2 to get another thread suspended on an empty queue. */ + tx_thread_resume(&thread_2); + + /* Now send 2 messages to wakeup both threads! */ + source_message[0]++; + status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT); + status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT); + + /* Check status and run count of other thread - it should have got the + message already. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 2) || (thread_2_counter != 1)) + { + + /* Queue error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG expected_message[2] = {0x12345678, 0}; +ULONG dest_message[2]; + + + /* Loop forever! */ + while(1) + { + + + /* Receive message from empty queue with suspension. We should always + suspend until thread 0 executes. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER); + + if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++)) + break; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +ULONG expected_message[2] = {0x12345679, 0}; +ULONG dest_message[2]; + + + /* Loop forever! */ + while(1) + { + + + /* Receive message from empty queue with suspension. We should always + suspend until thread 0 executes. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER); + + if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++)) + break; + + /* Increment the thread counter. */ + thread_2_counter++; + } +} + diff --git a/test/smp/regression/threadx_queue_flush_no_suspension_test.c b/test/smp/regression/threadx_queue_flush_no_suspension_test.c new file mode 100644 index 00000000..940259f2 --- /dev/null +++ b/test/smp/regression/threadx_queue_flush_no_suspension_test.c @@ -0,0 +1,216 @@ +/* This test is designed to test the queue flush operation on a queue that has no threads + suspended on it. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static TX_QUEUE queue_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void queue_notify(TX_QUEUE *queue_ptr) +{ + +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_flush_no_suspension_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Flush No Suspension Test.............................. ERROR #1\n"); + test_control_return(1); + } + + /* Create the queue. */ + status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG)); + pointer = pointer + 3*2*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Flush No Suspension Test.............................. ERROR #2\n"); + test_control_return(1); + } + + /* Setup queue send notification. */ + status = tx_queue_send_notify(&queue_0, queue_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Flush No Suspension Test.............................. ERROR #3\n"); + test_control_return(1); + } +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Queue Flush No Suspension Test.............................. ERROR #4\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG message[2] = {0x12345678, 0}; +UINT status; + + + /* Inform user. */ + printf("Running Queue Flush No Suspension Test.............................. "); + + /* Fill up the queue. */ + status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #5\n"); + test_control_return(1); + } + + status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #6\n"); + test_control_return(1); + } + + status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT); + + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Flush queue 0 to make more room. */ + status = tx_queue_flush(&queue_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #8\n"); + test_control_return(1); + } + + + /* Fill up the queue. */ + status = tx_queue_send(&queue_0, &message[2], TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #9\n"); + test_control_return(1); + } + + status = tx_queue_send(&queue_0, &message[2], TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #10\n"); + test_control_return(1); + } + + status = tx_queue_send(&queue_0, &message[2], TX_NO_WAIT); + + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Flush queue again to empty and then flush to test on an empty queue. */ + status = tx_queue_flush(&queue_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #12\n"); + test_control_return(1); + } + + status = tx_queue_flush(&queue_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Success if we get here. */ + printf("SUCCESS!\n"); + test_control_return(0); + + /* Increment the thread counter. */ + thread_0_counter++; +} + diff --git a/test/smp/regression/threadx_queue_flush_test.c b/test/smp/regression/threadx_queue_flush_test.c new file mode 100644 index 00000000..6d65c971 --- /dev/null +++ b/test/smp/regression/threadx_queue_flush_test.c @@ -0,0 +1,249 @@ +/* This test is designed to test the queue flush operation on a queue that has two threads + suspended on it. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static TX_QUEUE queue_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void queue_notify(TX_QUEUE *queue_ptr) +{ + +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_flush_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #3\n"); + test_control_return(1); + } + + + /* Create the queue. */ + status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG)); + pointer = pointer + 3*2*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #4\n"); + test_control_return(1); + } + + /* Setup queue send notification. */ + status = tx_queue_send_notify(&queue_0, queue_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #5\n"); + test_control_return(1); + } +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #6\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG message[2] = {0x12345678, 0}; +UINT status; + + + /* Inform user. */ + printf("Running Queue Flush w/Suspended Threads Test........................ "); + + /* Fill up the queue. */ + status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #7\n"); + test_control_return(1); + } + + status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #8\n"); + test_control_return(1); + } + + status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT); + + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Relinquish to get other threads suspended on the queue full. */ + tx_thread_relinquish(); + + /* Flush queue 0 which has the threads suspended on it. */ + status = tx_queue_flush(&queue_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Relinquish to let other threads run and finish! */ + tx_thread_relinquish(); + + /* Determine if the queue flush test was successful. */ + if ((thread_1_counter == 1) && (thread_2_counter == 1)) + { + + /* Successful queue flush test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } + else + { + + /* Queue Flush error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Increment the thread counter. */ + thread_0_counter++; +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +ULONG message[2] = {0x1, 0}; + + + /* Receive message from empty queue. */ + status = tx_queue_send(&queue_0, &message[0], TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + return; + + /* Increment the thread counter. */ + thread_1_counter++; +} + + +static void thread_2_entry(ULONG thread_input) +{ +UINT status; +ULONG message[2] = {0x2, 0}; + + + /* Receive message from empty queue. */ + status = tx_queue_send(&queue_0, &message[0], TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + return; + + /* Increment the thread counter. */ + thread_2_counter++; +} + diff --git a/test/smp/regression/threadx_queue_front_send_test.c b/test/smp/regression/threadx_queue_front_send_test.c new file mode 100644 index 00000000..5329670b --- /dev/null +++ b/test/smp/regression/threadx_queue_front_send_test.c @@ -0,0 +1,686 @@ +/* This test is designed to test immediate response queue services including queue front send. + This test is for queue sizes of 2 ULONG. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static TX_THREAD thread_2; + +static TX_QUEUE queue_0; + + +static unsigned long thread_1a_counter = 0; +static TX_THREAD thread_1a; + +static TX_THREAD thread_2a; + +static TX_QUEUE queue_0a; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_1a_entry(ULONG thread_input); +static void thread_2a_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void queue_notify(TX_QUEUE *queue_ptr) +{ + +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_front_send_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Front Test............................................ ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status = tx_thread_create(&thread_1a, "thread 1a", thread_1a_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Front Test............................................ ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status = tx_thread_create(&thread_2a, "thread 2a", thread_2a_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Front Test............................................ ERROR #3\n"); + test_control_return(1); + } + + /* Create the queues. */ + status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 2*2*sizeof(ULONG)); + pointer = pointer + 2*2*sizeof(ULONG); + status = tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, pointer, 2*1*sizeof(ULONG)); + pointer = pointer + 2*1*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Front Test............................................ ERROR #4\n"); + test_control_return(1); + } + + /* Setup queue send notification. */ + status = tx_queue_send_notify(&queue_0, queue_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Front Test............................................ ERROR #5\n"); + test_control_return(1); + } +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Queue Front Test............................................ ERROR #6\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG source_message[2] = {0x12345678, 0}; +ULONG dest_message[2]; +ULONG temp[2]; + + + /* Inform user. */ + printf("Running Queue Front Test............................................ "); + + /* Perform the 1 word queue front send test. */ + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Place something on queue 0a. */ + status = tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #7a\n"); + test_control_return(1); + } + + /* Place a new message on the front of the queue. */ + temp[0] = 0xF000001; + status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #8a\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0a. */ + status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (dest_message[0] != temp[0])) + { + + /* Queue error. */ + printf("ERROR #9a\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0a. */ + status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (dest_message[0] != source_message[0])) + { + + /* Queue error. */ + printf("ERROR #10a\n"); + test_control_return(1); + } + + /* Attempt to receive another message from the queue. */ + status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #11a\n"); + test_control_return(1); + } + + /* At this point the queue is empty. Resume another thread to + suspend on an empty queue. */ + tx_thread_resume(&thread_1a); + + /* Relinquish to get this thread suspended on the empty queue. */ + tx_thread_relinquish(); + + /* Resume thread 2a to get another thread suspended on the empty queue. */ + tx_thread_resume(&thread_2a); + + /* Now send something to the front of the queue, which will resume + the first waiting thread. */ + temp[0] = 0xFF00002; + status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #12a\n"); + test_control_return(1); + } + + /* Now send something to the front of the queue, which will resume + the second waiting thread. */ + temp[0] = 0xFF00002; + status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #13a\n"); + test_control_return(1); + } + + /* Now relinquish again to let the other thread process the message. */ + tx_thread_relinquish(); + + /* At this point, the other thread should have placed 2 messages on the queue + so we will now send to the front, but without suspension. */ + temp[0] = 0xFF00003; + status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT); + + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #14a\n"); + test_control_return(1); + } + + /* Now, we will now send to the front, but with suspension. */ + temp[0] = 0xFF00003; + status = tx_queue_front_send(&queue_0a, &temp[0], TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #15a\n"); + test_control_return(1); + } + + /* Now resume thread 2a to get another thread suspended on the queue. */ + tx_thread_resume(&thread_2a); + + temp[0] = 0xFF00004; + status = tx_queue_front_send(&queue_0a, &temp[0], TX_WAIT_FOREVER); + + /* When we get back, the other thread has received all the messages and + verified they are in order AND relinquished. */ + if ((status != TX_SUCCESS) || (thread_1a_counter != 1)) + { + + /* Queue error. */ + printf("ERROR #16a\n"); + test_control_return(1); + } + + + /* Perform the multiword queue front send test. */ + + + /* Increment thread 0 counter. */ + thread_0_counter = 1; + + /* Reset the source message. */ + source_message[0] = 0x12345678; + source_message[1] = 0; + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Place a new message on the front of the queue. */ + temp[0] = 0xF000001; + status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (dest_message[0] != temp[0])) + { + + /* Queue error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (dest_message[0] != source_message[0])) + { + + /* Queue error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Attempt to receive another message from the queue. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* At this point the queue is empty. Resume another thread to + suspend on an empty queue. */ + tx_thread_resume(&thread_1); + + /* Relinquish to get this thread suspended on the empty queue. */ + tx_thread_relinquish(); + + /* Resume thread 2 to get another thread suspended on the empty queue. */ + tx_thread_resume(&thread_2); + + /* Now send something to the front of the queue, which will resume + the first waiting thread. */ + temp[0] = 0xFF00002; + status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Now send something to the front of the queue, which will resume + the second waiting thread. */ + temp[0] = 0xFF00002; + status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Now relinquish again to let the other thread process the message. */ + tx_thread_relinquish(); + + /* At this point, the other thread should have placed 2 messages on the queue + so we will now send to the front, but without suspension. */ + temp[0] = 0xFF00003; + status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT); + + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Now, we will now send to the front, but with suspension. */ + temp[0] = 0xFF00003; + status = tx_queue_front_send(&queue_0, &temp[0], TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Now resume thread 2 to get another thread suspended on the queue. */ + tx_thread_resume(&thread_2); + + temp[0] = 0xFF00004; + status = tx_queue_front_send(&queue_0, &temp[0], TX_WAIT_FOREVER); + + /* When we get back, the other thread has received all the messages and + verified they are in order AND relinquished. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1)) + { + + /* Queue error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG source_message[2] = {0xEE000001, 0}; +ULONG dest_message[2]; + + + /* First, suspend on an empty queue. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER); + + /* Determine if the message is good. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00002)) + return; + + /* Now fill the queue with two messages. */ + status = tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER); + source_message[0]++; + status += tx_queue_front_send(&queue_0, &source_message[0], TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + return; + + /* Now let thread 0 send to the front of the queue with suspension. */ + tx_thread_relinquish(); + + /* Attempt to receive three messages from the queue. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00003)) + return; + + /* Attempt to receive three messages from the queue. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000002)) + return; + + /* Attempt to receive three messages from the queue. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000001)) + return; + + /* At this point, we are going to fill up the queue again. */ + source_message[0]++; + status = tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER); + source_message[0]++; + status += tx_queue_front_send(&queue_0, &source_message[0], TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + return; + + /* Now let thread 0 send to the front of the queue with suspension. */ + tx_thread_relinquish(); + + /* Attempt to receive four messages from the queue. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00004)) + return; + + /* Attempt to receive four messages from the queue. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xDD000001)) + return; + + /* Attempt to receive four messages from the queue. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000004)) + return; + + /* Attempt to receive three messages from the queue. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000003)) + return; + + /* Increment this threads counter. */ + thread_1_counter++; +} + + +static void thread_2_entry(ULONG thread_input) +{ + +ULONG source_message[2] = {0xDD000001, 0}; +ULONG destination_message[2]; + + + /* Receive message. */ + tx_queue_receive(&queue_0, &destination_message[0], TX_WAIT_FOREVER); + + /* Self suspend. */ + tx_thread_suspend(&thread_2); + + /* Send another message to the front of the queue. */ + tx_queue_front_send(&queue_0, &source_message[0], TX_WAIT_FOREVER); +} + + +static void thread_1a_entry(ULONG thread_input) +{ + +UINT status; +ULONG source_message[2] = {0xEE000001, 0}; +ULONG dest_message[2]; + + + /* First, suspend on an empty queue. */ + status = tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER); + + /* Determine if the message is good. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00002)) + return; + + /* Now fill the queue with two messages. */ + status = tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER); + source_message[0]++; + status += tx_queue_front_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + return; + + /* Now let thread 0 send to the front of the queue with suspension. */ + tx_thread_relinquish(); + + /* Attempt to receive three messages from the queue. */ + status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00003)) + return; + + /* Attempt to receive three messages from the queue. */ + status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000002)) + return; + + /* Attempt to receive three messages from the queue. */ + status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000001)) + return; + + /* At this point, we are going to fill up the queue again. */ + source_message[0]++; + status = tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER); + source_message[0]++; + status += tx_queue_front_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + return; + + /* Now let thread 0 send to the front of the queue with suspension. */ + tx_thread_relinquish(); + + /* Attempt to receive four messages from the queue. */ + status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00004)) + return; + + /* Attempt to receive four messages from the queue. */ + status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xDD000001)) + return; + + /* Attempt to receive four messages from the queue. */ + status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000004)) + return; + + /* Attempt to receive three messages from the queue. */ + status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT); + + /* Should be an error. */ + if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000003)) + return; + + /* Increment this threads counter. */ + thread_1a_counter++; +} + + +static void thread_2a_entry(ULONG thread_input) +{ + +ULONG source_message[2] = {0xDD000001, 0}; +ULONG destination_message[2]; + + + /* Receive message. */ + tx_queue_receive(&queue_0a, &destination_message[0], TX_WAIT_FOREVER); + + /* Self suspend. */ + tx_thread_suspend(&thread_2a); + + /* Send another message to the front of the queue. */ + tx_queue_front_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER); +} diff --git a/test/smp/regression/threadx_queue_full_suspension_test.c b/test/smp/regression/threadx_queue_full_suspension_test.c new file mode 100644 index 00000000..556a4c77 --- /dev/null +++ b/test/smp/regression/threadx_queue_full_suspension_test.c @@ -0,0 +1,368 @@ +/* This test is designed to test queue full suspension of queue that supports 3 messages + that are each 2 ULONG in size. */ + +#include +#include "tx_api.h" + +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static TX_QUEUE queue_0; + + +static unsigned long thread_1a_counter = 0; +static TX_THREAD thread_1a; + +static unsigned long thread_2a_counter = 0; +static TX_THREAD thread_2a; + +static TX_QUEUE queue_0a; + + +static ULONG queue_area[3]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_1a_entry(ULONG thread_input); +static void thread_2a_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void queue_notify(TX_QUEUE *queue_ptr) +{ + +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_full_suspension_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Full Suspension Test.................................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_create(&thread_1a, "thread 1a", thread_1a_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Full Suspension Test.................................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_create(&thread_2a, "thread 2a", thread_2a_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Full Suspension Test.................................. ERROR #3\n"); + test_control_return(1); + } + + /* Create the queue. */ + status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG)); + pointer = pointer + 3*2*sizeof(ULONG); + status += tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, pointer, 3*1*sizeof(ULONG)); + pointer = pointer + 3*1*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Full Suspension Test.................................. ERROR #4\n"); + test_control_return(1); + } + + /* Setup queue send notification. */ + status = tx_queue_send_notify(&queue_0, queue_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Full Suspension Test.................................. ERROR #5\n"); + test_control_return(1); + } +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Queue Full Suspension Test.................................. ERROR #6\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG source_message[2] = {0x12345678, 0}; +ULONG dest_message[2]; + + + /* Inform user. */ + printf("Running Queue Full Suspension Test.................................. "); + + /* Perform the one word queue version. */ + + /* Suspend to get thread 1a to pend on the queue. */ + tx_thread_suspend(&thread_0); + status = tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT); + tx_thread_suspend(&thread_0); + tx_thread_resume(&thread_1a); + tx_thread_resume(&thread_2a); + tx_queue_delete(&queue_0a); + status += tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, queue_area, sizeof(queue_area)); + + + /* Fill the queue with an initial 3 messages! */ + status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT); + status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT); + status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT); + source_message[0]++; + + /* Receive two of the messages back to put the first received message at the end + of the queue. */ + status += tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT); + status += tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT); + status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT); + source_message[0]++; + status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT); + source_message[0]++; + + /* Check status and run count of other thread. */ + if ((status != TX_SUCCESS) || (thread_1a_counter != 0)) + { + + /* Queue error. */ + printf("ERROR #6a\n"); + test_control_return(1); + } + + /* Send message that should cause this thread to suspend, until the + lower priority thread receives a message. */ + status = tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER); + + /* Check status and run count of other thread - it should have got the + message already even though its counter is still 0 (it was preempted + in the queue receive call. */ + if ((status != TX_SUCCESS) || (thread_1a_counter != 5) || (thread_2a_counter != 1)) + { + + /* Queue error. */ + printf("ERROR #7a\n"); + test_control_return(1); + } + + /* Perform the two word queue version. */ + + /* Reset the source message. */ + source_message[0] = 0x12345678; + source_message[1] = 0; + + /* Resume threads 1 and 2. */ + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + + /* Fill the queue with an initial 3 messages! */ + status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT); + status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT); + status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT); + source_message[0]++; + + /* Receive two of the messages back to put the first received message at the end + of the queue. */ + status += tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT); + status += tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT); + status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT); + source_message[0]++; + status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT); + source_message[0]++; + + /* Check status and run count of other thread. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 0)) + { + + /* Queue error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Send message that should cause this thread to suspend, until the + lower priority thread receives a message. */ + status = tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER); + + /* Check status and run count of other thread - it should have got the + message already even though its counter is still 0 (it was preempted + in the queue receive call. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 1)) + { + + /* Queue error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +ULONG expected_message[2] = {0x12345678, 0}; +ULONG dest_message[2]; +UINT old_priority; + + + /* Loop forever! */ + while(1) + { + + /* Receive messages and suspend. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER); + + if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++)) + break; + + /* Change thread 2 priority. */ + tx_thread_priority_change(&thread_2, 15, &old_priority); + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +ULONG source_message[2] = {0x1234567C, 0}; + + + /* Send one message to the queue. */ + tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER); + + /* Increment the thread counter. */ + thread_2_counter++; +} + + +static void thread_1a_entry(ULONG thread_input) +{ +UINT status; +ULONG expected_message[2] = {0x12345678, 0}; +ULONG dest_message[2]; +UINT old_priority; + + + /* Receive message and suspend. */ + status = tx_thread_resume(&thread_0); + status += tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER); + status += tx_thread_resume(&thread_0); + status += tx_thread_suspend(&thread_1a); + + if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0])) + return; + + /* Loop forever! */ + while(1) + { + + /* Receive messages and suspend. */ + status = tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER); + + if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++)) + break; + + /* Change thread 2a priority. */ + tx_thread_priority_change(&thread_2a, 15, &old_priority); + + /* Increment the thread counter. */ + thread_1a_counter++; + } +} + + +static void thread_2a_entry(ULONG thread_input) +{ + +ULONG source_message[2] = {0x1234567C, 0}; + + + /* Send one message to the queue. */ + tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER); + + /* Increment the thread counter. */ + thread_2a_counter++; +} diff --git a/test/smp/regression/threadx_queue_information_test.c b/test/smp/regression/threadx_queue_information_test.c new file mode 100644 index 00000000..c1db82ca --- /dev/null +++ b/test/smp/regression/threadx_queue_information_test.c @@ -0,0 +1,664 @@ +/* This test is designed to test the queue information services. */ + +#include +#include "tx_api.h" +#include "tx_queue.h" + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static TX_QUEUE queue_0; +static TX_QUEUE queue_1; +static TX_QUEUE queue_2; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +UINT _tx_queue_performance_info_get(TX_QUEUE *queue_ptr, ULONG *messages_sent, ULONG *messages_received, + ULONG *empty_suspensions, ULONG *full_suspensions, ULONG *full_errors, ULONG *timeouts); + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_information_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Information Test...................................... ERROR #1\n"); + test_control_return(1); + } + + /* Create the queues. */ + status = tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, sizeof(ULONG)); + pointer = pointer + sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Information Test...................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_queue_create(&queue_1, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG)); + pointer = pointer + 3*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Information Test...................................... ERROR #3\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG source_message = 0x12345678UL; +ULONG dest_message; +ULONG expected_message; +CHAR *name; +ULONG enqueued; +ULONG available_storage; +TX_THREAD *first_suspended; +ULONG suspended_count; +TX_QUEUE *next_queue; +ULONG messages_sent; +ULONG messages_received; +ULONG empty_suspensions; +ULONG full_suspensions; +ULONG full_errors; +ULONG timeouts; + + + /* Inform user. */ + printf("Running Queue Information Test...................................... "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Attempt to get info from a non-queue. */ + status = tx_queue_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #\n"); + test_control_return(1); + } + + /* Attempt to get info from a non-created queue. */ + queue_2.tx_queue_id = 0; + status = tx_queue_info_get(&queue_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #4\n"); + test_control_return(1); + } +#endif + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message != dest_message)) + { + + /* Queue error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + source_message++; + + /* Place something on queue 0. */ + status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT); + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 0. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (source_message != dest_message)) + { + + /* Queue error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Now we need to do the same thing with the queue with three entries. */ + + source_message++; + expected_message = source_message; + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + source_message++; + status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + source_message++; + status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + source_message++; + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message++ != dest_message)) + { + + /* Queue error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message++ != dest_message)) + { + + /* Queue error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message++ != dest_message)) + { + + /* Queue error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Make sure we can do the same thing again! */ + + /* Place something on queue 1. */ + status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + source_message++; + status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + source_message++; + status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + source_message++; + + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Attempt to place something on a full queue. */ + status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_FULL) + { + + /* Queue error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message++ != dest_message)) + { + + /* Queue error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message++ != dest_message)) + { + + /* Queue error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Attempt to receive something from queue 1. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be successful and dest_message should equal source. */ + if ((status != TX_SUCCESS) || (expected_message++ != dest_message)) + { + + /* Queue error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Attempt to receive something from an empty queue. */ + status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT); + + /* Should be an error. */ + if (status != TX_QUEUE_EMPTY) + { + + /* Queue error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Get queue information. */ + status = tx_queue_info_get(&queue_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_queue_info_get(&queue_0, &name, &enqueued, &available_storage, &first_suspended, &suspended_count, &next_queue); + + /* Check for errors. */ + if ((status != TX_SUCCESS) || (enqueued != queue_0.tx_queue_enqueued) || (available_storage != queue_0.tx_queue_available_storage) || + (first_suspended != queue_0.tx_queue_suspension_list) || (suspended_count != queue_0.tx_queue_suspended_count) || + (next_queue != queue_0.tx_queue_created_next)) + { + + /* Queue error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + +#ifdef TX_QUEUE_ENABLE_PERFORMANCE_INFO + + /* Test null pointer for queue performance info get. */ + status = _tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Should be an error! */ + if (status != TX_PTR_ERROR) + { + + /* Queue error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Get performance information. */ + status = tx_queue_performance_info_get(&queue_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_queue_performance_info_get(&queue_0, &messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts); + + /* Check for errors. */ + if ((status != TX_SUCCESS) || (messages_sent != queue_0.tx_queue_performance_messages_sent_count) || (messages_received != queue_0.tx_queue_performance_messages_received_count) || + (empty_suspensions != queue_0.tx_queue_performance_empty_suspension_count) || (full_suspensions != queue_0.tx_queue_performance_full_suspension_count) || + (full_errors != queue_0.tx_queue_performance_full_error_count) || (timeouts != queue_0.tx_queue_performance_timeout_count)) + { + + /* Queue error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Get system performance information. */ + status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_queue_performance_system_info_get(&messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts); + + /* Check for errors. */ + if ((status != TX_SUCCESS) || (messages_sent != _tx_queue_performance_messages_sent_count) || (messages_received != _tx_queue_performance__messages_received_count) || + (empty_suspensions != _tx_queue_performance_empty_suspension_count) || (full_suspensions != _tx_queue_performance_full_suspension_count) || + (full_errors != _tx_queue_performance_full_error_count) || (timeouts != _tx_queue_performance_timeout_count)) + { + + /* Queue error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + +#else + + /* Get performance information. */ + status = tx_queue_performance_info_get(&queue_0, &messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + + /* Get performance information. */ + status = tx_queue_performance_info_get(TX_NULL, &messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #30\n"); + test_control_return(1); + } + + /* Get performance information. */ + status = tx_queue_performance_info_get(TX_NULL, TX_NULL, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #31\n"); + test_control_return(1); + } + + /* Get performance information. */ + status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &empty_suspensions, &full_suspensions, &full_errors, &timeouts); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #32\n"); + test_control_return(1); + } + + /* Get performance information. */ + status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &full_suspensions, &full_errors, &timeouts); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #33\n"); + test_control_return(1); + } + + /* Get performance information. */ + status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &full_errors, &timeouts); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #34\n"); + test_control_return(1); + } + + /* Get performance information. */ + status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #35\n"); + test_control_return(1); + } + + /* Get performance information. */ + status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #36\n"); + test_control_return(1); + } + + /* Get system performance information. */ + status = tx_queue_performance_system_info_get(&messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #37\n"); + test_control_return(1); + } + + /* Get system performance information. */ + status = tx_queue_performance_system_info_get(TX_NULL, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #38\n"); + test_control_return(1); + } + + /* Get system performance information. */ + status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, &empty_suspensions, &full_suspensions, &full_errors, &timeouts); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #39\n"); + test_control_return(1); + } + + /* Get system performance information. */ + status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &full_suspensions, &full_errors, &timeouts); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #40\n"); + test_control_return(1); + } + + /* Get system performance information. */ + status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &full_errors, &timeouts); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #41\n"); + test_control_return(1); + } + + /* Get system performance information. */ + status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #42\n"); + test_control_return(1); + } + + /* Get system performance information. */ + status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Should be an error! */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Queue error. */ + printf("ERROR #43\n"); + test_control_return(1); + } + +#endif + + /* Delete the queues. */ + status = tx_queue_delete(&queue_1); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #44\n"); + test_control_return(1); + } + + status = tx_queue_delete(&queue_0); + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #45\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} diff --git a/test/smp/regression/threadx_queue_prioritize.c b/test/smp/regression/threadx_queue_prioritize.c new file mode 100644 index 00000000..7a9d2b44 --- /dev/null +++ b/test/smp/regression/threadx_queue_prioritize.c @@ -0,0 +1,534 @@ +/* This test is designed to test queue prioritize. */ + +#include +#include "tx_api.h" + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Define the external reference for the preempt disable flag. */ + +extern volatile UINT _tx_thread_preempt_disable; + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static TX_THREAD thread_2; + +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + +static unsigned long thread_5_counter = 0; +static TX_THREAD thread_5; + +static unsigned long thread_6_counter = 0; +static TX_THREAD thread_6; + +static TX_QUEUE queue_0; +static TX_QUEUE queue_1; + + +static int test_status; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); +static void thread_6_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void queue_notify(TX_QUEUE *queue_ptr) +{ + +} + + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + + /* Determine if the test case we are looking for is present. */ + if ((_tx_thread_preempt_disable) && (test_status == 1)) + { + + /* Determine if thread 3 is at the front of the suspension list. */ + if (queue_0.tx_queue_suspension_list == &thread_3) + { + + /* Abort the wait of thread 3. */ + tx_thread_wait_abort(&thread_3); + } + else + { + + /* Abort the wait of thread 5. */ + tx_thread_wait_abort(&thread_5); + + /* End the ISR processing. */ + test_status = 2; + test_isr_dispatch = TX_NULL; + } + } +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_prioritize_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Prioritize Test....................................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Prioritize Test....................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Prioritize Test....................................... ERROR #3\n"); + test_control_return(1); + } + + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 3, 3, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Prioritize Test....................................... ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 4, 4, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Prioritize Test....................................... ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, TEST_STACK_SIZE_PRINTF, + 5, 5, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Prioritize Test....................................... ERROR #6\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6, + pointer, TEST_STACK_SIZE_PRINTF, + 6, 6, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Prioritize Test....................................... ERROR #7\n"); + test_control_return(1); + } + + /* Create the queue. */ + status = tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, 3*2*sizeof(ULONG)); + pointer = pointer + 3*2*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Prioritize Test....................................... ERROR #8\n"); + test_control_return(1); + } + + /* Setup queue send notification. */ + status = tx_queue_send_notify(&queue_0, queue_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Prioritize Test....................................... ERROR #9\n"); + test_control_return(1); + } +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Queue Prioritize Test....................................... ERROR #10\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Queue Prioritize Test....................................... "); + + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Attempt to prioritize a non-queue. */ + status = tx_queue_prioritize(TX_NULL); + + /* Check for an error condition. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Attempt to prioritize a non-created queue. */ + queue_1.tx_queue_id = 0; + status = tx_queue_prioritize(&queue_1); + + /* Check for an error condition. */ + if (status != TX_QUEUE_ERROR) + { + + /* Queue error. */ + printf("ERROR #12\n"); + test_control_return(1); + } +#endif + + /* Nothing to do here, but check prioritization with no suspended threads. */ + status = tx_queue_prioritize(&queue_0); + + /* Check for an error condition. */ + if (status != TX_SUCCESS) + { + + /* Queue error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Make sure thread 1 and 2 are suspended on the queue. */ + if ((thread_1.tx_thread_state != TX_QUEUE_SUSP) || (thread_2.tx_thread_state != TX_QUEUE_SUSP) || + (queue_0.tx_queue_suspension_list != &thread_1)) + { + + /* Queue error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Prioritize the queue suspension list. */ + status = tx_queue_prioritize(&queue_0); + + /* Check status and make sure thread 2 is not at the head of the list. */ + if ((status != TX_SUCCESS) || (queue_0.tx_queue_suspension_list != &thread_2)) + { + + /* Queue error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Prioritize the queue suspension list again, but slightly different path because it was previously prioritized. */ + status = tx_queue_prioritize(&queue_0); + + /* Check status and make sure thread 2 not at the head of the list. */ + if ((status != TX_SUCCESS) || (queue_0.tx_queue_suspension_list != &thread_2)) + { + + /* Queue error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* At this point we are going to get more than 2 threads suspended. */ + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + tx_thread_resume(&thread_3); + tx_thread_resume(&thread_4); + tx_thread_resume(&thread_5); + tx_thread_resume(&thread_6); + + /* Prioritize the queue suspension list. */ + status = tx_queue_prioritize(&queue_0); + + /* Check status and make sure thread 3 is at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (queue_0.tx_queue_suspension_list != &thread_3)) + { + + /* Queue error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Now loop to test the interrupt of the prioritize loop logic. */ + test_status = 1; + test_isr_dispatch = test_isr; + do + { + + /* Prioritize the queue suspension list. */ + status = tx_queue_prioritize(&queue_0); + + /* Check status and make sure thread 1 is terminated. */ + if (status != TX_SUCCESS) + { + + /* Block Pool error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + } while (test_status == 1); + + /* Now determine if thread 4 is at the front of the list... It should be! */ + if (queue_0.tx_queue_suspension_list != &thread_4) + { + + /* Queue error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +ULONG dest_message; + + + /* Loop forever! */ + while(1) + { + + + /* Receive message from empty queue. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER); + + if (status != TX_QUEUE_EMPTY) + break; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ +UINT status; +ULONG dest_message; + + + /* Loop forever! */ + while(1) + { + + + /* Receive message from empty queue. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER); + + if (status != TX_QUEUE_EMPTY) + break; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + + +static void thread_3_entry(ULONG thread_input) +{ +UINT status; +ULONG dest_message; + + + /* Loop forever! */ + while(1) + { + + + /* Receive message from empty queue. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER); + + if (status != TX_QUEUE_EMPTY) + break; + + /* Increment the thread counter. */ + thread_3_counter++; + } +} + + +static void thread_4_entry(ULONG thread_input) +{ +UINT status; +ULONG dest_message; + + + /* Loop forever! */ + while(1) + { + + + /* Receive message from empty queue. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER); + + if (status != TX_QUEUE_EMPTY) + break; + + /* Increment the thread counter. */ + thread_4_counter++; + } +} + + +static void thread_5_entry(ULONG thread_input) +{ +UINT status; +ULONG dest_message; + + + /* Loop forever! */ + while(1) + { + + + /* Receive message from empty queue. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER); + + if (status != TX_QUEUE_EMPTY) + break; + + /* Increment the thread counter. */ + thread_5_counter++; + } +} + + +static void thread_6_entry(ULONG thread_input) +{ +UINT status; +ULONG dest_message; + + + /* Loop forever! */ + while(1) + { + + + /* Receive message from empty queue. */ + status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER); + + if (status != TX_QUEUE_EMPTY) + break; + + /* Increment the thread counter. */ + thread_6_counter++; + } +} + + diff --git a/test/smp/regression/threadx_queue_suspension_timeout_test.c b/test/smp/regression/threadx_queue_suspension_timeout_test.c new file mode 100644 index 00000000..a3c390ed --- /dev/null +++ b/test/smp/regression/threadx_queue_suspension_timeout_test.c @@ -0,0 +1,254 @@ +/* This test is designed to test queue full and empty suspension with timeouts on queues + that supports 3 messages that are each 2 ULONG in size. */ + +#include +#include "tx_api.h" + +//static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; + +static TX_THREAD thread_1; + +static TX_THREAD thread_2; +static unsigned long thread_2_counter = 0; + +static TX_QUEUE queue_0; +static TX_QUEUE queue_1; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void queue_notify(TX_QUEUE *queue_ptr) +{ + +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_suspension_timeout_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Suspension Timeout Test............................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Suspension Timeout Test............................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Suspension Timeout Test............................... ERROR #3\n"); + test_control_return(1); + } + + /* Create the queues. */ + status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG)); + pointer = pointer + 3*2*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Suspension Timeout Test............................... ERROR #4\n"); + test_control_return(1); + } + + status = tx_queue_create(&queue_1, "queue 1", TX_2_ULONG, pointer, 3*2*sizeof(ULONG)); + pointer = pointer + 3*2*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Suspension Timeout Test............................... ERROR #5\n"); + test_control_return(1); + } + + /* Setup queue send notification. */ + status = tx_queue_send_notify(&queue_0, queue_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Suspension Timeout Test............................... ERROR #6\n"); + test_control_return(1); + } +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Queue Suspension Timeout Test............................... ERROR #7\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG source_message[2] = {0x12345678, 0}; + + + /* Inform user. */ + printf("Running Queue Suspension Timeout Test............................... "); + + /* Fill the queue with an initial 3 messages! */ + status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT); + source_message[0]++; + status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT); + source_message[0]++; + status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT); + source_message[0]++; + + /* Check status and run count of other thread. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 0)) + { + + /* Queue error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Send message to the front of the queue that should cause this thread to suspend. The timeout + should cause it to resume with a TX_QUEUE_FULL error code. */ + status = tx_queue_front_send(&queue_0, &source_message[0], 3); + + if ((status != TX_QUEUE_FULL) || (thread_1_counter != 0) || (thread_2_counter != 0)) + { + + /* Queue error. */ + printf("ERROR #9a\n"); + test_control_return(1); + } + + /* Send message that should cause this thread to suspend. The timeout + should cause it to resume with a TX_QUEUE_FULL error code. */ + status = tx_queue_send(&queue_0, &source_message[0], 32); + + if ((status != TX_QUEUE_FULL) || (thread_1_counter != 1) || (thread_2_counter != 1)) + { + + /* Queue error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +ULONG dest_message[2]; + + + /* Loop forever! */ + while(1) + { + + + /* Receive message from empty queue with suspension and timeout. + We should wakeup after the timeout expires with an empty status. */ + status = tx_queue_receive(&queue_1, &dest_message[0], 20); + + if (status != TX_QUEUE_EMPTY) + break; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ +UINT status; +ULONG dest_message[2]; + + + /* Loop forever! */ + while(1) + { + + + /* Receive message from empty queue with suspension and timeout. + We should wakeup after the timeout expires with an empty status. */ + status = tx_queue_receive(&queue_1, &dest_message[0], 20); + + if (status != TX_QUEUE_EMPTY) + break; + + /* Increment the thread counter. */ + thread_2_counter++; + } +} diff --git a/test/smp/regression/threadx_queue_thread_terminate_test.c b/test/smp/regression/threadx_queue_thread_terminate_test.c new file mode 100644 index 00000000..d0834704 --- /dev/null +++ b/test/smp/regression/threadx_queue_thread_terminate_test.c @@ -0,0 +1,183 @@ +/* This test is designed to test thread terminate when the terminated thread is suspeded + on a queue. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static TX_QUEUE queue_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +static void queue_notify(TX_QUEUE *queue_ptr) +{ + +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_queue_thread_terminate_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Thread Terminate Test................................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Thread Terminate Test................................. ERROR #2\n"); + test_control_return(1); + } + + /* Create the queue. */ + status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG)); + pointer = pointer + 3*2*sizeof(ULONG); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Thread Terminate Test................................. ERROR #3\n"); + test_control_return(1); + } + + /* Setup queue send notification. */ + status = tx_queue_send_notify(&queue_0, queue_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Queue Thread Terminate Test................................. ERROR #4\n"); + test_control_return(1); + } +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Queue Thread Terminate Test................................. ERROR #5\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Queue Thread Terminate Test................................. "); + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Make sure thread 1 is suspended on the queue. */ + if (thread_1.tx_thread_state != TX_QUEUE_SUSP) + { + + /* Queue error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Terminate thread 1 which is suspended on queue 0. */ + status = tx_thread_terminate(&thread_1); + + /* Check status and make sure thread 1 is terminated. */ + if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_TERMINATED) || + (thread_1_counter != 0) || (queue_0.tx_queue_suspended_count)) + { + + /* Queue error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +ULONG dest_message[2]; + + + /* Loop forever! */ + while(1) + { + + + /* Receive message from empty queue. */ + status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER); + + if (status != TX_QUEUE_EMPTY) + break; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + diff --git a/test/smp/regression/threadx_semaphore_basic_test.c b/test/smp/regression/threadx_semaphore_basic_test.c new file mode 100644 index 00000000..f554257d --- /dev/null +++ b/test/smp/regression/threadx_semaphore_basic_test.c @@ -0,0 +1,545 @@ +/* This test is designed to test the semaphore create/delete and immediate return gets and puts. */ + +#include +#include "tx_api.h" + + +typedef struct SEMAPHORE_MEMORY_TEST_STRUCT +{ + ULONG first; + ULONG second; + TX_SEMAPHORE semaphore; + ULONG next_to_last; + ULONG last; + +} SEMAPHORE_MEMORY_TEST; + +static SEMAPHORE_MEMORY_TEST semaphore_memory; + + +/* Define the external symbol to obtain the status from a create call in initialization. */ + +extern UINT test_semaphore_from_init; + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static TX_THREAD thread_1; + + +static TX_TIMER timer_0; + + +static unsigned long error = 0; +static unsigned long timer_executed = 0; +static unsigned long isr_executed = 0; + + +static TX_SEMAPHORE semaphore_0; +static TX_SEMAPHORE semaphore_1; +static TX_SEMAPHORE semaphore_2; +static TX_SEMAPHORE semaphore_3; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +UINT _txe_semaphore_create(TX_SEMAPHORE *semaphore_ptr, CHAR *name_ptr, ULONG initial_count, UINT semaphore_control_block_size); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define the timer for this test. */ + +static void timer_entry(ULONG i) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +UINT status; + + + /* Determine if calling semaphore create from initialization was successful. */ + if (test_semaphore_from_init != TX_SUCCESS) + { + + /* Error! */ + error++; + } + + /* Attempt to create a semaphore from a timer. */ + status = tx_semaphore_create(&semaphore_2, "semaphore 2", 1); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to delete a semaphore from a timer. */ + status = tx_semaphore_delete(&semaphore_0); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to get a semaphore with suspension from a timer. */ + status = tx_semaphore_get(&semaphore_0, 100); + + /* Check for status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + + timer_executed = 1; +#endif +} + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +UINT status; + + + /* Attempt to create a semaphore from an ISR. */ + status = tx_semaphore_create(&semaphore_2, "semaphore 2", 1); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to delete a semaphore from an ISR. */ + status = tx_semaphore_delete(&semaphore_0); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to get a semaphore with suspension from an ISR. */ + status = tx_semaphore_get(&semaphore_0, 100); + + /* Check for status. */ + if (status != TX_WAIT_ERROR) + { + + /* Error! */ + error++; + } + + isr_executed = 1; +#endif +} + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_semaphore_basic_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Basic Test........................................ ERROR #1\n"); + test_control_return(1); + } + + /* Create a semaphore with an initial count of 1. */ + status = tx_semaphore_create(&semaphore_0, "semaphore 0", 1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Basic Test........................................ ERROR #2\n"); + test_control_return(1); + } + + /* Create a semaphore with an initial count of 0. */ + status = tx_semaphore_create(&semaphore_1, "semaphore 1", 1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Basic Test........................................ ERROR #3\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Inform user. */ + printf("Running Semaphore Basic Test........................................ "); + + /* Perform semaphore memory test. */ + semaphore_memory.first = 0x11223344; + semaphore_memory.second = 0x55667788; + semaphore_memory.next_to_last = 0x99aabbcc; + semaphore_memory.last = 0xddeeff00; + + /* Create the semaphore. */ + status = tx_semaphore_create(&semaphore_memory.semaphore, "semaphore memory", 0); + tx_semaphore_delete(&semaphore_memory.semaphore); + + /* Check for status. */ + if ((status != TX_SUCCESS) || + (semaphore_memory.first != 0x11223344) || + (semaphore_memory.second != 0x55667788) || + (semaphore_memory.next_to_last != 0x99aabbcc) || + (semaphore_memory.last != 0xddeeff00)) + { + + /* Semaphore error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Increment thread 0 counter. */ + thread_0_counter++; + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Attempt to create a non-semaphore. */ + status = tx_semaphore_create(TX_NULL, "semaphore 0", 1); + + /* Check for status. */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Attempt to create a semaphore with a bad sized block. */ + status = _txe_semaphore_create(&semaphore_3, "semaphore 3", 1, (sizeof(TX_SEMAPHORE)+1)); + + /* Check for status. */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Attempt to create an already created semaphore. */ + status = tx_semaphore_create(&semaphore_0, "semaphore 0", 1); + + /* Check for status. */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Attempt to delete a non-semaphore. */ + status = tx_semaphore_delete(TX_NULL); + + /* Check for status. */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Attempt to delete a non-created semaphore. */ + semaphore_2.tx_semaphore_id = 0; + status = tx_semaphore_delete(&semaphore_2); + + /* Check for status. */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to get a non-semaphore. */ + status = tx_semaphore_get(TX_NULL, TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Attempt to get a non-created semaphore. */ + semaphore_2.tx_semaphore_id = 0; + status = tx_semaphore_get(&semaphore_2, TX_NO_WAIT); + + /* Check for status. */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Attempt to put a non-semaphore. */ + status = tx_semaphore_put(TX_NULL); + + /* Check for status. */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Attempt to put a non-created semaphore. */ + semaphore_2.tx_semaphore_id = 0; + status = tx_semaphore_put(&semaphore_2); + + /* Check for status. */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Attempt to ceiling put a non-semaphore. */ + status = tx_semaphore_ceiling_put(TX_NULL, 0); + + /* Check for status. */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Attempt to ceiling put a non-created semaphore. */ + semaphore_2.tx_semaphore_id = 0; + status = tx_semaphore_ceiling_put(&semaphore_2, 0); + + /* Check for status. */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Attempt to ceiling put with an invalid ceiling of 0. */ + status = tx_semaphore_ceiling_put(&semaphore_0, 0); + + /* Check for status. */ + if (status != TX_INVALID_CEILING) + { + + /* Semaphore error. */ + printf("ERROR #16\n"); + test_control_return(1); + } +#endif + + /* Attempt to get from semaphore with an instance. Should be successful! */ + status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Semaphore error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Attempt to get from semaphore without an instance. Should be unsuccessful. */ + status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_NO_INSTANCE) + { + + /* Semaphore error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Put to semaphore that has an instance already. Should now be 2! */ + status = tx_semaphore_put(&semaphore_1); + + /* Check status. */ + if ((status != TX_SUCCESS) || (semaphore_1.tx_semaphore_count != 2)) + { + + /* Semaphore error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + + /* Attempt to get from semaphore with an instance. Should be successful! */ + status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Semaphore error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Attempt to get from semaphore with an instance. Should be successful. */ + status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Semaphore error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Create a timer for the test. */ + tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE); + + /* Setup the ISR. */ + test_isr_dispatch = test_isr; + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Resume the thread 1 so we can take an interrupt on top of it. */ + tx_thread_resume(&thread_1); + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Clear the ISR. */ + test_isr_dispatch = TX_NULL; + + /* Test for error. */ + if ((error) || (timer_executed != 1) || (isr_executed != 1)) + { + + /* Semaphore error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + +#endif + + /* Delete semaphores. */ + status = tx_semaphore_delete(&semaphore_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Semaphore error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + status = tx_semaphore_delete(&semaphore_1); + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Semaphore error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + } +} \ No newline at end of file diff --git a/test/smp/regression/threadx_semaphore_ceiling_put_test.c b/test/smp/regression/threadx_semaphore_ceiling_put_test.c new file mode 100644 index 00000000..5364d2d9 --- /dev/null +++ b/test/smp/regression/threadx_semaphore_ceiling_put_test.c @@ -0,0 +1,334 @@ +/* This test is designed to test the semaphore ceiling put. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + + +static TX_SEMAPHORE semaphore_0; +static TX_SEMAPHORE semaphore_1; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void put_notify(TX_SEMAPHORE *semaphore_ptr) +{ + + /* Don't need to do anything in here... */ +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_semaphore_ceiling_put_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Ceiling Put Test.................................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Ceiling Put Test.................................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Ceiling Put Test.................................. ERROR #3\n"); + test_control_return(1); + } + + /* Create a semaphore with an initial count of 0. */ + status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0); + status += tx_semaphore_create(&semaphore_1, "semaphore 1", 0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Ceiling Put Test.................................. ERROR #4\n"); + test_control_return(1); + } + + /* Setup the semaphore notify callback. */ + status = tx_semaphore_put_notify(&semaphore_0, put_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Ceiling Put Test.................................. ERROR #5\n"); + test_control_return(1); + } + +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Semaphore Ceiling Put Test.................................. ERROR #6\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Semaphore Ceiling Put Test.................................. "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Perform semaphore puts in order to exercise the ceiling put logic. */ + status = tx_semaphore_ceiling_put(&semaphore_0, 2); + status += tx_semaphore_ceiling_put(&semaphore_0, 2); + status += tx_semaphore_ceiling_put(&semaphore_0, 2); + status += tx_semaphore_get(&semaphore_0, TX_NO_WAIT); + status += tx_semaphore_get(&semaphore_0, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_CEILING_EXCEEDED) + { + + /* Semaphore error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Relinquish to make the other thread suspend on the semaphore. */ + tx_thread_relinquish(); + + /* Make sure the other thread has run. */ + if (thread_1_counter != 1) + { + + /* Semaphore error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Place an instance on the semaphore, this should resume the other thread + but not preempt this thread. */ + status = tx_semaphore_ceiling_put(&semaphore_0, 2); + + /* Check the status and the run counter of the other thread. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1)) + { + + /* Semaphore error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Relinquish to allow the other thread to run. */ + tx_thread_relinquish(); + + /* Make sure the other thread has run. */ + if (thread_1_counter != 3) + { + + /* Semaphore error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* At this point, we need to resume thread 2 and relinquish in order to get that thread suspended on the + semaphore as well. */ + tx_thread_resume(&thread_2); + tx_thread_relinquish(); + + /* Perform 2 semaphore put operations to resume both threads. */ + status = tx_semaphore_ceiling_put(&semaphore_0, 2); + status += tx_semaphore_ceiling_put(&semaphore_0, 2); + + /* Let both threads run again. */ + tx_thread_relinquish(); + + /* Check the status and the run counter of the other thread. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 3)) + { + + /* Semaphore error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Now turn off the semaphore notification. */ + status = tx_semaphore_put_notify(&semaphore_0, TX_NULL); + +#ifdef TX_DISABLE_NOTIFY_CALLBACKS + + /* Clear the status since we know this feature is disabled and will return an error. */ + status = TX_SUCCESS; +#endif + + /* Put a semaphore on a semaphore that does not have suspension. */ + status += tx_semaphore_ceiling_put(&semaphore_1, 2); + + /* Repeat the semaphore ceiling put without notification process! */ + + /* Place an instance on the semaphore, this should resume the other thread + but not preempt this thread. */ + status += tx_semaphore_ceiling_put(&semaphore_0, 2); + + /* Check the status and the run counter of the other thread. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 5)) + { + + /* Semaphore error. */ + printf("ERROR #9a\n"); + test_control_return(1); + } + + /* Relinquish to allow the other thread to run. */ + tx_thread_relinquish(); + + /* Make sure the other thread has run. */ + if (thread_1_counter != 7) + { + + /* Semaphore error. */ + printf("ERROR #10a\n"); + test_control_return(1); + } + + /* At this point, we need to resume thread 2 and relinquish in order to get that thread suspended on the + semaphore as well. */ + tx_thread_resume(&thread_2); + tx_thread_relinquish(); + + /* Perform 2 semaphore put operations to resume both threads. */ + status = tx_semaphore_ceiling_put(&semaphore_0, 2); + status += tx_semaphore_ceiling_put(&semaphore_0, 2); + + /* Let both threads run again. */ + tx_thread_relinquish(); + + /* Check the status and the run counter of the other thread. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 9) || (thread_2_counter != 5)) + { + + /* Semaphore error. */ + printf("ERROR #11a\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + while(1) + { + + /* Increment thread run counter. */ + thread_1_counter++; + + /* Suspend on the semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; + + while(1) + { + + /* Increment thread run counter. */ + thread_2_counter++; + + /* Suspend on the semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_2_counter++; + } +} diff --git a/test/smp/regression/threadx_semaphore_delete_test.c b/test/smp/regression/threadx_semaphore_delete_test.c new file mode 100644 index 00000000..f18d31dc --- /dev/null +++ b/test/smp/regression/threadx_semaphore_delete_test.c @@ -0,0 +1,213 @@ +/* This test is designed to test the semaphore suspension and semaphore delete with + suspended threads. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + + +static TX_SEMAPHORE semaphore_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void put_notify(TX_SEMAPHORE *semaphore_ptr) +{ + + /* Don't need to do anything in here... */ +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_semaphore_delete_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Delete Test....................................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Delete Test....................................... ERROR #2!\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Delete Test....................................... ERROR #3\n"); + test_control_return(1); + } + + /* Create a semaphore with an initial count of 0. */ + status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Delete Test....................................... ERROR #4\n"); + test_control_return(1); + } + + /* Setup the semaphore notify callback. */ + status = tx_semaphore_put_notify(&semaphore_0, put_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Delete Test....................................... ERROR #5\n"); + test_control_return(1); + } +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Semaphore Delete Test....................................... ERROR #6\n"); + test_control_return(1); + } + +#endif +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Semaphore Delete Test....................................... "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Relinquish to let other threads run. */ + tx_thread_relinquish(); + + /* Other threads should now be suspended on the semaphore. */ + + /* Delete the semaphore to test it out! */ + status = tx_semaphore_delete(&semaphore_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Semaphore error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Relinquish to allow other threads to run again before we return. */ + tx_thread_relinquish(); + + /* Now check the run counter of each thread. */ + if ((thread_1_counter != 1) || (thread_2_counter != 1)) + { + + /* Semaphore error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + + /* Suspend on the semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + /* Did we get the right status? */ + if (status == TX_DELETED) + thread_1_counter++; +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; + + + /* Suspend on the semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + /* Did we get the right status? */ + if (status == TX_DELETED) + thread_2_counter++; +} diff --git a/test/smp/regression/threadx_semaphore_information_test.c b/test/smp/regression/threadx_semaphore_information_test.c new file mode 100644 index 00000000..a8f6d242 --- /dev/null +++ b/test/smp/regression/threadx_semaphore_information_test.c @@ -0,0 +1,418 @@ +/* This test is designed to test the semaphore information services. */ + +#include +#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, ¤t_value, &first_suspended, &suspended_count, &next_semaphore); + + /* Check status. */ + if ((status != TX_SUCCESS) || (current_value != semaphore_0.tx_semaphore_count) || + (first_suspended != semaphore_0.tx_semaphore_suspension_list) || (suspended_count != semaphore_0.tx_semaphore_suspended_count) || + (next_semaphore != semaphore_0.tx_semaphore_created_next)) + { + + /* Semaphore error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + +#ifdef TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO + + /* Get semaphore performance information with NULL pointer. */ + status = _tx_semaphore_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for error. */ + if (status != TX_PTR_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Get semaphore performance information. */ + status = tx_semaphore_performance_info_get(&semaphore_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_semaphore_performance_info_get(&semaphore_0, &puts, &gets, &suspensions, &timeouts); + + /* Check status. */ + if ((status != TX_SUCCESS) || (puts != semaphore_0.tx_semaphore_performance_put_count) || (gets != semaphore_0.tx_semaphore_performance_get_count) || + (suspensions != semaphore_0.tx_semaphore_performance_suspension_count) || (timeouts != semaphore_0.tx_semaphore_performance_timeout_count)) + { + + /* Semaphore error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Get semaphore system performance information. */ + status = tx_semaphore_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_semaphore_performance_system_info_get(&puts, &gets, &suspensions, &timeouts); + + /* Check status. */ + if ((status != TX_SUCCESS) || (puts != _tx_semaphore_performance_put_count) || (gets != _tx_semaphore_performance_get_count) || + (suspensions != _tx_semaphore_performance_suspension_count) || (timeouts != _tx_semaphore_performance_timeout_count)) + { + + /* Semaphore error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + +#else + + /* Get semaphore performance information. */ + status = tx_semaphore_performance_info_get(&semaphore_0, &puts, &gets, &suspensions, &timeouts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Semaphore error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Get semaphore performance information. */ + status = tx_semaphore_performance_info_get(TX_NULL, &puts, &gets, &suspensions, &timeouts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Semaphore error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Get semaphore performance information. */ + status = tx_semaphore_performance_info_get(TX_NULL, TX_NULL, &gets, &suspensions, &timeouts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Semaphore error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Get semaphore performance information. */ + status = tx_semaphore_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Semaphore error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Get semaphore performance information. */ + status = tx_semaphore_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Semaphore error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Get semaphore performance information. */ + status = tx_semaphore_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Semaphore error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Get semaphore system performance information. */ + status = tx_semaphore_performance_system_info_get(&puts, &gets, &suspensions, &timeouts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Semaphore error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + /* Get semaphore system performance information. */ + status = tx_semaphore_performance_system_info_get(TX_NULL, &gets, &suspensions, &timeouts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Semaphore error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Get semaphore system performance information. */ + status = tx_semaphore_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Semaphore error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Get semaphore system performance information. */ + status = tx_semaphore_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Semaphore error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Get semaphore system performance information. */ + status = tx_semaphore_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Semaphore error. */ + printf("ERROR #25\n"); + test_control_return(1); + } +#endif + + /* Delete semaphores. */ + status = tx_semaphore_delete(&semaphore_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Semaphore error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + status = tx_semaphore_delete(&semaphore_1); + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Semaphore error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} diff --git a/test/smp/regression/threadx_semaphore_non_preemption_test.c b/test/smp/regression/threadx_semaphore_non_preemption_test.c new file mode 100644 index 00000000..40219546 --- /dev/null +++ b/test/smp/regression/threadx_semaphore_non_preemption_test.c @@ -0,0 +1,271 @@ +/* This test is designed to test the semaphore suspension and another thread resuming the + same priority thread by doing a semaphore put. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + + +static TX_SEMAPHORE semaphore_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void put_notify(TX_SEMAPHORE *semaphore_ptr) +{ + + /* Don't need to do anything in here... */ +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_semaphore_non_preemption_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Non Preemption Test............................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Non Preemption Test............................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Non Preemption Test............................... ERROR #3\n"); + test_control_return(1); + } + + /* Create a semaphore with an initial count of 0. */ + status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Non Preemption Test............................... ERROR #4\n"); + test_control_return(1); + } + + /* Setup the semaphore notify callback. */ + status = tx_semaphore_put_notify(&semaphore_0, put_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Non Preemption Test............................... ERROR #5\n"); + test_control_return(1); + } + +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Semaphore Non Preemption Test............................... ERROR #6\n"); + test_control_return(1); + } + +#endif +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Semaphore Non Preemption Test............................... "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Perform a semaphore put and get, just to exercise the notify path of a non-resumption + semaphore put. */ + status = tx_semaphore_put(&semaphore_0); + status += tx_semaphore_get(&semaphore_0, TX_NO_WAIT); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Semaphore error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Relinquish to make the other thread suspend on the semaphore. */ + tx_thread_relinquish(); + + /* Make sure the other thread has run. */ + if (thread_1_counter != 1) + { + + /* Semaphore error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Place an instance on the semaphore, this should resume the other thread + but not preempt this thread. */ + status = tx_semaphore_put(&semaphore_0); + + /* Check the status and the run counter of the other thread. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1)) + { + + /* Semaphore error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Relinquish to allow the other thread to run. */ + tx_thread_relinquish(); + + /* Make sure the other thread has run. */ + if (thread_1_counter != 3) + { + + /* Semaphore error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* At this point, we need to resume thread 2 and relinquish in order to get that thread suspended on the + semaphore as well. */ + tx_thread_resume(&thread_2); + tx_thread_relinquish(); + + /* Perform 2 semaphore put operations to resume both threads. */ + status = tx_semaphore_put(&semaphore_0); + status += tx_semaphore_put(&semaphore_0); + + /* Let both threads run again. */ + tx_thread_relinquish(); + + /* Check the status and the run counter of the other thread. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 3)) + { + + /* Semaphore error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + while(1) + { + + /* Increment thread run counter. */ + thread_1_counter++; + + /* Suspend on the semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; + + while(1) + { + + /* Increment thread run counter. */ + thread_2_counter++; + + /* Suspend on the semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_2_counter++; + } +} + diff --git a/test/smp/regression/threadx_semaphore_preemption_test.c b/test/smp/regression/threadx_semaphore_preemption_test.c new file mode 100644 index 00000000..347042bc --- /dev/null +++ b/test/smp/regression/threadx_semaphore_preemption_test.c @@ -0,0 +1,179 @@ +/* This test is designed to test the semaphore suspension and another thread resuming the + higher priority thread by doing a semaphore put. Higher-priority thread should preempt. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + + +static TX_SEMAPHORE semaphore_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void put_notify(TX_SEMAPHORE *semaphore_ptr) +{ + + /* Don't need to do anything in here... */ +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_semaphore_preemption_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Preemption Test................................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Preemption Test................................... ERROR #2\n"); + test_control_return(1); + } + + /* Create a semaphore with an initial count of 0. */ + status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Preemption Test................................... ERROR #3\n"); + test_control_return(1); + } + + /* Setup the semaphore notify callback. */ + status = tx_semaphore_put_notify(&semaphore_0, put_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Preemption Test................................... ERROR #4\n"); + test_control_return(1); + } +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Semaphore Preemption Test................................... ERROR #5\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Semaphore Preemption Test................................... "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* The other thread should now be suspended on the semaphore. */ + if (thread_1_counter != 1) + { + + /* Semaphore error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Place an instance on the semaphore, this should cause the other thread + to preempt. */ + status = tx_semaphore_put(&semaphore_0); + + /* Check status and run counter of other thread. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 2)) + { + + /* Semaphore error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Increment thread run counter. */ + thread_1_counter++; + + /* Suspend on the semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + /* Did we get the right status? */ + if (status == TX_SUCCESS) + thread_1_counter++; +} + diff --git a/test/smp/regression/threadx_semaphore_prioritize.c b/test/smp/regression/threadx_semaphore_prioritize.c new file mode 100644 index 00000000..79622667 --- /dev/null +++ b/test/smp/regression/threadx_semaphore_prioritize.c @@ -0,0 +1,525 @@ +/* This test is designed to test semaphore prioritize. */ + +#include +#include "tx_api.h" + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Define the external reference for the preempt disable flag. */ + +extern volatile UINT _tx_thread_preempt_disable; + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + +static unsigned long thread_5_counter = 0; +static TX_THREAD thread_5; + +static unsigned long thread_6_counter = 0; +static TX_THREAD thread_6; + +static TX_SEMAPHORE semaphore_0; +static TX_SEMAPHORE semaphore_1; + +static int test_status; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); +static void thread_6_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + + /* Determine if the test case we are looking for is present. */ + if ((_tx_thread_preempt_disable) && (test_status == 1)) + { + + /* Determine if thread 3 is at the front of the suspension list. */ + if (semaphore_0.tx_semaphore_suspension_list == &thread_3) + { + + /* Abort the wait of thread 3. */ + tx_thread_wait_abort(&thread_3); + } + else + { + + /* Abort the wait of thread 5. */ + tx_thread_wait_abort(&thread_5); + + /* End the ISR processing. */ + test_status = 2; + test_isr_dispatch = TX_NULL; + } + } +} + + +static void put_notify(TX_SEMAPHORE *semaphore_ptr) +{ + + /* Don't need to do anything in here... */ +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_semaphore_prioritize_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Prioritize Test................................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Prioritize Test................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Prioritize Test................................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 3, 3, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Prioritize Test................................... ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 4, 4, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Prioritize Test................................... ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, TEST_STACK_SIZE_PRINTF, + 5, 5, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Prioritize Test................................... ERROR #6\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6, + pointer, TEST_STACK_SIZE_PRINTF, + 6, 6, 100, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Prioritize Test................................... ERROR #7\n"); + test_control_return(1); + } + + /* Create the semaphore with no instances. */ + status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Prioritize Test................................... ERROR #8\n"); + test_control_return(1); + } + + /* Setup the semaphore notify callback. */ + status = tx_semaphore_put_notify(&semaphore_0, put_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Prioritize Test................................... ERROR #9\n"); + test_control_return(1); + } + +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Semaphore Prioritize Test................................... ERROR #10\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Semaphore Prioritize Test................................... "); + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Attempt to prioritize a non-semaphore. */ + status = tx_semaphore_prioritize(TX_NULL); + + /* Check status. */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Attempt to prioritize a non-created semaphore. */ + semaphore_1.tx_semaphore_id = 0; + status = tx_semaphore_prioritize(&semaphore_1); + + /* Check status. */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #12\n"); + test_control_return(1); + } +#endif + + /* Prioritize the semaphore suspension list - empty list case! */ + status = tx_semaphore_prioritize(&semaphore_0); + + /* Check status and make sure thread 1 is terminated. */ + if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != TX_NULL)) + { + + /* Semaphore error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Make sure thread 1 and 2 are suspended on the semaphore. */ + if ((thread_1.tx_thread_state != TX_SEMAPHORE_SUSP) || (thread_2.tx_thread_state != TX_SEMAPHORE_SUSP) || + (semaphore_0.tx_semaphore_suspension_list != &thread_1)) + { + + /* Semaphore error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Prioritize the semaphore suspension list. */ + status = tx_semaphore_prioritize(&semaphore_0); + + /* Check status and make sure thread 2 is not at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_2)) + { + + /* Semaphore error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Prioritize the semaphore suspension list again - in this case, the list is already prioritized. */ + status = tx_semaphore_prioritize(&semaphore_0); + + /* Check status and make sure thread 2 is not at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_2)) + { + + /* Semaphore error. */ + printf("ERROR #15a\n"); + test_control_return(1); + } + + /* At this point we are going to get more than 2 threads suspended. */ + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); + tx_thread_resume(&thread_3); + tx_thread_resume(&thread_4); + tx_thread_resume(&thread_5); + tx_thread_resume(&thread_6); + + /* Prioritize the semaphore suspension list. */ + status = tx_semaphore_prioritize(&semaphore_0); + + /* Check status and make sure thread 3 is now at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_3)) + { + + /* Semaphore error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Now loop to test the interrupt of the prioritize loop logic. */ + test_status = 1; + test_isr_dispatch = test_isr; + do + { + + /* Prioritize the semaphore suspension list. */ + status = tx_semaphore_prioritize(&semaphore_0); + + /* Check status and make sure thread 1 is terminated. */ + if (status != TX_SUCCESS) + { + + /* Semaphore error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + } while (test_status == 1); + + /* Check status and make sure thread 3 is now at the front of the suspension list. */ + if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_4)) + { + + /* Semaphore error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; + + /* Loop forever! */ + while(1) + { + + + /* Get semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ +UINT status; + + + /* Loop forever! */ + while(1) + { + + + /* Get semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_2_counter++; + } +} + + +static void thread_3_entry(ULONG thread_input) +{ +UINT status; + + + /* Loop forever! */ + while(1) + { + + + /* Get semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_3_counter++; + } +} + + +static void thread_4_entry(ULONG thread_input) +{ +UINT status; + + + /* Loop forever! */ + while(1) + { + + + /* Get semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_4_counter++; + } +} + + +static void thread_5_entry(ULONG thread_input) +{ +UINT status; + + + /* Loop forever! */ + while(1) + { + + + /* Get semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_5_counter++; + } +} + + +static void thread_6_entry(ULONG thread_input) +{ +UINT status; + + + /* Loop forever! */ + while(1) + { + + + /* Get semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + if (status != TX_SUCCESS) + break; + + /* Increment the thread counter. */ + thread_6_counter++; + } +} + diff --git a/test/smp/regression/threadx_semaphore_thread_terminate_test.c b/test/smp/regression/threadx_semaphore_thread_terminate_test.c new file mode 100644 index 00000000..b8beeff2 --- /dev/null +++ b/test/smp/regression/threadx_semaphore_thread_terminate_test.c @@ -0,0 +1,224 @@ +/* This test is designed to test thread terminate calls when threads are suspended on + a semaphore. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + + +static TX_SEMAPHORE semaphore_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void put_notify(TX_SEMAPHORE *semaphore_ptr) +{ + + /* Don't need to do anything in here... */ +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_semaphore_thread_terminate_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Thread Terminate Test............................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Thread Terminate Test............................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Thread Terminate Test............................. ERROR #3\n"); + test_control_return(1); + } + + /* Create a semaphore with an initial count of 0. */ + status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Thread Terminate Test............................. ERROR #4\n"); + test_control_return(1); + } + + /* Setup the semaphore notify callback. */ + status = tx_semaphore_put_notify(&semaphore_0, put_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Thread Terminate Test............................. ERROR #5\n"); + test_control_return(1); + } +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Semaphore Thread Terminate Test............................. ERROR #6\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Semaphore Thread Terminate Test............................. "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Relinquish to let other threads run. */ + tx_thread_relinquish(); + + /* Other threads should now be suspended on the semaphore. */ + if ((thread_1_counter != 1) || (thread_2_counter != 1)) + { + + /* Semaphore error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Terminate the other threads to make sure the semaphore gets + cleaned up. */ + status = tx_thread_terminate(&thread_1); + + /* Check status and run counters of other threads. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1)) + { + + /* Semaphore error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Terminate the other thread. */ + status = tx_thread_terminate(&thread_2); + + /* Relinquish just to make sure. */ + tx_thread_relinquish(); + + /* Check status and run counters of other threads. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1)) + { + + /* Semaphore error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + /* Increment thread run counter. */ + thread_1_counter++; + + /* Suspend on the semaphore. */ + tx_semaphore_get(&semaphore_0, 33); + + /* Should never get here! */ + thread_1_counter++; +} + + +static void thread_2_entry(ULONG thread_input) +{ + + /* Increment thread run counter. */ + thread_2_counter++; + + /* Suspend on the semaphore. */ + tx_semaphore_get(&semaphore_0, 44); + + /* Should never get here! */ + thread_2_counter++; +} diff --git a/test/smp/regression/threadx_semaphore_timeout_test.c b/test/smp/regression/threadx_semaphore_timeout_test.c new file mode 100644 index 00000000..55cd8a96 --- /dev/null +++ b/test/smp/regression/threadx_semaphore_timeout_test.c @@ -0,0 +1,165 @@ +/* This test is designed to test the semaphore suspension and timeout functionality. */ + +#include +#include "tx_api.h" + +//static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static TX_SEMAPHORE semaphore_0; +static TX_SEMAPHORE semaphore_1; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void put_notify(TX_SEMAPHORE *semaphore_ptr) +{ + + /* Don't need to do anything in here... */ +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_semaphore_timeout_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Suspension Timeout Test........................... ERROR #1\n"); + test_control_return(1); + } + + /* Create a semaphore with an initial count of 0. */ + status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Suspension Timeout Test........................... ERROR #2\n"); + test_control_return(1); + } + + /* Setup the semaphore notify callback. */ + status = tx_semaphore_put_notify(&semaphore_0, put_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Semaphore Suspension Timeout Test........................... ERROR #3\n"); + test_control_return(1); + } + +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Semaphore Suspension Timeout Test........................... ERROR #4\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Inform user. */ + printf("Running Semaphore Suspension Timeout Test........................... "); + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Attempt to setup semaphore notify callback on non-semaphore. */ + status = tx_semaphore_put_notify(TX_NULL, put_notify); + + /* Check status */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Attempt to setup semaphore notify callback on non-created semaphore. */ + semaphore_1.tx_semaphore_id = 0; + status = tx_semaphore_put_notify(&semaphore_1, put_notify); + + /* Check status */ + if (status != TX_SEMAPHORE_ERROR) + { + + /* Semaphore error. */ + printf("ERROR #6\n"); + test_control_return(1); + } +#endif + + /* Sleep for 2 ticks for fresh timer. */ + tx_thread_sleep(2); + + /* Set clock to 0. */ + tx_time_set(0); + + /* Suspend on the semaphore. */ + status = tx_semaphore_get(&semaphore_0, 33); + + /* Did we get the right status at the right time? */ + if ((status != TX_NO_INSTANCE) || (tx_time_get() != 33)) + { + + /* Semaphore error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + diff --git a/test/smp/regression/threadx_smp_multiple_threads_one_core_test.c b/test/smp/regression/threadx_smp_multiple_threads_one_core_test.c new file mode 100644 index 00000000..2ca5b947 --- /dev/null +++ b/test/smp/regression/threadx_smp_multiple_threads_one_core_test.c @@ -0,0 +1,348 @@ +/* Define the ThreadX SMP multiple threads excluded to one core test. */ + +#include +#include "tx_api.h" + + + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; +static TX_THREAD thread_4; +static TX_THREAD thread_5; +static TX_THREAD thread_6; +static TX_THREAD thread_7; + + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG thread_2_counter; +static ULONG thread_3_counter; +static ULONG thread_4_counter; +static ULONG thread_5_counter; +static ULONG thread_6_counter; +static ULONG thread_7_counter; + + +static unsigned long error = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); +static void thread_6_entry(ULONG thread_input); +static void thread_7_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_smp_multiple_threads_one_core_test(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 0, 0, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Multiple Threads One Core Test.......................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 1, 1, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_1, 0xD); /* Only core 1! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Multiple Threads One Core Test.......................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 2, 2, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_2, 0xB); /* Only core 2! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Multiple Threads One Core Test.......................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 2, 2, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_3, 0x7); /* Only core 3! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Multiple Threads One Core Test.......................... ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 2, 2, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_4, 0xE); /* Only core 0! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Multiple Threads One Core Test.......................... ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 2, 2, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_5, 0xD); /* Only core 1! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Multiple Threads One Core Test.......................... ERROR #6\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 2, 2, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_6, 0xB); /* Only core 2! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Multiple Threads One Core Test.......................... ERROR #7\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_7, "thread 7", thread_7_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 2, 2, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_7, 0x7); /* Only core 3! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Multiple Threads One Core Test.......................... ERROR #8\n"); + test_control_return(1); + } + + /* Resume thread 0. */ + status = tx_thread_resume(&thread_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Multiple Threads One Core Test.......................... ERROR #9\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + + /* Inform user. */ + printf("Running SMP Multiple Threads One Core Test.......................... "); + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_1); + status += tx_thread_resume(&thread_2); + status += tx_thread_resume(&thread_3); + status += tx_thread_resume(&thread_4); + status += tx_thread_resume(&thread_5); + status += tx_thread_resume(&thread_6); + status += tx_thread_resume(&thread_7); + + /* Suspend this thread to let the others run. */ + tx_thread_sleep(5); + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (error) || (thread_1_counter != 1) || (tx_thread_smp_core_get() != 0) || + (thread_2_counter != 1) || (thread_3_counter != 1) || (thread_4_counter != 1) || + (thread_5_counter != 1) || (thread_6_counter != 1) || (thread_7_counter != 1)) + { + + /* Execution error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + while(1) + { + /* Ensure this thread is on the correct core. */ + if (tx_thread_smp_core_get() != 1) + error++; + + thread_1_counter++; + tx_thread_suspend(&thread_1); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + + while(1) + { + + /* Ensure this thread is on the correct core. */ + if (tx_thread_smp_core_get() != 2) + error++; + + thread_2_counter++; + tx_thread_suspend(&thread_2); + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + + while(1) + { + + /* Ensure this thread is on the correct core. */ + if (tx_thread_smp_core_get() != 3) + error++; + + thread_3_counter++; + tx_thread_suspend(&thread_3); + } +} + + +static void thread_4_entry(ULONG thread_input) +{ + + while(1) + { + + /* Ensure this thread is on the correct core. */ + if (tx_thread_smp_core_get() != 0) + error++; + + thread_4_counter++; + tx_thread_suspend(&thread_4); + } +} + + +static void thread_5_entry(ULONG thread_input) +{ + + while(1) + { + + /* Ensure this thread is on the correct core. */ + if (tx_thread_smp_core_get() != 1) + error++; + + thread_5_counter++; + tx_thread_suspend(&thread_5); + } +} + + +static void thread_6_entry(ULONG thread_input) +{ + + while(1) + { + + /* Ensure this thread is on the correct core. */ + if (tx_thread_smp_core_get() != 2) + error++; + + thread_6_counter++; + tx_thread_suspend(&thread_6); + } +} + + +static void thread_7_entry(ULONG thread_input) +{ + + while(1) + { + + /* Ensure this thread is on the correct core. */ + if (tx_thread_smp_core_get() != 3) + error++; + + thread_7_counter++; + tx_thread_suspend(&thread_7); + } +} diff --git a/test/smp/regression/threadx_smp_non_trivial_scheduling_test.c b/test/smp/regression/threadx_smp_non_trivial_scheduling_test.c new file mode 100644 index 00000000..ded600da --- /dev/null +++ b/test/smp/regression/threadx_smp_non_trivial_scheduling_test.c @@ -0,0 +1,350 @@ +/* Define the ThreadX SMP non-trivial scheduling test. */ + +#include +#include "tx_api.h" + + + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; + + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG thread_2_counter; +static ULONG thread_3_counter; + + +extern TX_THREAD *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES]; + +static unsigned long error = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_smp_non_trivial_scheduling_test(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 0, 0, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Only allow core 0 for now */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 1, 1, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_1, 0x9); /* Exclude core 2 and 1 */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 2, 2, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_2, 0xB); /* Exclude core 3, 1 and 0 */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 3, 3, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_3, 0xE); /* Exclude core 0 */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #4\n"); + test_control_return(1); + } + + /* Resume thread 0. */ + status = tx_thread_resume(&thread_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #5\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT original_threshold; + + + /* Inform user. */ + printf("Running SMP Non-Trivial Scheduling Test............................. "); + + /* Move enable core 0 and 1. */ + status = tx_thread_smp_core_exclude(&thread_0, 0xC); /* Allow core 0 and 1 */ + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0)) + { + + /* Execution error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Resume thread 1. */ + status = tx_thread_resume(&thread_1); + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Resume thread 2. */ + status = tx_thread_resume(&thread_2); + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Resume thread 3. */ + status = tx_thread_resume(&thread_3); + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Suspend thread 2 and cause a rebalance of the execution list. */ + status = tx_thread_suspend(&thread_2); + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_3) || (_tx_thread_execute_ptr[1] != &thread_0) + || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #10"); + test_control_return(1); + } + + /* Now suspend threads 3 and 1. */ + status = tx_thread_suspend(&thread_3); + status += tx_thread_suspend(&thread_1); + + /* Use preemption-threshold to test the rebalance routine. */ + status += tx_thread_preemption_change(&thread_3, 2, &original_threshold); + + /* Move thread 0 back to core 0 and then allow core 1 again. */ + status += tx_thread_smp_core_exclude(&thread_0, 0xE); + status += tx_thread_smp_core_exclude(&thread_0, 0xC); + + /* Make sure threads 1 defaults to core 1. */ + status += tx_thread_smp_core_exclude(&thread_1, 0xD); + status += tx_thread_smp_core_exclude(&thread_1, 0x9); + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #11"); + test_control_return(1); + } + + /* Resume thread 1. */ + status = tx_thread_resume(&thread_1); + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Resume thread 2. */ + status = tx_thread_resume(&thread_2); + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Resume thread 3. */ + status = tx_thread_resume(&thread_3); + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Suspend thread 2 and cause a rebalance of the execution list. */ + status = tx_thread_suspend(&thread_2); + + /* With preemption-threshold disabled, thread_3 can not run since preemption-threshold is set to 0 and there is already a + zero priority thread running. */ +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_3) || (_tx_thread_execute_ptr[1] != &thread_0) + || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL)) +#else + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) +#endif + { + + /* Execution error. */ + printf("ERROR #15"); + test_control_return(1); + } + + /* Now suspend threads 3 and 1. */ + status = tx_thread_suspend(&thread_3); + status += tx_thread_suspend(&thread_1); + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != TX_NULL) || (_tx_thread_execute_ptr[1] != &thread_0) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) +#else + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) +#endif + { + + /* Execution error. */ + printf("ERROR #16"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + + while(1) + { + thread_1_counter++; + tx_thread_identify(); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + + while(1) + { + thread_2_counter++; + tx_thread_identify(); + } +} + +static void thread_3_entry(ULONG thread_input) +{ + + while(1) + { + thread_3_counter++; + tx_thread_identify(); + } +} + + diff --git a/test/smp/regression/threadx_smp_one_thread_dynamic_exclusion_test.c b/test/smp/regression/threadx_smp_one_thread_dynamic_exclusion_test.c new file mode 100644 index 00000000..82caeefa --- /dev/null +++ b/test/smp/regression/threadx_smp_one_thread_dynamic_exclusion_test.c @@ -0,0 +1,145 @@ +/* Define the ThreadX SMP one thread dynamic thread exclusion test. */ + +#include +#include "tx_api.h" + + + +static TX_THREAD thread_0; + + +static ULONG thread_0_counter; + + +static unsigned long error = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_smp_one_thread_dynamic_exclusion_test(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 0, 0, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_0, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP One Thread Dynamic Exclusion Test....................... ERROR #1\n"); + test_control_return(1); + } + + + /* Resume thread 0. */ + status = tx_thread_resume(&thread_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP One Thread Dynamic Exclusion Test....................... ERROR #2\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + + /* Inform user. */ + printf("Running SMP One Thread Dynamic Exclusion Test....................... "); + + /* Move to core 1. */ + status = tx_thread_smp_core_exclude(&thread_0, 0xD); /* Only core 1! */ + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (tx_thread_smp_core_get() != 1)) + { + + /* Execution error. */ + printf("ERROR #3\n"); + test_control_return(1); + } + + /* Move to core 2. */ + status = tx_thread_smp_core_exclude(&thread_0, 0xB); /* Only core 2! */ + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (tx_thread_smp_core_get() != 2)) + { + + /* Execution error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Move to core 3. */ + status = tx_thread_smp_core_exclude(&thread_0, 0x7); /* Only core 3! */ + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (tx_thread_smp_core_get() != 3)) + { + + /* Execution error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Move back to core 0. */ + status = tx_thread_smp_core_exclude(&thread_0, 0xE); /* Only core 0! */ + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (tx_thread_smp_core_get() != 0)) + { + + /* Execution error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + diff --git a/test/smp/regression/threadx_smp_preemption_threshold_test.c b/test/smp/regression/threadx_smp_preemption_threshold_test.c new file mode 100644 index 00000000..920c89b1 --- /dev/null +++ b/test/smp/regression/threadx_smp_preemption_threshold_test.c @@ -0,0 +1,534 @@ +/* Define the ThreadX SMP preemption-threshold test. */ + +#include +#include "tx_api.h" + +extern TX_THREAD *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES]; + + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_5; +static TX_THREAD thread_16; +static TX_THREAD thread_16_pt5; +static TX_THREAD thread_18; +static TX_THREAD thread_23_pt17; +static TX_THREAD thread_25; +static TX_THREAD thread_27_pt24; +static TX_THREAD thread_31; + +static ULONG thread_run_counter[10]; + + +static unsigned long error = 0; + + +/* Define thread prototypes. */ + +static void thread_entry(ULONG thread_input); +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void delay(UINT i) +{ + + /* Wait until the thread runs! */ + while (thread_run_counter[i] == 0) + { + } +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_smp_preemption_threshold_test(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; +UINT i; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 0, 0, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Preemption-Threshold Test............................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 1, 1, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_1, 0); /* Any core! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Preemption-Threshold Test............................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_5, "thread 5", thread_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 5, 5, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_5, 0); /* Any core! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Preemption-Threshold Test............................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_16, "thread 16", thread_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_16, 0); /* Any core! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Preemption-Threshold Test............................... ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_16_pt5, "thread 16 PT5", thread_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 5, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_16_pt5, 0); /* Any core! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Preemption-Threshold Test............................... ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_18, "thread 18", thread_entry, 5, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_18, 0); /* Any core! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Preemption-Threshold Test............................... ERROR #6\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_23_pt17, "thread 23 PT17", thread_entry, 6, + pointer, TEST_STACK_SIZE_PRINTF, + 23, 17, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_23_pt17, 0); /* Any core! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Preemption-Threshold Test............................... ERROR #7\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_25, "thread 25", thread_entry, 7, + pointer, TEST_STACK_SIZE_PRINTF, + 25, 25, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_25, 0); /* Any core! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Preemption-Threshold Test............................... ERROR #8\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_27_pt24, "thread 27 PT24", thread_entry, 8, + pointer, TEST_STACK_SIZE_PRINTF, + 27, 24, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_27_pt24, 0); /* Any core! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Preemption-Threshold Test............................... ERROR #9\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_31, "thread 31", thread_entry, 9, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31, 0); /* Any core! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Preemption-Threshold Test............................... ERROR #10\n"); + test_control_return(1); + } + + /* Clear the thread run count array. */ + for (i = 0; i < 10; i++) + { + thread_run_counter[i] = 0; + } + + /* Resume thread 0. */ + status = tx_thread_resume(&thread_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Preemption-Threshold Test............................... ERROR #11\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + + /* Inform user. */ + printf("Running SMP Preemption-Threshold Test............................... "); + + /* This test is only useful when preemption-threshold is enabled. */ +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD + + /* Resume thread. */ + status = tx_thread_resume(&thread_31); + delay(9); + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Resume thread. */ + status = tx_thread_resume(&thread_27_pt24); + delay(8); + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_27_pt24) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Resume thread. */ + status = tx_thread_resume(&thread_23_pt17); + delay(6); + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_23_pt17) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Resume thread. */ + status = tx_thread_resume(&thread_16_pt5); + delay(4); + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Resume thread. */ + status = tx_thread_resume(&thread_16); + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Resume thread. */ + status = tx_thread_resume(&thread_25); + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Resume thread. */ + status = tx_thread_resume(&thread_18); + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Resume thread. */ + status = tx_thread_resume(&thread_5); + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Resume thread. */ + status = tx_thread_resume(&thread_1); + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5) + || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Suspend Thread 16 pt5. */ + status = tx_thread_suspend(&thread_16_pt5); + + delay(2); + delay(3); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5) + || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_16)) + { + + /* Execution error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + + /* Suspend Thread 16. */ + status = tx_thread_suspend(&thread_16); + + delay(6); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5) + || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_23_pt17)) + { + + /* Execution error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Suspend Thread 23 pt 17. */ + status = tx_thread_suspend(&thread_23_pt17); + + delay(5); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5) + || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_18)) + { + + /* Execution error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + + /* Suspend Thread 18. */ + status = tx_thread_suspend(&thread_18); + + delay(8); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5) + || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_27_pt24)) + { + + /* Execution error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Suspend Thread 27 pt 24. */ + status = tx_thread_suspend(&thread_27_pt24); + + delay(7); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5) + || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_25)) + { + + /* Execution error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + + /* Suspend Thread 25. */ + status = tx_thread_suspend(&thread_25); + + delay(9); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5) + || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_31)) + { + + /* Execution error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Resume thread 16 pt 5. */ + status = tx_thread_resume(&thread_16_pt5); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5) + || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_31)) + { + + /* Execution error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Suspend thread 16 pt 5. */ + status = tx_thread_suspend(&thread_16_pt5); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5) + || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_31)) + { + + /* Execution error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + + /* Suspend thread 31. */ + status = tx_thread_suspend(&thread_31); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5) + || (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + + /* Suspend thread 1. */ + status = tx_thread_suspend(&thread_1); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #30\n"); + test_control_return(1); + } + + /* Suspend thread 5. */ + status = tx_thread_suspend(&thread_5); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #31\n"); + test_control_return(1); + } +#endif + + /* Successful test. */ + printf("SUCCESS!\n"); + + test_control_return(0); +} + + +static void thread_entry(ULONG thread_input) +{ + + /* Increment the run counter. */ + thread_run_counter[thread_input]++; + + while(1) + { + + tx_thread_identify(); + + /* Indicate the thread is running... */ + thread_run_counter[thread_input]++; + } +} diff --git a/test/smp/regression/threadx_smp_random_resume_suspend_exclusion_pt_test.c b/test/smp/regression/threadx_smp_random_resume_suspend_exclusion_pt_test.c new file mode 100644 index 00000000..cc2ecca0 --- /dev/null +++ b/test/smp/regression/threadx_smp_random_resume_suspend_exclusion_pt_test.c @@ -0,0 +1,2490 @@ +/* Define the ThreadX SMP random resume/suspend/exclude/pt test. */ + +#include +#include "tx_api.h" + +//#define MAX_PASSES 50000000 +//#define MAX_PASSES 50000 +#define MAX_PASSES 500 + + +/* Define the ThreadX object control blocks... Must have 256 priority levels... and assumes 4 cores. */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; +static TX_THREAD thread_4; +static TX_THREAD thread_5; +static TX_THREAD thread_6; +static TX_THREAD thread_7; +static TX_THREAD thread_8; +static TX_THREAD thread_9; +static TX_THREAD thread_10; +static TX_THREAD thread_11; +static TX_THREAD thread_12; +static TX_THREAD thread_13; +static TX_THREAD thread_14; +static TX_THREAD thread_15; +static TX_THREAD thread_16; +static TX_THREAD thread_17; +static TX_THREAD thread_18; +static TX_THREAD thread_19; +static TX_THREAD thread_20; +static TX_THREAD thread_21; +static TX_THREAD thread_22; +static TX_THREAD thread_23; +static TX_THREAD thread_24; +static TX_THREAD thread_25; +static TX_THREAD thread_26; +static TX_THREAD thread_27; +static TX_THREAD thread_28; +static TX_THREAD thread_29; +static TX_THREAD thread_30; +static TX_THREAD thread_31; +static TX_THREAD thread_32; +static TX_THREAD thread_33; +static TX_THREAD thread_34; +static TX_THREAD thread_35; +static TX_THREAD thread_36; +static TX_THREAD thread_37; +static TX_THREAD thread_38; +static TX_THREAD thread_39; +static TX_THREAD thread_40; +static TX_THREAD thread_41; +static TX_THREAD thread_42; +static TX_THREAD thread_43; +static TX_THREAD thread_44; +static TX_THREAD thread_45; +static TX_THREAD thread_46; +static TX_THREAD thread_47; +static TX_THREAD thread_48; +static TX_THREAD thread_49; +static TX_THREAD thread_50; +static TX_THREAD thread_51; +static TX_THREAD thread_52; +static TX_THREAD thread_53; +static TX_THREAD thread_54; +static TX_THREAD thread_55; +static TX_THREAD thread_56; +static TX_THREAD thread_57; +static TX_THREAD thread_58; +static TX_THREAD thread_59; +static TX_THREAD thread_60; +static TX_THREAD thread_61; +static TX_THREAD thread_62; +static TX_THREAD thread_63; +static TX_THREAD thread_64; +static TX_THREAD thread_65; +static TX_THREAD thread_66; +static TX_THREAD thread_67; +static TX_THREAD thread_68; +static TX_THREAD thread_69; +static TX_THREAD thread_70; +static TX_THREAD thread_71; +static TX_THREAD thread_72; +static TX_THREAD thread_73; +static TX_THREAD thread_74; +static TX_THREAD thread_75; +static TX_THREAD thread_76; +static TX_THREAD thread_77; +static TX_THREAD thread_78; +static TX_THREAD thread_79; +static TX_THREAD thread_80; +static TX_THREAD thread_81; +static TX_THREAD thread_82; +static TX_THREAD thread_83; +static TX_THREAD thread_84; +static TX_THREAD thread_85; +static TX_THREAD thread_86; +static TX_THREAD thread_87; +static TX_THREAD thread_88; +static TX_THREAD thread_89; +static TX_THREAD thread_90; +static TX_THREAD thread_91; +static TX_THREAD thread_92; +static TX_THREAD thread_93; +static TX_THREAD thread_94; +static TX_THREAD thread_95; +static TX_THREAD thread_96; +static TX_THREAD thread_97; +static TX_THREAD thread_98; +static TX_THREAD thread_99; +static TX_THREAD thread_100; +static TX_THREAD thread_101; +static TX_THREAD thread_102; +static TX_THREAD thread_103; +static TX_THREAD thread_104; +static TX_THREAD thread_105; +static TX_THREAD thread_106; +static TX_THREAD thread_107; +static TX_THREAD thread_108; +static TX_THREAD thread_109; +static TX_THREAD thread_110; +static TX_THREAD thread_111; +static TX_THREAD thread_112; +static TX_THREAD thread_113; +static TX_THREAD thread_114; +static TX_THREAD thread_115; +static TX_THREAD thread_116; +static TX_THREAD thread_117; +static TX_THREAD thread_118; +static TX_THREAD thread_119; +static TX_THREAD thread_120; +static TX_THREAD thread_121; +static TX_THREAD thread_122; +static TX_THREAD thread_123; +static TX_THREAD thread_124; +static TX_THREAD thread_125; +static TX_THREAD thread_126; +static TX_THREAD thread_127; +static TX_THREAD thread_128; +static TX_THREAD thread_129; +static TX_THREAD thread_130; +static TX_THREAD thread_131; +static TX_THREAD thread_132; +static TX_THREAD thread_133; +static TX_THREAD thread_134; +static TX_THREAD thread_135; +static TX_THREAD thread_136; +static TX_THREAD thread_137; +static TX_THREAD thread_138; +static TX_THREAD thread_139; +static TX_THREAD thread_140; +static TX_THREAD thread_141; +static TX_THREAD thread_142; +static TX_THREAD thread_143; +static TX_THREAD thread_144; +static TX_THREAD thread_145; +static TX_THREAD thread_146; +static TX_THREAD thread_147; +static TX_THREAD thread_148; +static TX_THREAD thread_149; +static TX_THREAD thread_150; +static TX_THREAD thread_151; +static TX_THREAD thread_152; +static TX_THREAD thread_153; +static TX_THREAD thread_154; +static TX_THREAD thread_155; +static TX_THREAD thread_156; +static TX_THREAD thread_157; +static TX_THREAD thread_158; +static TX_THREAD thread_159; +static TX_THREAD thread_160; +static TX_THREAD thread_161; +static TX_THREAD thread_162; +static TX_THREAD thread_163; +static TX_THREAD thread_164; +static TX_THREAD thread_165; +static TX_THREAD thread_166; +static TX_THREAD thread_167; +static TX_THREAD thread_168; +static TX_THREAD thread_169; +static TX_THREAD thread_170; +static TX_THREAD thread_171; +static TX_THREAD thread_172; +static TX_THREAD thread_173; +static TX_THREAD thread_174; +static TX_THREAD thread_175; +static TX_THREAD thread_176; +static TX_THREAD thread_177; +static TX_THREAD thread_178; +static TX_THREAD thread_179; +static TX_THREAD thread_180; +static TX_THREAD thread_181; +static TX_THREAD thread_182; +static TX_THREAD thread_183; +static TX_THREAD thread_184; +static TX_THREAD thread_185; +static TX_THREAD thread_186; +static TX_THREAD thread_187; +static TX_THREAD thread_188; +static TX_THREAD thread_189; +static TX_THREAD thread_190; +static TX_THREAD thread_191; +static TX_THREAD thread_192; +static TX_THREAD thread_193; +static TX_THREAD thread_194; +static TX_THREAD thread_195; +static TX_THREAD thread_196; +static TX_THREAD thread_197; +static TX_THREAD thread_198; +static TX_THREAD thread_199; +static TX_THREAD thread_200; +static TX_THREAD thread_201; +static TX_THREAD thread_202; +static TX_THREAD thread_203; +static TX_THREAD thread_204; +static TX_THREAD thread_205; +static TX_THREAD thread_206; +static TX_THREAD thread_207; +static TX_THREAD thread_208; +static TX_THREAD thread_209; +static TX_THREAD thread_210; +static TX_THREAD thread_211; +static TX_THREAD thread_212; +static TX_THREAD thread_213; +static TX_THREAD thread_214; +static TX_THREAD thread_215; +static TX_THREAD thread_216; +static TX_THREAD thread_217; +static TX_THREAD thread_218; +static TX_THREAD thread_219; +static TX_THREAD thread_220; +static TX_THREAD thread_221; +static TX_THREAD thread_222; +static TX_THREAD thread_223; +static TX_THREAD thread_224; +static TX_THREAD thread_225; +static TX_THREAD thread_226; +static TX_THREAD thread_227; +static TX_THREAD thread_228; +static TX_THREAD thread_229; +static TX_THREAD thread_230; +static TX_THREAD thread_231; +static TX_THREAD thread_232; +static TX_THREAD thread_233; +static TX_THREAD thread_234; +static TX_THREAD thread_235; +static TX_THREAD thread_236; +static TX_THREAD thread_237; +static TX_THREAD thread_238; +static TX_THREAD thread_239; +static TX_THREAD thread_240; +static TX_THREAD thread_241; +static TX_THREAD thread_242; +static TX_THREAD thread_243; +static TX_THREAD thread_244; +static TX_THREAD thread_245; +static TX_THREAD thread_246; +static TX_THREAD thread_247; +static TX_THREAD thread_248; +static TX_THREAD thread_249; +static TX_THREAD thread_250; +static TX_THREAD thread_251; +static TX_THREAD thread_252; +static TX_THREAD thread_253; +static TX_THREAD thread_254; +static TX_THREAD thread_255; + +static TX_THREAD thread_0_1; +static TX_THREAD thread_1_1; +static TX_THREAD thread_2_1; +static TX_THREAD thread_3_1; +static TX_THREAD thread_4_1; +static TX_THREAD thread_5_1; +static TX_THREAD thread_6_1; +static TX_THREAD thread_7_1; +static TX_THREAD thread_8_1; +static TX_THREAD thread_9_1; +static TX_THREAD thread_10_1; +static TX_THREAD thread_11_1; +static TX_THREAD thread_12_1; +static TX_THREAD thread_13_1; +static TX_THREAD thread_14_1; +static TX_THREAD thread_15_1; +static TX_THREAD thread_16_1; +static TX_THREAD thread_17_1; +static TX_THREAD thread_18_1; +static TX_THREAD thread_19_1; +static TX_THREAD thread_20_1; +static TX_THREAD thread_21_1; +static TX_THREAD thread_22_1; +static TX_THREAD thread_23_1; +static TX_THREAD thread_24_1; +static TX_THREAD thread_25_1; +static TX_THREAD thread_26_1; +static TX_THREAD thread_27_1; +static TX_THREAD thread_28_1; +static TX_THREAD thread_29_1; +static TX_THREAD thread_30_1; +static TX_THREAD thread_31_1; +static TX_THREAD thread_32_1; +static TX_THREAD thread_33_1; +static TX_THREAD thread_34_1; +static TX_THREAD thread_35_1; +static TX_THREAD thread_36_1; +static TX_THREAD thread_37_1; +static TX_THREAD thread_38_1; +static TX_THREAD thread_39_1; +static TX_THREAD thread_40_1; +static TX_THREAD thread_41_1; +static TX_THREAD thread_42_1; +static TX_THREAD thread_43_1; +static TX_THREAD thread_44_1; +static TX_THREAD thread_45_1; +static TX_THREAD thread_46_1; +static TX_THREAD thread_47_1; +static TX_THREAD thread_48_1; +static TX_THREAD thread_49_1; +static TX_THREAD thread_50_1; +static TX_THREAD thread_51_1; +static TX_THREAD thread_52_1; +static TX_THREAD thread_53_1; +static TX_THREAD thread_54_1; +static TX_THREAD thread_55_1; +static TX_THREAD thread_56_1; +static TX_THREAD thread_57_1; +static TX_THREAD thread_58_1; +static TX_THREAD thread_59_1; +static TX_THREAD thread_60_1; +static TX_THREAD thread_61_1; +static TX_THREAD thread_62_1; +static TX_THREAD thread_63_1; +static TX_THREAD thread_64_1; +static TX_THREAD thread_65_1; +static TX_THREAD thread_66_1; +static TX_THREAD thread_67_1; +static TX_THREAD thread_68_1; +static TX_THREAD thread_69_1; +static TX_THREAD thread_70_1; +static TX_THREAD thread_71_1; +static TX_THREAD thread_72_1; +static TX_THREAD thread_73_1; +static TX_THREAD thread_74_1; +static TX_THREAD thread_75_1; +static TX_THREAD thread_76_1; +static TX_THREAD thread_77_1; +static TX_THREAD thread_78_1; +static TX_THREAD thread_79_1; +static TX_THREAD thread_80_1; +static TX_THREAD thread_81_1; +static TX_THREAD thread_82_1; +static TX_THREAD thread_83_1; +static TX_THREAD thread_84_1; +static TX_THREAD thread_85_1; +static TX_THREAD thread_86_1; +static TX_THREAD thread_87_1; +static TX_THREAD thread_88_1; +static TX_THREAD thread_89_1; +static TX_THREAD thread_90_1; +static TX_THREAD thread_91_1; +static TX_THREAD thread_92_1; +static TX_THREAD thread_93_1; +static TX_THREAD thread_94_1; +static TX_THREAD thread_95_1; +static TX_THREAD thread_96_1; +static TX_THREAD thread_97_1; +static TX_THREAD thread_98_1; +static TX_THREAD thread_99_1; +static TX_THREAD thread_100_1; +static TX_THREAD thread_101_1; +static TX_THREAD thread_102_1; +static TX_THREAD thread_103_1; +static TX_THREAD thread_104_1; +static TX_THREAD thread_105_1; +static TX_THREAD thread_106_1; +static TX_THREAD thread_107_1; +static TX_THREAD thread_108_1; +static TX_THREAD thread_109_1; +static TX_THREAD thread_110_1; +static TX_THREAD thread_111_1; +static TX_THREAD thread_112_1; +static TX_THREAD thread_113_1; +static TX_THREAD thread_114_1; +static TX_THREAD thread_115_1; +static TX_THREAD thread_116_1; +static TX_THREAD thread_117_1; +static TX_THREAD thread_118_1; +static TX_THREAD thread_119_1; +static TX_THREAD thread_120_1; +static TX_THREAD thread_121_1; +static TX_THREAD thread_122_1; +static TX_THREAD thread_123_1; +static TX_THREAD thread_124_1; +static TX_THREAD thread_125_1; +static TX_THREAD thread_126_1; +static TX_THREAD thread_127_1; +static TX_THREAD thread_128_1; +static TX_THREAD thread_129_1; +static TX_THREAD thread_130_1; +static TX_THREAD thread_131_1; +static TX_THREAD thread_132_1; +static TX_THREAD thread_133_1; +static TX_THREAD thread_134_1; +static TX_THREAD thread_135_1; +static TX_THREAD thread_136_1; +static TX_THREAD thread_137_1; +static TX_THREAD thread_138_1; +static TX_THREAD thread_139_1; +static TX_THREAD thread_140_1; +static TX_THREAD thread_141_1; +static TX_THREAD thread_142_1; +static TX_THREAD thread_143_1; +static TX_THREAD thread_144_1; +static TX_THREAD thread_145_1; +static TX_THREAD thread_146_1; +static TX_THREAD thread_147_1; +static TX_THREAD thread_148_1; +static TX_THREAD thread_149_1; +static TX_THREAD thread_150_1; +static TX_THREAD thread_151_1; +static TX_THREAD thread_152_1; +static TX_THREAD thread_153_1; +static TX_THREAD thread_154_1; +static TX_THREAD thread_155_1; +static TX_THREAD thread_156_1; +static TX_THREAD thread_157_1; +static TX_THREAD thread_158_1; +static TX_THREAD thread_159_1; +static TX_THREAD thread_160_1; +static TX_THREAD thread_161_1; +static TX_THREAD thread_162_1; +static TX_THREAD thread_163_1; +static TX_THREAD thread_164_1; +static TX_THREAD thread_165_1; +static TX_THREAD thread_166_1; +static TX_THREAD thread_167_1; +static TX_THREAD thread_168_1; +static TX_THREAD thread_169_1; +static TX_THREAD thread_170_1; +static TX_THREAD thread_171_1; +static TX_THREAD thread_172_1; +static TX_THREAD thread_173_1; +static TX_THREAD thread_174_1; +static TX_THREAD thread_175_1; +static TX_THREAD thread_176_1; +static TX_THREAD thread_177_1; +static TX_THREAD thread_178_1; +static TX_THREAD thread_179_1; +static TX_THREAD thread_180_1; +static TX_THREAD thread_181_1; +static TX_THREAD thread_182_1; +static TX_THREAD thread_183_1; +static TX_THREAD thread_184_1; +static TX_THREAD thread_185_1; +static TX_THREAD thread_186_1; +static TX_THREAD thread_187_1; +static TX_THREAD thread_188_1; +static TX_THREAD thread_189_1; +static TX_THREAD thread_190_1; +static TX_THREAD thread_191_1; +static TX_THREAD thread_192_1; +static TX_THREAD thread_193_1; +static TX_THREAD thread_194_1; +static TX_THREAD thread_195_1; +static TX_THREAD thread_196_1; +static TX_THREAD thread_197_1; +static TX_THREAD thread_198_1; +static TX_THREAD thread_199_1; +static TX_THREAD thread_200_1; +static TX_THREAD thread_201_1; +static TX_THREAD thread_202_1; +static TX_THREAD thread_203_1; +static TX_THREAD thread_204_1; +static TX_THREAD thread_205_1; +static TX_THREAD thread_206_1; +static TX_THREAD thread_207_1; +static TX_THREAD thread_208_1; +static TX_THREAD thread_209_1; +static TX_THREAD thread_210_1; +static TX_THREAD thread_211_1; +static TX_THREAD thread_212_1; +static TX_THREAD thread_213_1; +static TX_THREAD thread_214_1; +static TX_THREAD thread_215_1; +static TX_THREAD thread_216_1; +static TX_THREAD thread_217_1; +static TX_THREAD thread_218_1; +static TX_THREAD thread_219_1; +static TX_THREAD thread_220_1; +static TX_THREAD thread_221_1; +static TX_THREAD thread_222_1; +static TX_THREAD thread_223_1; +static TX_THREAD thread_224_1; +static TX_THREAD thread_225_1; +static TX_THREAD thread_226_1; +static TX_THREAD thread_227_1; +static TX_THREAD thread_228_1; +static TX_THREAD thread_229_1; +static TX_THREAD thread_230_1; +static TX_THREAD thread_231_1; +static TX_THREAD thread_232_1; +static TX_THREAD thread_233_1; +static TX_THREAD thread_234_1; +static TX_THREAD thread_235_1; +static TX_THREAD thread_236_1; +static TX_THREAD thread_237_1; +static TX_THREAD thread_238_1; +static TX_THREAD thread_239_1; +static TX_THREAD thread_240_1; +static TX_THREAD thread_241_1; +static TX_THREAD thread_242_1; +static TX_THREAD thread_243_1; +static TX_THREAD thread_244_1; +static TX_THREAD thread_245_1; +static TX_THREAD thread_246_1; +static TX_THREAD thread_247_1; +static TX_THREAD thread_248_1; +static TX_THREAD thread_249_1; +static TX_THREAD thread_250_1; +static TX_THREAD thread_251_1; +static TX_THREAD thread_252_1; +static TX_THREAD thread_253_1; +static TX_THREAD thread_254_1; +static TX_THREAD thread_255_1; + +static TX_THREAD thread_0_2; +static TX_THREAD thread_1_2; +static TX_THREAD thread_2_2; +static TX_THREAD thread_3_2; +static TX_THREAD thread_4_2; +static TX_THREAD thread_5_2; +static TX_THREAD thread_6_2; +static TX_THREAD thread_7_2; +static TX_THREAD thread_8_2; +static TX_THREAD thread_9_2; +static TX_THREAD thread_10_2; +static TX_THREAD thread_11_2; +static TX_THREAD thread_12_2; +static TX_THREAD thread_13_2; +static TX_THREAD thread_14_2; +static TX_THREAD thread_15_2; +static TX_THREAD thread_16_2; +static TX_THREAD thread_17_2; +static TX_THREAD thread_18_2; +static TX_THREAD thread_19_2; +static TX_THREAD thread_20_2; +static TX_THREAD thread_21_2; +static TX_THREAD thread_22_2; +static TX_THREAD thread_23_2; +static TX_THREAD thread_24_2; +static TX_THREAD thread_25_2; +static TX_THREAD thread_26_2; +static TX_THREAD thread_27_2; +static TX_THREAD thread_28_2; +static TX_THREAD thread_29_2; +static TX_THREAD thread_30_2; +static TX_THREAD thread_31_2; +static TX_THREAD thread_32_2; +static TX_THREAD thread_33_2; +static TX_THREAD thread_34_2; +static TX_THREAD thread_35_2; +static TX_THREAD thread_36_2; +static TX_THREAD thread_37_2; +static TX_THREAD thread_38_2; +static TX_THREAD thread_39_2; +static TX_THREAD thread_40_2; +static TX_THREAD thread_41_2; +static TX_THREAD thread_42_2; +static TX_THREAD thread_43_2; +static TX_THREAD thread_44_2; +static TX_THREAD thread_45_2; +static TX_THREAD thread_46_2; +static TX_THREAD thread_47_2; +static TX_THREAD thread_48_2; +static TX_THREAD thread_49_2; +static TX_THREAD thread_50_2; +static TX_THREAD thread_51_2; +static TX_THREAD thread_52_2; +static TX_THREAD thread_53_2; +static TX_THREAD thread_54_2; +static TX_THREAD thread_55_2; +static TX_THREAD thread_56_2; +static TX_THREAD thread_57_2; +static TX_THREAD thread_58_2; +static TX_THREAD thread_59_2; +static TX_THREAD thread_60_2; +static TX_THREAD thread_61_2; +static TX_THREAD thread_62_2; +static TX_THREAD thread_63_2; +static TX_THREAD thread_64_2; +static TX_THREAD thread_65_2; +static TX_THREAD thread_66_2; +static TX_THREAD thread_67_2; +static TX_THREAD thread_68_2; +static TX_THREAD thread_69_2; +static TX_THREAD thread_70_2; +static TX_THREAD thread_71_2; +static TX_THREAD thread_72_2; +static TX_THREAD thread_73_2; +static TX_THREAD thread_74_2; +static TX_THREAD thread_75_2; +static TX_THREAD thread_76_2; +static TX_THREAD thread_77_2; +static TX_THREAD thread_78_2; +static TX_THREAD thread_79_2; +static TX_THREAD thread_80_2; +static TX_THREAD thread_81_2; +static TX_THREAD thread_82_2; +static TX_THREAD thread_83_2; +static TX_THREAD thread_84_2; +static TX_THREAD thread_85_2; +static TX_THREAD thread_86_2; +static TX_THREAD thread_87_2; +static TX_THREAD thread_88_2; +static TX_THREAD thread_89_2; +static TX_THREAD thread_90_2; +static TX_THREAD thread_91_2; +static TX_THREAD thread_92_2; +static TX_THREAD thread_93_2; +static TX_THREAD thread_94_2; +static TX_THREAD thread_95_2; +static TX_THREAD thread_96_2; +static TX_THREAD thread_97_2; +static TX_THREAD thread_98_2; +static TX_THREAD thread_99_2; +static TX_THREAD thread_100_2; +static TX_THREAD thread_101_2; +static TX_THREAD thread_102_2; +static TX_THREAD thread_103_2; +static TX_THREAD thread_104_2; +static TX_THREAD thread_105_2; +static TX_THREAD thread_106_2; +static TX_THREAD thread_107_2; +static TX_THREAD thread_108_2; +static TX_THREAD thread_109_2; +static TX_THREAD thread_110_2; +static TX_THREAD thread_111_2; +static TX_THREAD thread_112_2; +static TX_THREAD thread_113_2; +static TX_THREAD thread_114_2; +static TX_THREAD thread_115_2; +static TX_THREAD thread_116_2; +static TX_THREAD thread_117_2; +static TX_THREAD thread_118_2; +static TX_THREAD thread_119_2; +static TX_THREAD thread_120_2; +static TX_THREAD thread_121_2; +static TX_THREAD thread_122_2; +static TX_THREAD thread_123_2; +static TX_THREAD thread_124_2; +static TX_THREAD thread_125_2; +static TX_THREAD thread_126_2; +static TX_THREAD thread_127_2; +static TX_THREAD thread_128_2; +static TX_THREAD thread_129_2; +static TX_THREAD thread_130_2; +static TX_THREAD thread_131_2; +static TX_THREAD thread_132_2; +static TX_THREAD thread_133_2; +static TX_THREAD thread_134_2; +static TX_THREAD thread_135_2; +static TX_THREAD thread_136_2; +static TX_THREAD thread_137_2; +static TX_THREAD thread_138_2; +static TX_THREAD thread_139_2; +static TX_THREAD thread_140_2; +static TX_THREAD thread_141_2; +static TX_THREAD thread_142_2; +static TX_THREAD thread_143_2; +static TX_THREAD thread_144_2; +static TX_THREAD thread_145_2; +static TX_THREAD thread_146_2; +static TX_THREAD thread_147_2; +static TX_THREAD thread_148_2; +static TX_THREAD thread_149_2; +static TX_THREAD thread_150_2; +static TX_THREAD thread_151_2; +static TX_THREAD thread_152_2; +static TX_THREAD thread_153_2; +static TX_THREAD thread_154_2; +static TX_THREAD thread_155_2; +static TX_THREAD thread_156_2; +static TX_THREAD thread_157_2; +static TX_THREAD thread_158_2; +static TX_THREAD thread_159_2; +static TX_THREAD thread_160_2; +static TX_THREAD thread_161_2; +static TX_THREAD thread_162_2; +static TX_THREAD thread_163_2; +static TX_THREAD thread_164_2; +static TX_THREAD thread_165_2; +static TX_THREAD thread_166_2; +static TX_THREAD thread_167_2; +static TX_THREAD thread_168_2; +static TX_THREAD thread_169_2; +static TX_THREAD thread_170_2; +static TX_THREAD thread_171_2; +static TX_THREAD thread_172_2; +static TX_THREAD thread_173_2; +static TX_THREAD thread_174_2; +static TX_THREAD thread_175_2; +static TX_THREAD thread_176_2; +static TX_THREAD thread_177_2; +static TX_THREAD thread_178_2; +static TX_THREAD thread_179_2; +static TX_THREAD thread_180_2; +static TX_THREAD thread_181_2; +static TX_THREAD thread_182_2; +static TX_THREAD thread_183_2; +static TX_THREAD thread_184_2; +static TX_THREAD thread_185_2; +static TX_THREAD thread_186_2; +static TX_THREAD thread_187_2; +static TX_THREAD thread_188_2; +static TX_THREAD thread_189_2; +static TX_THREAD thread_190_2; +static TX_THREAD thread_191_2; +static TX_THREAD thread_192_2; +static TX_THREAD thread_193_2; +static TX_THREAD thread_194_2; +static TX_THREAD thread_195_2; +static TX_THREAD thread_196_2; +static TX_THREAD thread_197_2; +static TX_THREAD thread_198_2; +static TX_THREAD thread_199_2; +static TX_THREAD thread_200_2; +static TX_THREAD thread_201_2; +static TX_THREAD thread_202_2; +static TX_THREAD thread_203_2; +static TX_THREAD thread_204_2; +static TX_THREAD thread_205_2; +static TX_THREAD thread_206_2; +static TX_THREAD thread_207_2; +static TX_THREAD thread_208_2; +static TX_THREAD thread_209_2; +static TX_THREAD thread_210_2; +static TX_THREAD thread_211_2; +static TX_THREAD thread_212_2; +static TX_THREAD thread_213_2; +static TX_THREAD thread_214_2; +static TX_THREAD thread_215_2; +static TX_THREAD thread_216_2; +static TX_THREAD thread_217_2; +static TX_THREAD thread_218_2; +static TX_THREAD thread_219_2; +static TX_THREAD thread_220_2; +static TX_THREAD thread_221_2; +static TX_THREAD thread_222_2; +static TX_THREAD thread_223_2; +static TX_THREAD thread_224_2; +static TX_THREAD thread_225_2; +static TX_THREAD thread_226_2; +static TX_THREAD thread_227_2; +static TX_THREAD thread_228_2; +static TX_THREAD thread_229_2; +static TX_THREAD thread_230_2; +static TX_THREAD thread_231_2; +static TX_THREAD thread_232_2; +static TX_THREAD thread_233_2; +static TX_THREAD thread_234_2; +static TX_THREAD thread_235_2; +static TX_THREAD thread_236_2; +static TX_THREAD thread_237_2; +static TX_THREAD thread_238_2; +static TX_THREAD thread_239_2; +static TX_THREAD thread_240_2; +static TX_THREAD thread_241_2; +static TX_THREAD thread_242_2; +static TX_THREAD thread_243_2; +static TX_THREAD thread_244_2; +static TX_THREAD thread_245_2; +static TX_THREAD thread_246_2; +static TX_THREAD thread_247_2; +static TX_THREAD thread_248_2; +static TX_THREAD thread_249_2; +static TX_THREAD thread_250_2; +static TX_THREAD thread_251_2; +static TX_THREAD thread_252_2; +static TX_THREAD thread_253_2; +static TX_THREAD thread_254_2; +static TX_THREAD thread_255_2; + +static TX_THREAD thread_0_3; +static TX_THREAD thread_1_3; +static TX_THREAD thread_2_3; +static TX_THREAD thread_3_3; +static TX_THREAD thread_4_3; +static TX_THREAD thread_5_3; +static TX_THREAD thread_6_3; +static TX_THREAD thread_7_3; +static TX_THREAD thread_8_3; +static TX_THREAD thread_9_3; +static TX_THREAD thread_10_3; +static TX_THREAD thread_11_3; +static TX_THREAD thread_12_3; +static TX_THREAD thread_13_3; +static TX_THREAD thread_14_3; +static TX_THREAD thread_15_3; +static TX_THREAD thread_16_3; +static TX_THREAD thread_17_3; +static TX_THREAD thread_18_3; +static TX_THREAD thread_19_3; +static TX_THREAD thread_20_3; +static TX_THREAD thread_21_3; +static TX_THREAD thread_22_3; +static TX_THREAD thread_23_3; +static TX_THREAD thread_24_3; +static TX_THREAD thread_25_3; +static TX_THREAD thread_26_3; +static TX_THREAD thread_27_3; +static TX_THREAD thread_28_3; +static TX_THREAD thread_29_3; +static TX_THREAD thread_30_3; +static TX_THREAD thread_31_3; +static TX_THREAD thread_32_3; +static TX_THREAD thread_33_3; +static TX_THREAD thread_34_3; +static TX_THREAD thread_35_3; +static TX_THREAD thread_36_3; +static TX_THREAD thread_37_3; +static TX_THREAD thread_38_3; +static TX_THREAD thread_39_3; +static TX_THREAD thread_40_3; +static TX_THREAD thread_41_3; +static TX_THREAD thread_42_3; +static TX_THREAD thread_43_3; +static TX_THREAD thread_44_3; +static TX_THREAD thread_45_3; +static TX_THREAD thread_46_3; +static TX_THREAD thread_47_3; +static TX_THREAD thread_48_3; +static TX_THREAD thread_49_3; +static TX_THREAD thread_50_3; +static TX_THREAD thread_51_3; +static TX_THREAD thread_52_3; +static TX_THREAD thread_53_3; +static TX_THREAD thread_54_3; +static TX_THREAD thread_55_3; +static TX_THREAD thread_56_3; +static TX_THREAD thread_57_3; +static TX_THREAD thread_58_3; +static TX_THREAD thread_59_3; +static TX_THREAD thread_60_3; +static TX_THREAD thread_61_3; +static TX_THREAD thread_62_3; +static TX_THREAD thread_63_3; +static TX_THREAD thread_64_3; +static TX_THREAD thread_65_3; +static TX_THREAD thread_66_3; +static TX_THREAD thread_67_3; +static TX_THREAD thread_68_3; +static TX_THREAD thread_69_3; +static TX_THREAD thread_70_3; +static TX_THREAD thread_71_3; +static TX_THREAD thread_72_3; +static TX_THREAD thread_73_3; +static TX_THREAD thread_74_3; +static TX_THREAD thread_75_3; +static TX_THREAD thread_76_3; +static TX_THREAD thread_77_3; +static TX_THREAD thread_78_3; +static TX_THREAD thread_79_3; +static TX_THREAD thread_80_3; +static TX_THREAD thread_81_3; +static TX_THREAD thread_82_3; +static TX_THREAD thread_83_3; +static TX_THREAD thread_84_3; +static TX_THREAD thread_85_3; +static TX_THREAD thread_86_3; +static TX_THREAD thread_87_3; +static TX_THREAD thread_88_3; +static TX_THREAD thread_89_3; +static TX_THREAD thread_90_3; +static TX_THREAD thread_91_3; +static TX_THREAD thread_92_3; +static TX_THREAD thread_93_3; +static TX_THREAD thread_94_3; +static TX_THREAD thread_95_3; +static TX_THREAD thread_96_3; +static TX_THREAD thread_97_3; +static TX_THREAD thread_98_3; +static TX_THREAD thread_99_3; +static TX_THREAD thread_100_3; +static TX_THREAD thread_101_3; +static TX_THREAD thread_102_3; +static TX_THREAD thread_103_3; +static TX_THREAD thread_104_3; +static TX_THREAD thread_105_3; +static TX_THREAD thread_106_3; +static TX_THREAD thread_107_3; +static TX_THREAD thread_108_3; +static TX_THREAD thread_109_3; +static TX_THREAD thread_110_3; +static TX_THREAD thread_111_3; +static TX_THREAD thread_112_3; +static TX_THREAD thread_113_3; +static TX_THREAD thread_114_3; +static TX_THREAD thread_115_3; +static TX_THREAD thread_116_3; +static TX_THREAD thread_117_3; +static TX_THREAD thread_118_3; +static TX_THREAD thread_119_3; +static TX_THREAD thread_120_3; +static TX_THREAD thread_121_3; +static TX_THREAD thread_122_3; +static TX_THREAD thread_123_3; +static TX_THREAD thread_124_3; +static TX_THREAD thread_125_3; +static TX_THREAD thread_126_3; +static TX_THREAD thread_127_3; +static TX_THREAD thread_128_3; +static TX_THREAD thread_129_3; +static TX_THREAD thread_130_3; +static TX_THREAD thread_131_3; +static TX_THREAD thread_132_3; +static TX_THREAD thread_133_3; +static TX_THREAD thread_134_3; +static TX_THREAD thread_135_3; +static TX_THREAD thread_136_3; +static TX_THREAD thread_137_3; +static TX_THREAD thread_138_3; +static TX_THREAD thread_139_3; +static TX_THREAD thread_140_3; +static TX_THREAD thread_141_3; +static TX_THREAD thread_142_3; +static TX_THREAD thread_143_3; +static TX_THREAD thread_144_3; +static TX_THREAD thread_145_3; +static TX_THREAD thread_146_3; +static TX_THREAD thread_147_3; +static TX_THREAD thread_148_3; +static TX_THREAD thread_149_3; +static TX_THREAD thread_150_3; +static TX_THREAD thread_151_3; +static TX_THREAD thread_152_3; +static TX_THREAD thread_153_3; +static TX_THREAD thread_154_3; +static TX_THREAD thread_155_3; +static TX_THREAD thread_156_3; +static TX_THREAD thread_157_3; +static TX_THREAD thread_158_3; +static TX_THREAD thread_159_3; +static TX_THREAD thread_160_3; +static TX_THREAD thread_161_3; +static TX_THREAD thread_162_3; +static TX_THREAD thread_163_3; +static TX_THREAD thread_164_3; +static TX_THREAD thread_165_3; +static TX_THREAD thread_166_3; +static TX_THREAD thread_167_3; +static TX_THREAD thread_168_3; +static TX_THREAD thread_169_3; +static TX_THREAD thread_170_3; +static TX_THREAD thread_171_3; +static TX_THREAD thread_172_3; +static TX_THREAD thread_173_3; +static TX_THREAD thread_174_3; +static TX_THREAD thread_175_3; +static TX_THREAD thread_176_3; +static TX_THREAD thread_177_3; +static TX_THREAD thread_178_3; +static TX_THREAD thread_179_3; +static TX_THREAD thread_180_3; +static TX_THREAD thread_181_3; +static TX_THREAD thread_182_3; +static TX_THREAD thread_183_3; +static TX_THREAD thread_184_3; +static TX_THREAD thread_185_3; +static TX_THREAD thread_186_3; +static TX_THREAD thread_187_3; +static TX_THREAD thread_188_3; +static TX_THREAD thread_189_3; +static TX_THREAD thread_190_3; +static TX_THREAD thread_191_3; +static TX_THREAD thread_192_3; +static TX_THREAD thread_193_3; +static TX_THREAD thread_194_3; +static TX_THREAD thread_195_3; +static TX_THREAD thread_196_3; +static TX_THREAD thread_197_3; +static TX_THREAD thread_198_3; +static TX_THREAD thread_199_3; +static TX_THREAD thread_200_3; +static TX_THREAD thread_201_3; +static TX_THREAD thread_202_3; +static TX_THREAD thread_203_3; +static TX_THREAD thread_204_3; +static TX_THREAD thread_205_3; +static TX_THREAD thread_206_3; +static TX_THREAD thread_207_3; +static TX_THREAD thread_208_3; +static TX_THREAD thread_209_3; +static TX_THREAD thread_210_3; +static TX_THREAD thread_211_3; +static TX_THREAD thread_212_3; +static TX_THREAD thread_213_3; +static TX_THREAD thread_214_3; +static TX_THREAD thread_215_3; +static TX_THREAD thread_216_3; +static TX_THREAD thread_217_3; +static TX_THREAD thread_218_3; +static TX_THREAD thread_219_3; +static TX_THREAD thread_220_3; +static TX_THREAD thread_221_3; +static TX_THREAD thread_222_3; +static TX_THREAD thread_223_3; +static TX_THREAD thread_224_3; +static TX_THREAD thread_225_3; +static TX_THREAD thread_226_3; +static TX_THREAD thread_227_3; +static TX_THREAD thread_228_3; +static TX_THREAD thread_229_3; +static TX_THREAD thread_230_3; +static TX_THREAD thread_231_3; +static TX_THREAD thread_232_3; +static TX_THREAD thread_233_3; +static TX_THREAD thread_234_3; +static TX_THREAD thread_235_3; +static TX_THREAD thread_236_3; +static TX_THREAD thread_237_3; +static TX_THREAD thread_238_3; +static TX_THREAD thread_239_3; +static TX_THREAD thread_240_3; +static TX_THREAD thread_241_3; +static TX_THREAD thread_242_3; +static TX_THREAD thread_243_3; +static TX_THREAD thread_244_3; +static TX_THREAD thread_245_3; +static TX_THREAD thread_246_3; +static TX_THREAD thread_247_3; +static TX_THREAD thread_248_3; +static TX_THREAD thread_249_3; +static TX_THREAD thread_250_3; +static TX_THREAD thread_251_3; +static TX_THREAD thread_252_3; +static TX_THREAD thread_253_3; +static TX_THREAD thread_254_3; +static TX_THREAD thread_255_3; + +/* Define test array. */ + +static TX_THREAD *_smp_randomized_source_array[] = { +{&thread_0}, +{&thread_1}, +{&thread_2}, +{&thread_3}, +{&thread_4}, +{&thread_5}, +{&thread_6}, +{&thread_7}, +{&thread_8}, +{&thread_9}, +{&thread_10}, +{&thread_11}, +{&thread_12}, +{&thread_13}, +{&thread_14}, +{&thread_15}, +{&thread_16}, +{&thread_17}, +{&thread_18}, +{&thread_19}, +{&thread_20}, +{&thread_21}, +{&thread_22}, +{&thread_23}, +{&thread_24}, +{&thread_25}, +{&thread_26}, +{&thread_27}, +{&thread_28}, +{&thread_29}, +{&thread_30}, +{&thread_31}, +{&thread_32}, +{&thread_33}, +{&thread_34}, +{&thread_35}, +{&thread_36}, +{&thread_37}, +{&thread_38}, +{&thread_39}, +{&thread_40}, +{&thread_41}, +{&thread_42}, +{&thread_43}, +{&thread_44}, +{&thread_45}, +{&thread_46}, +{&thread_47}, +{&thread_48}, +{&thread_49}, +{&thread_50}, +{&thread_51}, +{&thread_52}, +{&thread_53}, +{&thread_54}, +{&thread_55}, +{&thread_56}, +{&thread_57}, +{&thread_58}, +{&thread_59}, +{&thread_60}, +{&thread_61}, +{&thread_62}, +{&thread_63}, +{&thread_64}, +{&thread_65}, +{&thread_66}, +{&thread_67}, +{&thread_68}, +{&thread_69}, +{&thread_70}, +{&thread_71}, +{&thread_72}, +{&thread_73}, +{&thread_74}, +{&thread_75}, +{&thread_76}, +{&thread_77}, +{&thread_78}, +{&thread_79}, +{&thread_80}, +{&thread_81}, +{&thread_82}, +{&thread_83}, +{&thread_84}, +{&thread_85}, +{&thread_86}, +{&thread_87}, +{&thread_88}, +{&thread_89}, +{&thread_90}, +{&thread_91}, +{&thread_92}, +{&thread_93}, +{&thread_94}, +{&thread_95}, +{&thread_96}, +{&thread_97}, +{&thread_98}, +{&thread_99}, +{&thread_100}, +{&thread_101}, +{&thread_102}, +{&thread_103}, +{&thread_104}, +{&thread_105}, +{&thread_106}, +{&thread_107}, +{&thread_108}, +{&thread_109}, +{&thread_110}, +{&thread_111}, +{&thread_112}, +{&thread_113}, +{&thread_114}, +{&thread_115}, +{&thread_116}, +{&thread_117}, +{&thread_118}, +{&thread_119}, +{&thread_120}, +{&thread_121}, +{&thread_122}, +{&thread_123}, +{&thread_124}, +{&thread_125}, +{&thread_126}, +{&thread_127}, +{&thread_128}, +{&thread_129}, +{&thread_130}, +{&thread_131}, +{&thread_132}, +{&thread_133}, +{&thread_134}, +{&thread_135}, +{&thread_136}, +{&thread_137}, +{&thread_138}, +{&thread_139}, +{&thread_140}, +{&thread_141}, +{&thread_142}, +{&thread_143}, +{&thread_144}, +{&thread_145}, +{&thread_146}, +{&thread_147}, +{&thread_148}, +{&thread_149}, +{&thread_150}, +{&thread_151}, +{&thread_152}, +{&thread_153}, +{&thread_154}, +{&thread_155}, +{&thread_156}, +{&thread_157}, +{&thread_158}, +{&thread_159}, +{&thread_160}, +{&thread_161}, +{&thread_162}, +{&thread_163}, +{&thread_164}, +{&thread_165}, +{&thread_166}, +{&thread_167}, +{&thread_168}, +{&thread_169}, +{&thread_170}, +{&thread_171}, +{&thread_172}, +{&thread_173}, +{&thread_174}, +{&thread_175}, +{&thread_176}, +{&thread_177}, +{&thread_178}, +{&thread_179}, +{&thread_180}, +{&thread_181}, +{&thread_182}, +{&thread_183}, +{&thread_184}, +{&thread_185}, +{&thread_186}, +{&thread_187}, +{&thread_188}, +{&thread_189}, +{&thread_190}, +{&thread_191}, +{&thread_192}, +{&thread_193}, +{&thread_194}, +{&thread_195}, +{&thread_196}, +{&thread_197}, +{&thread_198}, +{&thread_199}, +{&thread_200}, +{&thread_201}, +{&thread_202}, +{&thread_203}, +{&thread_204}, +{&thread_205}, +{&thread_206}, +{&thread_207}, +{&thread_208}, +{&thread_209}, +{&thread_210}, +{&thread_211}, +{&thread_212}, +{&thread_213}, +{&thread_214}, +{&thread_215}, +{&thread_216}, +{&thread_217}, +{&thread_218}, +{&thread_219}, +{&thread_220}, +{&thread_221}, +{&thread_222}, +{&thread_223}, +{&thread_224}, +{&thread_225}, +{&thread_226}, +{&thread_227}, +{&thread_228}, +{&thread_229}, +{&thread_230}, +{&thread_231}, +{&thread_232}, +{&thread_233}, +{&thread_234}, +{&thread_235}, +{&thread_236}, +{&thread_237}, +{&thread_238}, +{&thread_239}, +{&thread_240}, +{&thread_241}, +{&thread_242}, +{&thread_243}, +{&thread_244}, +{&thread_245}, +{&thread_246}, +{&thread_247}, +{&thread_248}, +{&thread_249}, +{&thread_250}, +{&thread_251}, +{&thread_252}, +{&thread_253}, +{&thread_254}, +{&thread_255}, + +{&thread_0_1}, +{&thread_1_1}, +{&thread_2_1}, +{&thread_3_1}, +{&thread_4_1}, +{&thread_5_1}, +{&thread_6_1}, +{&thread_7_1}, +{&thread_8_1}, +{&thread_9_1}, +{&thread_10_1}, +{&thread_11_1}, +{&thread_12_1}, +{&thread_13_1}, +{&thread_14_1}, +{&thread_15_1}, +{&thread_16_1}, +{&thread_17_1}, +{&thread_18_1}, +{&thread_19_1}, +{&thread_20_1}, +{&thread_21_1}, +{&thread_22_1}, +{&thread_23_1}, +{&thread_24_1}, +{&thread_25_1}, +{&thread_26_1}, +{&thread_27_1}, +{&thread_28_1}, +{&thread_29_1}, +{&thread_30_1}, +{&thread_31_1}, +{&thread_32_1}, +{&thread_33_1}, +{&thread_34_1}, +{&thread_35_1}, +{&thread_36_1}, +{&thread_37_1}, +{&thread_38_1}, +{&thread_39_1}, +{&thread_40_1}, +{&thread_41_1}, +{&thread_42_1}, +{&thread_43_1}, +{&thread_44_1}, +{&thread_45_1}, +{&thread_46_1}, +{&thread_47_1}, +{&thread_48_1}, +{&thread_49_1}, +{&thread_50_1}, +{&thread_51_1}, +{&thread_52_1}, +{&thread_53_1}, +{&thread_54_1}, +{&thread_55_1}, +{&thread_56_1}, +{&thread_57_1}, +{&thread_58_1}, +{&thread_59_1}, +{&thread_60_1}, +{&thread_61_1}, +{&thread_62_1}, +{&thread_63_1}, +{&thread_64_1}, +{&thread_65_1}, +{&thread_66_1}, +{&thread_67_1}, +{&thread_68_1}, +{&thread_69_1}, +{&thread_70_1}, +{&thread_71_1}, +{&thread_72_1}, +{&thread_73_1}, +{&thread_74_1}, +{&thread_75_1}, +{&thread_76_1}, +{&thread_77_1}, +{&thread_78_1}, +{&thread_79_1}, +{&thread_80_1}, +{&thread_81_1}, +{&thread_82_1}, +{&thread_83_1}, +{&thread_84_1}, +{&thread_85_1}, +{&thread_86_1}, +{&thread_87_1}, +{&thread_88_1}, +{&thread_89_1}, +{&thread_90_1}, +{&thread_91_1}, +{&thread_92_1}, +{&thread_93_1}, +{&thread_94_1}, +{&thread_95_1}, +{&thread_96_1}, +{&thread_97_1}, +{&thread_98_1}, +{&thread_99_1}, +{&thread_100_1}, +{&thread_101_1}, +{&thread_102_1}, +{&thread_103_1}, +{&thread_104_1}, +{&thread_105_1}, +{&thread_106_1}, +{&thread_107_1}, +{&thread_108_1}, +{&thread_109_1}, +{&thread_110_1}, +{&thread_111_1}, +{&thread_112_1}, +{&thread_113_1}, +{&thread_114_1}, +{&thread_115_1}, +{&thread_116_1}, +{&thread_117_1}, +{&thread_118_1}, +{&thread_119_1}, +{&thread_120_1}, +{&thread_121_1}, +{&thread_122_1}, +{&thread_123_1}, +{&thread_124_1}, +{&thread_125_1}, +{&thread_126_1}, +{&thread_127_1}, +{&thread_128_1}, +{&thread_129_1}, +{&thread_130_1}, +{&thread_131_1}, +{&thread_132_1}, +{&thread_133_1}, +{&thread_134_1}, +{&thread_135_1}, +{&thread_136_1}, +{&thread_137_1}, +{&thread_138_1}, +{&thread_139_1}, +{&thread_140_1}, +{&thread_141_1}, +{&thread_142_1}, +{&thread_143_1}, +{&thread_144_1}, +{&thread_145_1}, +{&thread_146_1}, +{&thread_147_1}, +{&thread_148_1}, +{&thread_149_1}, +{&thread_150_1}, +{&thread_151_1}, +{&thread_152_1}, +{&thread_153_1}, +{&thread_154_1}, +{&thread_155_1}, +{&thread_156_1}, +{&thread_157_1}, +{&thread_158_1}, +{&thread_159_1}, +{&thread_160_1}, +{&thread_161_1}, +{&thread_162_1}, +{&thread_163_1}, +{&thread_164_1}, +{&thread_165_1}, +{&thread_166_1}, +{&thread_167_1}, +{&thread_168_1}, +{&thread_169_1}, +{&thread_170_1}, +{&thread_171_1}, +{&thread_172_1}, +{&thread_173_1}, +{&thread_174_1}, +{&thread_175_1}, +{&thread_176_1}, +{&thread_177_1}, +{&thread_178_1}, +{&thread_179_1}, +{&thread_180_1}, +{&thread_181_1}, +{&thread_182_1}, +{&thread_183_1}, +{&thread_184_1}, +{&thread_185_1}, +{&thread_186_1}, +{&thread_187_1}, +{&thread_188_1}, +{&thread_189_1}, +{&thread_190_1}, +{&thread_191_1}, +{&thread_192_1}, +{&thread_193_1}, +{&thread_194_1}, +{&thread_195_1}, +{&thread_196_1}, +{&thread_197_1}, +{&thread_198_1}, +{&thread_199_1}, +{&thread_200_1}, +{&thread_201_1}, +{&thread_202_1}, +{&thread_203_1}, +{&thread_204_1}, +{&thread_205_1}, +{&thread_206_1}, +{&thread_207_1}, +{&thread_208_1}, +{&thread_209_1}, +{&thread_210_1}, +{&thread_211_1}, +{&thread_212_1}, +{&thread_213_1}, +{&thread_214_1}, +{&thread_215_1}, +{&thread_216_1}, +{&thread_217_1}, +{&thread_218_1}, +{&thread_219_1}, +{&thread_220_1}, +{&thread_221_1}, +{&thread_222_1}, +{&thread_223_1}, +{&thread_224_1}, +{&thread_225_1}, +{&thread_226_1}, +{&thread_227_1}, +{&thread_228_1}, +{&thread_229_1}, +{&thread_230_1}, +{&thread_231_1}, +{&thread_232_1}, +{&thread_233_1}, +{&thread_234_1}, +{&thread_235_1}, +{&thread_236_1}, +{&thread_237_1}, +{&thread_238_1}, +{&thread_239_1}, +{&thread_240_1}, +{&thread_241_1}, +{&thread_242_1}, +{&thread_243_1}, +{&thread_244_1}, +{&thread_245_1}, +{&thread_246_1}, +{&thread_247_1}, +{&thread_248_1}, +{&thread_249_1}, +{&thread_250_1}, +{&thread_251_1}, +{&thread_252_1}, +{&thread_253_1}, +{&thread_254_1}, +{&thread_255_1}, + +{&thread_0_2}, +{&thread_1_2}, +{&thread_2_2}, +{&thread_3_2}, +{&thread_4_2}, +{&thread_5_2}, +{&thread_6_2}, +{&thread_7_2}, +{&thread_8_2}, +{&thread_9_2}, +{&thread_10_2}, +{&thread_11_2}, +{&thread_12_2}, +{&thread_13_2}, +{&thread_14_2}, +{&thread_15_2}, +{&thread_16_2}, +{&thread_17_2}, +{&thread_18_2}, +{&thread_19_2}, +{&thread_20_2}, +{&thread_21_2}, +{&thread_22_2}, +{&thread_23_2}, +{&thread_24_2}, +{&thread_25_2}, +{&thread_26_2}, +{&thread_27_2}, +{&thread_28_2}, +{&thread_29_2}, +{&thread_30_2}, +{&thread_31_2}, +{&thread_32_2}, +{&thread_33_2}, +{&thread_34_2}, +{&thread_35_2}, +{&thread_36_2}, +{&thread_37_2}, +{&thread_38_2}, +{&thread_39_2}, +{&thread_40_2}, +{&thread_41_2}, +{&thread_42_2}, +{&thread_43_2}, +{&thread_44_2}, +{&thread_45_2}, +{&thread_46_2}, +{&thread_47_2}, +{&thread_48_2}, +{&thread_49_2}, +{&thread_50_2}, +{&thread_51_2}, +{&thread_52_2}, +{&thread_53_2}, +{&thread_54_2}, +{&thread_55_2}, +{&thread_56_2}, +{&thread_57_2}, +{&thread_58_2}, +{&thread_59_2}, +{&thread_60_2}, +{&thread_61_2}, +{&thread_62_2}, +{&thread_63_2}, +{&thread_64_2}, +{&thread_65_2}, +{&thread_66_2}, +{&thread_67_2}, +{&thread_68_2}, +{&thread_69_2}, +{&thread_70_2}, +{&thread_71_2}, +{&thread_72_2}, +{&thread_73_2}, +{&thread_74_2}, +{&thread_75_2}, +{&thread_76_2}, +{&thread_77_2}, +{&thread_78_2}, +{&thread_79_2}, +{&thread_80_2}, +{&thread_81_2}, +{&thread_82_2}, +{&thread_83_2}, +{&thread_84_2}, +{&thread_85_2}, +{&thread_86_2}, +{&thread_87_2}, +{&thread_88_2}, +{&thread_89_2}, +{&thread_90_2}, +{&thread_91_2}, +{&thread_92_2}, +{&thread_93_2}, +{&thread_94_2}, +{&thread_95_2}, +{&thread_96_2}, +{&thread_97_2}, +{&thread_98_2}, +{&thread_99_2}, +{&thread_100_2}, +{&thread_101_2}, +{&thread_102_2}, +{&thread_103_2}, +{&thread_104_2}, +{&thread_105_2}, +{&thread_106_2}, +{&thread_107_2}, +{&thread_108_2}, +{&thread_109_2}, +{&thread_110_2}, +{&thread_111_2}, +{&thread_112_2}, +{&thread_113_2}, +{&thread_114_2}, +{&thread_115_2}, +{&thread_116_2}, +{&thread_117_2}, +{&thread_118_2}, +{&thread_119_2}, +{&thread_120_2}, +{&thread_121_2}, +{&thread_122_2}, +{&thread_123_2}, +{&thread_124_2}, +{&thread_125_2}, +{&thread_126_2}, +{&thread_127_2}, +{&thread_128_2}, +{&thread_129_2}, +{&thread_130_2}, +{&thread_131_2}, +{&thread_132_2}, +{&thread_133_2}, +{&thread_134_2}, +{&thread_135_2}, +{&thread_136_2}, +{&thread_137_2}, +{&thread_138_2}, +{&thread_139_2}, +{&thread_140_2}, +{&thread_141_2}, +{&thread_142_2}, +{&thread_143_2}, +{&thread_144_2}, +{&thread_145_2}, +{&thread_146_2}, +{&thread_147_2}, +{&thread_148_2}, +{&thread_149_2}, +{&thread_150_2}, +{&thread_151_2}, +{&thread_152_2}, +{&thread_153_2}, +{&thread_154_2}, +{&thread_155_2}, +{&thread_156_2}, +{&thread_157_2}, +{&thread_158_2}, +{&thread_159_2}, +{&thread_160_2}, +{&thread_161_2}, +{&thread_162_2}, +{&thread_163_2}, +{&thread_164_2}, +{&thread_165_2}, +{&thread_166_2}, +{&thread_167_2}, +{&thread_168_2}, +{&thread_169_2}, +{&thread_170_2}, +{&thread_171_2}, +{&thread_172_2}, +{&thread_173_2}, +{&thread_174_2}, +{&thread_175_2}, +{&thread_176_2}, +{&thread_177_2}, +{&thread_178_2}, +{&thread_179_2}, +{&thread_180_2}, +{&thread_181_2}, +{&thread_182_2}, +{&thread_183_2}, +{&thread_184_2}, +{&thread_185_2}, +{&thread_186_2}, +{&thread_187_2}, +{&thread_188_2}, +{&thread_189_2}, +{&thread_190_2}, +{&thread_191_2}, +{&thread_192_2}, +{&thread_193_2}, +{&thread_194_2}, +{&thread_195_2}, +{&thread_196_2}, +{&thread_197_2}, +{&thread_198_2}, +{&thread_199_2}, +{&thread_200_2}, +{&thread_201_2}, +{&thread_202_2}, +{&thread_203_2}, +{&thread_204_2}, +{&thread_205_2}, +{&thread_206_2}, +{&thread_207_2}, +{&thread_208_2}, +{&thread_209_2}, +{&thread_210_2}, +{&thread_211_2}, +{&thread_212_2}, +{&thread_213_2}, +{&thread_214_2}, +{&thread_215_2}, +{&thread_216_2}, +{&thread_217_2}, +{&thread_218_2}, +{&thread_219_2}, +{&thread_220_2}, +{&thread_221_2}, +{&thread_222_2}, +{&thread_223_2}, +{&thread_224_2}, +{&thread_225_2}, +{&thread_226_2}, +{&thread_227_2}, +{&thread_228_2}, +{&thread_229_2}, +{&thread_230_2}, +{&thread_231_2}, +{&thread_232_2}, +{&thread_233_2}, +{&thread_234_2}, +{&thread_235_2}, +{&thread_236_2}, +{&thread_237_2}, +{&thread_238_2}, +{&thread_239_2}, +{&thread_240_2}, +{&thread_241_2}, +{&thread_242_2}, +{&thread_243_2}, +{&thread_244_2}, +{&thread_245_2}, +{&thread_246_2}, +{&thread_247_2}, +{&thread_248_2}, +{&thread_249_2}, +{&thread_250_2}, +{&thread_251_2}, +{&thread_252_2}, +{&thread_253_2}, +{&thread_254_2}, +{&thread_255_2}, + +{&thread_0_3}, +{&thread_1_3}, +{&thread_2_3}, +{&thread_3_3}, +{&thread_4_3}, +{&thread_5_3}, +{&thread_6_3}, +{&thread_7_3}, +{&thread_8_3}, +{&thread_9_3}, +{&thread_10_3}, +{&thread_11_3}, +{&thread_12_3}, +{&thread_13_3}, +{&thread_14_3}, +{&thread_15_3}, +{&thread_16_3}, +{&thread_17_3}, +{&thread_18_3}, +{&thread_19_3}, +{&thread_20_3}, +{&thread_21_3}, +{&thread_22_3}, +{&thread_23_3}, +{&thread_24_3}, +{&thread_25_3}, +{&thread_26_3}, +{&thread_27_3}, +{&thread_28_3}, +{&thread_29_3}, +{&thread_30_3}, +{&thread_31_3}, +{&thread_32_3}, +{&thread_33_3}, +{&thread_34_3}, +{&thread_35_3}, +{&thread_36_3}, +{&thread_37_3}, +{&thread_38_3}, +{&thread_39_3}, +{&thread_40_3}, +{&thread_41_3}, +{&thread_42_3}, +{&thread_43_3}, +{&thread_44_3}, +{&thread_45_3}, +{&thread_46_3}, +{&thread_47_3}, +{&thread_48_3}, +{&thread_49_3}, +{&thread_50_3}, +{&thread_51_3}, +{&thread_52_3}, +{&thread_53_3}, +{&thread_54_3}, +{&thread_55_3}, +{&thread_56_3}, +{&thread_57_3}, +{&thread_58_3}, +{&thread_59_3}, +{&thread_60_3}, +{&thread_61_3}, +{&thread_62_3}, +{&thread_63_3}, +{&thread_64_3}, +{&thread_65_3}, +{&thread_66_3}, +{&thread_67_3}, +{&thread_68_3}, +{&thread_69_3}, +{&thread_70_3}, +{&thread_71_3}, +{&thread_72_3}, +{&thread_73_3}, +{&thread_74_3}, +{&thread_75_3}, +{&thread_76_3}, +{&thread_77_3}, +{&thread_78_3}, +{&thread_79_3}, +{&thread_80_3}, +{&thread_81_3}, +{&thread_82_3}, +{&thread_83_3}, +{&thread_84_3}, +{&thread_85_3}, +{&thread_86_3}, +{&thread_87_3}, +{&thread_88_3}, +{&thread_89_3}, +{&thread_90_3}, +{&thread_91_3}, +{&thread_92_3}, +{&thread_93_3}, +{&thread_94_3}, +{&thread_95_3}, +{&thread_96_3}, +{&thread_97_3}, +{&thread_98_3}, +{&thread_99_3}, +{&thread_100_3}, +{&thread_101_3}, +{&thread_102_3}, +{&thread_103_3}, +{&thread_104_3}, +{&thread_105_3}, +{&thread_106_3}, +{&thread_107_3}, +{&thread_108_3}, +{&thread_109_3}, +{&thread_110_3}, +{&thread_111_3}, +{&thread_112_3}, +{&thread_113_3}, +{&thread_114_3}, +{&thread_115_3}, +{&thread_116_3}, +{&thread_117_3}, +{&thread_118_3}, +{&thread_119_3}, +{&thread_120_3}, +{&thread_121_3}, +{&thread_122_3}, +{&thread_123_3}, +{&thread_124_3}, +{&thread_125_3}, +{&thread_126_3}, +{&thread_127_3}, +{&thread_128_3}, +{&thread_129_3}, +{&thread_130_3}, +{&thread_131_3}, +{&thread_132_3}, +{&thread_133_3}, +{&thread_134_3}, +{&thread_135_3}, +{&thread_136_3}, +{&thread_137_3}, +{&thread_138_3}, +{&thread_139_3}, +{&thread_140_3}, +{&thread_141_3}, +{&thread_142_3}, +{&thread_143_3}, +{&thread_144_3}, +{&thread_145_3}, +{&thread_146_3}, +{&thread_147_3}, +{&thread_148_3}, +{&thread_149_3}, +{&thread_150_3}, +{&thread_151_3}, +{&thread_152_3}, +{&thread_153_3}, +{&thread_154_3}, +{&thread_155_3}, +{&thread_156_3}, +{&thread_157_3}, +{&thread_158_3}, +{&thread_159_3}, +{&thread_160_3}, +{&thread_161_3}, +{&thread_162_3}, +{&thread_163_3}, +{&thread_164_3}, +{&thread_165_3}, +{&thread_166_3}, +{&thread_167_3}, +{&thread_168_3}, +{&thread_169_3}, +{&thread_170_3}, +{&thread_171_3}, +{&thread_172_3}, +{&thread_173_3}, +{&thread_174_3}, +{&thread_175_3}, +{&thread_176_3}, +{&thread_177_3}, +{&thread_178_3}, +{&thread_179_3}, +{&thread_180_3}, +{&thread_181_3}, +{&thread_182_3}, +{&thread_183_3}, +{&thread_184_3}, +{&thread_185_3}, +{&thread_186_3}, +{&thread_187_3}, +{&thread_188_3}, +{&thread_189_3}, +{&thread_190_3}, +{&thread_191_3}, +{&thread_192_3}, +{&thread_193_3}, +{&thread_194_3}, +{&thread_195_3}, +{&thread_196_3}, +{&thread_197_3}, +{&thread_198_3}, +{&thread_199_3}, +{&thread_200_3}, +{&thread_201_3}, +{&thread_202_3}, +{&thread_203_3}, +{&thread_204_3}, +{&thread_205_3}, +{&thread_206_3}, +{&thread_207_3}, +{&thread_208_3}, +{&thread_209_3}, +{&thread_210_3}, +{&thread_211_3}, +{&thread_212_3}, +{&thread_213_3}, +{&thread_214_3}, +{&thread_215_3}, +{&thread_216_3}, +{&thread_217_3}, +{&thread_218_3}, +{&thread_219_3}, +{&thread_220_3}, +{&thread_221_3}, +{&thread_222_3}, +{&thread_223_3}, +{&thread_224_3}, +{&thread_225_3}, +{&thread_226_3}, +{&thread_227_3}, +{&thread_228_3}, +{&thread_229_3}, +{&thread_230_3}, +{&thread_231_3}, +{&thread_232_3}, +{&thread_233_3}, +{&thread_234_3}, +{&thread_235_3}, +{&thread_236_3}, +{&thread_237_3}, +{&thread_238_3}, +{&thread_239_3}, +{&thread_240_3}, +{&thread_241_3}, +{&thread_242_3}, +{&thread_243_3}, +{&thread_244_3}, +{&thread_245_3}, +{&thread_246_3}, +{&thread_247_3}, +{&thread_248_3}, +{&thread_249_3}, +{&thread_250_3}, +{&thread_251_3}, +{&thread_252_3}, +{&thread_253_3}, +{&thread_254_3}, +{&thread_255_3} +}; + +/* Define the test array. This used to store the randomized test. */ + +static TX_THREAD *_smp_randomized_test_array[TX_THREAD_SMP_MAX_CORES*2]; + + +/* Define thread entry prototype. Since it won't be used it can be the same. */ + +static void control_thread_entry(ULONG thread_input); +static void thread_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + + +static UINT pass; +static UINT start_pass; +static UINT end_pass; +static UINT mapping_error; +static UINT preemption_threshold_error; + + +extern TX_THREAD *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES]; + + +/* Create a test control thread. */ + +static TX_THREAD control_thread; + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_smp_random_resume_suspend_exclusion_pt_test(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a control thread to run the test. */ + status = tx_thread_create(&control_thread, "control thread", control_thread_entry, 0, + pointer, 1024, + 0, 0, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check status. */ + if (status != TX_SUCCESS) + { + printf("Running SMP Random Suspensions/Resumptions/Exclusions/PT Test....... ERROR #1\n"); + test_control_return(1); + } +} + + +static void control_thread_entry(ULONG thread_input) +{ + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD +TX_INTERRUPT_SAVE_AREA + +UINT i, j; +UINT priority; +UINT source_index; +UINT successful_tests = 0; +UINT test_errors = 0; +TX_THREAD *thread_ptr; +TX_THREAD *current_thread; +UINT original_priority; +UINT original_threshold; +ULONG exclusions; +UINT status; + + + /* Clear mapping error flag. */ + mapping_error = TX_FALSE; + + /* Clear the preemption-threshold error flag. */ + preemption_threshold_error = TX_FALSE; + + /* Pickup the current thread pointer. */ + current_thread = tx_thread_identify(); + + /* Loop to create all the threads. */ + i = 0; + priority = 0; + status = TX_SUCCESS; + while (i < 1024) + { + + /* Create each thread. */ + status += tx_thread_create(_smp_randomized_source_array[i], "test thread", thread_entry, i, +// (void *) pointer, 512, + malloc(1024), 1024, + priority, priority, TX_NO_TIME_SLICE, TX_DONT_START); +// pointer = pointer + 512; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Random Suspensions/Resumptions/Exclusions/PT Test....... ERROR #2\n"); + test_control_return(1); + break; + } + + /* Move to next entry/priority. */ + i++; + priority++; + + /* Should priority be reset? */ + if (priority >= TX_MAX_PRIORITIES) + { + + /* Yes, reset the priority. */ + priority = 0; + } + } + + /* Start random test. */ + printf("Running SMP Random Suspensions/Resumptions/Exclusions/PT Test....... "); + + /* Special test for specific path in rebalance. */ + status = tx_thread_smp_core_exclude(&thread_2, 0x7); + status += tx_thread_smp_core_exclude(&thread_4, 0x7); + status += tx_thread_smp_core_exclude(&thread_16, 0x7); + status += tx_thread_smp_core_exclude(&thread_22, 0); + status += tx_thread_preemption_change(&thread_16, 8, &original_threshold); + status += tx_thread_resume(&thread_16); + status += tx_thread_resume(&thread_4); + status += tx_thread_resume(&thread_22); + status += tx_thread_resume(&thread_2); + + /* Call rebalance directly. */ + TX_DISABLE + _tx_thread_smp_rebalance_execute_list(0); + TX_RESTORE + + status += tx_thread_sleep(4); + + /* Check status and make sure all the threads ran and suspended. */ + if ((status != TX_SUCCESS) || (thread_2.tx_thread_run_count == 0) || + (thread_4.tx_thread_run_count == 0) || + (thread_16.tx_thread_run_count == 0) || + (thread_22.tx_thread_run_count == 0)) + { + + printf("ERROR #3\n"); + test_control_return(1); + } + + /* Clean everything up. */ + status = tx_thread_smp_core_exclude(&thread_2, 0); + status += tx_thread_smp_core_exclude(&thread_4, 0); + status += tx_thread_smp_core_exclude(&thread_16, 0); + status += tx_thread_smp_core_exclude(&thread_22, 0); + status += tx_thread_preemption_change(&thread_4, 4, &original_threshold); + status += tx_thread_preemption_change(&thread_16, 16, &original_threshold); + + /* Clear the run counters. */ + thread_2.tx_thread_run_count = 0; + thread_4.tx_thread_run_count = 0; + thread_16.tx_thread_run_count = 0; + thread_22.tx_thread_run_count = 0; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Clear system counters. */ + pass = 0; + start_pass = 0; + end_pass = start_pass + MAX_PASSES; + do + { + + /* Clear the randomized test array. */ + for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++) + { + _smp_randomized_test_array[i] = TX_NULL; + } + + /* Build the randomized test array. */ + for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++) + { + do + { + source_index = (rand())%1024; + + /* Determine if this index has repeated. */ + thread_ptr = _smp_randomized_source_array[source_index]; + + /* Is this thread already in the test array? */ + j = 0; + while (j < TX_THREAD_SMP_MAX_CORES*2) + { + /* Is the entry NULL? */ + if (_smp_randomized_test_array[j] == TX_NULL) + { + j = (TX_THREAD_SMP_MAX_CORES*2); + } + + /* Determine if we have a duplicate. */ + if (_smp_randomized_test_array[j] == thread_ptr) + thread_ptr = TX_NULL; + + j++; + } + + } while (thread_ptr == TX_NULL); + + /* Clear run counter. */ + thread_ptr -> tx_thread_run_count = 0; + + /* Setup the exclusion for this thread. */ + exclusions = (ULONG) (rand()%15); + tx_thread_smp_core_exclude(thread_ptr, exclusions); + + /* See if we should setup a preemption-threshold. */ + if ((thread_ptr -> tx_thread_priority > 40) && + (exclusions & 1)) + { + /* Change preemption-threshold to enable it. */ + tx_thread_preemption_change(thread_ptr, thread_ptr -> tx_thread_priority - 20, &original_threshold); + } + + /* Save the thread pointer. */ + _smp_randomized_test_array[i] = thread_ptr; + } + + /* Now make all the random threads ready. */ + for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++) + { + status = tx_thread_resume(_smp_randomized_test_array[i]); + + /* Check for an error. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #5\n"); + test_control_return(1); + break; + } + } + + /* Check the status. */ + if (status) + break; + + /* Move to the lowest priority. */ + status += tx_thread_priority_change(current_thread, TX_MAX_PRIORITIES-1, &original_priority); + tx_thread_relinquish(); + + /* At this point all the threads have run, or should have. */ + + /* Restore priority. */ + status += tx_thread_priority_change(current_thread, original_priority, &original_priority); + + /* Was there an error? */ + if (status != TX_SUCCESS) + { + + printf("ERROR #6\n"); + test_control_return(1); + break; + } + + /* Determine if all the threads in the the random sample ran. */ + for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++) + { + + /* Pickup the thread pointer. */ + thread_ptr = _smp_randomized_test_array[i]; + + /* Check to see if each thread has run. */ + if (thread_ptr -> tx_thread_run_count == 0) + { + + /* First, try to sleep to see if this helps! */ + tx_thread_sleep(1); + } + + /* Has the run count incremented? */ + if (thread_ptr -> tx_thread_run_count == 0) + { + + /* No, this thread didn't really run! */ + printf("ERROR #7\n"); + test_control_return(1); + break; + } + + /* Make sure this thread suspended. */ + while (thread_ptr -> tx_thread_state != TX_SUSPENDED) + { + /* Wait for the thread to complete! */ + tx_thread_relinquish(); + } + + /* Reset the exclusion for this thread. */ + tx_thread_smp_core_exclude(thread_ptr, 0); + + /* Reset preemption-threshold if needed. */ + if (thread_ptr -> tx_thread_priority != thread_ptr -> tx_thread_preempt_threshold) + { + + /* Change preemption-threshold to enable it. */ + tx_thread_preemption_change(thread_ptr, thread_ptr -> tx_thread_priority, &original_threshold); + } + + /* Check for mapping error. */ + if (mapping_error) + { + + /* No, a thread ran on inccorect core! */ + printf("ERROR #8\n"); + test_control_return(1); + break; + } + + /* Check for preemption-threshold error. */ + if (preemption_threshold_error) + { + + /* No, a thread's preemption-threshold was violated! */ + printf("ERROR #9\n"); + test_control_return(1); + break; + } + + } + + /* Increment the pass counter. */ + pass++; + + } while (pass < end_pass); + + /* Test is successful! */ + printf("SUCCESS!\n"); + test_control_return(0); +#else + printf("Running SMP Random Suspensions/Resumptions/Exclusions/PT Test....... SUCCESS!\n"); + test_control_return(0); +#endif +} + + +static void thread_entry(ULONG id) +{ + +UINT core; +ULONG core_bit_map; +TX_THREAD *thread_ptr; +UINT i; +TX_THREAD *other_thread; + + + /* While forever loop! */ + while(1) + { + + /* Get thread. */ + thread_ptr = _smp_randomized_source_array[id]; + + /* Determine if this thread is running on a valid core. */ + core = tx_thread_smp_core_get(); + + /* Build a bit map for this core. */ + core_bit_map = (((ULONG) 1) << core); + + /* Is this a valid core? */ + if (core_bit_map & thread_ptr -> tx_thread_smp_cores_excluded) + { + + /* Invalid core, set error flag. */ + mapping_error = TX_TRUE; + } + + /* Now check for a preemption-threshold error. */ + if (thread_ptr -> tx_thread_priority != thread_ptr -> tx_thread_preempt_threshold) + { + + /* Loop through the execute list to determine if any other threads have a priority or preemption-threshold less than this thread. */ + for (i = 0; i < TX_THREAD_SMP_MAX_CORES; i++) + { + + /* Pickup thread for the core. */ + other_thread = _tx_thread_execute_ptr[i]; + + /* Is it this thread? */ + if ((other_thread == TX_NULL) || (other_thread == thread_ptr)) + continue; + + /* Does this thread violate the preemption-thread of the current thread? */ + if (other_thread -> tx_thread_preempt_threshold >= thread_ptr -> tx_thread_preempt_threshold) + { + + /* This violated preemption-threshold. Set the flag. */ + preemption_threshold_error = TX_TRUE; + } + } + } + + /* Suspend thread! */ + tx_thread_suspend(thread_ptr); + } +} diff --git a/test/smp/regression/threadx_smp_random_resume_suspend_exclusion_test.c b/test/smp/regression/threadx_smp_random_resume_suspend_exclusion_test.c new file mode 100644 index 00000000..6c2f885f --- /dev/null +++ b/test/smp/regression/threadx_smp_random_resume_suspend_exclusion_test.c @@ -0,0 +1,2373 @@ +/* Define the ThreadX SMP random resume/suspend/exclude test. */ + +#include +#include "tx_api.h" + +//#define MAX_PASSES 50000000 +//#define MAX_PASSES 50000 +#define MAX_PASSES 500 + + +/* Define the ThreadX object control blocks... Must have 256 priority levels... and assumes 4 cores. */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; +static TX_THREAD thread_4; +static TX_THREAD thread_5; +static TX_THREAD thread_6; +static TX_THREAD thread_7; +static TX_THREAD thread_8; +static TX_THREAD thread_9; +static TX_THREAD thread_10; +static TX_THREAD thread_11; +static TX_THREAD thread_12; +static TX_THREAD thread_13; +static TX_THREAD thread_14; +static TX_THREAD thread_15; +static TX_THREAD thread_16; +static TX_THREAD thread_17; +static TX_THREAD thread_18; +static TX_THREAD thread_19; +static TX_THREAD thread_20; +static TX_THREAD thread_21; +static TX_THREAD thread_22; +static TX_THREAD thread_23; +static TX_THREAD thread_24; +static TX_THREAD thread_25; +static TX_THREAD thread_26; +static TX_THREAD thread_27; +static TX_THREAD thread_28; +static TX_THREAD thread_29; +static TX_THREAD thread_30; +static TX_THREAD thread_31; +static TX_THREAD thread_32; +static TX_THREAD thread_33; +static TX_THREAD thread_34; +static TX_THREAD thread_35; +static TX_THREAD thread_36; +static TX_THREAD thread_37; +static TX_THREAD thread_38; +static TX_THREAD thread_39; +static TX_THREAD thread_40; +static TX_THREAD thread_41; +static TX_THREAD thread_42; +static TX_THREAD thread_43; +static TX_THREAD thread_44; +static TX_THREAD thread_45; +static TX_THREAD thread_46; +static TX_THREAD thread_47; +static TX_THREAD thread_48; +static TX_THREAD thread_49; +static TX_THREAD thread_50; +static TX_THREAD thread_51; +static TX_THREAD thread_52; +static TX_THREAD thread_53; +static TX_THREAD thread_54; +static TX_THREAD thread_55; +static TX_THREAD thread_56; +static TX_THREAD thread_57; +static TX_THREAD thread_58; +static TX_THREAD thread_59; +static TX_THREAD thread_60; +static TX_THREAD thread_61; +static TX_THREAD thread_62; +static TX_THREAD thread_63; +static TX_THREAD thread_64; +static TX_THREAD thread_65; +static TX_THREAD thread_66; +static TX_THREAD thread_67; +static TX_THREAD thread_68; +static TX_THREAD thread_69; +static TX_THREAD thread_70; +static TX_THREAD thread_71; +static TX_THREAD thread_72; +static TX_THREAD thread_73; +static TX_THREAD thread_74; +static TX_THREAD thread_75; +static TX_THREAD thread_76; +static TX_THREAD thread_77; +static TX_THREAD thread_78; +static TX_THREAD thread_79; +static TX_THREAD thread_80; +static TX_THREAD thread_81; +static TX_THREAD thread_82; +static TX_THREAD thread_83; +static TX_THREAD thread_84; +static TX_THREAD thread_85; +static TX_THREAD thread_86; +static TX_THREAD thread_87; +static TX_THREAD thread_88; +static TX_THREAD thread_89; +static TX_THREAD thread_90; +static TX_THREAD thread_91; +static TX_THREAD thread_92; +static TX_THREAD thread_93; +static TX_THREAD thread_94; +static TX_THREAD thread_95; +static TX_THREAD thread_96; +static TX_THREAD thread_97; +static TX_THREAD thread_98; +static TX_THREAD thread_99; +static TX_THREAD thread_100; +static TX_THREAD thread_101; +static TX_THREAD thread_102; +static TX_THREAD thread_103; +static TX_THREAD thread_104; +static TX_THREAD thread_105; +static TX_THREAD thread_106; +static TX_THREAD thread_107; +static TX_THREAD thread_108; +static TX_THREAD thread_109; +static TX_THREAD thread_110; +static TX_THREAD thread_111; +static TX_THREAD thread_112; +static TX_THREAD thread_113; +static TX_THREAD thread_114; +static TX_THREAD thread_115; +static TX_THREAD thread_116; +static TX_THREAD thread_117; +static TX_THREAD thread_118; +static TX_THREAD thread_119; +static TX_THREAD thread_120; +static TX_THREAD thread_121; +static TX_THREAD thread_122; +static TX_THREAD thread_123; +static TX_THREAD thread_124; +static TX_THREAD thread_125; +static TX_THREAD thread_126; +static TX_THREAD thread_127; +static TX_THREAD thread_128; +static TX_THREAD thread_129; +static TX_THREAD thread_130; +static TX_THREAD thread_131; +static TX_THREAD thread_132; +static TX_THREAD thread_133; +static TX_THREAD thread_134; +static TX_THREAD thread_135; +static TX_THREAD thread_136; +static TX_THREAD thread_137; +static TX_THREAD thread_138; +static TX_THREAD thread_139; +static TX_THREAD thread_140; +static TX_THREAD thread_141; +static TX_THREAD thread_142; +static TX_THREAD thread_143; +static TX_THREAD thread_144; +static TX_THREAD thread_145; +static TX_THREAD thread_146; +static TX_THREAD thread_147; +static TX_THREAD thread_148; +static TX_THREAD thread_149; +static TX_THREAD thread_150; +static TX_THREAD thread_151; +static TX_THREAD thread_152; +static TX_THREAD thread_153; +static TX_THREAD thread_154; +static TX_THREAD thread_155; +static TX_THREAD thread_156; +static TX_THREAD thread_157; +static TX_THREAD thread_158; +static TX_THREAD thread_159; +static TX_THREAD thread_160; +static TX_THREAD thread_161; +static TX_THREAD thread_162; +static TX_THREAD thread_163; +static TX_THREAD thread_164; +static TX_THREAD thread_165; +static TX_THREAD thread_166; +static TX_THREAD thread_167; +static TX_THREAD thread_168; +static TX_THREAD thread_169; +static TX_THREAD thread_170; +static TX_THREAD thread_171; +static TX_THREAD thread_172; +static TX_THREAD thread_173; +static TX_THREAD thread_174; +static TX_THREAD thread_175; +static TX_THREAD thread_176; +static TX_THREAD thread_177; +static TX_THREAD thread_178; +static TX_THREAD thread_179; +static TX_THREAD thread_180; +static TX_THREAD thread_181; +static TX_THREAD thread_182; +static TX_THREAD thread_183; +static TX_THREAD thread_184; +static TX_THREAD thread_185; +static TX_THREAD thread_186; +static TX_THREAD thread_187; +static TX_THREAD thread_188; +static TX_THREAD thread_189; +static TX_THREAD thread_190; +static TX_THREAD thread_191; +static TX_THREAD thread_192; +static TX_THREAD thread_193; +static TX_THREAD thread_194; +static TX_THREAD thread_195; +static TX_THREAD thread_196; +static TX_THREAD thread_197; +static TX_THREAD thread_198; +static TX_THREAD thread_199; +static TX_THREAD thread_200; +static TX_THREAD thread_201; +static TX_THREAD thread_202; +static TX_THREAD thread_203; +static TX_THREAD thread_204; +static TX_THREAD thread_205; +static TX_THREAD thread_206; +static TX_THREAD thread_207; +static TX_THREAD thread_208; +static TX_THREAD thread_209; +static TX_THREAD thread_210; +static TX_THREAD thread_211; +static TX_THREAD thread_212; +static TX_THREAD thread_213; +static TX_THREAD thread_214; +static TX_THREAD thread_215; +static TX_THREAD thread_216; +static TX_THREAD thread_217; +static TX_THREAD thread_218; +static TX_THREAD thread_219; +static TX_THREAD thread_220; +static TX_THREAD thread_221; +static TX_THREAD thread_222; +static TX_THREAD thread_223; +static TX_THREAD thread_224; +static TX_THREAD thread_225; +static TX_THREAD thread_226; +static TX_THREAD thread_227; +static TX_THREAD thread_228; +static TX_THREAD thread_229; +static TX_THREAD thread_230; +static TX_THREAD thread_231; +static TX_THREAD thread_232; +static TX_THREAD thread_233; +static TX_THREAD thread_234; +static TX_THREAD thread_235; +static TX_THREAD thread_236; +static TX_THREAD thread_237; +static TX_THREAD thread_238; +static TX_THREAD thread_239; +static TX_THREAD thread_240; +static TX_THREAD thread_241; +static TX_THREAD thread_242; +static TX_THREAD thread_243; +static TX_THREAD thread_244; +static TX_THREAD thread_245; +static TX_THREAD thread_246; +static TX_THREAD thread_247; +static TX_THREAD thread_248; +static TX_THREAD thread_249; +static TX_THREAD thread_250; +static TX_THREAD thread_251; +static TX_THREAD thread_252; +static TX_THREAD thread_253; +static TX_THREAD thread_254; +static TX_THREAD thread_255; + +static TX_THREAD thread_0_1; +static TX_THREAD thread_1_1; +static TX_THREAD thread_2_1; +static TX_THREAD thread_3_1; +static TX_THREAD thread_4_1; +static TX_THREAD thread_5_1; +static TX_THREAD thread_6_1; +static TX_THREAD thread_7_1; +static TX_THREAD thread_8_1; +static TX_THREAD thread_9_1; +static TX_THREAD thread_10_1; +static TX_THREAD thread_11_1; +static TX_THREAD thread_12_1; +static TX_THREAD thread_13_1; +static TX_THREAD thread_14_1; +static TX_THREAD thread_15_1; +static TX_THREAD thread_16_1; +static TX_THREAD thread_17_1; +static TX_THREAD thread_18_1; +static TX_THREAD thread_19_1; +static TX_THREAD thread_20_1; +static TX_THREAD thread_21_1; +static TX_THREAD thread_22_1; +static TX_THREAD thread_23_1; +static TX_THREAD thread_24_1; +static TX_THREAD thread_25_1; +static TX_THREAD thread_26_1; +static TX_THREAD thread_27_1; +static TX_THREAD thread_28_1; +static TX_THREAD thread_29_1; +static TX_THREAD thread_30_1; +static TX_THREAD thread_31_1; +static TX_THREAD thread_32_1; +static TX_THREAD thread_33_1; +static TX_THREAD thread_34_1; +static TX_THREAD thread_35_1; +static TX_THREAD thread_36_1; +static TX_THREAD thread_37_1; +static TX_THREAD thread_38_1; +static TX_THREAD thread_39_1; +static TX_THREAD thread_40_1; +static TX_THREAD thread_41_1; +static TX_THREAD thread_42_1; +static TX_THREAD thread_43_1; +static TX_THREAD thread_44_1; +static TX_THREAD thread_45_1; +static TX_THREAD thread_46_1; +static TX_THREAD thread_47_1; +static TX_THREAD thread_48_1; +static TX_THREAD thread_49_1; +static TX_THREAD thread_50_1; +static TX_THREAD thread_51_1; +static TX_THREAD thread_52_1; +static TX_THREAD thread_53_1; +static TX_THREAD thread_54_1; +static TX_THREAD thread_55_1; +static TX_THREAD thread_56_1; +static TX_THREAD thread_57_1; +static TX_THREAD thread_58_1; +static TX_THREAD thread_59_1; +static TX_THREAD thread_60_1; +static TX_THREAD thread_61_1; +static TX_THREAD thread_62_1; +static TX_THREAD thread_63_1; +static TX_THREAD thread_64_1; +static TX_THREAD thread_65_1; +static TX_THREAD thread_66_1; +static TX_THREAD thread_67_1; +static TX_THREAD thread_68_1; +static TX_THREAD thread_69_1; +static TX_THREAD thread_70_1; +static TX_THREAD thread_71_1; +static TX_THREAD thread_72_1; +static TX_THREAD thread_73_1; +static TX_THREAD thread_74_1; +static TX_THREAD thread_75_1; +static TX_THREAD thread_76_1; +static TX_THREAD thread_77_1; +static TX_THREAD thread_78_1; +static TX_THREAD thread_79_1; +static TX_THREAD thread_80_1; +static TX_THREAD thread_81_1; +static TX_THREAD thread_82_1; +static TX_THREAD thread_83_1; +static TX_THREAD thread_84_1; +static TX_THREAD thread_85_1; +static TX_THREAD thread_86_1; +static TX_THREAD thread_87_1; +static TX_THREAD thread_88_1; +static TX_THREAD thread_89_1; +static TX_THREAD thread_90_1; +static TX_THREAD thread_91_1; +static TX_THREAD thread_92_1; +static TX_THREAD thread_93_1; +static TX_THREAD thread_94_1; +static TX_THREAD thread_95_1; +static TX_THREAD thread_96_1; +static TX_THREAD thread_97_1; +static TX_THREAD thread_98_1; +static TX_THREAD thread_99_1; +static TX_THREAD thread_100_1; +static TX_THREAD thread_101_1; +static TX_THREAD thread_102_1; +static TX_THREAD thread_103_1; +static TX_THREAD thread_104_1; +static TX_THREAD thread_105_1; +static TX_THREAD thread_106_1; +static TX_THREAD thread_107_1; +static TX_THREAD thread_108_1; +static TX_THREAD thread_109_1; +static TX_THREAD thread_110_1; +static TX_THREAD thread_111_1; +static TX_THREAD thread_112_1; +static TX_THREAD thread_113_1; +static TX_THREAD thread_114_1; +static TX_THREAD thread_115_1; +static TX_THREAD thread_116_1; +static TX_THREAD thread_117_1; +static TX_THREAD thread_118_1; +static TX_THREAD thread_119_1; +static TX_THREAD thread_120_1; +static TX_THREAD thread_121_1; +static TX_THREAD thread_122_1; +static TX_THREAD thread_123_1; +static TX_THREAD thread_124_1; +static TX_THREAD thread_125_1; +static TX_THREAD thread_126_1; +static TX_THREAD thread_127_1; +static TX_THREAD thread_128_1; +static TX_THREAD thread_129_1; +static TX_THREAD thread_130_1; +static TX_THREAD thread_131_1; +static TX_THREAD thread_132_1; +static TX_THREAD thread_133_1; +static TX_THREAD thread_134_1; +static TX_THREAD thread_135_1; +static TX_THREAD thread_136_1; +static TX_THREAD thread_137_1; +static TX_THREAD thread_138_1; +static TX_THREAD thread_139_1; +static TX_THREAD thread_140_1; +static TX_THREAD thread_141_1; +static TX_THREAD thread_142_1; +static TX_THREAD thread_143_1; +static TX_THREAD thread_144_1; +static TX_THREAD thread_145_1; +static TX_THREAD thread_146_1; +static TX_THREAD thread_147_1; +static TX_THREAD thread_148_1; +static TX_THREAD thread_149_1; +static TX_THREAD thread_150_1; +static TX_THREAD thread_151_1; +static TX_THREAD thread_152_1; +static TX_THREAD thread_153_1; +static TX_THREAD thread_154_1; +static TX_THREAD thread_155_1; +static TX_THREAD thread_156_1; +static TX_THREAD thread_157_1; +static TX_THREAD thread_158_1; +static TX_THREAD thread_159_1; +static TX_THREAD thread_160_1; +static TX_THREAD thread_161_1; +static TX_THREAD thread_162_1; +static TX_THREAD thread_163_1; +static TX_THREAD thread_164_1; +static TX_THREAD thread_165_1; +static TX_THREAD thread_166_1; +static TX_THREAD thread_167_1; +static TX_THREAD thread_168_1; +static TX_THREAD thread_169_1; +static TX_THREAD thread_170_1; +static TX_THREAD thread_171_1; +static TX_THREAD thread_172_1; +static TX_THREAD thread_173_1; +static TX_THREAD thread_174_1; +static TX_THREAD thread_175_1; +static TX_THREAD thread_176_1; +static TX_THREAD thread_177_1; +static TX_THREAD thread_178_1; +static TX_THREAD thread_179_1; +static TX_THREAD thread_180_1; +static TX_THREAD thread_181_1; +static TX_THREAD thread_182_1; +static TX_THREAD thread_183_1; +static TX_THREAD thread_184_1; +static TX_THREAD thread_185_1; +static TX_THREAD thread_186_1; +static TX_THREAD thread_187_1; +static TX_THREAD thread_188_1; +static TX_THREAD thread_189_1; +static TX_THREAD thread_190_1; +static TX_THREAD thread_191_1; +static TX_THREAD thread_192_1; +static TX_THREAD thread_193_1; +static TX_THREAD thread_194_1; +static TX_THREAD thread_195_1; +static TX_THREAD thread_196_1; +static TX_THREAD thread_197_1; +static TX_THREAD thread_198_1; +static TX_THREAD thread_199_1; +static TX_THREAD thread_200_1; +static TX_THREAD thread_201_1; +static TX_THREAD thread_202_1; +static TX_THREAD thread_203_1; +static TX_THREAD thread_204_1; +static TX_THREAD thread_205_1; +static TX_THREAD thread_206_1; +static TX_THREAD thread_207_1; +static TX_THREAD thread_208_1; +static TX_THREAD thread_209_1; +static TX_THREAD thread_210_1; +static TX_THREAD thread_211_1; +static TX_THREAD thread_212_1; +static TX_THREAD thread_213_1; +static TX_THREAD thread_214_1; +static TX_THREAD thread_215_1; +static TX_THREAD thread_216_1; +static TX_THREAD thread_217_1; +static TX_THREAD thread_218_1; +static TX_THREAD thread_219_1; +static TX_THREAD thread_220_1; +static TX_THREAD thread_221_1; +static TX_THREAD thread_222_1; +static TX_THREAD thread_223_1; +static TX_THREAD thread_224_1; +static TX_THREAD thread_225_1; +static TX_THREAD thread_226_1; +static TX_THREAD thread_227_1; +static TX_THREAD thread_228_1; +static TX_THREAD thread_229_1; +static TX_THREAD thread_230_1; +static TX_THREAD thread_231_1; +static TX_THREAD thread_232_1; +static TX_THREAD thread_233_1; +static TX_THREAD thread_234_1; +static TX_THREAD thread_235_1; +static TX_THREAD thread_236_1; +static TX_THREAD thread_237_1; +static TX_THREAD thread_238_1; +static TX_THREAD thread_239_1; +static TX_THREAD thread_240_1; +static TX_THREAD thread_241_1; +static TX_THREAD thread_242_1; +static TX_THREAD thread_243_1; +static TX_THREAD thread_244_1; +static TX_THREAD thread_245_1; +static TX_THREAD thread_246_1; +static TX_THREAD thread_247_1; +static TX_THREAD thread_248_1; +static TX_THREAD thread_249_1; +static TX_THREAD thread_250_1; +static TX_THREAD thread_251_1; +static TX_THREAD thread_252_1; +static TX_THREAD thread_253_1; +static TX_THREAD thread_254_1; +static TX_THREAD thread_255_1; + +static TX_THREAD thread_0_2; +static TX_THREAD thread_1_2; +static TX_THREAD thread_2_2; +static TX_THREAD thread_3_2; +static TX_THREAD thread_4_2; +static TX_THREAD thread_5_2; +static TX_THREAD thread_6_2; +static TX_THREAD thread_7_2; +static TX_THREAD thread_8_2; +static TX_THREAD thread_9_2; +static TX_THREAD thread_10_2; +static TX_THREAD thread_11_2; +static TX_THREAD thread_12_2; +static TX_THREAD thread_13_2; +static TX_THREAD thread_14_2; +static TX_THREAD thread_15_2; +static TX_THREAD thread_16_2; +static TX_THREAD thread_17_2; +static TX_THREAD thread_18_2; +static TX_THREAD thread_19_2; +static TX_THREAD thread_20_2; +static TX_THREAD thread_21_2; +static TX_THREAD thread_22_2; +static TX_THREAD thread_23_2; +static TX_THREAD thread_24_2; +static TX_THREAD thread_25_2; +static TX_THREAD thread_26_2; +static TX_THREAD thread_27_2; +static TX_THREAD thread_28_2; +static TX_THREAD thread_29_2; +static TX_THREAD thread_30_2; +static TX_THREAD thread_31_2; +static TX_THREAD thread_32_2; +static TX_THREAD thread_33_2; +static TX_THREAD thread_34_2; +static TX_THREAD thread_35_2; +static TX_THREAD thread_36_2; +static TX_THREAD thread_37_2; +static TX_THREAD thread_38_2; +static TX_THREAD thread_39_2; +static TX_THREAD thread_40_2; +static TX_THREAD thread_41_2; +static TX_THREAD thread_42_2; +static TX_THREAD thread_43_2; +static TX_THREAD thread_44_2; +static TX_THREAD thread_45_2; +static TX_THREAD thread_46_2; +static TX_THREAD thread_47_2; +static TX_THREAD thread_48_2; +static TX_THREAD thread_49_2; +static TX_THREAD thread_50_2; +static TX_THREAD thread_51_2; +static TX_THREAD thread_52_2; +static TX_THREAD thread_53_2; +static TX_THREAD thread_54_2; +static TX_THREAD thread_55_2; +static TX_THREAD thread_56_2; +static TX_THREAD thread_57_2; +static TX_THREAD thread_58_2; +static TX_THREAD thread_59_2; +static TX_THREAD thread_60_2; +static TX_THREAD thread_61_2; +static TX_THREAD thread_62_2; +static TX_THREAD thread_63_2; +static TX_THREAD thread_64_2; +static TX_THREAD thread_65_2; +static TX_THREAD thread_66_2; +static TX_THREAD thread_67_2; +static TX_THREAD thread_68_2; +static TX_THREAD thread_69_2; +static TX_THREAD thread_70_2; +static TX_THREAD thread_71_2; +static TX_THREAD thread_72_2; +static TX_THREAD thread_73_2; +static TX_THREAD thread_74_2; +static TX_THREAD thread_75_2; +static TX_THREAD thread_76_2; +static TX_THREAD thread_77_2; +static TX_THREAD thread_78_2; +static TX_THREAD thread_79_2; +static TX_THREAD thread_80_2; +static TX_THREAD thread_81_2; +static TX_THREAD thread_82_2; +static TX_THREAD thread_83_2; +static TX_THREAD thread_84_2; +static TX_THREAD thread_85_2; +static TX_THREAD thread_86_2; +static TX_THREAD thread_87_2; +static TX_THREAD thread_88_2; +static TX_THREAD thread_89_2; +static TX_THREAD thread_90_2; +static TX_THREAD thread_91_2; +static TX_THREAD thread_92_2; +static TX_THREAD thread_93_2; +static TX_THREAD thread_94_2; +static TX_THREAD thread_95_2; +static TX_THREAD thread_96_2; +static TX_THREAD thread_97_2; +static TX_THREAD thread_98_2; +static TX_THREAD thread_99_2; +static TX_THREAD thread_100_2; +static TX_THREAD thread_101_2; +static TX_THREAD thread_102_2; +static TX_THREAD thread_103_2; +static TX_THREAD thread_104_2; +static TX_THREAD thread_105_2; +static TX_THREAD thread_106_2; +static TX_THREAD thread_107_2; +static TX_THREAD thread_108_2; +static TX_THREAD thread_109_2; +static TX_THREAD thread_110_2; +static TX_THREAD thread_111_2; +static TX_THREAD thread_112_2; +static TX_THREAD thread_113_2; +static TX_THREAD thread_114_2; +static TX_THREAD thread_115_2; +static TX_THREAD thread_116_2; +static TX_THREAD thread_117_2; +static TX_THREAD thread_118_2; +static TX_THREAD thread_119_2; +static TX_THREAD thread_120_2; +static TX_THREAD thread_121_2; +static TX_THREAD thread_122_2; +static TX_THREAD thread_123_2; +static TX_THREAD thread_124_2; +static TX_THREAD thread_125_2; +static TX_THREAD thread_126_2; +static TX_THREAD thread_127_2; +static TX_THREAD thread_128_2; +static TX_THREAD thread_129_2; +static TX_THREAD thread_130_2; +static TX_THREAD thread_131_2; +static TX_THREAD thread_132_2; +static TX_THREAD thread_133_2; +static TX_THREAD thread_134_2; +static TX_THREAD thread_135_2; +static TX_THREAD thread_136_2; +static TX_THREAD thread_137_2; +static TX_THREAD thread_138_2; +static TX_THREAD thread_139_2; +static TX_THREAD thread_140_2; +static TX_THREAD thread_141_2; +static TX_THREAD thread_142_2; +static TX_THREAD thread_143_2; +static TX_THREAD thread_144_2; +static TX_THREAD thread_145_2; +static TX_THREAD thread_146_2; +static TX_THREAD thread_147_2; +static TX_THREAD thread_148_2; +static TX_THREAD thread_149_2; +static TX_THREAD thread_150_2; +static TX_THREAD thread_151_2; +static TX_THREAD thread_152_2; +static TX_THREAD thread_153_2; +static TX_THREAD thread_154_2; +static TX_THREAD thread_155_2; +static TX_THREAD thread_156_2; +static TX_THREAD thread_157_2; +static TX_THREAD thread_158_2; +static TX_THREAD thread_159_2; +static TX_THREAD thread_160_2; +static TX_THREAD thread_161_2; +static TX_THREAD thread_162_2; +static TX_THREAD thread_163_2; +static TX_THREAD thread_164_2; +static TX_THREAD thread_165_2; +static TX_THREAD thread_166_2; +static TX_THREAD thread_167_2; +static TX_THREAD thread_168_2; +static TX_THREAD thread_169_2; +static TX_THREAD thread_170_2; +static TX_THREAD thread_171_2; +static TX_THREAD thread_172_2; +static TX_THREAD thread_173_2; +static TX_THREAD thread_174_2; +static TX_THREAD thread_175_2; +static TX_THREAD thread_176_2; +static TX_THREAD thread_177_2; +static TX_THREAD thread_178_2; +static TX_THREAD thread_179_2; +static TX_THREAD thread_180_2; +static TX_THREAD thread_181_2; +static TX_THREAD thread_182_2; +static TX_THREAD thread_183_2; +static TX_THREAD thread_184_2; +static TX_THREAD thread_185_2; +static TX_THREAD thread_186_2; +static TX_THREAD thread_187_2; +static TX_THREAD thread_188_2; +static TX_THREAD thread_189_2; +static TX_THREAD thread_190_2; +static TX_THREAD thread_191_2; +static TX_THREAD thread_192_2; +static TX_THREAD thread_193_2; +static TX_THREAD thread_194_2; +static TX_THREAD thread_195_2; +static TX_THREAD thread_196_2; +static TX_THREAD thread_197_2; +static TX_THREAD thread_198_2; +static TX_THREAD thread_199_2; +static TX_THREAD thread_200_2; +static TX_THREAD thread_201_2; +static TX_THREAD thread_202_2; +static TX_THREAD thread_203_2; +static TX_THREAD thread_204_2; +static TX_THREAD thread_205_2; +static TX_THREAD thread_206_2; +static TX_THREAD thread_207_2; +static TX_THREAD thread_208_2; +static TX_THREAD thread_209_2; +static TX_THREAD thread_210_2; +static TX_THREAD thread_211_2; +static TX_THREAD thread_212_2; +static TX_THREAD thread_213_2; +static TX_THREAD thread_214_2; +static TX_THREAD thread_215_2; +static TX_THREAD thread_216_2; +static TX_THREAD thread_217_2; +static TX_THREAD thread_218_2; +static TX_THREAD thread_219_2; +static TX_THREAD thread_220_2; +static TX_THREAD thread_221_2; +static TX_THREAD thread_222_2; +static TX_THREAD thread_223_2; +static TX_THREAD thread_224_2; +static TX_THREAD thread_225_2; +static TX_THREAD thread_226_2; +static TX_THREAD thread_227_2; +static TX_THREAD thread_228_2; +static TX_THREAD thread_229_2; +static TX_THREAD thread_230_2; +static TX_THREAD thread_231_2; +static TX_THREAD thread_232_2; +static TX_THREAD thread_233_2; +static TX_THREAD thread_234_2; +static TX_THREAD thread_235_2; +static TX_THREAD thread_236_2; +static TX_THREAD thread_237_2; +static TX_THREAD thread_238_2; +static TX_THREAD thread_239_2; +static TX_THREAD thread_240_2; +static TX_THREAD thread_241_2; +static TX_THREAD thread_242_2; +static TX_THREAD thread_243_2; +static TX_THREAD thread_244_2; +static TX_THREAD thread_245_2; +static TX_THREAD thread_246_2; +static TX_THREAD thread_247_2; +static TX_THREAD thread_248_2; +static TX_THREAD thread_249_2; +static TX_THREAD thread_250_2; +static TX_THREAD thread_251_2; +static TX_THREAD thread_252_2; +static TX_THREAD thread_253_2; +static TX_THREAD thread_254_2; +static TX_THREAD thread_255_2; + +static TX_THREAD thread_0_3; +static TX_THREAD thread_1_3; +static TX_THREAD thread_2_3; +static TX_THREAD thread_3_3; +static TX_THREAD thread_4_3; +static TX_THREAD thread_5_3; +static TX_THREAD thread_6_3; +static TX_THREAD thread_7_3; +static TX_THREAD thread_8_3; +static TX_THREAD thread_9_3; +static TX_THREAD thread_10_3; +static TX_THREAD thread_11_3; +static TX_THREAD thread_12_3; +static TX_THREAD thread_13_3; +static TX_THREAD thread_14_3; +static TX_THREAD thread_15_3; +static TX_THREAD thread_16_3; +static TX_THREAD thread_17_3; +static TX_THREAD thread_18_3; +static TX_THREAD thread_19_3; +static TX_THREAD thread_20_3; +static TX_THREAD thread_21_3; +static TX_THREAD thread_22_3; +static TX_THREAD thread_23_3; +static TX_THREAD thread_24_3; +static TX_THREAD thread_25_3; +static TX_THREAD thread_26_3; +static TX_THREAD thread_27_3; +static TX_THREAD thread_28_3; +static TX_THREAD thread_29_3; +static TX_THREAD thread_30_3; +static TX_THREAD thread_31_3; +static TX_THREAD thread_32_3; +static TX_THREAD thread_33_3; +static TX_THREAD thread_34_3; +static TX_THREAD thread_35_3; +static TX_THREAD thread_36_3; +static TX_THREAD thread_37_3; +static TX_THREAD thread_38_3; +static TX_THREAD thread_39_3; +static TX_THREAD thread_40_3; +static TX_THREAD thread_41_3; +static TX_THREAD thread_42_3; +static TX_THREAD thread_43_3; +static TX_THREAD thread_44_3; +static TX_THREAD thread_45_3; +static TX_THREAD thread_46_3; +static TX_THREAD thread_47_3; +static TX_THREAD thread_48_3; +static TX_THREAD thread_49_3; +static TX_THREAD thread_50_3; +static TX_THREAD thread_51_3; +static TX_THREAD thread_52_3; +static TX_THREAD thread_53_3; +static TX_THREAD thread_54_3; +static TX_THREAD thread_55_3; +static TX_THREAD thread_56_3; +static TX_THREAD thread_57_3; +static TX_THREAD thread_58_3; +static TX_THREAD thread_59_3; +static TX_THREAD thread_60_3; +static TX_THREAD thread_61_3; +static TX_THREAD thread_62_3; +static TX_THREAD thread_63_3; +static TX_THREAD thread_64_3; +static TX_THREAD thread_65_3; +static TX_THREAD thread_66_3; +static TX_THREAD thread_67_3; +static TX_THREAD thread_68_3; +static TX_THREAD thread_69_3; +static TX_THREAD thread_70_3; +static TX_THREAD thread_71_3; +static TX_THREAD thread_72_3; +static TX_THREAD thread_73_3; +static TX_THREAD thread_74_3; +static TX_THREAD thread_75_3; +static TX_THREAD thread_76_3; +static TX_THREAD thread_77_3; +static TX_THREAD thread_78_3; +static TX_THREAD thread_79_3; +static TX_THREAD thread_80_3; +static TX_THREAD thread_81_3; +static TX_THREAD thread_82_3; +static TX_THREAD thread_83_3; +static TX_THREAD thread_84_3; +static TX_THREAD thread_85_3; +static TX_THREAD thread_86_3; +static TX_THREAD thread_87_3; +static TX_THREAD thread_88_3; +static TX_THREAD thread_89_3; +static TX_THREAD thread_90_3; +static TX_THREAD thread_91_3; +static TX_THREAD thread_92_3; +static TX_THREAD thread_93_3; +static TX_THREAD thread_94_3; +static TX_THREAD thread_95_3; +static TX_THREAD thread_96_3; +static TX_THREAD thread_97_3; +static TX_THREAD thread_98_3; +static TX_THREAD thread_99_3; +static TX_THREAD thread_100_3; +static TX_THREAD thread_101_3; +static TX_THREAD thread_102_3; +static TX_THREAD thread_103_3; +static TX_THREAD thread_104_3; +static TX_THREAD thread_105_3; +static TX_THREAD thread_106_3; +static TX_THREAD thread_107_3; +static TX_THREAD thread_108_3; +static TX_THREAD thread_109_3; +static TX_THREAD thread_110_3; +static TX_THREAD thread_111_3; +static TX_THREAD thread_112_3; +static TX_THREAD thread_113_3; +static TX_THREAD thread_114_3; +static TX_THREAD thread_115_3; +static TX_THREAD thread_116_3; +static TX_THREAD thread_117_3; +static TX_THREAD thread_118_3; +static TX_THREAD thread_119_3; +static TX_THREAD thread_120_3; +static TX_THREAD thread_121_3; +static TX_THREAD thread_122_3; +static TX_THREAD thread_123_3; +static TX_THREAD thread_124_3; +static TX_THREAD thread_125_3; +static TX_THREAD thread_126_3; +static TX_THREAD thread_127_3; +static TX_THREAD thread_128_3; +static TX_THREAD thread_129_3; +static TX_THREAD thread_130_3; +static TX_THREAD thread_131_3; +static TX_THREAD thread_132_3; +static TX_THREAD thread_133_3; +static TX_THREAD thread_134_3; +static TX_THREAD thread_135_3; +static TX_THREAD thread_136_3; +static TX_THREAD thread_137_3; +static TX_THREAD thread_138_3; +static TX_THREAD thread_139_3; +static TX_THREAD thread_140_3; +static TX_THREAD thread_141_3; +static TX_THREAD thread_142_3; +static TX_THREAD thread_143_3; +static TX_THREAD thread_144_3; +static TX_THREAD thread_145_3; +static TX_THREAD thread_146_3; +static TX_THREAD thread_147_3; +static TX_THREAD thread_148_3; +static TX_THREAD thread_149_3; +static TX_THREAD thread_150_3; +static TX_THREAD thread_151_3; +static TX_THREAD thread_152_3; +static TX_THREAD thread_153_3; +static TX_THREAD thread_154_3; +static TX_THREAD thread_155_3; +static TX_THREAD thread_156_3; +static TX_THREAD thread_157_3; +static TX_THREAD thread_158_3; +static TX_THREAD thread_159_3; +static TX_THREAD thread_160_3; +static TX_THREAD thread_161_3; +static TX_THREAD thread_162_3; +static TX_THREAD thread_163_3; +static TX_THREAD thread_164_3; +static TX_THREAD thread_165_3; +static TX_THREAD thread_166_3; +static TX_THREAD thread_167_3; +static TX_THREAD thread_168_3; +static TX_THREAD thread_169_3; +static TX_THREAD thread_170_3; +static TX_THREAD thread_171_3; +static TX_THREAD thread_172_3; +static TX_THREAD thread_173_3; +static TX_THREAD thread_174_3; +static TX_THREAD thread_175_3; +static TX_THREAD thread_176_3; +static TX_THREAD thread_177_3; +static TX_THREAD thread_178_3; +static TX_THREAD thread_179_3; +static TX_THREAD thread_180_3; +static TX_THREAD thread_181_3; +static TX_THREAD thread_182_3; +static TX_THREAD thread_183_3; +static TX_THREAD thread_184_3; +static TX_THREAD thread_185_3; +static TX_THREAD thread_186_3; +static TX_THREAD thread_187_3; +static TX_THREAD thread_188_3; +static TX_THREAD thread_189_3; +static TX_THREAD thread_190_3; +static TX_THREAD thread_191_3; +static TX_THREAD thread_192_3; +static TX_THREAD thread_193_3; +static TX_THREAD thread_194_3; +static TX_THREAD thread_195_3; +static TX_THREAD thread_196_3; +static TX_THREAD thread_197_3; +static TX_THREAD thread_198_3; +static TX_THREAD thread_199_3; +static TX_THREAD thread_200_3; +static TX_THREAD thread_201_3; +static TX_THREAD thread_202_3; +static TX_THREAD thread_203_3; +static TX_THREAD thread_204_3; +static TX_THREAD thread_205_3; +static TX_THREAD thread_206_3; +static TX_THREAD thread_207_3; +static TX_THREAD thread_208_3; +static TX_THREAD thread_209_3; +static TX_THREAD thread_210_3; +static TX_THREAD thread_211_3; +static TX_THREAD thread_212_3; +static TX_THREAD thread_213_3; +static TX_THREAD thread_214_3; +static TX_THREAD thread_215_3; +static TX_THREAD thread_216_3; +static TX_THREAD thread_217_3; +static TX_THREAD thread_218_3; +static TX_THREAD thread_219_3; +static TX_THREAD thread_220_3; +static TX_THREAD thread_221_3; +static TX_THREAD thread_222_3; +static TX_THREAD thread_223_3; +static TX_THREAD thread_224_3; +static TX_THREAD thread_225_3; +static TX_THREAD thread_226_3; +static TX_THREAD thread_227_3; +static TX_THREAD thread_228_3; +static TX_THREAD thread_229_3; +static TX_THREAD thread_230_3; +static TX_THREAD thread_231_3; +static TX_THREAD thread_232_3; +static TX_THREAD thread_233_3; +static TX_THREAD thread_234_3; +static TX_THREAD thread_235_3; +static TX_THREAD thread_236_3; +static TX_THREAD thread_237_3; +static TX_THREAD thread_238_3; +static TX_THREAD thread_239_3; +static TX_THREAD thread_240_3; +static TX_THREAD thread_241_3; +static TX_THREAD thread_242_3; +static TX_THREAD thread_243_3; +static TX_THREAD thread_244_3; +static TX_THREAD thread_245_3; +static TX_THREAD thread_246_3; +static TX_THREAD thread_247_3; +static TX_THREAD thread_248_3; +static TX_THREAD thread_249_3; +static TX_THREAD thread_250_3; +static TX_THREAD thread_251_3; +static TX_THREAD thread_252_3; +static TX_THREAD thread_253_3; +static TX_THREAD thread_254_3; +static TX_THREAD thread_255_3; + +/* Define test array. */ + +static TX_THREAD *_smp_randomized_source_array[] = { +{&thread_0}, +{&thread_1}, +{&thread_2}, +{&thread_3}, +{&thread_4}, +{&thread_5}, +{&thread_6}, +{&thread_7}, +{&thread_8}, +{&thread_9}, +{&thread_10}, +{&thread_11}, +{&thread_12}, +{&thread_13}, +{&thread_14}, +{&thread_15}, +{&thread_16}, +{&thread_17}, +{&thread_18}, +{&thread_19}, +{&thread_20}, +{&thread_21}, +{&thread_22}, +{&thread_23}, +{&thread_24}, +{&thread_25}, +{&thread_26}, +{&thread_27}, +{&thread_28}, +{&thread_29}, +{&thread_30}, +{&thread_31}, +{&thread_32}, +{&thread_33}, +{&thread_34}, +{&thread_35}, +{&thread_36}, +{&thread_37}, +{&thread_38}, +{&thread_39}, +{&thread_40}, +{&thread_41}, +{&thread_42}, +{&thread_43}, +{&thread_44}, +{&thread_45}, +{&thread_46}, +{&thread_47}, +{&thread_48}, +{&thread_49}, +{&thread_50}, +{&thread_51}, +{&thread_52}, +{&thread_53}, +{&thread_54}, +{&thread_55}, +{&thread_56}, +{&thread_57}, +{&thread_58}, +{&thread_59}, +{&thread_60}, +{&thread_61}, +{&thread_62}, +{&thread_63}, +{&thread_64}, +{&thread_65}, +{&thread_66}, +{&thread_67}, +{&thread_68}, +{&thread_69}, +{&thread_70}, +{&thread_71}, +{&thread_72}, +{&thread_73}, +{&thread_74}, +{&thread_75}, +{&thread_76}, +{&thread_77}, +{&thread_78}, +{&thread_79}, +{&thread_80}, +{&thread_81}, +{&thread_82}, +{&thread_83}, +{&thread_84}, +{&thread_85}, +{&thread_86}, +{&thread_87}, +{&thread_88}, +{&thread_89}, +{&thread_90}, +{&thread_91}, +{&thread_92}, +{&thread_93}, +{&thread_94}, +{&thread_95}, +{&thread_96}, +{&thread_97}, +{&thread_98}, +{&thread_99}, +{&thread_100}, +{&thread_101}, +{&thread_102}, +{&thread_103}, +{&thread_104}, +{&thread_105}, +{&thread_106}, +{&thread_107}, +{&thread_108}, +{&thread_109}, +{&thread_110}, +{&thread_111}, +{&thread_112}, +{&thread_113}, +{&thread_114}, +{&thread_115}, +{&thread_116}, +{&thread_117}, +{&thread_118}, +{&thread_119}, +{&thread_120}, +{&thread_121}, +{&thread_122}, +{&thread_123}, +{&thread_124}, +{&thread_125}, +{&thread_126}, +{&thread_127}, +{&thread_128}, +{&thread_129}, +{&thread_130}, +{&thread_131}, +{&thread_132}, +{&thread_133}, +{&thread_134}, +{&thread_135}, +{&thread_136}, +{&thread_137}, +{&thread_138}, +{&thread_139}, +{&thread_140}, +{&thread_141}, +{&thread_142}, +{&thread_143}, +{&thread_144}, +{&thread_145}, +{&thread_146}, +{&thread_147}, +{&thread_148}, +{&thread_149}, +{&thread_150}, +{&thread_151}, +{&thread_152}, +{&thread_153}, +{&thread_154}, +{&thread_155}, +{&thread_156}, +{&thread_157}, +{&thread_158}, +{&thread_159}, +{&thread_160}, +{&thread_161}, +{&thread_162}, +{&thread_163}, +{&thread_164}, +{&thread_165}, +{&thread_166}, +{&thread_167}, +{&thread_168}, +{&thread_169}, +{&thread_170}, +{&thread_171}, +{&thread_172}, +{&thread_173}, +{&thread_174}, +{&thread_175}, +{&thread_176}, +{&thread_177}, +{&thread_178}, +{&thread_179}, +{&thread_180}, +{&thread_181}, +{&thread_182}, +{&thread_183}, +{&thread_184}, +{&thread_185}, +{&thread_186}, +{&thread_187}, +{&thread_188}, +{&thread_189}, +{&thread_190}, +{&thread_191}, +{&thread_192}, +{&thread_193}, +{&thread_194}, +{&thread_195}, +{&thread_196}, +{&thread_197}, +{&thread_198}, +{&thread_199}, +{&thread_200}, +{&thread_201}, +{&thread_202}, +{&thread_203}, +{&thread_204}, +{&thread_205}, +{&thread_206}, +{&thread_207}, +{&thread_208}, +{&thread_209}, +{&thread_210}, +{&thread_211}, +{&thread_212}, +{&thread_213}, +{&thread_214}, +{&thread_215}, +{&thread_216}, +{&thread_217}, +{&thread_218}, +{&thread_219}, +{&thread_220}, +{&thread_221}, +{&thread_222}, +{&thread_223}, +{&thread_224}, +{&thread_225}, +{&thread_226}, +{&thread_227}, +{&thread_228}, +{&thread_229}, +{&thread_230}, +{&thread_231}, +{&thread_232}, +{&thread_233}, +{&thread_234}, +{&thread_235}, +{&thread_236}, +{&thread_237}, +{&thread_238}, +{&thread_239}, +{&thread_240}, +{&thread_241}, +{&thread_242}, +{&thread_243}, +{&thread_244}, +{&thread_245}, +{&thread_246}, +{&thread_247}, +{&thread_248}, +{&thread_249}, +{&thread_250}, +{&thread_251}, +{&thread_252}, +{&thread_253}, +{&thread_254}, +{&thread_255}, + +{&thread_0_1}, +{&thread_1_1}, +{&thread_2_1}, +{&thread_3_1}, +{&thread_4_1}, +{&thread_5_1}, +{&thread_6_1}, +{&thread_7_1}, +{&thread_8_1}, +{&thread_9_1}, +{&thread_10_1}, +{&thread_11_1}, +{&thread_12_1}, +{&thread_13_1}, +{&thread_14_1}, +{&thread_15_1}, +{&thread_16_1}, +{&thread_17_1}, +{&thread_18_1}, +{&thread_19_1}, +{&thread_20_1}, +{&thread_21_1}, +{&thread_22_1}, +{&thread_23_1}, +{&thread_24_1}, +{&thread_25_1}, +{&thread_26_1}, +{&thread_27_1}, +{&thread_28_1}, +{&thread_29_1}, +{&thread_30_1}, +{&thread_31_1}, +{&thread_32_1}, +{&thread_33_1}, +{&thread_34_1}, +{&thread_35_1}, +{&thread_36_1}, +{&thread_37_1}, +{&thread_38_1}, +{&thread_39_1}, +{&thread_40_1}, +{&thread_41_1}, +{&thread_42_1}, +{&thread_43_1}, +{&thread_44_1}, +{&thread_45_1}, +{&thread_46_1}, +{&thread_47_1}, +{&thread_48_1}, +{&thread_49_1}, +{&thread_50_1}, +{&thread_51_1}, +{&thread_52_1}, +{&thread_53_1}, +{&thread_54_1}, +{&thread_55_1}, +{&thread_56_1}, +{&thread_57_1}, +{&thread_58_1}, +{&thread_59_1}, +{&thread_60_1}, +{&thread_61_1}, +{&thread_62_1}, +{&thread_63_1}, +{&thread_64_1}, +{&thread_65_1}, +{&thread_66_1}, +{&thread_67_1}, +{&thread_68_1}, +{&thread_69_1}, +{&thread_70_1}, +{&thread_71_1}, +{&thread_72_1}, +{&thread_73_1}, +{&thread_74_1}, +{&thread_75_1}, +{&thread_76_1}, +{&thread_77_1}, +{&thread_78_1}, +{&thread_79_1}, +{&thread_80_1}, +{&thread_81_1}, +{&thread_82_1}, +{&thread_83_1}, +{&thread_84_1}, +{&thread_85_1}, +{&thread_86_1}, +{&thread_87_1}, +{&thread_88_1}, +{&thread_89_1}, +{&thread_90_1}, +{&thread_91_1}, +{&thread_92_1}, +{&thread_93_1}, +{&thread_94_1}, +{&thread_95_1}, +{&thread_96_1}, +{&thread_97_1}, +{&thread_98_1}, +{&thread_99_1}, +{&thread_100_1}, +{&thread_101_1}, +{&thread_102_1}, +{&thread_103_1}, +{&thread_104_1}, +{&thread_105_1}, +{&thread_106_1}, +{&thread_107_1}, +{&thread_108_1}, +{&thread_109_1}, +{&thread_110_1}, +{&thread_111_1}, +{&thread_112_1}, +{&thread_113_1}, +{&thread_114_1}, +{&thread_115_1}, +{&thread_116_1}, +{&thread_117_1}, +{&thread_118_1}, +{&thread_119_1}, +{&thread_120_1}, +{&thread_121_1}, +{&thread_122_1}, +{&thread_123_1}, +{&thread_124_1}, +{&thread_125_1}, +{&thread_126_1}, +{&thread_127_1}, +{&thread_128_1}, +{&thread_129_1}, +{&thread_130_1}, +{&thread_131_1}, +{&thread_132_1}, +{&thread_133_1}, +{&thread_134_1}, +{&thread_135_1}, +{&thread_136_1}, +{&thread_137_1}, +{&thread_138_1}, +{&thread_139_1}, +{&thread_140_1}, +{&thread_141_1}, +{&thread_142_1}, +{&thread_143_1}, +{&thread_144_1}, +{&thread_145_1}, +{&thread_146_1}, +{&thread_147_1}, +{&thread_148_1}, +{&thread_149_1}, +{&thread_150_1}, +{&thread_151_1}, +{&thread_152_1}, +{&thread_153_1}, +{&thread_154_1}, +{&thread_155_1}, +{&thread_156_1}, +{&thread_157_1}, +{&thread_158_1}, +{&thread_159_1}, +{&thread_160_1}, +{&thread_161_1}, +{&thread_162_1}, +{&thread_163_1}, +{&thread_164_1}, +{&thread_165_1}, +{&thread_166_1}, +{&thread_167_1}, +{&thread_168_1}, +{&thread_169_1}, +{&thread_170_1}, +{&thread_171_1}, +{&thread_172_1}, +{&thread_173_1}, +{&thread_174_1}, +{&thread_175_1}, +{&thread_176_1}, +{&thread_177_1}, +{&thread_178_1}, +{&thread_179_1}, +{&thread_180_1}, +{&thread_181_1}, +{&thread_182_1}, +{&thread_183_1}, +{&thread_184_1}, +{&thread_185_1}, +{&thread_186_1}, +{&thread_187_1}, +{&thread_188_1}, +{&thread_189_1}, +{&thread_190_1}, +{&thread_191_1}, +{&thread_192_1}, +{&thread_193_1}, +{&thread_194_1}, +{&thread_195_1}, +{&thread_196_1}, +{&thread_197_1}, +{&thread_198_1}, +{&thread_199_1}, +{&thread_200_1}, +{&thread_201_1}, +{&thread_202_1}, +{&thread_203_1}, +{&thread_204_1}, +{&thread_205_1}, +{&thread_206_1}, +{&thread_207_1}, +{&thread_208_1}, +{&thread_209_1}, +{&thread_210_1}, +{&thread_211_1}, +{&thread_212_1}, +{&thread_213_1}, +{&thread_214_1}, +{&thread_215_1}, +{&thread_216_1}, +{&thread_217_1}, +{&thread_218_1}, +{&thread_219_1}, +{&thread_220_1}, +{&thread_221_1}, +{&thread_222_1}, +{&thread_223_1}, +{&thread_224_1}, +{&thread_225_1}, +{&thread_226_1}, +{&thread_227_1}, +{&thread_228_1}, +{&thread_229_1}, +{&thread_230_1}, +{&thread_231_1}, +{&thread_232_1}, +{&thread_233_1}, +{&thread_234_1}, +{&thread_235_1}, +{&thread_236_1}, +{&thread_237_1}, +{&thread_238_1}, +{&thread_239_1}, +{&thread_240_1}, +{&thread_241_1}, +{&thread_242_1}, +{&thread_243_1}, +{&thread_244_1}, +{&thread_245_1}, +{&thread_246_1}, +{&thread_247_1}, +{&thread_248_1}, +{&thread_249_1}, +{&thread_250_1}, +{&thread_251_1}, +{&thread_252_1}, +{&thread_253_1}, +{&thread_254_1}, +{&thread_255_1}, + +{&thread_0_2}, +{&thread_1_2}, +{&thread_2_2}, +{&thread_3_2}, +{&thread_4_2}, +{&thread_5_2}, +{&thread_6_2}, +{&thread_7_2}, +{&thread_8_2}, +{&thread_9_2}, +{&thread_10_2}, +{&thread_11_2}, +{&thread_12_2}, +{&thread_13_2}, +{&thread_14_2}, +{&thread_15_2}, +{&thread_16_2}, +{&thread_17_2}, +{&thread_18_2}, +{&thread_19_2}, +{&thread_20_2}, +{&thread_21_2}, +{&thread_22_2}, +{&thread_23_2}, +{&thread_24_2}, +{&thread_25_2}, +{&thread_26_2}, +{&thread_27_2}, +{&thread_28_2}, +{&thread_29_2}, +{&thread_30_2}, +{&thread_31_2}, +{&thread_32_2}, +{&thread_33_2}, +{&thread_34_2}, +{&thread_35_2}, +{&thread_36_2}, +{&thread_37_2}, +{&thread_38_2}, +{&thread_39_2}, +{&thread_40_2}, +{&thread_41_2}, +{&thread_42_2}, +{&thread_43_2}, +{&thread_44_2}, +{&thread_45_2}, +{&thread_46_2}, +{&thread_47_2}, +{&thread_48_2}, +{&thread_49_2}, +{&thread_50_2}, +{&thread_51_2}, +{&thread_52_2}, +{&thread_53_2}, +{&thread_54_2}, +{&thread_55_2}, +{&thread_56_2}, +{&thread_57_2}, +{&thread_58_2}, +{&thread_59_2}, +{&thread_60_2}, +{&thread_61_2}, +{&thread_62_2}, +{&thread_63_2}, +{&thread_64_2}, +{&thread_65_2}, +{&thread_66_2}, +{&thread_67_2}, +{&thread_68_2}, +{&thread_69_2}, +{&thread_70_2}, +{&thread_71_2}, +{&thread_72_2}, +{&thread_73_2}, +{&thread_74_2}, +{&thread_75_2}, +{&thread_76_2}, +{&thread_77_2}, +{&thread_78_2}, +{&thread_79_2}, +{&thread_80_2}, +{&thread_81_2}, +{&thread_82_2}, +{&thread_83_2}, +{&thread_84_2}, +{&thread_85_2}, +{&thread_86_2}, +{&thread_87_2}, +{&thread_88_2}, +{&thread_89_2}, +{&thread_90_2}, +{&thread_91_2}, +{&thread_92_2}, +{&thread_93_2}, +{&thread_94_2}, +{&thread_95_2}, +{&thread_96_2}, +{&thread_97_2}, +{&thread_98_2}, +{&thread_99_2}, +{&thread_100_2}, +{&thread_101_2}, +{&thread_102_2}, +{&thread_103_2}, +{&thread_104_2}, +{&thread_105_2}, +{&thread_106_2}, +{&thread_107_2}, +{&thread_108_2}, +{&thread_109_2}, +{&thread_110_2}, +{&thread_111_2}, +{&thread_112_2}, +{&thread_113_2}, +{&thread_114_2}, +{&thread_115_2}, +{&thread_116_2}, +{&thread_117_2}, +{&thread_118_2}, +{&thread_119_2}, +{&thread_120_2}, +{&thread_121_2}, +{&thread_122_2}, +{&thread_123_2}, +{&thread_124_2}, +{&thread_125_2}, +{&thread_126_2}, +{&thread_127_2}, +{&thread_128_2}, +{&thread_129_2}, +{&thread_130_2}, +{&thread_131_2}, +{&thread_132_2}, +{&thread_133_2}, +{&thread_134_2}, +{&thread_135_2}, +{&thread_136_2}, +{&thread_137_2}, +{&thread_138_2}, +{&thread_139_2}, +{&thread_140_2}, +{&thread_141_2}, +{&thread_142_2}, +{&thread_143_2}, +{&thread_144_2}, +{&thread_145_2}, +{&thread_146_2}, +{&thread_147_2}, +{&thread_148_2}, +{&thread_149_2}, +{&thread_150_2}, +{&thread_151_2}, +{&thread_152_2}, +{&thread_153_2}, +{&thread_154_2}, +{&thread_155_2}, +{&thread_156_2}, +{&thread_157_2}, +{&thread_158_2}, +{&thread_159_2}, +{&thread_160_2}, +{&thread_161_2}, +{&thread_162_2}, +{&thread_163_2}, +{&thread_164_2}, +{&thread_165_2}, +{&thread_166_2}, +{&thread_167_2}, +{&thread_168_2}, +{&thread_169_2}, +{&thread_170_2}, +{&thread_171_2}, +{&thread_172_2}, +{&thread_173_2}, +{&thread_174_2}, +{&thread_175_2}, +{&thread_176_2}, +{&thread_177_2}, +{&thread_178_2}, +{&thread_179_2}, +{&thread_180_2}, +{&thread_181_2}, +{&thread_182_2}, +{&thread_183_2}, +{&thread_184_2}, +{&thread_185_2}, +{&thread_186_2}, +{&thread_187_2}, +{&thread_188_2}, +{&thread_189_2}, +{&thread_190_2}, +{&thread_191_2}, +{&thread_192_2}, +{&thread_193_2}, +{&thread_194_2}, +{&thread_195_2}, +{&thread_196_2}, +{&thread_197_2}, +{&thread_198_2}, +{&thread_199_2}, +{&thread_200_2}, +{&thread_201_2}, +{&thread_202_2}, +{&thread_203_2}, +{&thread_204_2}, +{&thread_205_2}, +{&thread_206_2}, +{&thread_207_2}, +{&thread_208_2}, +{&thread_209_2}, +{&thread_210_2}, +{&thread_211_2}, +{&thread_212_2}, +{&thread_213_2}, +{&thread_214_2}, +{&thread_215_2}, +{&thread_216_2}, +{&thread_217_2}, +{&thread_218_2}, +{&thread_219_2}, +{&thread_220_2}, +{&thread_221_2}, +{&thread_222_2}, +{&thread_223_2}, +{&thread_224_2}, +{&thread_225_2}, +{&thread_226_2}, +{&thread_227_2}, +{&thread_228_2}, +{&thread_229_2}, +{&thread_230_2}, +{&thread_231_2}, +{&thread_232_2}, +{&thread_233_2}, +{&thread_234_2}, +{&thread_235_2}, +{&thread_236_2}, +{&thread_237_2}, +{&thread_238_2}, +{&thread_239_2}, +{&thread_240_2}, +{&thread_241_2}, +{&thread_242_2}, +{&thread_243_2}, +{&thread_244_2}, +{&thread_245_2}, +{&thread_246_2}, +{&thread_247_2}, +{&thread_248_2}, +{&thread_249_2}, +{&thread_250_2}, +{&thread_251_2}, +{&thread_252_2}, +{&thread_253_2}, +{&thread_254_2}, +{&thread_255_2}, + +{&thread_0_3}, +{&thread_1_3}, +{&thread_2_3}, +{&thread_3_3}, +{&thread_4_3}, +{&thread_5_3}, +{&thread_6_3}, +{&thread_7_3}, +{&thread_8_3}, +{&thread_9_3}, +{&thread_10_3}, +{&thread_11_3}, +{&thread_12_3}, +{&thread_13_3}, +{&thread_14_3}, +{&thread_15_3}, +{&thread_16_3}, +{&thread_17_3}, +{&thread_18_3}, +{&thread_19_3}, +{&thread_20_3}, +{&thread_21_3}, +{&thread_22_3}, +{&thread_23_3}, +{&thread_24_3}, +{&thread_25_3}, +{&thread_26_3}, +{&thread_27_3}, +{&thread_28_3}, +{&thread_29_3}, +{&thread_30_3}, +{&thread_31_3}, +{&thread_32_3}, +{&thread_33_3}, +{&thread_34_3}, +{&thread_35_3}, +{&thread_36_3}, +{&thread_37_3}, +{&thread_38_3}, +{&thread_39_3}, +{&thread_40_3}, +{&thread_41_3}, +{&thread_42_3}, +{&thread_43_3}, +{&thread_44_3}, +{&thread_45_3}, +{&thread_46_3}, +{&thread_47_3}, +{&thread_48_3}, +{&thread_49_3}, +{&thread_50_3}, +{&thread_51_3}, +{&thread_52_3}, +{&thread_53_3}, +{&thread_54_3}, +{&thread_55_3}, +{&thread_56_3}, +{&thread_57_3}, +{&thread_58_3}, +{&thread_59_3}, +{&thread_60_3}, +{&thread_61_3}, +{&thread_62_3}, +{&thread_63_3}, +{&thread_64_3}, +{&thread_65_3}, +{&thread_66_3}, +{&thread_67_3}, +{&thread_68_3}, +{&thread_69_3}, +{&thread_70_3}, +{&thread_71_3}, +{&thread_72_3}, +{&thread_73_3}, +{&thread_74_3}, +{&thread_75_3}, +{&thread_76_3}, +{&thread_77_3}, +{&thread_78_3}, +{&thread_79_3}, +{&thread_80_3}, +{&thread_81_3}, +{&thread_82_3}, +{&thread_83_3}, +{&thread_84_3}, +{&thread_85_3}, +{&thread_86_3}, +{&thread_87_3}, +{&thread_88_3}, +{&thread_89_3}, +{&thread_90_3}, +{&thread_91_3}, +{&thread_92_3}, +{&thread_93_3}, +{&thread_94_3}, +{&thread_95_3}, +{&thread_96_3}, +{&thread_97_3}, +{&thread_98_3}, +{&thread_99_3}, +{&thread_100_3}, +{&thread_101_3}, +{&thread_102_3}, +{&thread_103_3}, +{&thread_104_3}, +{&thread_105_3}, +{&thread_106_3}, +{&thread_107_3}, +{&thread_108_3}, +{&thread_109_3}, +{&thread_110_3}, +{&thread_111_3}, +{&thread_112_3}, +{&thread_113_3}, +{&thread_114_3}, +{&thread_115_3}, +{&thread_116_3}, +{&thread_117_3}, +{&thread_118_3}, +{&thread_119_3}, +{&thread_120_3}, +{&thread_121_3}, +{&thread_122_3}, +{&thread_123_3}, +{&thread_124_3}, +{&thread_125_3}, +{&thread_126_3}, +{&thread_127_3}, +{&thread_128_3}, +{&thread_129_3}, +{&thread_130_3}, +{&thread_131_3}, +{&thread_132_3}, +{&thread_133_3}, +{&thread_134_3}, +{&thread_135_3}, +{&thread_136_3}, +{&thread_137_3}, +{&thread_138_3}, +{&thread_139_3}, +{&thread_140_3}, +{&thread_141_3}, +{&thread_142_3}, +{&thread_143_3}, +{&thread_144_3}, +{&thread_145_3}, +{&thread_146_3}, +{&thread_147_3}, +{&thread_148_3}, +{&thread_149_3}, +{&thread_150_3}, +{&thread_151_3}, +{&thread_152_3}, +{&thread_153_3}, +{&thread_154_3}, +{&thread_155_3}, +{&thread_156_3}, +{&thread_157_3}, +{&thread_158_3}, +{&thread_159_3}, +{&thread_160_3}, +{&thread_161_3}, +{&thread_162_3}, +{&thread_163_3}, +{&thread_164_3}, +{&thread_165_3}, +{&thread_166_3}, +{&thread_167_3}, +{&thread_168_3}, +{&thread_169_3}, +{&thread_170_3}, +{&thread_171_3}, +{&thread_172_3}, +{&thread_173_3}, +{&thread_174_3}, +{&thread_175_3}, +{&thread_176_3}, +{&thread_177_3}, +{&thread_178_3}, +{&thread_179_3}, +{&thread_180_3}, +{&thread_181_3}, +{&thread_182_3}, +{&thread_183_3}, +{&thread_184_3}, +{&thread_185_3}, +{&thread_186_3}, +{&thread_187_3}, +{&thread_188_3}, +{&thread_189_3}, +{&thread_190_3}, +{&thread_191_3}, +{&thread_192_3}, +{&thread_193_3}, +{&thread_194_3}, +{&thread_195_3}, +{&thread_196_3}, +{&thread_197_3}, +{&thread_198_3}, +{&thread_199_3}, +{&thread_200_3}, +{&thread_201_3}, +{&thread_202_3}, +{&thread_203_3}, +{&thread_204_3}, +{&thread_205_3}, +{&thread_206_3}, +{&thread_207_3}, +{&thread_208_3}, +{&thread_209_3}, +{&thread_210_3}, +{&thread_211_3}, +{&thread_212_3}, +{&thread_213_3}, +{&thread_214_3}, +{&thread_215_3}, +{&thread_216_3}, +{&thread_217_3}, +{&thread_218_3}, +{&thread_219_3}, +{&thread_220_3}, +{&thread_221_3}, +{&thread_222_3}, +{&thread_223_3}, +{&thread_224_3}, +{&thread_225_3}, +{&thread_226_3}, +{&thread_227_3}, +{&thread_228_3}, +{&thread_229_3}, +{&thread_230_3}, +{&thread_231_3}, +{&thread_232_3}, +{&thread_233_3}, +{&thread_234_3}, +{&thread_235_3}, +{&thread_236_3}, +{&thread_237_3}, +{&thread_238_3}, +{&thread_239_3}, +{&thread_240_3}, +{&thread_241_3}, +{&thread_242_3}, +{&thread_243_3}, +{&thread_244_3}, +{&thread_245_3}, +{&thread_246_3}, +{&thread_247_3}, +{&thread_248_3}, +{&thread_249_3}, +{&thread_250_3}, +{&thread_251_3}, +{&thread_252_3}, +{&thread_253_3}, +{&thread_254_3}, +{&thread_255_3} +}; + +/* Define the test array. This used to store the randomized test. */ + +static TX_THREAD *_smp_randomized_test_array[TX_THREAD_SMP_MAX_CORES*2]; + + +/* Define thread entry prototype. Since it won't be used it can be the same. */ + +static void control_thread_entry(ULONG thread_input); +static void thread_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + + +static UINT pass; +static UINT start_pass; +static UINT end_pass; +static UINT mapping_error; + + +/* Create a test control thread. */ + +static TX_THREAD control_thread; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_smp_random_resume_suspend_exclusion_test(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a control thread to run the test. */ + status = tx_thread_create(&control_thread, "control thread", control_thread_entry, 0, + pointer, 1024, + 0, 0, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Random Suspensions/Resumptions/Exclusions Test.......... ERROR #1\n"); + test_control_return(1); + } +} + + +static void control_thread_entry(ULONG thread_input) +{ + +UINT i, j; +UINT priority; +UINT source_index; +UINT successful_tests = 0; +UINT test_errors = 0; +TX_THREAD *thread_ptr; +TX_THREAD *current_thread; +UINT original_priority; +ULONG exclusions; +UINT status; + + + /* Clear mapping error flag. */ + mapping_error = TX_FALSE; + + /* Pickup the current thread pointer. */ + current_thread = tx_thread_identify(); + + /* Loop to create all the threads. */ + i = 0; + priority = 0; + status = TX_SUCCESS; + while (i < 1024) + { + + /* Create each thread. */ + status += tx_thread_create(_smp_randomized_source_array[i], "test thread", thread_entry, i, +// (void *) pointer, 512, + malloc(1024), 1024, + priority, priority, TX_NO_TIME_SLICE, TX_DONT_START); +// pointer = pointer + 512; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Random Suspensions/Resumptions/Exclusions Test.......... ERROR #2\n"); + test_control_return(1); + break; + } + + /* Move to next entry/priority. */ + i++; + priority++; + + /* Should priority be reset? */ + if (priority >= TX_MAX_PRIORITIES) + { + + /* Yes, reset the priority. */ + priority = 0; + } + } + + /* Start random test. */ + printf("Running SMP Random Suspensions/Resumptions/Exclusions Test.......... "); + + /* Clear system counters. */ + pass = 0; + start_pass = 0; + end_pass = start_pass + MAX_PASSES; + do + { + + /* Clear the randomized test array. */ + for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++) + { + _smp_randomized_test_array[i] = TX_NULL; + } + + /* Build the randomized test array. */ + for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++) + { + do + { + + source_index = (rand())%1024; + + /* Determine if this index has repeated. */ + thread_ptr = _smp_randomized_source_array[source_index]; + + /* Is this thread already in the test array? */ + j = 0; + while (j < TX_THREAD_SMP_MAX_CORES*2) + { + + /* Is the entry NULL? */ + if (_smp_randomized_test_array[j] == TX_NULL) + { + j = (TX_THREAD_SMP_MAX_CORES*2); + } + + /* Determine if we have a duplicate. */ + if (_smp_randomized_test_array[j] == thread_ptr) + thread_ptr = TX_NULL; + + j++; + } + + } while (thread_ptr == TX_NULL); + + /* Clear run counter. */ + thread_ptr -> tx_thread_run_count = 0; + + /* Setup the exclusion for this thread. */ + exclusions = (ULONG) (rand()%15); + tx_thread_smp_core_exclude(thread_ptr, exclusions); + + /* Save the thread pointer. */ + _smp_randomized_test_array[i] = thread_ptr; + } + + /* Now make all the random threads ready. */ + for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++) + { + status = tx_thread_resume(_smp_randomized_test_array[i]); + + /* Check for an error. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #3\n"); + test_control_return(1); + break; + } + } + + /* Check the status. */ + if (status) + break; + + /* Move to the lowest priority. */ + status += tx_thread_priority_change(current_thread, TX_MAX_PRIORITIES-1, &original_priority); + tx_thread_relinquish(); + + /* At this point all the threads have run, or should have. */ + + /* Restore priority. */ + status += tx_thread_priority_change(current_thread, original_priority, &original_priority); + + /* Was there an error? */ + if (status != TX_SUCCESS) + { + + printf("ERROR #4\n"); + test_control_return(1); + break; + } + + /* Determine if all the threads in the the random sample ran. */ + for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++) + { + + /* Pickup the thread pointer. */ + thread_ptr = _smp_randomized_test_array[i]; + + /* Check to see if each thread has run. */ + if (thread_ptr -> tx_thread_run_count == 0) + { + + /* First, try to sleep to see if this helps! */ + tx_thread_sleep(1); + } + + /* Has the run count incremented? */ + if (thread_ptr -> tx_thread_run_count == 0) + { + + /* No, this thread didn't really run! */ + printf("ERROR #5\n"); + test_control_return(1); + break; + } + + /* Make sure this thread suspended. */ + while (thread_ptr -> tx_thread_state != TX_SUSPENDED) + { + + /* Wait for the thread to complete! */ + tx_thread_relinquish(); + } + + /* Reset the exclusion for this thread. */ + tx_thread_smp_core_exclude(thread_ptr, 0); + + /* Check for mapping error. */ + if (mapping_error) + { + + /* No, this thread ran on inccorect core! */ + printf("ERROR #6\n"); + test_control_return(1); + break; + } + } + + /* Increment the pass counter. */ + pass++; + + } while (pass < end_pass); + + /* Test is successful! */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_entry(ULONG id) +{ + +UINT core; +ULONG core_bit_map; +TX_THREAD *thread_ptr; + + /* While forever loop! */ + while(1) + { + + /* Get thread. */ + thread_ptr = _smp_randomized_source_array[id]; + + /* Determine if this thread is running on a valid core. */ + core = tx_thread_smp_core_get(); + + /* Build a bit map for this core. */ + core_bit_map = (((ULONG) 1) << core); + + /* Is this a valid core? */ + if (core_bit_map & thread_ptr -> tx_thread_smp_cores_excluded) + { + + /* Invalid core, set error flag. */ + mapping_error = TX_TRUE; + } + + /* Suspend thread! */ + tx_thread_suspend(thread_ptr); + } +} + diff --git a/test/smp/regression/threadx_smp_random_resume_suspend_test.c b/test/smp/regression/threadx_smp_random_resume_suspend_test.c new file mode 100644 index 00000000..e7a6dc2c --- /dev/null +++ b/test/smp/regression/threadx_smp_random_resume_suspend_test.c @@ -0,0 +1,2329 @@ +/* Define the ThreadX SMP random resume/suspend test. */ + +#include +#include "tx_api.h" + +//#define MAX_PASSES 50000000 +//#define MAX_PASSES 50000 +#define MAX_PASSES 500 + + +/* Define the ThreadX object control blocks... Must have 256 priority levels... and assumes 4 cores. */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; +static TX_THREAD thread_4; +static TX_THREAD thread_5; +static TX_THREAD thread_6; +static TX_THREAD thread_7; +static TX_THREAD thread_8; +static TX_THREAD thread_9; +static TX_THREAD thread_10; +static TX_THREAD thread_11; +static TX_THREAD thread_12; +static TX_THREAD thread_13; +static TX_THREAD thread_14; +static TX_THREAD thread_15; +static TX_THREAD thread_16; +static TX_THREAD thread_17; +static TX_THREAD thread_18; +static TX_THREAD thread_19; +static TX_THREAD thread_20; +static TX_THREAD thread_21; +static TX_THREAD thread_22; +static TX_THREAD thread_23; +static TX_THREAD thread_24; +static TX_THREAD thread_25; +static TX_THREAD thread_26; +static TX_THREAD thread_27; +static TX_THREAD thread_28; +static TX_THREAD thread_29; +static TX_THREAD thread_30; +static TX_THREAD thread_31; +static TX_THREAD thread_32; +static TX_THREAD thread_33; +static TX_THREAD thread_34; +static TX_THREAD thread_35; +static TX_THREAD thread_36; +static TX_THREAD thread_37; +static TX_THREAD thread_38; +static TX_THREAD thread_39; +static TX_THREAD thread_40; +static TX_THREAD thread_41; +static TX_THREAD thread_42; +static TX_THREAD thread_43; +static TX_THREAD thread_44; +static TX_THREAD thread_45; +static TX_THREAD thread_46; +static TX_THREAD thread_47; +static TX_THREAD thread_48; +static TX_THREAD thread_49; +static TX_THREAD thread_50; +static TX_THREAD thread_51; +static TX_THREAD thread_52; +static TX_THREAD thread_53; +static TX_THREAD thread_54; +static TX_THREAD thread_55; +static TX_THREAD thread_56; +static TX_THREAD thread_57; +static TX_THREAD thread_58; +static TX_THREAD thread_59; +static TX_THREAD thread_60; +static TX_THREAD thread_61; +static TX_THREAD thread_62; +static TX_THREAD thread_63; +static TX_THREAD thread_64; +static TX_THREAD thread_65; +static TX_THREAD thread_66; +static TX_THREAD thread_67; +static TX_THREAD thread_68; +static TX_THREAD thread_69; +static TX_THREAD thread_70; +static TX_THREAD thread_71; +static TX_THREAD thread_72; +static TX_THREAD thread_73; +static TX_THREAD thread_74; +static TX_THREAD thread_75; +static TX_THREAD thread_76; +static TX_THREAD thread_77; +static TX_THREAD thread_78; +static TX_THREAD thread_79; +static TX_THREAD thread_80; +static TX_THREAD thread_81; +static TX_THREAD thread_82; +static TX_THREAD thread_83; +static TX_THREAD thread_84; +static TX_THREAD thread_85; +static TX_THREAD thread_86; +static TX_THREAD thread_87; +static TX_THREAD thread_88; +static TX_THREAD thread_89; +static TX_THREAD thread_90; +static TX_THREAD thread_91; +static TX_THREAD thread_92; +static TX_THREAD thread_93; +static TX_THREAD thread_94; +static TX_THREAD thread_95; +static TX_THREAD thread_96; +static TX_THREAD thread_97; +static TX_THREAD thread_98; +static TX_THREAD thread_99; +static TX_THREAD thread_100; +static TX_THREAD thread_101; +static TX_THREAD thread_102; +static TX_THREAD thread_103; +static TX_THREAD thread_104; +static TX_THREAD thread_105; +static TX_THREAD thread_106; +static TX_THREAD thread_107; +static TX_THREAD thread_108; +static TX_THREAD thread_109; +static TX_THREAD thread_110; +static TX_THREAD thread_111; +static TX_THREAD thread_112; +static TX_THREAD thread_113; +static TX_THREAD thread_114; +static TX_THREAD thread_115; +static TX_THREAD thread_116; +static TX_THREAD thread_117; +static TX_THREAD thread_118; +static TX_THREAD thread_119; +static TX_THREAD thread_120; +static TX_THREAD thread_121; +static TX_THREAD thread_122; +static TX_THREAD thread_123; +static TX_THREAD thread_124; +static TX_THREAD thread_125; +static TX_THREAD thread_126; +static TX_THREAD thread_127; +static TX_THREAD thread_128; +static TX_THREAD thread_129; +static TX_THREAD thread_130; +static TX_THREAD thread_131; +static TX_THREAD thread_132; +static TX_THREAD thread_133; +static TX_THREAD thread_134; +static TX_THREAD thread_135; +static TX_THREAD thread_136; +static TX_THREAD thread_137; +static TX_THREAD thread_138; +static TX_THREAD thread_139; +static TX_THREAD thread_140; +static TX_THREAD thread_141; +static TX_THREAD thread_142; +static TX_THREAD thread_143; +static TX_THREAD thread_144; +static TX_THREAD thread_145; +static TX_THREAD thread_146; +static TX_THREAD thread_147; +static TX_THREAD thread_148; +static TX_THREAD thread_149; +static TX_THREAD thread_150; +static TX_THREAD thread_151; +static TX_THREAD thread_152; +static TX_THREAD thread_153; +static TX_THREAD thread_154; +static TX_THREAD thread_155; +static TX_THREAD thread_156; +static TX_THREAD thread_157; +static TX_THREAD thread_158; +static TX_THREAD thread_159; +static TX_THREAD thread_160; +static TX_THREAD thread_161; +static TX_THREAD thread_162; +static TX_THREAD thread_163; +static TX_THREAD thread_164; +static TX_THREAD thread_165; +static TX_THREAD thread_166; +static TX_THREAD thread_167; +static TX_THREAD thread_168; +static TX_THREAD thread_169; +static TX_THREAD thread_170; +static TX_THREAD thread_171; +static TX_THREAD thread_172; +static TX_THREAD thread_173; +static TX_THREAD thread_174; +static TX_THREAD thread_175; +static TX_THREAD thread_176; +static TX_THREAD thread_177; +static TX_THREAD thread_178; +static TX_THREAD thread_179; +static TX_THREAD thread_180; +static TX_THREAD thread_181; +static TX_THREAD thread_182; +static TX_THREAD thread_183; +static TX_THREAD thread_184; +static TX_THREAD thread_185; +static TX_THREAD thread_186; +static TX_THREAD thread_187; +static TX_THREAD thread_188; +static TX_THREAD thread_189; +static TX_THREAD thread_190; +static TX_THREAD thread_191; +static TX_THREAD thread_192; +static TX_THREAD thread_193; +static TX_THREAD thread_194; +static TX_THREAD thread_195; +static TX_THREAD thread_196; +static TX_THREAD thread_197; +static TX_THREAD thread_198; +static TX_THREAD thread_199; +static TX_THREAD thread_200; +static TX_THREAD thread_201; +static TX_THREAD thread_202; +static TX_THREAD thread_203; +static TX_THREAD thread_204; +static TX_THREAD thread_205; +static TX_THREAD thread_206; +static TX_THREAD thread_207; +static TX_THREAD thread_208; +static TX_THREAD thread_209; +static TX_THREAD thread_210; +static TX_THREAD thread_211; +static TX_THREAD thread_212; +static TX_THREAD thread_213; +static TX_THREAD thread_214; +static TX_THREAD thread_215; +static TX_THREAD thread_216; +static TX_THREAD thread_217; +static TX_THREAD thread_218; +static TX_THREAD thread_219; +static TX_THREAD thread_220; +static TX_THREAD thread_221; +static TX_THREAD thread_222; +static TX_THREAD thread_223; +static TX_THREAD thread_224; +static TX_THREAD thread_225; +static TX_THREAD thread_226; +static TX_THREAD thread_227; +static TX_THREAD thread_228; +static TX_THREAD thread_229; +static TX_THREAD thread_230; +static TX_THREAD thread_231; +static TX_THREAD thread_232; +static TX_THREAD thread_233; +static TX_THREAD thread_234; +static TX_THREAD thread_235; +static TX_THREAD thread_236; +static TX_THREAD thread_237; +static TX_THREAD thread_238; +static TX_THREAD thread_239; +static TX_THREAD thread_240; +static TX_THREAD thread_241; +static TX_THREAD thread_242; +static TX_THREAD thread_243; +static TX_THREAD thread_244; +static TX_THREAD thread_245; +static TX_THREAD thread_246; +static TX_THREAD thread_247; +static TX_THREAD thread_248; +static TX_THREAD thread_249; +static TX_THREAD thread_250; +static TX_THREAD thread_251; +static TX_THREAD thread_252; +static TX_THREAD thread_253; +static TX_THREAD thread_254; +static TX_THREAD thread_255; + +static TX_THREAD thread_0_1; +static TX_THREAD thread_1_1; +static TX_THREAD thread_2_1; +static TX_THREAD thread_3_1; +static TX_THREAD thread_4_1; +static TX_THREAD thread_5_1; +static TX_THREAD thread_6_1; +static TX_THREAD thread_7_1; +static TX_THREAD thread_8_1; +static TX_THREAD thread_9_1; +static TX_THREAD thread_10_1; +static TX_THREAD thread_11_1; +static TX_THREAD thread_12_1; +static TX_THREAD thread_13_1; +static TX_THREAD thread_14_1; +static TX_THREAD thread_15_1; +static TX_THREAD thread_16_1; +static TX_THREAD thread_17_1; +static TX_THREAD thread_18_1; +static TX_THREAD thread_19_1; +static TX_THREAD thread_20_1; +static TX_THREAD thread_21_1; +static TX_THREAD thread_22_1; +static TX_THREAD thread_23_1; +static TX_THREAD thread_24_1; +static TX_THREAD thread_25_1; +static TX_THREAD thread_26_1; +static TX_THREAD thread_27_1; +static TX_THREAD thread_28_1; +static TX_THREAD thread_29_1; +static TX_THREAD thread_30_1; +static TX_THREAD thread_31_1; +static TX_THREAD thread_32_1; +static TX_THREAD thread_33_1; +static TX_THREAD thread_34_1; +static TX_THREAD thread_35_1; +static TX_THREAD thread_36_1; +static TX_THREAD thread_37_1; +static TX_THREAD thread_38_1; +static TX_THREAD thread_39_1; +static TX_THREAD thread_40_1; +static TX_THREAD thread_41_1; +static TX_THREAD thread_42_1; +static TX_THREAD thread_43_1; +static TX_THREAD thread_44_1; +static TX_THREAD thread_45_1; +static TX_THREAD thread_46_1; +static TX_THREAD thread_47_1; +static TX_THREAD thread_48_1; +static TX_THREAD thread_49_1; +static TX_THREAD thread_50_1; +static TX_THREAD thread_51_1; +static TX_THREAD thread_52_1; +static TX_THREAD thread_53_1; +static TX_THREAD thread_54_1; +static TX_THREAD thread_55_1; +static TX_THREAD thread_56_1; +static TX_THREAD thread_57_1; +static TX_THREAD thread_58_1; +static TX_THREAD thread_59_1; +static TX_THREAD thread_60_1; +static TX_THREAD thread_61_1; +static TX_THREAD thread_62_1; +static TX_THREAD thread_63_1; +static TX_THREAD thread_64_1; +static TX_THREAD thread_65_1; +static TX_THREAD thread_66_1; +static TX_THREAD thread_67_1; +static TX_THREAD thread_68_1; +static TX_THREAD thread_69_1; +static TX_THREAD thread_70_1; +static TX_THREAD thread_71_1; +static TX_THREAD thread_72_1; +static TX_THREAD thread_73_1; +static TX_THREAD thread_74_1; +static TX_THREAD thread_75_1; +static TX_THREAD thread_76_1; +static TX_THREAD thread_77_1; +static TX_THREAD thread_78_1; +static TX_THREAD thread_79_1; +static TX_THREAD thread_80_1; +static TX_THREAD thread_81_1; +static TX_THREAD thread_82_1; +static TX_THREAD thread_83_1; +static TX_THREAD thread_84_1; +static TX_THREAD thread_85_1; +static TX_THREAD thread_86_1; +static TX_THREAD thread_87_1; +static TX_THREAD thread_88_1; +static TX_THREAD thread_89_1; +static TX_THREAD thread_90_1; +static TX_THREAD thread_91_1; +static TX_THREAD thread_92_1; +static TX_THREAD thread_93_1; +static TX_THREAD thread_94_1; +static TX_THREAD thread_95_1; +static TX_THREAD thread_96_1; +static TX_THREAD thread_97_1; +static TX_THREAD thread_98_1; +static TX_THREAD thread_99_1; +static TX_THREAD thread_100_1; +static TX_THREAD thread_101_1; +static TX_THREAD thread_102_1; +static TX_THREAD thread_103_1; +static TX_THREAD thread_104_1; +static TX_THREAD thread_105_1; +static TX_THREAD thread_106_1; +static TX_THREAD thread_107_1; +static TX_THREAD thread_108_1; +static TX_THREAD thread_109_1; +static TX_THREAD thread_110_1; +static TX_THREAD thread_111_1; +static TX_THREAD thread_112_1; +static TX_THREAD thread_113_1; +static TX_THREAD thread_114_1; +static TX_THREAD thread_115_1; +static TX_THREAD thread_116_1; +static TX_THREAD thread_117_1; +static TX_THREAD thread_118_1; +static TX_THREAD thread_119_1; +static TX_THREAD thread_120_1; +static TX_THREAD thread_121_1; +static TX_THREAD thread_122_1; +static TX_THREAD thread_123_1; +static TX_THREAD thread_124_1; +static TX_THREAD thread_125_1; +static TX_THREAD thread_126_1; +static TX_THREAD thread_127_1; +static TX_THREAD thread_128_1; +static TX_THREAD thread_129_1; +static TX_THREAD thread_130_1; +static TX_THREAD thread_131_1; +static TX_THREAD thread_132_1; +static TX_THREAD thread_133_1; +static TX_THREAD thread_134_1; +static TX_THREAD thread_135_1; +static TX_THREAD thread_136_1; +static TX_THREAD thread_137_1; +static TX_THREAD thread_138_1; +static TX_THREAD thread_139_1; +static TX_THREAD thread_140_1; +static TX_THREAD thread_141_1; +static TX_THREAD thread_142_1; +static TX_THREAD thread_143_1; +static TX_THREAD thread_144_1; +static TX_THREAD thread_145_1; +static TX_THREAD thread_146_1; +static TX_THREAD thread_147_1; +static TX_THREAD thread_148_1; +static TX_THREAD thread_149_1; +static TX_THREAD thread_150_1; +static TX_THREAD thread_151_1; +static TX_THREAD thread_152_1; +static TX_THREAD thread_153_1; +static TX_THREAD thread_154_1; +static TX_THREAD thread_155_1; +static TX_THREAD thread_156_1; +static TX_THREAD thread_157_1; +static TX_THREAD thread_158_1; +static TX_THREAD thread_159_1; +static TX_THREAD thread_160_1; +static TX_THREAD thread_161_1; +static TX_THREAD thread_162_1; +static TX_THREAD thread_163_1; +static TX_THREAD thread_164_1; +static TX_THREAD thread_165_1; +static TX_THREAD thread_166_1; +static TX_THREAD thread_167_1; +static TX_THREAD thread_168_1; +static TX_THREAD thread_169_1; +static TX_THREAD thread_170_1; +static TX_THREAD thread_171_1; +static TX_THREAD thread_172_1; +static TX_THREAD thread_173_1; +static TX_THREAD thread_174_1; +static TX_THREAD thread_175_1; +static TX_THREAD thread_176_1; +static TX_THREAD thread_177_1; +static TX_THREAD thread_178_1; +static TX_THREAD thread_179_1; +static TX_THREAD thread_180_1; +static TX_THREAD thread_181_1; +static TX_THREAD thread_182_1; +static TX_THREAD thread_183_1; +static TX_THREAD thread_184_1; +static TX_THREAD thread_185_1; +static TX_THREAD thread_186_1; +static TX_THREAD thread_187_1; +static TX_THREAD thread_188_1; +static TX_THREAD thread_189_1; +static TX_THREAD thread_190_1; +static TX_THREAD thread_191_1; +static TX_THREAD thread_192_1; +static TX_THREAD thread_193_1; +static TX_THREAD thread_194_1; +static TX_THREAD thread_195_1; +static TX_THREAD thread_196_1; +static TX_THREAD thread_197_1; +static TX_THREAD thread_198_1; +static TX_THREAD thread_199_1; +static TX_THREAD thread_200_1; +static TX_THREAD thread_201_1; +static TX_THREAD thread_202_1; +static TX_THREAD thread_203_1; +static TX_THREAD thread_204_1; +static TX_THREAD thread_205_1; +static TX_THREAD thread_206_1; +static TX_THREAD thread_207_1; +static TX_THREAD thread_208_1; +static TX_THREAD thread_209_1; +static TX_THREAD thread_210_1; +static TX_THREAD thread_211_1; +static TX_THREAD thread_212_1; +static TX_THREAD thread_213_1; +static TX_THREAD thread_214_1; +static TX_THREAD thread_215_1; +static TX_THREAD thread_216_1; +static TX_THREAD thread_217_1; +static TX_THREAD thread_218_1; +static TX_THREAD thread_219_1; +static TX_THREAD thread_220_1; +static TX_THREAD thread_221_1; +static TX_THREAD thread_222_1; +static TX_THREAD thread_223_1; +static TX_THREAD thread_224_1; +static TX_THREAD thread_225_1; +static TX_THREAD thread_226_1; +static TX_THREAD thread_227_1; +static TX_THREAD thread_228_1; +static TX_THREAD thread_229_1; +static TX_THREAD thread_230_1; +static TX_THREAD thread_231_1; +static TX_THREAD thread_232_1; +static TX_THREAD thread_233_1; +static TX_THREAD thread_234_1; +static TX_THREAD thread_235_1; +static TX_THREAD thread_236_1; +static TX_THREAD thread_237_1; +static TX_THREAD thread_238_1; +static TX_THREAD thread_239_1; +static TX_THREAD thread_240_1; +static TX_THREAD thread_241_1; +static TX_THREAD thread_242_1; +static TX_THREAD thread_243_1; +static TX_THREAD thread_244_1; +static TX_THREAD thread_245_1; +static TX_THREAD thread_246_1; +static TX_THREAD thread_247_1; +static TX_THREAD thread_248_1; +static TX_THREAD thread_249_1; +static TX_THREAD thread_250_1; +static TX_THREAD thread_251_1; +static TX_THREAD thread_252_1; +static TX_THREAD thread_253_1; +static TX_THREAD thread_254_1; +static TX_THREAD thread_255_1; + +static TX_THREAD thread_0_2; +static TX_THREAD thread_1_2; +static TX_THREAD thread_2_2; +static TX_THREAD thread_3_2; +static TX_THREAD thread_4_2; +static TX_THREAD thread_5_2; +static TX_THREAD thread_6_2; +static TX_THREAD thread_7_2; +static TX_THREAD thread_8_2; +static TX_THREAD thread_9_2; +static TX_THREAD thread_10_2; +static TX_THREAD thread_11_2; +static TX_THREAD thread_12_2; +static TX_THREAD thread_13_2; +static TX_THREAD thread_14_2; +static TX_THREAD thread_15_2; +static TX_THREAD thread_16_2; +static TX_THREAD thread_17_2; +static TX_THREAD thread_18_2; +static TX_THREAD thread_19_2; +static TX_THREAD thread_20_2; +static TX_THREAD thread_21_2; +static TX_THREAD thread_22_2; +static TX_THREAD thread_23_2; +static TX_THREAD thread_24_2; +static TX_THREAD thread_25_2; +static TX_THREAD thread_26_2; +static TX_THREAD thread_27_2; +static TX_THREAD thread_28_2; +static TX_THREAD thread_29_2; +static TX_THREAD thread_30_2; +static TX_THREAD thread_31_2; +static TX_THREAD thread_32_2; +static TX_THREAD thread_33_2; +static TX_THREAD thread_34_2; +static TX_THREAD thread_35_2; +static TX_THREAD thread_36_2; +static TX_THREAD thread_37_2; +static TX_THREAD thread_38_2; +static TX_THREAD thread_39_2; +static TX_THREAD thread_40_2; +static TX_THREAD thread_41_2; +static TX_THREAD thread_42_2; +static TX_THREAD thread_43_2; +static TX_THREAD thread_44_2; +static TX_THREAD thread_45_2; +static TX_THREAD thread_46_2; +static TX_THREAD thread_47_2; +static TX_THREAD thread_48_2; +static TX_THREAD thread_49_2; +static TX_THREAD thread_50_2; +static TX_THREAD thread_51_2; +static TX_THREAD thread_52_2; +static TX_THREAD thread_53_2; +static TX_THREAD thread_54_2; +static TX_THREAD thread_55_2; +static TX_THREAD thread_56_2; +static TX_THREAD thread_57_2; +static TX_THREAD thread_58_2; +static TX_THREAD thread_59_2; +static TX_THREAD thread_60_2; +static TX_THREAD thread_61_2; +static TX_THREAD thread_62_2; +static TX_THREAD thread_63_2; +static TX_THREAD thread_64_2; +static TX_THREAD thread_65_2; +static TX_THREAD thread_66_2; +static TX_THREAD thread_67_2; +static TX_THREAD thread_68_2; +static TX_THREAD thread_69_2; +static TX_THREAD thread_70_2; +static TX_THREAD thread_71_2; +static TX_THREAD thread_72_2; +static TX_THREAD thread_73_2; +static TX_THREAD thread_74_2; +static TX_THREAD thread_75_2; +static TX_THREAD thread_76_2; +static TX_THREAD thread_77_2; +static TX_THREAD thread_78_2; +static TX_THREAD thread_79_2; +static TX_THREAD thread_80_2; +static TX_THREAD thread_81_2; +static TX_THREAD thread_82_2; +static TX_THREAD thread_83_2; +static TX_THREAD thread_84_2; +static TX_THREAD thread_85_2; +static TX_THREAD thread_86_2; +static TX_THREAD thread_87_2; +static TX_THREAD thread_88_2; +static TX_THREAD thread_89_2; +static TX_THREAD thread_90_2; +static TX_THREAD thread_91_2; +static TX_THREAD thread_92_2; +static TX_THREAD thread_93_2; +static TX_THREAD thread_94_2; +static TX_THREAD thread_95_2; +static TX_THREAD thread_96_2; +static TX_THREAD thread_97_2; +static TX_THREAD thread_98_2; +static TX_THREAD thread_99_2; +static TX_THREAD thread_100_2; +static TX_THREAD thread_101_2; +static TX_THREAD thread_102_2; +static TX_THREAD thread_103_2; +static TX_THREAD thread_104_2; +static TX_THREAD thread_105_2; +static TX_THREAD thread_106_2; +static TX_THREAD thread_107_2; +static TX_THREAD thread_108_2; +static TX_THREAD thread_109_2; +static TX_THREAD thread_110_2; +static TX_THREAD thread_111_2; +static TX_THREAD thread_112_2; +static TX_THREAD thread_113_2; +static TX_THREAD thread_114_2; +static TX_THREAD thread_115_2; +static TX_THREAD thread_116_2; +static TX_THREAD thread_117_2; +static TX_THREAD thread_118_2; +static TX_THREAD thread_119_2; +static TX_THREAD thread_120_2; +static TX_THREAD thread_121_2; +static TX_THREAD thread_122_2; +static TX_THREAD thread_123_2; +static TX_THREAD thread_124_2; +static TX_THREAD thread_125_2; +static TX_THREAD thread_126_2; +static TX_THREAD thread_127_2; +static TX_THREAD thread_128_2; +static TX_THREAD thread_129_2; +static TX_THREAD thread_130_2; +static TX_THREAD thread_131_2; +static TX_THREAD thread_132_2; +static TX_THREAD thread_133_2; +static TX_THREAD thread_134_2; +static TX_THREAD thread_135_2; +static TX_THREAD thread_136_2; +static TX_THREAD thread_137_2; +static TX_THREAD thread_138_2; +static TX_THREAD thread_139_2; +static TX_THREAD thread_140_2; +static TX_THREAD thread_141_2; +static TX_THREAD thread_142_2; +static TX_THREAD thread_143_2; +static TX_THREAD thread_144_2; +static TX_THREAD thread_145_2; +static TX_THREAD thread_146_2; +static TX_THREAD thread_147_2; +static TX_THREAD thread_148_2; +static TX_THREAD thread_149_2; +static TX_THREAD thread_150_2; +static TX_THREAD thread_151_2; +static TX_THREAD thread_152_2; +static TX_THREAD thread_153_2; +static TX_THREAD thread_154_2; +static TX_THREAD thread_155_2; +static TX_THREAD thread_156_2; +static TX_THREAD thread_157_2; +static TX_THREAD thread_158_2; +static TX_THREAD thread_159_2; +static TX_THREAD thread_160_2; +static TX_THREAD thread_161_2; +static TX_THREAD thread_162_2; +static TX_THREAD thread_163_2; +static TX_THREAD thread_164_2; +static TX_THREAD thread_165_2; +static TX_THREAD thread_166_2; +static TX_THREAD thread_167_2; +static TX_THREAD thread_168_2; +static TX_THREAD thread_169_2; +static TX_THREAD thread_170_2; +static TX_THREAD thread_171_2; +static TX_THREAD thread_172_2; +static TX_THREAD thread_173_2; +static TX_THREAD thread_174_2; +static TX_THREAD thread_175_2; +static TX_THREAD thread_176_2; +static TX_THREAD thread_177_2; +static TX_THREAD thread_178_2; +static TX_THREAD thread_179_2; +static TX_THREAD thread_180_2; +static TX_THREAD thread_181_2; +static TX_THREAD thread_182_2; +static TX_THREAD thread_183_2; +static TX_THREAD thread_184_2; +static TX_THREAD thread_185_2; +static TX_THREAD thread_186_2; +static TX_THREAD thread_187_2; +static TX_THREAD thread_188_2; +static TX_THREAD thread_189_2; +static TX_THREAD thread_190_2; +static TX_THREAD thread_191_2; +static TX_THREAD thread_192_2; +static TX_THREAD thread_193_2; +static TX_THREAD thread_194_2; +static TX_THREAD thread_195_2; +static TX_THREAD thread_196_2; +static TX_THREAD thread_197_2; +static TX_THREAD thread_198_2; +static TX_THREAD thread_199_2; +static TX_THREAD thread_200_2; +static TX_THREAD thread_201_2; +static TX_THREAD thread_202_2; +static TX_THREAD thread_203_2; +static TX_THREAD thread_204_2; +static TX_THREAD thread_205_2; +static TX_THREAD thread_206_2; +static TX_THREAD thread_207_2; +static TX_THREAD thread_208_2; +static TX_THREAD thread_209_2; +static TX_THREAD thread_210_2; +static TX_THREAD thread_211_2; +static TX_THREAD thread_212_2; +static TX_THREAD thread_213_2; +static TX_THREAD thread_214_2; +static TX_THREAD thread_215_2; +static TX_THREAD thread_216_2; +static TX_THREAD thread_217_2; +static TX_THREAD thread_218_2; +static TX_THREAD thread_219_2; +static TX_THREAD thread_220_2; +static TX_THREAD thread_221_2; +static TX_THREAD thread_222_2; +static TX_THREAD thread_223_2; +static TX_THREAD thread_224_2; +static TX_THREAD thread_225_2; +static TX_THREAD thread_226_2; +static TX_THREAD thread_227_2; +static TX_THREAD thread_228_2; +static TX_THREAD thread_229_2; +static TX_THREAD thread_230_2; +static TX_THREAD thread_231_2; +static TX_THREAD thread_232_2; +static TX_THREAD thread_233_2; +static TX_THREAD thread_234_2; +static TX_THREAD thread_235_2; +static TX_THREAD thread_236_2; +static TX_THREAD thread_237_2; +static TX_THREAD thread_238_2; +static TX_THREAD thread_239_2; +static TX_THREAD thread_240_2; +static TX_THREAD thread_241_2; +static TX_THREAD thread_242_2; +static TX_THREAD thread_243_2; +static TX_THREAD thread_244_2; +static TX_THREAD thread_245_2; +static TX_THREAD thread_246_2; +static TX_THREAD thread_247_2; +static TX_THREAD thread_248_2; +static TX_THREAD thread_249_2; +static TX_THREAD thread_250_2; +static TX_THREAD thread_251_2; +static TX_THREAD thread_252_2; +static TX_THREAD thread_253_2; +static TX_THREAD thread_254_2; +static TX_THREAD thread_255_2; + +static TX_THREAD thread_0_3; +static TX_THREAD thread_1_3; +static TX_THREAD thread_2_3; +static TX_THREAD thread_3_3; +static TX_THREAD thread_4_3; +static TX_THREAD thread_5_3; +static TX_THREAD thread_6_3; +static TX_THREAD thread_7_3; +static TX_THREAD thread_8_3; +static TX_THREAD thread_9_3; +static TX_THREAD thread_10_3; +static TX_THREAD thread_11_3; +static TX_THREAD thread_12_3; +static TX_THREAD thread_13_3; +static TX_THREAD thread_14_3; +static TX_THREAD thread_15_3; +static TX_THREAD thread_16_3; +static TX_THREAD thread_17_3; +static TX_THREAD thread_18_3; +static TX_THREAD thread_19_3; +static TX_THREAD thread_20_3; +static TX_THREAD thread_21_3; +static TX_THREAD thread_22_3; +static TX_THREAD thread_23_3; +static TX_THREAD thread_24_3; +static TX_THREAD thread_25_3; +static TX_THREAD thread_26_3; +static TX_THREAD thread_27_3; +static TX_THREAD thread_28_3; +static TX_THREAD thread_29_3; +static TX_THREAD thread_30_3; +static TX_THREAD thread_31_3; +static TX_THREAD thread_32_3; +static TX_THREAD thread_33_3; +static TX_THREAD thread_34_3; +static TX_THREAD thread_35_3; +static TX_THREAD thread_36_3; +static TX_THREAD thread_37_3; +static TX_THREAD thread_38_3; +static TX_THREAD thread_39_3; +static TX_THREAD thread_40_3; +static TX_THREAD thread_41_3; +static TX_THREAD thread_42_3; +static TX_THREAD thread_43_3; +static TX_THREAD thread_44_3; +static TX_THREAD thread_45_3; +static TX_THREAD thread_46_3; +static TX_THREAD thread_47_3; +static TX_THREAD thread_48_3; +static TX_THREAD thread_49_3; +static TX_THREAD thread_50_3; +static TX_THREAD thread_51_3; +static TX_THREAD thread_52_3; +static TX_THREAD thread_53_3; +static TX_THREAD thread_54_3; +static TX_THREAD thread_55_3; +static TX_THREAD thread_56_3; +static TX_THREAD thread_57_3; +static TX_THREAD thread_58_3; +static TX_THREAD thread_59_3; +static TX_THREAD thread_60_3; +static TX_THREAD thread_61_3; +static TX_THREAD thread_62_3; +static TX_THREAD thread_63_3; +static TX_THREAD thread_64_3; +static TX_THREAD thread_65_3; +static TX_THREAD thread_66_3; +static TX_THREAD thread_67_3; +static TX_THREAD thread_68_3; +static TX_THREAD thread_69_3; +static TX_THREAD thread_70_3; +static TX_THREAD thread_71_3; +static TX_THREAD thread_72_3; +static TX_THREAD thread_73_3; +static TX_THREAD thread_74_3; +static TX_THREAD thread_75_3; +static TX_THREAD thread_76_3; +static TX_THREAD thread_77_3; +static TX_THREAD thread_78_3; +static TX_THREAD thread_79_3; +static TX_THREAD thread_80_3; +static TX_THREAD thread_81_3; +static TX_THREAD thread_82_3; +static TX_THREAD thread_83_3; +static TX_THREAD thread_84_3; +static TX_THREAD thread_85_3; +static TX_THREAD thread_86_3; +static TX_THREAD thread_87_3; +static TX_THREAD thread_88_3; +static TX_THREAD thread_89_3; +static TX_THREAD thread_90_3; +static TX_THREAD thread_91_3; +static TX_THREAD thread_92_3; +static TX_THREAD thread_93_3; +static TX_THREAD thread_94_3; +static TX_THREAD thread_95_3; +static TX_THREAD thread_96_3; +static TX_THREAD thread_97_3; +static TX_THREAD thread_98_3; +static TX_THREAD thread_99_3; +static TX_THREAD thread_100_3; +static TX_THREAD thread_101_3; +static TX_THREAD thread_102_3; +static TX_THREAD thread_103_3; +static TX_THREAD thread_104_3; +static TX_THREAD thread_105_3; +static TX_THREAD thread_106_3; +static TX_THREAD thread_107_3; +static TX_THREAD thread_108_3; +static TX_THREAD thread_109_3; +static TX_THREAD thread_110_3; +static TX_THREAD thread_111_3; +static TX_THREAD thread_112_3; +static TX_THREAD thread_113_3; +static TX_THREAD thread_114_3; +static TX_THREAD thread_115_3; +static TX_THREAD thread_116_3; +static TX_THREAD thread_117_3; +static TX_THREAD thread_118_3; +static TX_THREAD thread_119_3; +static TX_THREAD thread_120_3; +static TX_THREAD thread_121_3; +static TX_THREAD thread_122_3; +static TX_THREAD thread_123_3; +static TX_THREAD thread_124_3; +static TX_THREAD thread_125_3; +static TX_THREAD thread_126_3; +static TX_THREAD thread_127_3; +static TX_THREAD thread_128_3; +static TX_THREAD thread_129_3; +static TX_THREAD thread_130_3; +static TX_THREAD thread_131_3; +static TX_THREAD thread_132_3; +static TX_THREAD thread_133_3; +static TX_THREAD thread_134_3; +static TX_THREAD thread_135_3; +static TX_THREAD thread_136_3; +static TX_THREAD thread_137_3; +static TX_THREAD thread_138_3; +static TX_THREAD thread_139_3; +static TX_THREAD thread_140_3; +static TX_THREAD thread_141_3; +static TX_THREAD thread_142_3; +static TX_THREAD thread_143_3; +static TX_THREAD thread_144_3; +static TX_THREAD thread_145_3; +static TX_THREAD thread_146_3; +static TX_THREAD thread_147_3; +static TX_THREAD thread_148_3; +static TX_THREAD thread_149_3; +static TX_THREAD thread_150_3; +static TX_THREAD thread_151_3; +static TX_THREAD thread_152_3; +static TX_THREAD thread_153_3; +static TX_THREAD thread_154_3; +static TX_THREAD thread_155_3; +static TX_THREAD thread_156_3; +static TX_THREAD thread_157_3; +static TX_THREAD thread_158_3; +static TX_THREAD thread_159_3; +static TX_THREAD thread_160_3; +static TX_THREAD thread_161_3; +static TX_THREAD thread_162_3; +static TX_THREAD thread_163_3; +static TX_THREAD thread_164_3; +static TX_THREAD thread_165_3; +static TX_THREAD thread_166_3; +static TX_THREAD thread_167_3; +static TX_THREAD thread_168_3; +static TX_THREAD thread_169_3; +static TX_THREAD thread_170_3; +static TX_THREAD thread_171_3; +static TX_THREAD thread_172_3; +static TX_THREAD thread_173_3; +static TX_THREAD thread_174_3; +static TX_THREAD thread_175_3; +static TX_THREAD thread_176_3; +static TX_THREAD thread_177_3; +static TX_THREAD thread_178_3; +static TX_THREAD thread_179_3; +static TX_THREAD thread_180_3; +static TX_THREAD thread_181_3; +static TX_THREAD thread_182_3; +static TX_THREAD thread_183_3; +static TX_THREAD thread_184_3; +static TX_THREAD thread_185_3; +static TX_THREAD thread_186_3; +static TX_THREAD thread_187_3; +static TX_THREAD thread_188_3; +static TX_THREAD thread_189_3; +static TX_THREAD thread_190_3; +static TX_THREAD thread_191_3; +static TX_THREAD thread_192_3; +static TX_THREAD thread_193_3; +static TX_THREAD thread_194_3; +static TX_THREAD thread_195_3; +static TX_THREAD thread_196_3; +static TX_THREAD thread_197_3; +static TX_THREAD thread_198_3; +static TX_THREAD thread_199_3; +static TX_THREAD thread_200_3; +static TX_THREAD thread_201_3; +static TX_THREAD thread_202_3; +static TX_THREAD thread_203_3; +static TX_THREAD thread_204_3; +static TX_THREAD thread_205_3; +static TX_THREAD thread_206_3; +static TX_THREAD thread_207_3; +static TX_THREAD thread_208_3; +static TX_THREAD thread_209_3; +static TX_THREAD thread_210_3; +static TX_THREAD thread_211_3; +static TX_THREAD thread_212_3; +static TX_THREAD thread_213_3; +static TX_THREAD thread_214_3; +static TX_THREAD thread_215_3; +static TX_THREAD thread_216_3; +static TX_THREAD thread_217_3; +static TX_THREAD thread_218_3; +static TX_THREAD thread_219_3; +static TX_THREAD thread_220_3; +static TX_THREAD thread_221_3; +static TX_THREAD thread_222_3; +static TX_THREAD thread_223_3; +static TX_THREAD thread_224_3; +static TX_THREAD thread_225_3; +static TX_THREAD thread_226_3; +static TX_THREAD thread_227_3; +static TX_THREAD thread_228_3; +static TX_THREAD thread_229_3; +static TX_THREAD thread_230_3; +static TX_THREAD thread_231_3; +static TX_THREAD thread_232_3; +static TX_THREAD thread_233_3; +static TX_THREAD thread_234_3; +static TX_THREAD thread_235_3; +static TX_THREAD thread_236_3; +static TX_THREAD thread_237_3; +static TX_THREAD thread_238_3; +static TX_THREAD thread_239_3; +static TX_THREAD thread_240_3; +static TX_THREAD thread_241_3; +static TX_THREAD thread_242_3; +static TX_THREAD thread_243_3; +static TX_THREAD thread_244_3; +static TX_THREAD thread_245_3; +static TX_THREAD thread_246_3; +static TX_THREAD thread_247_3; +static TX_THREAD thread_248_3; +static TX_THREAD thread_249_3; +static TX_THREAD thread_250_3; +static TX_THREAD thread_251_3; +static TX_THREAD thread_252_3; +static TX_THREAD thread_253_3; +static TX_THREAD thread_254_3; +static TX_THREAD thread_255_3; + +/* Define test array. */ + +static TX_THREAD *_smp_randomized_source_array[] = { +{&thread_0}, +{&thread_1}, +{&thread_2}, +{&thread_3}, +{&thread_4}, +{&thread_5}, +{&thread_6}, +{&thread_7}, +{&thread_8}, +{&thread_9}, +{&thread_10}, +{&thread_11}, +{&thread_12}, +{&thread_13}, +{&thread_14}, +{&thread_15}, +{&thread_16}, +{&thread_17}, +{&thread_18}, +{&thread_19}, +{&thread_20}, +{&thread_21}, +{&thread_22}, +{&thread_23}, +{&thread_24}, +{&thread_25}, +{&thread_26}, +{&thread_27}, +{&thread_28}, +{&thread_29}, +{&thread_30}, +{&thread_31}, +{&thread_32}, +{&thread_33}, +{&thread_34}, +{&thread_35}, +{&thread_36}, +{&thread_37}, +{&thread_38}, +{&thread_39}, +{&thread_40}, +{&thread_41}, +{&thread_42}, +{&thread_43}, +{&thread_44}, +{&thread_45}, +{&thread_46}, +{&thread_47}, +{&thread_48}, +{&thread_49}, +{&thread_50}, +{&thread_51}, +{&thread_52}, +{&thread_53}, +{&thread_54}, +{&thread_55}, +{&thread_56}, +{&thread_57}, +{&thread_58}, +{&thread_59}, +{&thread_60}, +{&thread_61}, +{&thread_62}, +{&thread_63}, +{&thread_64}, +{&thread_65}, +{&thread_66}, +{&thread_67}, +{&thread_68}, +{&thread_69}, +{&thread_70}, +{&thread_71}, +{&thread_72}, +{&thread_73}, +{&thread_74}, +{&thread_75}, +{&thread_76}, +{&thread_77}, +{&thread_78}, +{&thread_79}, +{&thread_80}, +{&thread_81}, +{&thread_82}, +{&thread_83}, +{&thread_84}, +{&thread_85}, +{&thread_86}, +{&thread_87}, +{&thread_88}, +{&thread_89}, +{&thread_90}, +{&thread_91}, +{&thread_92}, +{&thread_93}, +{&thread_94}, +{&thread_95}, +{&thread_96}, +{&thread_97}, +{&thread_98}, +{&thread_99}, +{&thread_100}, +{&thread_101}, +{&thread_102}, +{&thread_103}, +{&thread_104}, +{&thread_105}, +{&thread_106}, +{&thread_107}, +{&thread_108}, +{&thread_109}, +{&thread_110}, +{&thread_111}, +{&thread_112}, +{&thread_113}, +{&thread_114}, +{&thread_115}, +{&thread_116}, +{&thread_117}, +{&thread_118}, +{&thread_119}, +{&thread_120}, +{&thread_121}, +{&thread_122}, +{&thread_123}, +{&thread_124}, +{&thread_125}, +{&thread_126}, +{&thread_127}, +{&thread_128}, +{&thread_129}, +{&thread_130}, +{&thread_131}, +{&thread_132}, +{&thread_133}, +{&thread_134}, +{&thread_135}, +{&thread_136}, +{&thread_137}, +{&thread_138}, +{&thread_139}, +{&thread_140}, +{&thread_141}, +{&thread_142}, +{&thread_143}, +{&thread_144}, +{&thread_145}, +{&thread_146}, +{&thread_147}, +{&thread_148}, +{&thread_149}, +{&thread_150}, +{&thread_151}, +{&thread_152}, +{&thread_153}, +{&thread_154}, +{&thread_155}, +{&thread_156}, +{&thread_157}, +{&thread_158}, +{&thread_159}, +{&thread_160}, +{&thread_161}, +{&thread_162}, +{&thread_163}, +{&thread_164}, +{&thread_165}, +{&thread_166}, +{&thread_167}, +{&thread_168}, +{&thread_169}, +{&thread_170}, +{&thread_171}, +{&thread_172}, +{&thread_173}, +{&thread_174}, +{&thread_175}, +{&thread_176}, +{&thread_177}, +{&thread_178}, +{&thread_179}, +{&thread_180}, +{&thread_181}, +{&thread_182}, +{&thread_183}, +{&thread_184}, +{&thread_185}, +{&thread_186}, +{&thread_187}, +{&thread_188}, +{&thread_189}, +{&thread_190}, +{&thread_191}, +{&thread_192}, +{&thread_193}, +{&thread_194}, +{&thread_195}, +{&thread_196}, +{&thread_197}, +{&thread_198}, +{&thread_199}, +{&thread_200}, +{&thread_201}, +{&thread_202}, +{&thread_203}, +{&thread_204}, +{&thread_205}, +{&thread_206}, +{&thread_207}, +{&thread_208}, +{&thread_209}, +{&thread_210}, +{&thread_211}, +{&thread_212}, +{&thread_213}, +{&thread_214}, +{&thread_215}, +{&thread_216}, +{&thread_217}, +{&thread_218}, +{&thread_219}, +{&thread_220}, +{&thread_221}, +{&thread_222}, +{&thread_223}, +{&thread_224}, +{&thread_225}, +{&thread_226}, +{&thread_227}, +{&thread_228}, +{&thread_229}, +{&thread_230}, +{&thread_231}, +{&thread_232}, +{&thread_233}, +{&thread_234}, +{&thread_235}, +{&thread_236}, +{&thread_237}, +{&thread_238}, +{&thread_239}, +{&thread_240}, +{&thread_241}, +{&thread_242}, +{&thread_243}, +{&thread_244}, +{&thread_245}, +{&thread_246}, +{&thread_247}, +{&thread_248}, +{&thread_249}, +{&thread_250}, +{&thread_251}, +{&thread_252}, +{&thread_253}, +{&thread_254}, +{&thread_255}, + +{&thread_0_1}, +{&thread_1_1}, +{&thread_2_1}, +{&thread_3_1}, +{&thread_4_1}, +{&thread_5_1}, +{&thread_6_1}, +{&thread_7_1}, +{&thread_8_1}, +{&thread_9_1}, +{&thread_10_1}, +{&thread_11_1}, +{&thread_12_1}, +{&thread_13_1}, +{&thread_14_1}, +{&thread_15_1}, +{&thread_16_1}, +{&thread_17_1}, +{&thread_18_1}, +{&thread_19_1}, +{&thread_20_1}, +{&thread_21_1}, +{&thread_22_1}, +{&thread_23_1}, +{&thread_24_1}, +{&thread_25_1}, +{&thread_26_1}, +{&thread_27_1}, +{&thread_28_1}, +{&thread_29_1}, +{&thread_30_1}, +{&thread_31_1}, +{&thread_32_1}, +{&thread_33_1}, +{&thread_34_1}, +{&thread_35_1}, +{&thread_36_1}, +{&thread_37_1}, +{&thread_38_1}, +{&thread_39_1}, +{&thread_40_1}, +{&thread_41_1}, +{&thread_42_1}, +{&thread_43_1}, +{&thread_44_1}, +{&thread_45_1}, +{&thread_46_1}, +{&thread_47_1}, +{&thread_48_1}, +{&thread_49_1}, +{&thread_50_1}, +{&thread_51_1}, +{&thread_52_1}, +{&thread_53_1}, +{&thread_54_1}, +{&thread_55_1}, +{&thread_56_1}, +{&thread_57_1}, +{&thread_58_1}, +{&thread_59_1}, +{&thread_60_1}, +{&thread_61_1}, +{&thread_62_1}, +{&thread_63_1}, +{&thread_64_1}, +{&thread_65_1}, +{&thread_66_1}, +{&thread_67_1}, +{&thread_68_1}, +{&thread_69_1}, +{&thread_70_1}, +{&thread_71_1}, +{&thread_72_1}, +{&thread_73_1}, +{&thread_74_1}, +{&thread_75_1}, +{&thread_76_1}, +{&thread_77_1}, +{&thread_78_1}, +{&thread_79_1}, +{&thread_80_1}, +{&thread_81_1}, +{&thread_82_1}, +{&thread_83_1}, +{&thread_84_1}, +{&thread_85_1}, +{&thread_86_1}, +{&thread_87_1}, +{&thread_88_1}, +{&thread_89_1}, +{&thread_90_1}, +{&thread_91_1}, +{&thread_92_1}, +{&thread_93_1}, +{&thread_94_1}, +{&thread_95_1}, +{&thread_96_1}, +{&thread_97_1}, +{&thread_98_1}, +{&thread_99_1}, +{&thread_100_1}, +{&thread_101_1}, +{&thread_102_1}, +{&thread_103_1}, +{&thread_104_1}, +{&thread_105_1}, +{&thread_106_1}, +{&thread_107_1}, +{&thread_108_1}, +{&thread_109_1}, +{&thread_110_1}, +{&thread_111_1}, +{&thread_112_1}, +{&thread_113_1}, +{&thread_114_1}, +{&thread_115_1}, +{&thread_116_1}, +{&thread_117_1}, +{&thread_118_1}, +{&thread_119_1}, +{&thread_120_1}, +{&thread_121_1}, +{&thread_122_1}, +{&thread_123_1}, +{&thread_124_1}, +{&thread_125_1}, +{&thread_126_1}, +{&thread_127_1}, +{&thread_128_1}, +{&thread_129_1}, +{&thread_130_1}, +{&thread_131_1}, +{&thread_132_1}, +{&thread_133_1}, +{&thread_134_1}, +{&thread_135_1}, +{&thread_136_1}, +{&thread_137_1}, +{&thread_138_1}, +{&thread_139_1}, +{&thread_140_1}, +{&thread_141_1}, +{&thread_142_1}, +{&thread_143_1}, +{&thread_144_1}, +{&thread_145_1}, +{&thread_146_1}, +{&thread_147_1}, +{&thread_148_1}, +{&thread_149_1}, +{&thread_150_1}, +{&thread_151_1}, +{&thread_152_1}, +{&thread_153_1}, +{&thread_154_1}, +{&thread_155_1}, +{&thread_156_1}, +{&thread_157_1}, +{&thread_158_1}, +{&thread_159_1}, +{&thread_160_1}, +{&thread_161_1}, +{&thread_162_1}, +{&thread_163_1}, +{&thread_164_1}, +{&thread_165_1}, +{&thread_166_1}, +{&thread_167_1}, +{&thread_168_1}, +{&thread_169_1}, +{&thread_170_1}, +{&thread_171_1}, +{&thread_172_1}, +{&thread_173_1}, +{&thread_174_1}, +{&thread_175_1}, +{&thread_176_1}, +{&thread_177_1}, +{&thread_178_1}, +{&thread_179_1}, +{&thread_180_1}, +{&thread_181_1}, +{&thread_182_1}, +{&thread_183_1}, +{&thread_184_1}, +{&thread_185_1}, +{&thread_186_1}, +{&thread_187_1}, +{&thread_188_1}, +{&thread_189_1}, +{&thread_190_1}, +{&thread_191_1}, +{&thread_192_1}, +{&thread_193_1}, +{&thread_194_1}, +{&thread_195_1}, +{&thread_196_1}, +{&thread_197_1}, +{&thread_198_1}, +{&thread_199_1}, +{&thread_200_1}, +{&thread_201_1}, +{&thread_202_1}, +{&thread_203_1}, +{&thread_204_1}, +{&thread_205_1}, +{&thread_206_1}, +{&thread_207_1}, +{&thread_208_1}, +{&thread_209_1}, +{&thread_210_1}, +{&thread_211_1}, +{&thread_212_1}, +{&thread_213_1}, +{&thread_214_1}, +{&thread_215_1}, +{&thread_216_1}, +{&thread_217_1}, +{&thread_218_1}, +{&thread_219_1}, +{&thread_220_1}, +{&thread_221_1}, +{&thread_222_1}, +{&thread_223_1}, +{&thread_224_1}, +{&thread_225_1}, +{&thread_226_1}, +{&thread_227_1}, +{&thread_228_1}, +{&thread_229_1}, +{&thread_230_1}, +{&thread_231_1}, +{&thread_232_1}, +{&thread_233_1}, +{&thread_234_1}, +{&thread_235_1}, +{&thread_236_1}, +{&thread_237_1}, +{&thread_238_1}, +{&thread_239_1}, +{&thread_240_1}, +{&thread_241_1}, +{&thread_242_1}, +{&thread_243_1}, +{&thread_244_1}, +{&thread_245_1}, +{&thread_246_1}, +{&thread_247_1}, +{&thread_248_1}, +{&thread_249_1}, +{&thread_250_1}, +{&thread_251_1}, +{&thread_252_1}, +{&thread_253_1}, +{&thread_254_1}, +{&thread_255_1}, + +{&thread_0_2}, +{&thread_1_2}, +{&thread_2_2}, +{&thread_3_2}, +{&thread_4_2}, +{&thread_5_2}, +{&thread_6_2}, +{&thread_7_2}, +{&thread_8_2}, +{&thread_9_2}, +{&thread_10_2}, +{&thread_11_2}, +{&thread_12_2}, +{&thread_13_2}, +{&thread_14_2}, +{&thread_15_2}, +{&thread_16_2}, +{&thread_17_2}, +{&thread_18_2}, +{&thread_19_2}, +{&thread_20_2}, +{&thread_21_2}, +{&thread_22_2}, +{&thread_23_2}, +{&thread_24_2}, +{&thread_25_2}, +{&thread_26_2}, +{&thread_27_2}, +{&thread_28_2}, +{&thread_29_2}, +{&thread_30_2}, +{&thread_31_2}, +{&thread_32_2}, +{&thread_33_2}, +{&thread_34_2}, +{&thread_35_2}, +{&thread_36_2}, +{&thread_37_2}, +{&thread_38_2}, +{&thread_39_2}, +{&thread_40_2}, +{&thread_41_2}, +{&thread_42_2}, +{&thread_43_2}, +{&thread_44_2}, +{&thread_45_2}, +{&thread_46_2}, +{&thread_47_2}, +{&thread_48_2}, +{&thread_49_2}, +{&thread_50_2}, +{&thread_51_2}, +{&thread_52_2}, +{&thread_53_2}, +{&thread_54_2}, +{&thread_55_2}, +{&thread_56_2}, +{&thread_57_2}, +{&thread_58_2}, +{&thread_59_2}, +{&thread_60_2}, +{&thread_61_2}, +{&thread_62_2}, +{&thread_63_2}, +{&thread_64_2}, +{&thread_65_2}, +{&thread_66_2}, +{&thread_67_2}, +{&thread_68_2}, +{&thread_69_2}, +{&thread_70_2}, +{&thread_71_2}, +{&thread_72_2}, +{&thread_73_2}, +{&thread_74_2}, +{&thread_75_2}, +{&thread_76_2}, +{&thread_77_2}, +{&thread_78_2}, +{&thread_79_2}, +{&thread_80_2}, +{&thread_81_2}, +{&thread_82_2}, +{&thread_83_2}, +{&thread_84_2}, +{&thread_85_2}, +{&thread_86_2}, +{&thread_87_2}, +{&thread_88_2}, +{&thread_89_2}, +{&thread_90_2}, +{&thread_91_2}, +{&thread_92_2}, +{&thread_93_2}, +{&thread_94_2}, +{&thread_95_2}, +{&thread_96_2}, +{&thread_97_2}, +{&thread_98_2}, +{&thread_99_2}, +{&thread_100_2}, +{&thread_101_2}, +{&thread_102_2}, +{&thread_103_2}, +{&thread_104_2}, +{&thread_105_2}, +{&thread_106_2}, +{&thread_107_2}, +{&thread_108_2}, +{&thread_109_2}, +{&thread_110_2}, +{&thread_111_2}, +{&thread_112_2}, +{&thread_113_2}, +{&thread_114_2}, +{&thread_115_2}, +{&thread_116_2}, +{&thread_117_2}, +{&thread_118_2}, +{&thread_119_2}, +{&thread_120_2}, +{&thread_121_2}, +{&thread_122_2}, +{&thread_123_2}, +{&thread_124_2}, +{&thread_125_2}, +{&thread_126_2}, +{&thread_127_2}, +{&thread_128_2}, +{&thread_129_2}, +{&thread_130_2}, +{&thread_131_2}, +{&thread_132_2}, +{&thread_133_2}, +{&thread_134_2}, +{&thread_135_2}, +{&thread_136_2}, +{&thread_137_2}, +{&thread_138_2}, +{&thread_139_2}, +{&thread_140_2}, +{&thread_141_2}, +{&thread_142_2}, +{&thread_143_2}, +{&thread_144_2}, +{&thread_145_2}, +{&thread_146_2}, +{&thread_147_2}, +{&thread_148_2}, +{&thread_149_2}, +{&thread_150_2}, +{&thread_151_2}, +{&thread_152_2}, +{&thread_153_2}, +{&thread_154_2}, +{&thread_155_2}, +{&thread_156_2}, +{&thread_157_2}, +{&thread_158_2}, +{&thread_159_2}, +{&thread_160_2}, +{&thread_161_2}, +{&thread_162_2}, +{&thread_163_2}, +{&thread_164_2}, +{&thread_165_2}, +{&thread_166_2}, +{&thread_167_2}, +{&thread_168_2}, +{&thread_169_2}, +{&thread_170_2}, +{&thread_171_2}, +{&thread_172_2}, +{&thread_173_2}, +{&thread_174_2}, +{&thread_175_2}, +{&thread_176_2}, +{&thread_177_2}, +{&thread_178_2}, +{&thread_179_2}, +{&thread_180_2}, +{&thread_181_2}, +{&thread_182_2}, +{&thread_183_2}, +{&thread_184_2}, +{&thread_185_2}, +{&thread_186_2}, +{&thread_187_2}, +{&thread_188_2}, +{&thread_189_2}, +{&thread_190_2}, +{&thread_191_2}, +{&thread_192_2}, +{&thread_193_2}, +{&thread_194_2}, +{&thread_195_2}, +{&thread_196_2}, +{&thread_197_2}, +{&thread_198_2}, +{&thread_199_2}, +{&thread_200_2}, +{&thread_201_2}, +{&thread_202_2}, +{&thread_203_2}, +{&thread_204_2}, +{&thread_205_2}, +{&thread_206_2}, +{&thread_207_2}, +{&thread_208_2}, +{&thread_209_2}, +{&thread_210_2}, +{&thread_211_2}, +{&thread_212_2}, +{&thread_213_2}, +{&thread_214_2}, +{&thread_215_2}, +{&thread_216_2}, +{&thread_217_2}, +{&thread_218_2}, +{&thread_219_2}, +{&thread_220_2}, +{&thread_221_2}, +{&thread_222_2}, +{&thread_223_2}, +{&thread_224_2}, +{&thread_225_2}, +{&thread_226_2}, +{&thread_227_2}, +{&thread_228_2}, +{&thread_229_2}, +{&thread_230_2}, +{&thread_231_2}, +{&thread_232_2}, +{&thread_233_2}, +{&thread_234_2}, +{&thread_235_2}, +{&thread_236_2}, +{&thread_237_2}, +{&thread_238_2}, +{&thread_239_2}, +{&thread_240_2}, +{&thread_241_2}, +{&thread_242_2}, +{&thread_243_2}, +{&thread_244_2}, +{&thread_245_2}, +{&thread_246_2}, +{&thread_247_2}, +{&thread_248_2}, +{&thread_249_2}, +{&thread_250_2}, +{&thread_251_2}, +{&thread_252_2}, +{&thread_253_2}, +{&thread_254_2}, +{&thread_255_2}, + +{&thread_0_3}, +{&thread_1_3}, +{&thread_2_3}, +{&thread_3_3}, +{&thread_4_3}, +{&thread_5_3}, +{&thread_6_3}, +{&thread_7_3}, +{&thread_8_3}, +{&thread_9_3}, +{&thread_10_3}, +{&thread_11_3}, +{&thread_12_3}, +{&thread_13_3}, +{&thread_14_3}, +{&thread_15_3}, +{&thread_16_3}, +{&thread_17_3}, +{&thread_18_3}, +{&thread_19_3}, +{&thread_20_3}, +{&thread_21_3}, +{&thread_22_3}, +{&thread_23_3}, +{&thread_24_3}, +{&thread_25_3}, +{&thread_26_3}, +{&thread_27_3}, +{&thread_28_3}, +{&thread_29_3}, +{&thread_30_3}, +{&thread_31_3}, +{&thread_32_3}, +{&thread_33_3}, +{&thread_34_3}, +{&thread_35_3}, +{&thread_36_3}, +{&thread_37_3}, +{&thread_38_3}, +{&thread_39_3}, +{&thread_40_3}, +{&thread_41_3}, +{&thread_42_3}, +{&thread_43_3}, +{&thread_44_3}, +{&thread_45_3}, +{&thread_46_3}, +{&thread_47_3}, +{&thread_48_3}, +{&thread_49_3}, +{&thread_50_3}, +{&thread_51_3}, +{&thread_52_3}, +{&thread_53_3}, +{&thread_54_3}, +{&thread_55_3}, +{&thread_56_3}, +{&thread_57_3}, +{&thread_58_3}, +{&thread_59_3}, +{&thread_60_3}, +{&thread_61_3}, +{&thread_62_3}, +{&thread_63_3}, +{&thread_64_3}, +{&thread_65_3}, +{&thread_66_3}, +{&thread_67_3}, +{&thread_68_3}, +{&thread_69_3}, +{&thread_70_3}, +{&thread_71_3}, +{&thread_72_3}, +{&thread_73_3}, +{&thread_74_3}, +{&thread_75_3}, +{&thread_76_3}, +{&thread_77_3}, +{&thread_78_3}, +{&thread_79_3}, +{&thread_80_3}, +{&thread_81_3}, +{&thread_82_3}, +{&thread_83_3}, +{&thread_84_3}, +{&thread_85_3}, +{&thread_86_3}, +{&thread_87_3}, +{&thread_88_3}, +{&thread_89_3}, +{&thread_90_3}, +{&thread_91_3}, +{&thread_92_3}, +{&thread_93_3}, +{&thread_94_3}, +{&thread_95_3}, +{&thread_96_3}, +{&thread_97_3}, +{&thread_98_3}, +{&thread_99_3}, +{&thread_100_3}, +{&thread_101_3}, +{&thread_102_3}, +{&thread_103_3}, +{&thread_104_3}, +{&thread_105_3}, +{&thread_106_3}, +{&thread_107_3}, +{&thread_108_3}, +{&thread_109_3}, +{&thread_110_3}, +{&thread_111_3}, +{&thread_112_3}, +{&thread_113_3}, +{&thread_114_3}, +{&thread_115_3}, +{&thread_116_3}, +{&thread_117_3}, +{&thread_118_3}, +{&thread_119_3}, +{&thread_120_3}, +{&thread_121_3}, +{&thread_122_3}, +{&thread_123_3}, +{&thread_124_3}, +{&thread_125_3}, +{&thread_126_3}, +{&thread_127_3}, +{&thread_128_3}, +{&thread_129_3}, +{&thread_130_3}, +{&thread_131_3}, +{&thread_132_3}, +{&thread_133_3}, +{&thread_134_3}, +{&thread_135_3}, +{&thread_136_3}, +{&thread_137_3}, +{&thread_138_3}, +{&thread_139_3}, +{&thread_140_3}, +{&thread_141_3}, +{&thread_142_3}, +{&thread_143_3}, +{&thread_144_3}, +{&thread_145_3}, +{&thread_146_3}, +{&thread_147_3}, +{&thread_148_3}, +{&thread_149_3}, +{&thread_150_3}, +{&thread_151_3}, +{&thread_152_3}, +{&thread_153_3}, +{&thread_154_3}, +{&thread_155_3}, +{&thread_156_3}, +{&thread_157_3}, +{&thread_158_3}, +{&thread_159_3}, +{&thread_160_3}, +{&thread_161_3}, +{&thread_162_3}, +{&thread_163_3}, +{&thread_164_3}, +{&thread_165_3}, +{&thread_166_3}, +{&thread_167_3}, +{&thread_168_3}, +{&thread_169_3}, +{&thread_170_3}, +{&thread_171_3}, +{&thread_172_3}, +{&thread_173_3}, +{&thread_174_3}, +{&thread_175_3}, +{&thread_176_3}, +{&thread_177_3}, +{&thread_178_3}, +{&thread_179_3}, +{&thread_180_3}, +{&thread_181_3}, +{&thread_182_3}, +{&thread_183_3}, +{&thread_184_3}, +{&thread_185_3}, +{&thread_186_3}, +{&thread_187_3}, +{&thread_188_3}, +{&thread_189_3}, +{&thread_190_3}, +{&thread_191_3}, +{&thread_192_3}, +{&thread_193_3}, +{&thread_194_3}, +{&thread_195_3}, +{&thread_196_3}, +{&thread_197_3}, +{&thread_198_3}, +{&thread_199_3}, +{&thread_200_3}, +{&thread_201_3}, +{&thread_202_3}, +{&thread_203_3}, +{&thread_204_3}, +{&thread_205_3}, +{&thread_206_3}, +{&thread_207_3}, +{&thread_208_3}, +{&thread_209_3}, +{&thread_210_3}, +{&thread_211_3}, +{&thread_212_3}, +{&thread_213_3}, +{&thread_214_3}, +{&thread_215_3}, +{&thread_216_3}, +{&thread_217_3}, +{&thread_218_3}, +{&thread_219_3}, +{&thread_220_3}, +{&thread_221_3}, +{&thread_222_3}, +{&thread_223_3}, +{&thread_224_3}, +{&thread_225_3}, +{&thread_226_3}, +{&thread_227_3}, +{&thread_228_3}, +{&thread_229_3}, +{&thread_230_3}, +{&thread_231_3}, +{&thread_232_3}, +{&thread_233_3}, +{&thread_234_3}, +{&thread_235_3}, +{&thread_236_3}, +{&thread_237_3}, +{&thread_238_3}, +{&thread_239_3}, +{&thread_240_3}, +{&thread_241_3}, +{&thread_242_3}, +{&thread_243_3}, +{&thread_244_3}, +{&thread_245_3}, +{&thread_246_3}, +{&thread_247_3}, +{&thread_248_3}, +{&thread_249_3}, +{&thread_250_3}, +{&thread_251_3}, +{&thread_252_3}, +{&thread_253_3}, +{&thread_254_3}, +{&thread_255_3} +}; + +/* Define the test array. This used to store the randomized test. */ + +static TX_THREAD *_smp_randomized_test_array[TX_THREAD_SMP_MAX_CORES*2]; + + +/* Define thread entry prototype. Since it won't be used it can be the same. */ + +static void control_thread_entry(ULONG thread_input); +static void thread_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + + +static UINT pass; +static UINT start_pass; +static UINT end_pass; + + +/* Create a test control thread. */ + +static TX_THREAD control_thread; + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_smp_random_resume_suspend_test(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a control thread to run the test. */ + status = tx_thread_create(&control_thread, "control thread", control_thread_entry, 0, + pointer, 1024, + 0, 0, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Random Suspensions/Resumptions Test..................... ERROR #1\n"); + test_control_return(1); + } +} + + +static void control_thread_entry(ULONG thread_input) +{ + +UINT i, j; +UINT priority; +UINT source_index; +UINT successful_tests = 0; +UINT test_errors = 0; +TX_THREAD *thread_ptr; +TX_THREAD *current_thread; +UINT original_priority; +UINT status; + + + /* Pickup the current thread pointer. */ + current_thread = tx_thread_identify(); + + /* Loop to create all the threads. */ + i = 0; + priority = 0; + status = TX_SUCCESS; + while (i < 1024) + { + + /* Create each thread. */ + status += tx_thread_create(_smp_randomized_source_array[i], "test thread", thread_entry, i, +// (void *) pointer, 512, + malloc(1024), 1024, + priority, priority, TX_NO_TIME_SLICE, TX_DONT_START); +// pointer = pointer + 512; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Random Suspensions/Resumptions Test..................... ERROR #2\n"); + test_control_return(1); + break; + } + + /* Move to next entry/priority. */ + i++; + priority++; + + /* Should priority be reset? */ + if (priority >= TX_MAX_PRIORITIES) + { + + /* Yes, reset the priority. */ + priority = 0; + } + } + + /* Start random test. */ + printf("Running SMP Random Suspensions/Resumptions Test..................... "); + + /* Clear system counters. */ + pass = 0; + start_pass = 0; + end_pass = start_pass + MAX_PASSES; + do + { + + /* Clear the randomized test array. */ + for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++) + { + _smp_randomized_test_array[i] = TX_NULL; + } + + /* Build the randomized test array. */ + for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++) + { + do + { + source_index = (rand())%1024; + + /* Determine if this index has repeated. */ + thread_ptr = _smp_randomized_source_array[source_index]; + + /* Is this thread already in the test array? */ + j = 0; + while (j < TX_THREAD_SMP_MAX_CORES*2) + { + /* Is the entry NULL? */ + if (_smp_randomized_test_array[j] == TX_NULL) + { + j = (TX_THREAD_SMP_MAX_CORES*2); + } + + /* Determine if we have a duplicate. */ + if (_smp_randomized_test_array[j] == thread_ptr) + thread_ptr = TX_NULL; + + j++; + } + + } while (thread_ptr == TX_NULL); + + /* Clear run counter. */ + thread_ptr -> tx_thread_run_count = 0; + + /* Save the thread pointer. */ + _smp_randomized_test_array[i] = thread_ptr; + } + + /* Now make all the random threads ready. */ + for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++) + { + status = tx_thread_resume(_smp_randomized_test_array[i]); + + /* Check for an error. */ + if (status != TX_SUCCESS) + { + + printf("ERROR #3\n"); + test_control_return(1); + break; + } + } + + /* Check the status. */ + if (status) + break; + + /* Move to the lowest priority. */ + status += tx_thread_priority_change(current_thread, TX_MAX_PRIORITIES-1, &original_priority); + tx_thread_relinquish(); + + /* At this point all the threads have run, or should have. */ + + /* Restore priority. */ + status += tx_thread_priority_change(current_thread, original_priority, &original_priority); + + /* Was there an error? */ + if (status != TX_SUCCESS) + { + + printf("ERROR #4\n"); + test_control_return(1); + break; + } + + /* Determine if all the threads in the the random sample ran. */ + for (i = 0; i < (TX_THREAD_SMP_MAX_CORES*2); i++) + { + + /* Pickup the thread pointer. */ + thread_ptr = _smp_randomized_test_array[i]; + + /* Check to see if each thread has run. */ + if (thread_ptr -> tx_thread_run_count == 0) + { + + /* First, try to sleep to see if this helps! */ + tx_thread_sleep(1); + } + + /* Has the run count incremented? */ + if (thread_ptr -> tx_thread_run_count == 0) + { + + /* No, this thread didn't really run! */ + printf("ERROR #5\n"); + test_control_return(1); + break; + } + + /* Make sure this thread suspended. */ + while (thread_ptr -> tx_thread_state != TX_SUSPENDED) + { + /* Wait for the thread to complete! */ + tx_thread_relinquish(); + } + } + + /* Increment the pass counter. */ + pass++; + + } while (pass < end_pass); + + /* Test is successful! */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_entry(ULONG id) +{ + + /* While forever loop! */ + while(1) + { + + /* Suspend thread! */ + tx_thread_suspend(_smp_randomized_source_array[id]); + } +} + + diff --git a/test/smp/regression/threadx_smp_rebalance_exclusion_test.c b/test/smp/regression/threadx_smp_rebalance_exclusion_test.c new file mode 100644 index 00000000..9c03c8bd --- /dev/null +++ b/test/smp/regression/threadx_smp_rebalance_exclusion_test.c @@ -0,0 +1,204 @@ +/* Define the ThreadX SMP rebalance exclusion test. */ + +#include +#include "tx_api.h" + + + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_31k; + + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG thread_2_counter; +static ULONG thread_31k_counter; + + +static unsigned long error = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_31k_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_smp_rebalance_exclustion_test(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 0, 0, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_0, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Rebalance Exclusion Test................................ ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 1, 1, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_1, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Rebalance Exclusion Test................................ ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 2, 2, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_2, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Rebalance Exclusion Test................................ ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_31k, "thread 31k", thread_31k_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 15, 16, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31k, 0xE); /* Core 0 only! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Rebalance Exclusion Test................................ ERROR #4\n"); + test_control_return(1); + } + + /* Resume thread 0. */ + status = tx_thread_resume(&thread_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Rebalance Exclusion Test................................ ERROR #5\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + + /* Inform user. */ + printf("Running SMP Rebalance Exclusion Test................................ "); + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_1); + status += tx_thread_resume(&thread_2); + status += tx_thread_resume(&thread_31k); + + /* Suspend this thread to let the others run. */ + tx_thread_sleep(5); + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (error) || (thread_1_counter != 1) || + (thread_2_counter != 1) || (thread_31k_counter != 1)) + { + + /* Execution error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + while(1) + { + + thread_1_counter++; + tx_thread_suspend(&thread_1); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + + while(1) + { + + thread_2_counter++; + tx_thread_suspend(&thread_2); + } +} + + +static void thread_31k_entry(ULONG thread_input) +{ + + while(1) + { + + /* Ensure this thread is on the correct core. */ + if (tx_thread_smp_core_get() != 0) + error++; + + thread_31k_counter++; + tx_thread_suspend(&thread_31k); + } +} diff --git a/test/smp/regression/threadx_smp_relinquish_test.c b/test/smp/regression/threadx_smp_relinquish_test.c new file mode 100644 index 00000000..d7aac1ca --- /dev/null +++ b/test/smp/regression/threadx_smp_relinquish_test.c @@ -0,0 +1,365 @@ +/* Define the ThreadX SMP relinquish test. */ + +#include +#include "tx_api.h" + +static TX_THREAD thread_0; +static TX_THREAD thread_31a; +static TX_THREAD thread_31b; +static TX_THREAD thread_31c; +static TX_THREAD thread_31d; +static TX_THREAD thread_31e; +static TX_THREAD thread_31f; +static TX_THREAD thread_31g; +static TX_THREAD thread_31h; + + +static ULONG thread_31a_counter; +static ULONG thread_31b_counter; +static ULONG thread_31c_counter; +static ULONG thread_31d_counter; +static ULONG thread_31e_counter; +static ULONG thread_31f_counter; +static ULONG thread_31g_counter; +static ULONG thread_31h_counter; + + +static unsigned long error = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_31a_entry(ULONG thread_input); +static void thread_31b_entry(ULONG thread_input); +static void thread_31c_entry(ULONG thread_input); +static void thread_31d_entry(ULONG thread_input); +static void thread_31e_entry(ULONG thread_input); +static void thread_31f_entry(ULONG thread_input); +static void thread_31g_entry(ULONG thread_input); +static void thread_31h_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_smp_relinquish_test(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; +UINT i; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 0, 0, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Relinquish Test......................................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_31a, "thread 31a", thread_31a_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31a, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Relinquish Test......................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_31b, "thread 31b", thread_31b_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31b, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Relinquish Test......................................... ERROR #3\n"); + test_control_return(1); + } + + + status = tx_thread_create(&thread_31c, "thread 31c", thread_31c_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31c, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Relinquish Test......................................... ERROR #4\n"); + test_control_return(1); + } + + + status = tx_thread_create(&thread_31d, "thread 31d", thread_31d_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31d, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Relinquish Test......................................... ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_31e, "thread 31e", thread_31e_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31e, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Relinquish Test......................................... ERROR #6\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_31f, "thread 31f", thread_31f_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31f, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Relinquish Test......................................... ERROR #7\n"); + test_control_return(1); + } + + + status = tx_thread_create(&thread_31g, "thread 31g", thread_31g_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31g, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Relinquish Test......................................... ERROR #8\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_31h, "thread 31h", thread_31h_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31h, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Relinquish Test......................................... ERROR #9\n"); + test_control_return(1); + } + + /* Clear all the counters. */ + thread_31a_counter = 0; + thread_31b_counter = 0; + thread_31c_counter = 0; + thread_31d_counter = 0; + thread_31e_counter = 0; + thread_31f_counter = 0; + thread_31g_counter = 0; + thread_31h_counter = 0; + + /* Resume thread 0. */ + status = tx_thread_resume(&thread_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Relinquish Test......................................... ERROR #10\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + + /* Inform user. */ + printf("Running SMP Relinquish Test......................................... "); + + /* Resume all the same priority threads. */ + status = tx_thread_resume(&thread_31a); + status += tx_thread_resume(&thread_31b); + status += tx_thread_resume(&thread_31c); + status += tx_thread_resume(&thread_31d); + status += tx_thread_resume(&thread_31e); + status += tx_thread_resume(&thread_31f); + status += tx_thread_resume(&thread_31g); + status += tx_thread_resume(&thread_31h); + + /* Now sleep for 10 ticks to let see if all the threads execute. */ + tx_thread_sleep(10); + + /* Now check and make sure all the threads ran. */ + if ((status != TX_SUCCESS) || (thread_31a_counter == 0) || (thread_31b_counter == 0) || (thread_31c_counter == 0) || (thread_31d_counter == 0) || + (thread_31e_counter == 0) || (thread_31f_counter == 0) || (thread_31g_counter == 0) || (thread_31h_counter == 0)) + { + + /* Execution error. */ + printf("ERROR #31\n"); + test_control_return(1); + } + + /* Successful test. */ + printf("SUCCESS!\n"); + + test_control_return(0); +} + + +static void thread_31a_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + + thread_31a_counter++; + } +} + + +static void thread_31b_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + + thread_31b_counter++; + } +} + + +static void thread_31c_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + + thread_31c_counter++; + } +} + + +static void thread_31d_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + + thread_31d_counter++; + } +} + + +static void thread_31e_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + + thread_31e_counter++; + } +} + + +static void thread_31f_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + + thread_31f_counter++; + } +} + + +static void thread_31g_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + + thread_31g_counter++; + } +} + + +static void thread_31h_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + + thread_31h_counter++; + } +} + diff --git a/test/smp/regression/threadx_smp_resume_suspend_accending_order_test.c b/test/smp/regression/threadx_smp_resume_suspend_accending_order_test.c new file mode 100644 index 00000000..3a845878 --- /dev/null +++ b/test/smp/regression/threadx_smp_resume_suspend_accending_order_test.c @@ -0,0 +1,1428 @@ +/* Define the ThreadX SMP resume and suspend threads in accending order test. */ + +#include +#include "tx_api.h" + +extern TX_THREAD *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES]; + + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; +static TX_THREAD thread_4; +static TX_THREAD thread_5; +static TX_THREAD thread_6; +static TX_THREAD thread_7; +static TX_THREAD thread_8; +static TX_THREAD thread_9; +static TX_THREAD thread_10; +static TX_THREAD thread_11; +static TX_THREAD thread_12; +static TX_THREAD thread_13; +static TX_THREAD thread_14; +static TX_THREAD thread_15; +static TX_THREAD thread_16; +static TX_THREAD thread_17; +static TX_THREAD thread_18; +static TX_THREAD thread_19; +static TX_THREAD thread_20; +static TX_THREAD thread_21; +static TX_THREAD thread_22; +static TX_THREAD thread_23; +static TX_THREAD thread_24; +static TX_THREAD thread_25; +static TX_THREAD thread_26; +static TX_THREAD thread_27; +static TX_THREAD thread_28; +static TX_THREAD thread_29; +static TX_THREAD thread_30; +static TX_THREAD thread_31; + +static ULONG thread_run_counter[32]; + + +static unsigned long error = 0; + + +/* Define thread prototypes. */ + +static void thread_entry(ULONG thread_input); +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void delay(UINT i) +{ + + /* Wait until the thread runs! */ + while (thread_run_counter[i] == 0) + { + } +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_smp_resume_suspend_accending_order_test(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; +UINT i; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 0, 0, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 1, 1, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_1, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 2, 2, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_2, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 3, 3, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_3, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_4, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_5, "thread 5", thread_entry, 5, + pointer, TEST_STACK_SIZE_PRINTF, + 5, 5, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_5, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #6\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_6, "thread 6", thread_entry, 6, + pointer, TEST_STACK_SIZE_PRINTF, + 6, 6, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_6, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #7\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_7, "thread 7", thread_entry, 7, + pointer, TEST_STACK_SIZE_PRINTF, + 7, 7, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_7, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #8\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_8, "thread 8", thread_entry, 8, + pointer, TEST_STACK_SIZE_PRINTF, + 8, 8, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_8, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #9\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_9, "thread 9", thread_entry, 9, + pointer, TEST_STACK_SIZE_PRINTF, + 9, 9, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_9, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #9\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_10, "thread 10", thread_entry, 10, + pointer, TEST_STACK_SIZE_PRINTF, + 10, 10, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_10, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #11\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_11, "thread 11", thread_entry, 11, + pointer, TEST_STACK_SIZE_PRINTF, + 11, 11, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_11, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #12\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_12, "thread 12", thread_entry, 12, + pointer, TEST_STACK_SIZE_PRINTF, + 12, 12, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_12, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #13\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_13, "thread 13", thread_entry, 13, + pointer, TEST_STACK_SIZE_PRINTF, + 13, 13, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_13, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #14\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_14, "thread 14", thread_entry, 14, + pointer, TEST_STACK_SIZE_PRINTF, + 14, 14, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_14, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #15\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_15, "thread 15", thread_entry, 15, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_15, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #16\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_16, "thread 16", thread_entry, 16, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_16, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #17\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_17, "thread 17", thread_entry, 17, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_17, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #18\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_18, "thread 18", thread_entry, 18, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_18, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #19\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_19, "thread 19", thread_entry, 19, + pointer, TEST_STACK_SIZE_PRINTF, + 19, 19, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_19, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #20\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_20, "thread 20", thread_entry, 20, + pointer, TEST_STACK_SIZE_PRINTF, + 20, 20, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_20, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #21\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_21, "thread 21", thread_entry, 21, + pointer, TEST_STACK_SIZE_PRINTF, + 21, 21, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_21, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #22\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_22, "thread 22", thread_entry, 22, + pointer, TEST_STACK_SIZE_PRINTF, + 22, 22, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_22, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #23\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_23, "thread 23", thread_entry, 23, + pointer, TEST_STACK_SIZE_PRINTF, + 23, 23, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_23, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #24\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_24, "thread 24", thread_entry, 24, + pointer, TEST_STACK_SIZE_PRINTF, + 24, 24, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_24, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #25\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_25, "thread 25", thread_entry, 25, + pointer, TEST_STACK_SIZE_PRINTF, + 25, 25, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_25, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #26\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_26, "thread 26", thread_entry, 26, + pointer, TEST_STACK_SIZE_PRINTF, + 26, 26, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_26, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #27\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_27, "thread 27", thread_entry, 27, + pointer, TEST_STACK_SIZE_PRINTF, + 27, 27, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_27, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #28\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_28, "thread 28", thread_entry, 28, + pointer, TEST_STACK_SIZE_PRINTF, + 28, 28, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_28, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #29\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_29, "thread 29", thread_entry, 29, + pointer, TEST_STACK_SIZE_PRINTF, + 29, 29, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_29, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #30\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_30, "thread 30", thread_entry, 30, + pointer, TEST_STACK_SIZE_PRINTF, + 30, 30, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_30, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #31\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_31, "thread 31", thread_entry, 31, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #32\n"); + test_control_return(1); + } + + /* Clear the thread run count array. */ + for (i = 0; i < 32; i++) + { + thread_run_counter[i] = 0; + } + + /* Resume thread 0. */ + status = tx_thread_resume(&thread_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Accending Priority Order Test............ ERROR #33\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + + /* Inform user. */ + printf("Running SMP Resume-Suspend Accending Priority Order Test............ "); + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_1); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #34\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_2); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #35\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_3); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #36\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_4); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #37\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_5); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #38\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_6); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #39\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_7); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #40\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_8); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #41\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_9); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #42\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_10); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #43\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_11); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #44\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_12); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #45\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_13); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #46\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_14); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #47\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_15); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #48\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_16); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #49\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_17); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #50\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_18); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #51\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_19); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #52\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_20); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #53\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_21); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #54\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_22); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #55\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_23); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #56\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_24); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #57\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_25); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #58\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_26); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #59\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_27); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #60\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_28); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #61\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_29); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #62\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_30); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #63\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_31); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #64\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(1); + status = tx_thread_suspend(&thread_1); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_4) + || (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #65\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(2); + status = tx_thread_suspend(&thread_2); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_4) + || (_tx_thread_execute_ptr[2] != &thread_5) || (_tx_thread_execute_ptr[3] != &thread_3)) + { + + /* Execution error. */ + printf("ERROR #66\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(3); + status = tx_thread_suspend(&thread_3); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_4) + || (_tx_thread_execute_ptr[2] != &thread_5) || (_tx_thread_execute_ptr[3] != &thread_6)) + { + + /* Execution error. */ + printf("ERROR #67\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(4); + status = tx_thread_suspend(&thread_4); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_7) + || (_tx_thread_execute_ptr[2] != &thread_5) || (_tx_thread_execute_ptr[3] != &thread_6)) + { + + /* Execution error. */ + printf("ERROR #68\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(5); + status = tx_thread_suspend(&thread_5); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_7) + || (_tx_thread_execute_ptr[2] != &thread_8) || (_tx_thread_execute_ptr[3] != &thread_6)) + { + + /* Execution error. */ + printf("ERROR #69\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(6); + status = tx_thread_suspend(&thread_6); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_7) + || (_tx_thread_execute_ptr[2] != &thread_8) || (_tx_thread_execute_ptr[3] != &thread_9)) + { + + /* Execution error. */ + printf("ERROR #70\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(7); + status = tx_thread_suspend(&thread_7); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_10) + || (_tx_thread_execute_ptr[2] != &thread_8) || (_tx_thread_execute_ptr[3] != &thread_9)) + { + + /* Execution error. */ + printf("ERROR #71\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(8); + status = tx_thread_suspend(&thread_8); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_10) + || (_tx_thread_execute_ptr[2] != &thread_11) || (_tx_thread_execute_ptr[3] != &thread_9)) + { + + /* Execution error. */ + printf("ERROR #72\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(9); + status = tx_thread_suspend(&thread_9); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_10) + || (_tx_thread_execute_ptr[2] != &thread_11) || (_tx_thread_execute_ptr[3] != &thread_12)) + { + + /* Execution error. */ + printf("ERROR #73\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(10); + status = tx_thread_suspend(&thread_10); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_13) + || (_tx_thread_execute_ptr[2] != &thread_11) || (_tx_thread_execute_ptr[3] != &thread_12)) + { + + /* Execution error. */ + printf("ERROR #74\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(11); + status = tx_thread_suspend(&thread_11); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_13) + || (_tx_thread_execute_ptr[2] != &thread_14) || (_tx_thread_execute_ptr[3] != &thread_12)) + { + + /* Execution error. */ + printf("ERROR #75\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(12); + status = tx_thread_suspend(&thread_12); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_13) + || (_tx_thread_execute_ptr[2] != &thread_14) || (_tx_thread_execute_ptr[3] != &thread_15)) + { + + /* Execution error. */ + printf("ERROR #76\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(13); + status = tx_thread_suspend(&thread_13); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16) + || (_tx_thread_execute_ptr[2] != &thread_14) || (_tx_thread_execute_ptr[3] != &thread_15)) + { + + /* Execution error. */ + printf("ERROR #77\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(14); + status = tx_thread_suspend(&thread_14); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16) + || (_tx_thread_execute_ptr[2] != &thread_17) || (_tx_thread_execute_ptr[3] != &thread_15)) + { + + /* Execution error. */ + printf("ERROR #78\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(15); + status = tx_thread_suspend(&thread_15); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16) + || (_tx_thread_execute_ptr[2] != &thread_17) || (_tx_thread_execute_ptr[3] != &thread_18)) + { + + /* Execution error. */ + printf("ERROR #79\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(16); + status = tx_thread_suspend(&thread_16); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_19) + || (_tx_thread_execute_ptr[2] != &thread_17) || (_tx_thread_execute_ptr[3] != &thread_18)) + { + + /* Execution error. */ + printf("ERROR #80\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(17); + status = tx_thread_suspend(&thread_17); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_19) + || (_tx_thread_execute_ptr[2] != &thread_20) || (_tx_thread_execute_ptr[3] != &thread_18)) + { + + /* Execution error. */ + printf("ERROR #81\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(18); + status = tx_thread_suspend(&thread_18); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_19) + || (_tx_thread_execute_ptr[2] != &thread_20) || (_tx_thread_execute_ptr[3] != &thread_21)) + { + + /* Execution error. */ + printf("ERROR #82\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(19); + status = tx_thread_suspend(&thread_19); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_22) + || (_tx_thread_execute_ptr[2] != &thread_20) || (_tx_thread_execute_ptr[3] != &thread_21)) + { + + /* Execution error. */ + printf("ERROR #83\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(20); + status = tx_thread_suspend(&thread_20); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_22) + || (_tx_thread_execute_ptr[2] != &thread_23) || (_tx_thread_execute_ptr[3] != &thread_21)) + { + + /* Execution error. */ + printf("ERROR #84\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(21); + status = tx_thread_suspend(&thread_21); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_22) + || (_tx_thread_execute_ptr[2] != &thread_23) || (_tx_thread_execute_ptr[3] != &thread_24)) + { + + /* Execution error. */ + printf("ERROR #85\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(22); + status = tx_thread_suspend(&thread_22); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_25) + || (_tx_thread_execute_ptr[2] != &thread_23) || (_tx_thread_execute_ptr[3] != &thread_24)) + { + + /* Execution error. */ + printf("ERROR #86\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(23); + status = tx_thread_suspend(&thread_23); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_25) + || (_tx_thread_execute_ptr[2] != &thread_26) || (_tx_thread_execute_ptr[3] != &thread_24)) + { + + /* Execution error. */ + printf("ERROR #87\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(24); + status = tx_thread_suspend(&thread_24); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_25) + || (_tx_thread_execute_ptr[2] != &thread_26) || (_tx_thread_execute_ptr[3] != &thread_27)) + { + + /* Execution error. */ + printf("ERROR #88\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(25); + status = tx_thread_suspend(&thread_25); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_28) + || (_tx_thread_execute_ptr[2] != &thread_26) || (_tx_thread_execute_ptr[3] != &thread_27)) + { + + /* Execution error. */ + printf("ERROR #89\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(26); + status = tx_thread_suspend(&thread_26); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_28) + || (_tx_thread_execute_ptr[2] != &thread_29) || (_tx_thread_execute_ptr[3] != &thread_27)) + { + + /* Execution error. */ + printf("ERROR #90\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(27); + status = tx_thread_suspend(&thread_27); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_28) + || (_tx_thread_execute_ptr[2] != &thread_29) || (_tx_thread_execute_ptr[3] != &thread_30)) + { + + /* Execution error. */ + printf("ERROR #91\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(28); + status = tx_thread_suspend(&thread_28); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31) + || (_tx_thread_execute_ptr[2] != &thread_29) || (_tx_thread_execute_ptr[3] != &thread_30)) + { + + /* Execution error. */ + printf("ERROR #92\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(29); + status = tx_thread_suspend(&thread_29); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != &thread_30)) + { + + /* Execution error. */ + printf("ERROR #93\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(30); + status = tx_thread_suspend(&thread_30); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #94\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + delay(31); + status = tx_thread_suspend(&thread_31); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #95\n"); + test_control_return(1); + } + + + /* Successful test. */ + printf("SUCCESS!\n"); + + test_control_return(0); +} + + +static void thread_entry(ULONG thread_input) +{ + + /* Increment the run counter. */ + thread_run_counter[thread_input]++; + + while(1) + { + + tx_thread_identify(); + + /* Indicate the thread is running... */ + thread_run_counter[thread_input]++; + } +} diff --git a/test/smp/regression/threadx_smp_resume_suspend_decending_order_test.c b/test/smp/regression/threadx_smp_resume_suspend_decending_order_test.c new file mode 100644 index 00000000..6eae504e --- /dev/null +++ b/test/smp/regression/threadx_smp_resume_suspend_decending_order_test.c @@ -0,0 +1,1427 @@ +/* Define the ThreadX SMP resume and suspend threads in accending order test. */ + +#include +#include "tx_api.h" + +extern TX_THREAD *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES]; + + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; +static TX_THREAD thread_4; +static TX_THREAD thread_5; +static TX_THREAD thread_6; +static TX_THREAD thread_7; +static TX_THREAD thread_8; +static TX_THREAD thread_9; +static TX_THREAD thread_10; +static TX_THREAD thread_11; +static TX_THREAD thread_12; +static TX_THREAD thread_13; +static TX_THREAD thread_14; +static TX_THREAD thread_15; +static TX_THREAD thread_16; +static TX_THREAD thread_17; +static TX_THREAD thread_18; +static TX_THREAD thread_19; +static TX_THREAD thread_20; +static TX_THREAD thread_21; +static TX_THREAD thread_22; +static TX_THREAD thread_23; +static TX_THREAD thread_24; +static TX_THREAD thread_25; +static TX_THREAD thread_26; +static TX_THREAD thread_27; +static TX_THREAD thread_28; +static TX_THREAD thread_29; +static TX_THREAD thread_30; +static TX_THREAD thread_31; + +static ULONG thread_run_counter[32]; + + +static unsigned long error = 0; + + +/* Define thread prototypes. */ + +static void thread_entry(ULONG thread_input); +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void delay(UINT i) +{ + + /* Wait until the thread runs! */ + while (thread_run_counter[i] == 0) + { + } +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_smp_resume_suspend_decending_order_test(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; +UINT i; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 0, 0, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 1, 1, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_1, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 2, 2, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_2, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 3, 3, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_3, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_4, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_5, "thread 5", thread_entry, 5, + pointer, TEST_STACK_SIZE_PRINTF, + 5, 5, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_5, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #6\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_6, "thread 6", thread_entry, 6, + pointer, TEST_STACK_SIZE_PRINTF, + 6, 6, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_6, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #7\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_7, "thread 7", thread_entry, 7, + pointer, TEST_STACK_SIZE_PRINTF, + 7, 7, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_7, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #8\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_8, "thread 8", thread_entry, 8, + pointer, TEST_STACK_SIZE_PRINTF, + 8, 8, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_8, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #9\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_9, "thread 9", thread_entry, 9, + pointer, TEST_STACK_SIZE_PRINTF, + 9, 9, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_9, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #9\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_10, "thread 10", thread_entry, 10, + pointer, TEST_STACK_SIZE_PRINTF, + 10, 10, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_10, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #11\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_11, "thread 11", thread_entry, 11, + pointer, TEST_STACK_SIZE_PRINTF, + 11, 11, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_11, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #12\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_12, "thread 12", thread_entry, 12, + pointer, TEST_STACK_SIZE_PRINTF, + 12, 12, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_12, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #13\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_13, "thread 13", thread_entry, 13, + pointer, TEST_STACK_SIZE_PRINTF, + 13, 13, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_13, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #14\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_14, "thread 14", thread_entry, 14, + pointer, TEST_STACK_SIZE_PRINTF, + 14, 14, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_14, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #15\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_15, "thread 15", thread_entry, 15, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_15, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #16\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_16, "thread 16", thread_entry, 16, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_16, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #17\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_17, "thread 17", thread_entry, 17, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_17, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #18\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_18, "thread 18", thread_entry, 18, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_18, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #19\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_19, "thread 19", thread_entry, 19, + pointer, TEST_STACK_SIZE_PRINTF, + 19, 19, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_19, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #20\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_20, "thread 20", thread_entry, 20, + pointer, TEST_STACK_SIZE_PRINTF, + 20, 20, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_20, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #21\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_21, "thread 21", thread_entry, 21, + pointer, TEST_STACK_SIZE_PRINTF, + 21, 21, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_21, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #22\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_22, "thread 22", thread_entry, 22, + pointer, TEST_STACK_SIZE_PRINTF, + 22, 22, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_22, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #23\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_23, "thread 23", thread_entry, 23, + pointer, TEST_STACK_SIZE_PRINTF, + 23, 23, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_23, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #24\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_24, "thread 24", thread_entry, 24, + pointer, TEST_STACK_SIZE_PRINTF, + 24, 24, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_24, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #25\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_25, "thread 25", thread_entry, 25, + pointer, TEST_STACK_SIZE_PRINTF, + 25, 25, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_25, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #26\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_26, "thread 26", thread_entry, 26, + pointer, TEST_STACK_SIZE_PRINTF, + 26, 26, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_26, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #27\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_27, "thread 27", thread_entry, 27, + pointer, TEST_STACK_SIZE_PRINTF, + 27, 27, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_27, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #28\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_28, "thread 28", thread_entry, 28, + pointer, TEST_STACK_SIZE_PRINTF, + 28, 28, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_28, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #29\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_29, "thread 29", thread_entry, 29, + pointer, TEST_STACK_SIZE_PRINTF, + 29, 29, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_29, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #30\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_30, "thread 30", thread_entry, 30, + pointer, TEST_STACK_SIZE_PRINTF, + 30, 30, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_30, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #31\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_31, "thread 31", thread_entry, 31, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #32\n"); + test_control_return(1); + } + + /* Clear the thread run count array. */ + for (i = 0; i < 32; i++) + { + thread_run_counter[i] = 0; + } + + /* Resume thread 0. */ + status = tx_thread_resume(&thread_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Resume-Suspend Decending Priority Order Test............ ERROR #33\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + + /* Inform user. */ + printf("Running SMP Resume-Suspend Decending Priority Order Test............ "); + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_31); + delay(31); + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #34\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_30); + delay(30); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31) + || (_tx_thread_execute_ptr[2] != &thread_30) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #35\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_29); + delay(29); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31) + || (_tx_thread_execute_ptr[2] != &thread_30) || (_tx_thread_execute_ptr[3] != &thread_29)) + { + + /* Execution error. */ + printf("ERROR #36\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_28); + delay(28); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_28) + || (_tx_thread_execute_ptr[2] != &thread_30) || (_tx_thread_execute_ptr[3] != &thread_29)) + { + + /* Execution error. */ + printf("ERROR #37\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_27); + delay(27); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_28) + || (_tx_thread_execute_ptr[2] != &thread_27) || (_tx_thread_execute_ptr[3] != &thread_29)) + { + + /* Execution error. */ + printf("ERROR #38\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_26); + delay(26); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_28) + || (_tx_thread_execute_ptr[2] != &thread_27) || (_tx_thread_execute_ptr[3] != &thread_26)) + { + + /* Execution error. */ + printf("ERROR #39\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_25); + delay(25); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_25) + || (_tx_thread_execute_ptr[2] != &thread_27) || (_tx_thread_execute_ptr[3] != &thread_26)) + { + + /* Execution error. */ + printf("ERROR #40\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_24); + delay(24); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_25) + || (_tx_thread_execute_ptr[2] != &thread_24) || (_tx_thread_execute_ptr[3] != &thread_26)) + { + + /* Execution error. */ + printf("ERROR #41\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_23); + delay(23); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_25) + || (_tx_thread_execute_ptr[2] != &thread_24) || (_tx_thread_execute_ptr[3] != &thread_23)) + { + + /* Execution error. */ + printf("ERROR #42\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_22); + delay(22); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_22) + || (_tx_thread_execute_ptr[2] != &thread_24) || (_tx_thread_execute_ptr[3] != &thread_23)) + { + + /* Execution error. */ + printf("ERROR #43\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_21); + delay(21); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_22) + || (_tx_thread_execute_ptr[2] != &thread_21) || (_tx_thread_execute_ptr[3] != &thread_23)) + { + + /* Execution error. */ + printf("ERROR #44\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_20); + delay(20); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_22) + || (_tx_thread_execute_ptr[2] != &thread_21) || (_tx_thread_execute_ptr[3] != &thread_20)) + { + + /* Execution error. */ + printf("ERROR #45\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_19); + delay(19); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_19) + || (_tx_thread_execute_ptr[2] != &thread_21) || (_tx_thread_execute_ptr[3] != &thread_20)) + { + + /* Execution error. */ + printf("ERROR #46\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_18); + delay(18); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_19) + || (_tx_thread_execute_ptr[2] != &thread_18) || (_tx_thread_execute_ptr[3] != &thread_20)) + { + + /* Execution error. */ + printf("ERROR #47\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_17); + delay(17); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_19) + || (_tx_thread_execute_ptr[2] != &thread_18) || (_tx_thread_execute_ptr[3] != &thread_17)) + { + + /* Execution error. */ + printf("ERROR #48\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_16); + delay(16); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16) + || (_tx_thread_execute_ptr[2] != &thread_18) || (_tx_thread_execute_ptr[3] != &thread_17)) + { + + /* Execution error. */ + printf("ERROR #49\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_15); + delay(15); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16) + || (_tx_thread_execute_ptr[2] != &thread_15) || (_tx_thread_execute_ptr[3] != &thread_17)) + { + + /* Execution error. */ + printf("ERROR #50\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_14); + delay(14); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16) + || (_tx_thread_execute_ptr[2] != &thread_15) || (_tx_thread_execute_ptr[3] != &thread_14)) + { + + /* Execution error. */ + printf("ERROR #51\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_13); + delay(13); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_13) + || (_tx_thread_execute_ptr[2] != &thread_15) || (_tx_thread_execute_ptr[3] != &thread_14)) + { + + /* Execution error. */ + printf("ERROR #52\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_12); + delay(12); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_13) + || (_tx_thread_execute_ptr[2] != &thread_12) || (_tx_thread_execute_ptr[3] != &thread_14)) + { + + /* Execution error. */ + printf("ERROR #53\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_11); + delay(11); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_13) + || (_tx_thread_execute_ptr[2] != &thread_12) || (_tx_thread_execute_ptr[3] != &thread_11)) + { + + /* Execution error. */ + printf("ERROR #54\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_10); + delay(10); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_10) + || (_tx_thread_execute_ptr[2] != &thread_12) || (_tx_thread_execute_ptr[3] != &thread_11)) + { + + /* Execution error. */ + printf("ERROR #55\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_9); + delay(9); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_10) + || (_tx_thread_execute_ptr[2] != &thread_9) || (_tx_thread_execute_ptr[3] != &thread_11)) + { + + /* Execution error. */ + printf("ERROR #56\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_8); + delay(8); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_10) + || (_tx_thread_execute_ptr[2] != &thread_9) || (_tx_thread_execute_ptr[3] != &thread_8)) + { + + /* Execution error. */ + printf("ERROR #57\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_7); + delay(7); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_7) + || (_tx_thread_execute_ptr[2] != &thread_9) || (_tx_thread_execute_ptr[3] != &thread_8)) + { + + /* Execution error. */ + printf("ERROR #58\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_6); + delay(6); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_7) + || (_tx_thread_execute_ptr[2] != &thread_6) || (_tx_thread_execute_ptr[3] != &thread_8)) + { + + /* Execution error. */ + printf("ERROR #59\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_5); + delay(5); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_7) + || (_tx_thread_execute_ptr[2] != &thread_6) || (_tx_thread_execute_ptr[3] != &thread_5)) + { + + /* Execution error. */ + printf("ERROR #60\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_4); + delay(4); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_4) + || (_tx_thread_execute_ptr[2] != &thread_6) || (_tx_thread_execute_ptr[3] != &thread_5)) + { + + /* Execution error. */ + printf("ERROR #61\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_3); + delay(3); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_4) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_5)) + { + + /* Execution error. */ + printf("ERROR #62\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_2); + delay(2); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_4) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #63\n"); + test_control_return(1); + } + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_1); + delay(1); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #64\n"); + test_control_return(1); + } + + /* Suspend thread in decending priority. */ + status = tx_thread_suspend(&thread_31); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #65\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_30); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #66\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_29); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #67\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_28); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #68\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_27); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #69\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_26); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #70\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_25); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #71\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_24); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #72\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_23); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #73\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_22); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #74\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_21); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #75\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_20); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #76\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_19); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #77\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_18); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #78\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_17); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #79\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_16); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #80\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_15); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #81\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_14); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #82\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_13); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #83\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_12); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #84\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_11); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #85\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_10); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #86\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_9); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #87\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_8); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #88\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_7); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #89\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_6); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #90\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_5); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #91\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_4); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != &thread_3) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #92\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_3); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != &thread_2)) + { + + /* Execution error. */ + printf("ERROR #93\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_2); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #94\n"); + test_control_return(1); + } + + /* Suspend thread in accending priority. */ + status = tx_thread_suspend(&thread_1); + + /* Check for the correct results. */ + if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL) + || (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL)) + { + + /* Execution error. */ + printf("ERROR #95\n"); + test_control_return(1); + } + + + /* Successful test. */ + printf("SUCCESS!\n"); + + test_control_return(0); +} + + +static void thread_entry(ULONG thread_input) +{ + + /* Increment the run counter. */ + thread_run_counter[thread_input]++; + + while(1) + { + + tx_thread_identify(); + + /* Indicate the thread is running... */ + thread_run_counter[thread_input]++; + } +} diff --git a/test/smp/regression/threadx_smp_time_slice_test.c b/test/smp/regression/threadx_smp_time_slice_test.c new file mode 100644 index 00000000..b58f789f --- /dev/null +++ b/test/smp/regression/threadx_smp_time_slice_test.c @@ -0,0 +1,361 @@ +/* Define the ThreadX SMP time-slice test. */ + +#include +#include "tx_api.h" + +static TX_THREAD thread_0; +static TX_THREAD thread_31a; +static TX_THREAD thread_31b; +static TX_THREAD thread_31c; +static TX_THREAD thread_31d; +static TX_THREAD thread_31e; +static TX_THREAD thread_31f; +static TX_THREAD thread_31g; +static TX_THREAD thread_31h; + + +static ULONG thread_31a_counter; +static ULONG thread_31b_counter; +static ULONG thread_31c_counter; +static ULONG thread_31d_counter; +static ULONG thread_31e_counter; +static ULONG thread_31f_counter; +static ULONG thread_31g_counter; +static ULONG thread_31h_counter; + + +static unsigned long error = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_31a_entry(ULONG thread_input); +static void thread_31b_entry(ULONG thread_input); +static void thread_31c_entry(ULONG thread_input); +static void thread_31d_entry(ULONG thread_input); +static void thread_31e_entry(ULONG thread_input); +static void thread_31f_entry(ULONG thread_input); +static void thread_31g_entry(ULONG thread_input); +static void thread_31h_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_smp_time_slice_test(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; +UINT i; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 0, 0, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Time-Slice Test......................................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_31a, "thread 31a", thread_31a_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31a, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Time-Slice Test......................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_31b, "thread 31b", thread_31b_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31b, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Time-Slice Test......................................... ERROR #3\n"); + test_control_return(1); + } + + + status = tx_thread_create(&thread_31c, "thread 31c", thread_31c_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31c, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Time-Slice Test......................................... ERROR #4\n"); + test_control_return(1); + } + + + status = tx_thread_create(&thread_31d, "thread 31d", thread_31d_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31d, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Time-Slice Test......................................... ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_31e, "thread 31e", thread_31e_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31e, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Time-Slice Test......................................... ERROR #6\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_31f, "thread 31f", thread_31f_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31f, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Time-Slice Test......................................... ERROR #7\n"); + test_control_return(1); + } + + + status = tx_thread_create(&thread_31g, "thread 31g", thread_31g_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31g, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Time-Slice Test......................................... ERROR #8\n"); + test_control_return(1); + } + + /* Enable preemption-threshold for this thread to hit branch in tx_thread_time_slice + where the expired time-slice thread is replaced by a thread with preemption-threshold + enabled. */ + status = tx_thread_create(&thread_31h, "thread 31h", thread_31h_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 30, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_31h, 0); /* Any core. */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Time-Slice Test......................................... ERROR #9\n"); + test_control_return(1); + } + + /* Clear all the counters. */ + thread_31a_counter = 0; + thread_31b_counter = 0; + thread_31c_counter = 0; + thread_31d_counter = 0; + thread_31e_counter = 0; + thread_31f_counter = 0; + thread_31g_counter = 0; + thread_31h_counter = 0; + + /* Resume thread 0. */ + status = tx_thread_resume(&thread_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Time-Slice Test......................................... ERROR #10\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + + /* Inform user. */ + printf("Running SMP Time-Slice Test......................................... "); + + /* Resume all the same priority threads. */ + status = tx_thread_resume(&thread_31a); + status += tx_thread_resume(&thread_31b); + status += tx_thread_resume(&thread_31c); + status += tx_thread_resume(&thread_31d); + status += tx_thread_resume(&thread_31e); + status += tx_thread_resume(&thread_31f); + status += tx_thread_resume(&thread_31g); + status += tx_thread_resume(&thread_31h); + + /* Now sleep for 20 ticks to let see if all the threads execute. */ + tx_thread_sleep(20); + + /* Now check and make sure all the threads ran. */ + if ((status != TX_SUCCESS) || (thread_31a_counter == 0) || (thread_31b_counter == 0) || (thread_31c_counter == 0) || (thread_31d_counter == 0) || + (thread_31e_counter == 0) || (thread_31f_counter == 0) || (thread_31g_counter == 0) || (thread_31h_counter == 0)) + { + + /* Execution error. */ + printf("ERROR #31\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_31a_entry(ULONG thread_input) +{ + + while(1) + { + tx_thread_identify(); + thread_31a_counter++; + } +} + + +static void thread_31b_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_identify(); + thread_31b_counter++; + } +} + + +static void thread_31c_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_identify(); + thread_31c_counter++; + } +} + + +static void thread_31d_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_identify(); + thread_31d_counter++; + } +} + + +static void thread_31e_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_identify(); + thread_31e_counter++; + } +} + + +static void thread_31f_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_identify(); + thread_31f_counter++; + } +} + + +static void thread_31g_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_identify(); + thread_31g_counter++; + } +} + + +static void thread_31h_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_identify(); + thread_31h_counter++; + } +} + diff --git a/test/smp/regression/threadx_smp_two_threads_one_core_test.c b/test/smp/regression/threadx_smp_two_threads_one_core_test.c new file mode 100644 index 00000000..a6dc1c80 --- /dev/null +++ b/test/smp/regression/threadx_smp_two_threads_one_core_test.c @@ -0,0 +1,268 @@ +/* Define the ThreadX SMP two threads excluded to one core test. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" + + + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; + + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG thread_2_counter; + + +static unsigned long error = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_smp_two_threads_one_core_test(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; +ULONG exclusion_map; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 0, 0, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_0, 0x0); /* No exclusions! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Two Threads One Core Test............................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 1, 1, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_1, 0xD); /* Only core 1! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Two Threads One Core Test............................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 2, 2, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_smp_core_exclude(&thread_2, 0xD); /* Only core 1! */ + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Two Threads One Core Test............................... ERROR #3\n"); + test_control_return(1); + } + + /* Resume thread 0. */ + status = tx_thread_resume(&thread_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running SMP Two Threads One Core Test............................... ERROR #4\n"); + test_control_return(1); + } + + /* Attempt to call the core-exclusion API with a NULL pointer. */ + status = tx_thread_smp_core_exclude(TX_NULL, 1); + + /* Check status. */ + if (status != TX_THREAD_ERROR) + { + + printf("Running SMP Two Threads One Core Test............................... ERROR #5\n"); + test_control_return(1); + } + + /* Attempt to call the core-exclusion API with a bad thread pointer. */ + thread_3.tx_thread_id = 0; + status = tx_thread_smp_core_exclude(&thread_3, 1); + + /* Check status. */ + if (status != TX_THREAD_ERROR) + { + + printf("Running SMP Two Threads One Core Test............................... ERROR #6\n"); + test_control_return(1); + } + + /* Test the core exclusion get API. */ + status = tx_thread_smp_core_exclude_get(TX_NULL, TX_NULL); + + /* Check status. */ + if (status != TX_THREAD_ERROR) + { + + printf("Running SMP Two Threads One Core Test............................... ERROR #7\n"); + test_control_return(1); + } + + /* Test the core exclusion get API with a bad thread pointer. */ + status = tx_thread_smp_core_exclude_get(&thread_3, TX_NULL); + + /* Check status. */ + if (status != TX_THREAD_ERROR) + { + + printf("Running SMP Two Threads One Core Test............................... ERROR #8\n"); + test_control_return(1); + } + + /* Test the core exclusion get API with a good thread pointer, but a bad return pointer. */ + status = tx_thread_smp_core_exclude_get(&thread_2, TX_NULL); + + /* Check status. */ + if (status != TX_PTR_ERROR) + { + + printf("Running SMP Two Threads One Core Test............................... ERROR #9\n"); + test_control_return(1); + } + + /* Now test the proper usage for the core exclusiong get API. */ + status = tx_thread_smp_core_exclude_get(&thread_2, &exclusion_map); + + /* Check status. */ + if ((status != TX_SUCCESS) || (exclusion_map != 0xD)) + { + + printf("Running SMP Two Threads One Core Test............................... ERROR #10\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + + /* Inform user. */ + printf("Running SMP Two Threads One Core Test............................... "); + + /* Resume all the threads. */ + status = tx_thread_resume(&thread_1); + status += tx_thread_resume(&thread_2); + + /* Suspend this thread to let the others run. */ + tx_thread_sleep(10); + + /* Determine if the test was successful or there was an error. */ + if ((status != TX_SUCCESS) || (error) || (thread_1_counter != 1) || + (thread_2_counter != 1)) + { + + /* Execution error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + while(1) + { + /* Ensure this thread is on the correct core. */ + if (tx_thread_smp_core_get() != 1) + error++; + + thread_1_counter++; + tx_thread_suspend(&thread_1); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ +TX_INTERRUPT_SAVE_AREA + + + while(1) + { + + /* Ensure this thread is on the correct core. */ + if (tx_thread_smp_core_get() != 1) + error++; + + thread_2_counter++; + + + /* Disable interrupts. */ + TX_DISABLE + + /* Increment the preempt disable flag. */ + _tx_thread_preempt_disable++; + + /* Now call the exclude routine to exclude core 1 - move the thread. */ + if (tx_thread_smp_core_exclude(&thread_2, 0x2)) + error++; + + /* Decrement the preempt disable flag. */ + _tx_thread_preempt_disable--; + + /* Restore interrupts. */ + TX_RESTORE + + /* Suspend thread. */ + tx_thread_suspend(&thread_2); + } +} diff --git a/test/smp/regression/threadx_thread_basic_execution_test.c b/test/smp/regression/threadx_thread_basic_execution_test.c new file mode 100644 index 00000000..02e18d24 --- /dev/null +++ b/test/smp/regression/threadx_thread_basic_execution_test.c @@ -0,0 +1,863 @@ +/* This test is designed to see if one thread can be created and executed. + It thread_0_entry is hit, then the thread was successfully scheduled. + On success, thread_0_counter gets incremented. */ + +#include +#include "tx_api.h" +#include "tx_block_pool.h" +#include "tx_byte_pool.h" +#include "tx_event_flags.h" +#include "tx_mutex.h" +#include "tx_queue.h" +#include "tx_semaphore.h" +#include "tx_thread.h" + + +typedef struct THREAD_MEMORY_TEST_STRUCT +{ + ULONG first; + ULONG second; + TX_THREAD thread_block; + ULONG first_middle; + ULONG second_middle; + ULONG stack[2048/sizeof(ULONG)]; + ULONG next_to_last; + ULONG last; + +} THREAD_MEMORY_TEST; + +static THREAD_MEMORY_TEST thread_memory; + + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; +static TX_THREAD test_thread; + +static TX_TIMER timer_0; + + +static UCHAR not_used_stack[TEST_STACK_SIZE_PRINTF]; + +static unsigned long error = 0; +static unsigned long timer_executed = 0; +static unsigned long isr_executed = 0; + + +/* Define task prototypes. */ + +static void thread_0_entry(ULONG task_input); + +UINT _txe_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr, + VOID (*entry_function)(ULONG), ULONG entry_input, + VOID *stack_start, ULONG stack_size, + UINT priority, UINT preempt_threshold, + ULONG time_slice, UINT auto_start, UINT thread_control_block_size); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define the timer for this test. */ + +static void timer_entry(ULONG i) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +UINT status; +CHAR *pointer; + + /* Attempt to create a thread from a timer. */ + pointer = (CHAR *) 0x3000; + status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_DONT_START); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt a thread reset from a timer. */ + status = tx_thread_reset(&thread_0); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + timer_executed = 1; +#endif +} + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +CHAR *pointer; +UINT status; +UINT old_value; +ULONG old_time_slice; + + + /* Call tx_thread_relinquish from ISR to make sure the error checking discards the call. */ + tx_thread_relinquish(); + + /* Attempt to create a thread from a timer. */ + pointer = (CHAR *) not_used_stack; + status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_DONT_START); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to delete a thread from an ISR. */ + status = tx_thread_delete(&thread_0); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to change preemption from an ISR. */ + status = tx_thread_preemption_change(&thread_0, 1, &old_value); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to change priority from an ISR. */ + status = tx_thread_priority_change(&thread_0, 1, &old_value); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt a thread reset from an ISR. */ + status = tx_thread_reset(&thread_0); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt a thread terminate from an ISR. */ + status = tx_thread_terminate(&thread_0); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt a thread time slice change from an ISR. */ + status = tx_thread_time_slice_change(&thread_0, 1, &old_time_slice); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + isr_executed = 1; +#endif + + /* Test thread sleep call from ISR. */ + status = tx_thread_sleep(11); + + /* Check for status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } +} + +#if 0 +static void test_thread_entry(ULONG thread_input) +{ + /* Do nothing here! */ +} +#endif + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_basic_execution_application_define(void *first_unused_memory) +#endif +{ + +INT status; +CHAR *pointer; +TX_THREAD fake_thread; + + + /* Setup a pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Adjust it forward just to make sure there is some space for the test below. */ + pointer = pointer + 200; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Basic Execution Test................................. ERROR #1\n"); + test_control_return(1); + } + +#ifndef TX_NOT_INTERRUPTABLE + + /* Now setup a fake thread to generate the other NULL pointer test in the cleanup routines. */ + fake_thread.tx_thread_suspend_control_block = TX_NULL; + _tx_semaphore_cleanup(&fake_thread, 0); + _tx_queue_cleanup(&fake_thread, 0); + _tx_mutex_cleanup(&fake_thread, 0); + _tx_event_flags_cleanup(&fake_thread, 0); + _tx_byte_pool_cleanup(&fake_thread, 0); + _tx_block_pool_cleanup(&fake_thread, 0); +#endif +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING +UINT status; +CHAR *pointer; +UINT old_value; +ULONG old_time_slice; +#endif + +VOID (*temp_mutex_release)(TX_THREAD *thread_ptr); + + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Inform user of success getting to this test. */ + printf("Running Thread Basic Execution Test................................. "); + + /* Setup test thread to make sure _tx_thread_wait_abort can handle a NULL cleanup. */ + test_thread.tx_thread_state = TX_IO_DRIVER; + test_thread.tx_thread_suspend_cleanup = TX_NULL; + test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + test_thread.tx_thread_suspending = TX_TRUE; + test_thread.tx_thread_delayed_suspend = TX_TRUE; + if(_tx_thread_wait_abort(&test_thread) != TX_WAIT_ABORT_ERROR) + { + printf("ERROR #XX\n"); + test_control_return(1); + } + + /* Setup test thread to make sure _tx_thread_timeout can handle a NULL cleanup. */ + test_thread.tx_thread_state = TX_IO_DRIVER; + test_thread.tx_thread_suspend_cleanup = TX_NULL; + test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + test_thread.tx_thread_suspending = TX_TRUE; + test_thread.tx_thread_delayed_suspend = TX_TRUE; + _tx_thread_timeout((ULONG) &test_thread); + + /* Setup test thread to make sure _tx_thread_terminate can handle a NULL mutex release function pointer. */ + temp_mutex_release = _tx_thread_mutex_release; + _tx_thread_mutex_release = TX_NULL; + test_thread.tx_thread_state = TX_TERMINATED; + test_thread.tx_thread_suspend_cleanup = TX_NULL; + test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + test_thread.tx_thread_suspending = TX_TRUE; + test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL; + test_thread.tx_thread_delayed_suspend = TX_TRUE; + status = _tx_thread_terminate(&test_thread); + _tx_thread_mutex_release = temp_mutex_release; /* Recover Mutex release pointer. */ + + /* Perform thread memory test. */ + thread_memory.first = 0x11223344; + thread_memory.second = 0x55667788; + thread_memory.first_middle = 0x21314151; + thread_memory.second_middle= 0x61718191; + thread_memory.next_to_last = 0x99aabbcc; + thread_memory.last = 0xddeeff00; + + /* Create the thread. */ + status += tx_thread_create(&thread_memory.thread_block, "thread memory", thread_0_entry, 1, + &thread_memory.stack[0], (2048*sizeof(ULONG))/sizeof(ULONG), + 16, 16, TX_NO_TIME_SLICE, TX_DONT_START); + tx_thread_delete(&thread_memory.thread_block); + + /* Check for status. */ + if ((status != TX_SUCCESS) || + (thread_memory.first != 0x11223344) || + (thread_memory.second != 0x55667788) || + (thread_memory.first_middle != 0x21314151) || + (thread_memory.second_middle != 0x61718191) || + (thread_memory.next_to_last != 0x99aabbcc) || + (thread_memory.last != 0xddeeff00)) + { + + /* Memory overwrite error. */ + printf("ERROR #2\n"); + test_control_return(1); + } + + + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Attempt to create a thread with a null pointer. */ + pointer = (CHAR *) not_used_stack; + status = tx_thread_create(TX_NULL, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #3\n"); + test_control_return(1); + } + + /* Attempt to create a thread with a bad control block size. */ + pointer = (CHAR *) not_used_stack; + status = _txe_thread_create(&thread_3, "thread 3", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START, (sizeof(TX_THREAD)+1)); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Attempt to create a thread with a NULL entry function. */ + pointer = (CHAR *) not_used_stack; + status = tx_thread_create(&thread_3, "thread 3", TX_NULL, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_PTR_ERROR) + { + + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Attempt to create a thread that has already been created. */ + pointer = (CHAR *) not_used_stack; + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Attempt to create a thread with an overlapping stack. */ + status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1, + thread_0.tx_thread_stack_ptr, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_PTR_ERROR) + { + + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Attempt to create a thread with another variation of an overlapping stack. */ + pointer = thread_0.tx_thread_stack_start; + pointer = pointer - 20; + status = tx_thread_create(&thread_1, "thread 1", TX_NULL, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_PTR_ERROR) + { + + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Attempt to create a thread an extra small stack. */ + pointer = (CHAR *) not_used_stack; + status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1, + pointer, 1, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_SIZE_ERROR) + { + + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to create a thread with an invalid thread priority. */ + pointer = (CHAR *) not_used_stack; + status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 5000, 5000, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_PRIORITY_ERROR) + { + + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Attempt to create a thread with an invalid preemption-threshold. */ + pointer = (CHAR *) not_used_stack; + status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 17, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_THRESH_ERROR) + { + + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Attempt to create a thread with an invalid auto start. */ + pointer = (CHAR *) not_used_stack; + status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, 3456); + + /* Check for status. */ + if (status != TX_START_ERROR) + { + + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Attempt to delete a non-thread. */ + status = tx_thread_delete(TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Attempt to delete a non-created thread. */ + thread_2.tx_thread_id = 0; + status = tx_thread_delete(&thread_2); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Attempt to register a entry/exit callback on a non-thread. */ + status = tx_thread_entry_exit_notify(TX_NULL, TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Attempt to register a entry/exit callback on a non-created thread. */ + thread_2.tx_thread_id = 0; + status = tx_thread_entry_exit_notify(&thread_2, TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Attempt to get info on a non-thread. */ + status = tx_thread_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Attempt to get info on a non-created thread. */ + thread_2.tx_thread_id = 0; + status = tx_thread_info_get(&thread_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Attempt to change preemption of a non-thread. */ + status = tx_thread_preemption_change(TX_NULL, 1, TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Attempt to change preemption of a non-created thread. */ + thread_2.tx_thread_id = 0; + status = tx_thread_preemption_change(&thread_2, 1, TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Attempt to change preemption with a NULL return value. */ + status = tx_thread_preemption_change(&thread_0, 1, TX_NULL); + + /* Check for status. */ + if (status != TX_PTR_ERROR) + { + + printf("ERROR #21\n"); + test_control_return(1); + } + + /* Attempt to change preemption with a bad threshold value. */ + status = tx_thread_preemption_change(&thread_0, 17, &old_value); + + /* Check for status. */ + if (status != TX_THRESH_ERROR) + { + + printf("ERROR #22\n"); + test_control_return(1); + } + + + /* Attempt to change priority of a non-thread. */ + status = tx_thread_priority_change(TX_NULL, 1, TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Attempt to change priority of a non-created thread. */ + thread_2.tx_thread_id = 0; + status = tx_thread_priority_change(&thread_2, 1, TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Attempt to change priority with a NULL return value. */ + status = tx_thread_priority_change(&thread_0, 1, TX_NULL); + + /* Check for status. */ + if (status != TX_PTR_ERROR) + { + + printf("ERROR #25\n"); + test_control_return(1); + } + + /* Attempt to change priority with a bad priority value. */ + status = tx_thread_priority_change(&thread_0, 2046, &old_value); + + /* Check for status. */ + if (status != TX_PRIORITY_ERROR) + { + + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Attempt a thread reset for a non-thread. */ + status = tx_thread_reset(TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Attempt a thread reset from same thread. */ + status = tx_thread_reset(&thread_0); + + /* Check for status. */ + if (status != TX_NOT_DONE) + { + + printf("ERROR #28\n"); + test_control_return(1); + } + + /* Attempt a thread reset for a non-created thread. */ + thread_2.tx_thread_id = 0; + status = tx_thread_reset(&thread_2); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #29\n"); + test_control_return(1); + } + + /* Attempt a thread resume with a NULL pointer. */ + status = tx_thread_resume(TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #30\n"); + test_control_return(1); + } + + /* Attempt a thread resume on a non-created thread. */ + thread_2.tx_thread_id = 0; + status = tx_thread_resume(&thread_2); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #31\n"); + test_control_return(1); + } + + /* Attempt a thread suspend with a NULL pointer. */ + status = tx_thread_suspend(TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #32\n"); + test_control_return(1); + } + + /* Attempt a thread suspend on a non-created thread. */ + thread_2.tx_thread_id = 0; + status = tx_thread_suspend(&thread_2); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #33\n"); + test_control_return(1); + } + + /* Attempt a thread termiante with a NULL pointer. */ + status = tx_thread_terminate(TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #34\n"); + test_control_return(1); + } + + /* Attempt a thread terminate on a non-created thread. */ + thread_2.tx_thread_id = 0; + status = tx_thread_terminate(&thread_2); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #35\n"); + test_control_return(1); + } + + /* Attempt a thread time-slice chagne with a NULL pointer. */ + status = tx_thread_time_slice_change(TX_NULL, 1, &old_time_slice); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #36\n"); + test_control_return(1); + } + + /* Attempt a thread time-slice change on a non-created thread. */ + thread_2.tx_thread_id = 0; + status = tx_thread_time_slice_change(&thread_2, 1, &old_time_slice); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #37\n"); + test_control_return(1); + } + + /* Attempt a thread time-slice change with a null return pointer. */ + status = tx_thread_time_slice_change(&thread_0, 1, TX_NULL); + + /* Check for status. */ + if (status != TX_PTR_ERROR) + { + + printf("ERROR #38\n"); + test_control_return(1); + } + + /* Attempt a thread wait abort with a NULL pointer. */ + status = tx_thread_wait_abort(TX_NULL); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #39\n"); + test_control_return(1); + } + + /* Attempt a thread wait abort on a non-created thread. */ + thread_2.tx_thread_id = 0; + status = tx_thread_wait_abort(&thread_2); + + /* Check for status. */ + if (status != TX_THREAD_ERROR) + { + + printf("ERROR #40\n"); + test_control_return(1); + } + + /* Create a timer for the test. */ + tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE); + + /* Setup the ISR. */ + test_isr_dispatch = test_isr; + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Clear the ISR. */ + test_isr_dispatch = TX_NULL; + + /* Test for error. */ + if ((error) || (timer_executed != 1) || (isr_executed != 1)) + { + + /* Thread error. */ + printf("ERROR #41\n"); + test_control_return(1); + } + +#endif + + /* Check status. */ + if (error) + { + + /* Block memory error. */ + printf("ERROR #42\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } + +} diff --git a/test/smp/regression/threadx_thread_basic_time_slice_test.c b/test/smp/regression/threadx_thread_basic_time_slice_test.c new file mode 100644 index 00000000..9a4f4373 --- /dev/null +++ b/test/smp/regression/threadx_thread_basic_time_slice_test.c @@ -0,0 +1,117 @@ +/* This test is designed to see if a thread can be created with a time-slice. + No time-slice occurs, only the processing to check for time-slicing. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_basic_time_slice_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *memory; + + + memory = (UCHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + memory, TEST_STACK_SIZE_PRINTF, + 16, 16, 1, TX_AUTO_START); + memory = memory + TEST_STACK_SIZE_PRINTF; + status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + memory, TEST_STACK_SIZE_PRINTF, + 16, 16, 1, TX_DONT_START); + status += tx_thread_smp_core_exclude(&thread_1, 0xF); + status += tx_thread_resume(&thread_1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Basic Time-Slice Test................................ ERROR #1\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG target_time; + + + /* Inform user. */ + printf("Running Thread Basic Time-Slice Test................................ "); + + /* Calculate the target running time. */ + target_time = tx_time_get() + 20; + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Determine if we are done. */ + if (tx_time_get() >= target_time) + { + + /* Determine if thread 1 executed. */ + if (thread_1_counter != 0) + { + + /* Error, thread 1 has all cores excluded so it should never run. */ + printf("ERROR #2\n"); + test_control_return(0); + } + else + { + + /* Successful Time-slice test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } + } + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + /* Loop forever. */ + while(1) + { + + /* Increment counter. */ + thread_1_counter++; + } +} diff --git a/test/smp/regression/threadx_thread_completed_test.c b/test/smp/regression/threadx_thread_completed_test.c new file mode 100644 index 00000000..068058d0 --- /dev/null +++ b/test/smp/regression/threadx_thread_completed_test.c @@ -0,0 +1,258 @@ +/* This test is designed to see if one thread can be created, executed, and + return to the thread shell function. The thread shell function places + the thread in a finished state. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" + + +static unsigned long thread_0_counter = 0; +static unsigned long thread_0_enter = 0; +static unsigned long thread_0_exit = 0; +static unsigned long thread_1_counter = 0; + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD *saved_ptr; +static ULONG saved_count; + +/* Define task prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void entry_exit_notify(TX_THREAD *thread_ptr, UINT type) +{ + + /* Check for the appropriate thread. */ + if (thread_ptr != &thread_0) + return; + + /* Check for type. */ + if (type == TX_THREAD_ENTRY) + thread_0_enter++; + else if (type == TX_THREAD_EXIT) + thread_0_exit++; +} + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_completed_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Setup the notify call to test that logic. */ + status += tx_thread_entry_exit_notify(&thread_0, entry_exit_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Completed Test....................................... ERROR #1\n"); + test_control_return(1); + } + +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Thread Completed Test....................................... ERROR #2\n"); + test_control_return(1); + } + +#endif + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Completed Test....................................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Completed Test....................................... ERROR #4\n"); + test_control_return(1); + } + + /* Move the created pointer to thread 1 to test the delete path fully. */ + saved_ptr = _tx_thread_created_ptr; + _tx_thread_created_ptr = &thread_0; +} + + + +/* Define the test thread. */ + +static void thread_0_entry(ULONG thread_input) +{ + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Fall through to the return in order to place the thread in a finished + state. */ +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Thread Completed Test....................................... "); + + /* Increment thread 1 counter. */ + thread_1_counter++; + + /* Attempt to delete thread 2, which is in the wrong stat for deleting. */ + status = tx_thread_delete(&thread_2); + + /* Check for the proper status. */ + if (status != TX_DELETE_ERROR) + { + + /* Thread delete error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Attempt to suspend thread 0, which is in a completed state. */ + status = tx_thread_suspend(&thread_0); + + /* Check for the correct status. */ + if (status != TX_SUSPEND_ERROR) + { + + /* Thread suspend error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Attempt to delete thread 0. */ + status = tx_thread_delete(&thread_0); + + /* Check for the proper status. */ + if (status != TX_SUCCESS) + { + + /* Thread delete error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Sleep to let thread 2 run. */ + tx_thread_sleep(2); + + /* Save the created count. */ + saved_count = _tx_thread_created_count; + + /* Now setup things so we can fake a delete of one thread. */ + _tx_thread_created_ptr = &thread_2; + thread_2.tx_thread_created_next = &thread_2; + thread_2.tx_thread_created_previous = &thread_2; + _tx_thread_created_count = 1; + + /* Attempt to delete thread 2. */ + status = tx_thread_delete(&thread_2); + + /* Check for the proper status. */ + if (status != TX_SUCCESS) + { + + /* Thread delete error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* if still okay, restore the saved thread pointer. */ + if (saved_ptr -> tx_thread_id == TX_THREAD_ID) + { + /* Restore. */ + _tx_thread_created_ptr = saved_ptr; + + /* Setup the link pointers again. */ + saved_ptr -> tx_thread_created_previous = &thread_1; + thread_1.tx_thread_created_next = saved_ptr; + + /* Setup the created count. */ + _tx_thread_created_count = saved_count - 1; + } + + /* Determine if the first Thread has run and if it's current state is + finished. */ + if ((thread_0.tx_thread_state == TX_COMPLETED) && (thread_0_counter == 1) && +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + (thread_0_enter == 1) && (thread_0_exit == 1)) +#else + (thread_0_enter == 0) && (thread_0_exit == 0)) +#endif + { + + /* Successful thread finish test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } + else + { + + /* Thread Finish error. */ + printf("ERROR #9\n"); + test_control_return(1); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + + /* Fall through to the return in order to place the thread in a finished + state. */ +} diff --git a/test/smp/regression/threadx_thread_create_preemption_threshold_test.c b/test/smp/regression/threadx_thread_create_preemption_threshold_test.c new file mode 100644 index 00000000..ad0d1d4e --- /dev/null +++ b/test/smp/regression/threadx_thread_create_preemption_threshold_test.c @@ -0,0 +1,140 @@ +/* This test is designed to test for preemption-threshold use during thread creation during initialization. */ + +#include +#include "tx_api.h" + +//static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_create_preemption_threshold_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 0, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Create Preemption-Threshold from Init Test........... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 0, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Create Preemption-Threshold from Init Test........... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 0, 100, TX_DONT_START); + status += tx_thread_resume(&thread_0); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Create Preemption-Threshold from Init Test........... ERROR #3\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + /* Inform user. */ + printf("Running Thread Create Preemption-Threshold from Init Test........... "); + + /* If either of the other threads have run, an error is present. */ + if ((thread_1_counter) || (thread_2_counter)) + { + + /* Test error! */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Sleep for two ticks (one is insufficient to guarantee the other + tasks will run, if this executes too close to the tick interrupt. */ + tx_thread_sleep(2); + + + /* Now, both threads should have run. */ + if ((thread_1_counter != 1) || (thread_2_counter != 1)) + { + + /* Test error! */ + printf("ERROR #5\n"); + test_control_return(2); + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + + /* Increment this thread's counter. */ + thread_1_counter++; +} + + +static void thread_2_entry(ULONG thread_input) +{ + + /* Increment the thread counter. */ + thread_2_counter++; +} + diff --git a/test/smp/regression/threadx_thread_delayed_suspension_test.c b/test/smp/regression/threadx_thread_delayed_suspension_test.c new file mode 100644 index 00000000..6d6d27d0 --- /dev/null +++ b/test/smp/regression/threadx_thread_delayed_suspension_test.c @@ -0,0 +1,390 @@ +/* This test checks out the delayed suspension clear from tx_thread_resume. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" +#include "tx_timer.h" + + +#define DEMO_STACK_SIZE TEST_STACK_SIZE_PRINTF + + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_SEMAPHORE semaphore_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define the ISR dispatch routine. */ + +#ifndef TX_NOT_INTERRUPTABLE + +#if defined(TX_WIN32_MEMORY_SIZE) || defined(TX_LINUX_MEMORY_SIZE) +/* Use larger array size when running on Win32 test platform because of greater speed. */ +#define ARRAY_SIZE 100 +#else +#define ARRAY_SIZE 10 +#endif + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); +static void thread_2_entry(ULONG thread_input); + +static UINT delayed_suspend_set; + +static ULONG thread_2_counter; +static ULONG thread_2_counter_capture; + +static ULONG min_loop_count; +static ULONG max_loop_count; +static ULONG loop_count; +static volatile ULONG count; +static volatile ULONG destination = 0; +static ULONG start_time; +static ULONG lower_bound; +static ULONG upper_bound; +static ULONG current_itterations; +#ifdef DEBUG_1 +static ULONG last_loop_count; +#endif +static TX_THREAD thread_2; +static TX_SEMAPHORE semaphore_1; + +static ULONG array_delay[ARRAY_SIZE]; + +static ULONG delay_function(void) +{ + +ULONG accumulator; +ULONG i; + + for (i = 0; i < ARRAY_SIZE; i++) + array_delay[i] = i; + + for (i = 0; i < ARRAY_SIZE-4; i++) + { + array_delay[i] = (array_delay[i+1] * array_delay[i+2]) * (array_delay[i+3] * array_delay[i+4]); + } + + accumulator = 0; + for (i = 0; i < ARRAY_SIZE; i++) + accumulator = accumulator + array_delay[i]; + + return(accumulator); +} + + +static void test_isr(void) +{ +ULONG i; + + /* Determine if we are in calibration mode. */ + if (loop_count != 0xFFFFFFFF) + { + if (loop_count < min_loop_count) + min_loop_count = loop_count; + if (loop_count > max_loop_count) + max_loop_count = loop_count; + + lower_bound = loop_count - 1; + upper_bound = loop_count + 1; + if (lower_bound < min_loop_count) + lower_bound = min_loop_count; + if (upper_bound > max_loop_count) + lower_bound = max_loop_count; + + if ((current_itterations < lower_bound) || (current_itterations > upper_bound)) + current_itterations = lower_bound; + +#ifdef DEBUG_1 + /* Last loop count. */ + last_loop_count = loop_count; +#endif + + /* Reset the loop count to all ones! */ + loop_count = 0xFFFFFFFF; + } + count++; + for (i = 0; i < (count%32); i++) + destination++; + + /* Check to see if the interrupt occurred in the middle of the suspension. */ + if ((thread_2.tx_thread_suspending) && (delayed_suspend_set == 0)) + { + + /* Yes, we have taken the interrupt in the middle of a thread suspension. */ + + /* Indicate we have got the condition. */ + delayed_suspend_set = 1; + + /* Capture the current thread 2 counter. */ + thread_2_counter_capture = thread_2_counter; + + /* Now attempt to set the delayed suspension. */ + tx_thread_suspend(&thread_2); + + /* Check for the delayed suspension flag being set. */ + if (thread_2.tx_thread_delayed_suspend != 1) + { + + /* Error! Setup the counters to indicate an error. */ + thread_2_counter = 0xEEEEEEEE; + thread_2_counter_capture = 0xFFFFFFFF; + } + + /* Now, abort the suspension for thread 2... the thread should switch to a pure suspended state. */ + tx_thread_wait_abort(&thread_2); + + /* Check for the proper state. */ + if (thread_2.tx_thread_state != TX_SUSPENDED) + { + + /* Error! Setup the counters to indicate an error. */ + thread_2_counter = 0xEEEEEEEE; + thread_2_counter_capture = 0xFFFFFFFF; + } + } + +} +#endif + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_delayed_suspension_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create threads 1 and 2. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, DEMO_STACK_SIZE, + 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the semaphore. */ + tx_semaphore_create(&semaphore_0, "semaphore 0", 0); + +#ifndef TX_NOT_INTERRUPTABLE + + tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, DEMO_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_1, "semaphore 1", 0); + + thread_2_counter = 0; + thread_2_counter_capture = 0; + min_loop_count = 0xFFFFFFFF; + max_loop_count = 0; + loop_count = 0xFFFFFFFF; +#ifdef DEBUG_1 + last_loop_count = 0; +#endif +#endif +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Thread Delayed Suspension Clearing Test..................... "); + + /* Relinquish to the other thread. */ + tx_thread_relinquish(); + + /* At this point thread 1 has suspended on the semaphore. */ + + /* Suspend the already suspended thread. */ + tx_thread_suspend(&thread_1); + + /* Set the semaphore, which should make it go into a suspend state. */ + tx_semaphore_put(&semaphore_0); + + /* Resume the other thread so it runs again. */ + tx_thread_resume(&thread_1); + + /* Relinquish so it can run again. */ + tx_thread_relinquish(); + + /* Suspend the already suspended thread. */ + tx_thread_suspend(&thread_1); + + /* Now, clear the delayed suspension. */ + status = tx_thread_resume(&thread_1); + + if (status != TX_SUSPEND_LIFTED) + { + + /* Delayed suspension error. */ + printf("ERROR #1\n"); + test_control_return(1); + } + +#ifndef TX_NOT_INTERRUPTABLE + + /* Setup the test ISR. */ + test_isr_dispatch = test_isr; + + /* Resume the test thread. */ + tx_thread_resume(&thread_2); + + /* Wait until we see the delayed suspension set flag. */ + while(delayed_suspend_set == 0) + { + + /* Abort the suspension for thread 2. */ + tx_thread_wait_abort(&thread_2); + + /* Just relinquish. */ + tx_thread_relinquish(); + } + + /* Relinquish one more time to make sure thread 2 could run if it is ready. */ + tx_thread_relinquish(); + + /* At this point, check for an error. */ + if (thread_2_counter != thread_2_counter_capture) + { + + /* Delayed suspension error... thread kept running! */ + printf("ERROR #2\n"); + test_control_return(1); + } +#endif + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* This thread simply gets the semaphore... */ + while(1) + { + + /* Get semaphore. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + /* Check completion status. */ + if (status != TX_SUCCESS) + break; + } +} + + +#ifndef TX_NOT_INTERRUPTABLE + + +static void thread_2_entry(ULONG thread_input) +{ + +ULONG i; + + /* Callibrate the loop count from thread sleep. */ + for (i = 0; i < 10; i++) + { + + /* Sleep to get a fresh time. */ + tx_thread_sleep(1); + + start_time = _tx_timer_system_clock; + do + { + + /* Call delay function. */ + delay_function(); + loop_count++; + } while (start_time == _tx_timer_system_clock); + + /* Wait to reset the loop count. */ + tx_thread_sleep(1); + } + + /* Setup the lower and upper bounds. */ + lower_bound = min_loop_count; + if (lower_bound > 5) + lower_bound = lower_bound - 5; + upper_bound = max_loop_count + 5; + + current_itterations = lower_bound; + + /* This thread simply suspends over and over... */ + while(1) + { + + /* Sleep to get a fresh starting time. */ + tx_thread_sleep(1); + + loop_count = 0; + start_time = _tx_timer_system_clock; + do + { + /* Call delay function. */ + delay_function(); + loop_count++; + } while (loop_count < current_itterations); + + /* Suspend this thread. */ + tx_semaphore_get(&semaphore_1, TX_WAIT_FOREVER); + + /* Adjust the current itterations. */ + current_itterations++; + if (current_itterations > upper_bound) + { + if (lower_bound > min_loop_count) + lower_bound--; + if (upper_bound < max_loop_count) + upper_bound++; + current_itterations = lower_bound; + } + + /* Increment the thread counter. */ + thread_2_counter++; + } +} + +#endif diff --git a/test/smp/regression/threadx_thread_information_test.c b/test/smp/regression/threadx_thread_information_test.c new file mode 100644 index 00000000..b72a2363 --- /dev/null +++ b/test/smp/regression/threadx_thread_information_test.c @@ -0,0 +1,474 @@ +/* This test is for the thread information services. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +/* Define task prototypes. */ + +static void thread_0_entry(ULONG task_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_information_application_define(void *first_unused_memory) +#endif +{ + +INT status; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + first_unused_memory, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Information Test..................................... ERROR #1\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR *name; +UINT state; +ULONG run_count; +UINT priority; +UINT preemption_threshold; +ULONG time_slice; +TX_THREAD *next_thread; +TX_THREAD *suspended_thread; +ULONG resumptions; +ULONG suspensions; +ULONG solicited_preemptions; +ULONG interrupt_preemptions; +ULONG priority_inversions; +ULONG time_slices; +ULONG relinquishes; +ULONG timeouts; +ULONG wait_aborts; +TX_THREAD *last_preempted_by; +ULONG non_idle_returns; +ULONG idle_returns; + + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Inform user of success getting to this test. */ + printf("Running Thread Information Test..................................... "); + + /* Get information about this thread. */ + status = tx_thread_info_get(&thread_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_thread_info_get(&thread_0, &name, &state, &run_count, &priority, &preemption_threshold, &time_slice, &next_thread, &suspended_thread); + + /* Check for error status. */ + if ((status != TX_SUCCESS) || (state != TX_READY) || (run_count != thread_0.tx_thread_run_count) || (priority != 16) || (preemption_threshold != 16) || + (time_slice != 0) || (next_thread != thread_0.tx_thread_created_next) || (suspended_thread != thread_0.tx_thread_suspended_next)) + { + + /* Thread error. */ + printf("ERROR #2\n"); + test_control_return(1); + } + + +#ifdef TX_THREAD_ENABLE_PERFORMANCE_INFO + + /* Get the performance information about a NULL thread pointer. */ + status = _tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check status. */ + if (status != TX_PTR_ERROR) + { + + /* Thread error. */ + printf("ERROR #3\n"); + test_control_return(1); + } + + /* Get the performance information about this thread. */ + status = tx_thread_performance_info_get(&thread_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_thread_performance_info_get(&thread_0, &resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &last_preempted_by); + + /* Check for error. */ + if ((status != TX_SUCCESS) || (resumptions != thread_0.tx_thread_performance_resume_count) || (suspensions != thread_0.tx_thread_performance_suspend_count) || + (solicited_preemptions != thread_0.tx_thread_performance_solicited_preemption_count) || (interrupt_preemptions != thread_0.tx_thread_performance_interrupt_preemption_count) || + (priority_inversions != thread_0.tx_thread_performance_priority_inversion_count) || (time_slices != thread_0.tx_thread_performance_time_slice_count) || + (relinquishes != thread_0.tx_thread_performance_relinquish_count) || (timeouts != thread_0.tx_thread_performance_timeout_count) || (wait_aborts != thread_0.tx_thread_performance_wait_abort_count) || + (last_preempted_by != thread_0.tx_thread_performance_last_preempting_thread)) + { + + /* Thread error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Get the system performance information. */ + status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_thread_performance_system_info_get(&resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns); + + /* Check for error. */ + if ((status != TX_SUCCESS) || (resumptions != _tx_thread_performance_resume_count) || (suspensions != _tx_thread_performance_suspend_count) || + (solicited_preemptions != _tx_thread_performance_solicited_preemption_count) || (interrupt_preemptions != _tx_thread_performance_interrupt_preemption_count) || + (priority_inversions != _tx_thread_performance_priority_inversion_count) || (time_slices != _tx_thread_performance_time_slice_count) || + (relinquishes != _tx_thread_performance_relinquish_count) || (timeouts != _tx_thread_performance_timeout_count) || (wait_aborts != _tx_thread_performance_wait_abort_count) || + (non_idle_returns != _tx_thread_performance_non_idle_return_count) || (idle_returns != _tx_thread_performance_idle_return_count)) + { + + /* Thread error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + else + { + + /* Success! */ + printf("SUCCESS!\n"); + test_control_return(0); + } +#else + + /* Get the performance information about this thread. */ + status = tx_thread_performance_info_get(&thread_0, &resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &last_preempted_by); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Get the performance information about this thread. */ + status = tx_thread_performance_info_get(TX_NULL, &resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &last_preempted_by); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Get the performance information about this thread. */ + status = tx_thread_performance_info_get(TX_NULL, TX_NULL, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &last_preempted_by); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Get the performance information about this thread. */ + status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &last_preempted_by); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Get the performance information about this thread. */ + status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &interrupt_preemptions, &priority_inversions, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &last_preempted_by); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Get the performance information about this thread. */ + status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &priority_inversions, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &last_preempted_by); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Get the performance information about this thread. */ + status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &last_preempted_by); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Get the performance information about this thread. */ + status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, + &relinquishes, &timeouts, &wait_aborts, &last_preempted_by); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Get the performance information about this thread. */ + status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, + TX_NULL, &timeouts, &wait_aborts, &last_preempted_by); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Get the performance information about this thread. */ + status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, + TX_NULL, TX_NULL, &wait_aborts, &last_preempted_by); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Get the performance information about this thread. */ + status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, + TX_NULL, TX_NULL, TX_NULL, &last_preempted_by); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Get the performance information about this thread. */ + status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, + TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Get the system performance information. */ + status = tx_thread_performance_system_info_get(&resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Get the system performance information. */ + status = tx_thread_performance_system_info_get(TX_NULL, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Get the system performance information. */ + status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Get the system performance information. */ + status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &interrupt_preemptions, &priority_inversions, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + /* Get the system performance information. */ + status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &priority_inversions, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Get the system performance information. */ + status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &time_slices, + &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Get the system performance information. */ + status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, + &relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Get the system performance information. */ + status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, + TX_NULL, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + + /* Get the system performance information. */ + status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, + TX_NULL, TX_NULL, &wait_aborts, &non_idle_returns, &idle_returns); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Get the system performance information. */ + status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, + TX_NULL, TX_NULL, TX_NULL, &non_idle_returns, &idle_returns); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Get the system performance information. */ + status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, + TX_NULL, TX_NULL, TX_NULL, TX_NULL, &idle_returns); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + + /* Get the system performance information. */ + status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, + TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Thread error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + + /* Success! */ + printf("SUCCESS!\n"); + test_control_return(0); + +#endif + +} diff --git a/test/smp/regression/threadx_thread_multi_level_preemption_threshold_test.c b/test/smp/regression/threadx_thread_multi_level_preemption_threshold_test.c new file mode 100644 index 00000000..034d4f56 --- /dev/null +++ b/test/smp/regression/threadx_thread_multi_level_preemption_threshold_test.c @@ -0,0 +1,982 @@ +/* This test is designed to test multi-level preemption threshold. The protection placed + by a thread must be preserved after higher-priority thread preemption that is above the threshold. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_2a_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static unsigned long thread_1_counter = 0; + +static unsigned long thread_2_counter = 0; + +static unsigned long thread_2a_counter = 0; +static TX_THREAD thread_2a; + +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + +#endif + +static TX_THREAD thread_0; + + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD + +/* Define new preemption-threshold threads for complete bit map checking. */ + +static TX_THREAD thread_1_0; +static TX_THREAD thread_2_1; +static TX_THREAD thread_3_2; +static TX_THREAD thread_4_3; +static TX_THREAD thread_6_5; +static TX_THREAD thread_8_7; +static TX_THREAD thread_10_9; +static TX_THREAD thread_12_11; +static TX_THREAD thread_14_13; +static TX_THREAD thread_16_15; +static TX_THREAD thread_18_17; +static TX_THREAD thread_20_19; +static TX_THREAD thread_22_21; +static TX_THREAD thread_24_23; +static TX_THREAD thread_26_25; +static TX_THREAD thread_28_27; +static TX_THREAD thread_30_29; + + +/* Define timer for preemption of priority 1 test. */ + +static TX_TIMER timer_0; + + +/* Define counters. */ + +static unsigned long timer_0_counter = 0; +static unsigned long thread_1_0_counter = 0; +static unsigned long thread_2_1_counter = 0; +static unsigned long thread_3_2_counter = 0; +static unsigned long thread_4_3_counter = 0; +static unsigned long thread_6_5_counter = 0; +static unsigned long thread_8_7_counter = 0; +static unsigned long thread_10_9_counter = 0; +static unsigned long thread_12_11_counter = 0; +static unsigned long thread_14_13_counter = 0; +static unsigned long thread_16_15_counter = 0; +static unsigned long thread_18_17_counter = 0; +static unsigned long thread_20_19_counter = 0; +static unsigned long thread_22_21_counter = 0; +static unsigned long thread_24_23_counter = 0; +static unsigned long thread_26_25_counter = 0; +static unsigned long thread_28_27_counter = 0; +static unsigned long thread_30_29_counter = 0; + + +/* Define new preemption-threshold test thread entry points. */ + +static void thread_1_0_entry(ULONG thread_input); +static void thread_2_1_entry(ULONG thread_input); +static void thread_3_2_entry(ULONG thread_input); +static void thread_4_3_entry(ULONG thread_input); +static void thread_6_5_entry(ULONG thread_input); +static void thread_8_7_entry(ULONG thread_input); +static void thread_10_9_entry(ULONG thread_input); +static void thread_12_11_entry(ULONG thread_input); +static void thread_14_13_entry(ULONG thread_input); +static void thread_16_15_entry(ULONG thread_input); +static void thread_18_17_entry(ULONG thread_input); +static void thread_20_19_entry(ULONG thread_input); +static void thread_22_21_entry(ULONG thread_input); +static void thread_24_23_entry(ULONG thread_input); +static void thread_26_25_entry(ULONG thread_input); +static void thread_28_27_entry(ULONG thread_input); +static void thread_30_29_entry(ULONG thread_input); + +/* Define timer 1 entry. */ + +static void timer_0_entry(ULONG id); + + +#endif + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_multi_level_preemption_threshold_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + (TX_MAX_PRIORITIES-1), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #1\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */ + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + (TX_MAX_PRIORITIES/2), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 10, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2a, "thread 2a", thread_2a_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 11, 11, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 9, 9, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #6\n"); + test_control_return(1); + } + + /* Create new cascading preemption-threshold test threads. */ + + status = tx_thread_create(&thread_30_29, "thread 30-29", thread_30_29_entry, 30, + pointer, TEST_STACK_SIZE_PRINTF, + 30, 29, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #7\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_28_27, "thread 28-27", thread_28_27_entry, 28, + pointer, TEST_STACK_SIZE_PRINTF, + 28, 27, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #8\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_26_25, "thread 26-25", thread_26_25_entry, 26, + pointer, TEST_STACK_SIZE_PRINTF, + 26, 25, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #9\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_24_23, "thread 24-23", thread_24_23_entry, 24, + pointer, TEST_STACK_SIZE_PRINTF, + 24, 23, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #10\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_22_21, "thread 22-21", thread_22_21_entry, 22, + pointer, TEST_STACK_SIZE_PRINTF, + 22, 21, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #11\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_20_19, "thread 20-19", thread_20_19_entry, 20, + pointer, TEST_STACK_SIZE_PRINTF, + 20,19, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #12\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_18_17, "thread 18-17", thread_18_17_entry, 18, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 17, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #13\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_16_15, "thread 16-15", thread_16_15_entry, 16, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 15, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #14\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_14_13, "thread 14-13", thread_14_13_entry, 14, + pointer, TEST_STACK_SIZE_PRINTF, + 14, 13, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #15\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_12_11, "thread 12-11", thread_12_11_entry, 12, + pointer, TEST_STACK_SIZE_PRINTF, + 12, 11, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #16\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_10_9, "thread 10-9", thread_10_9_entry, 10, + pointer, TEST_STACK_SIZE_PRINTF, + 10, 9, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #17\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_8_7, "thread 8-7", thread_8_7_entry, 8, + pointer, TEST_STACK_SIZE_PRINTF, + 8, 7, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #18\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_6_5, "thread 6-5", thread_6_5_entry, 6, + pointer, TEST_STACK_SIZE_PRINTF, + 6, 5, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #19\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4_3, "thread 4-3", thread_4_3_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 4, 3, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #20\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3_2, "thread 3-2", thread_3_2_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 3, 2, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #21\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2_1, "thread 2-1", thread_2_1_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 2, 1, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #22\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1_0, "thread 1-0", thread_1_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 1, 1, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #23\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 0, TX_NO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #24\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD +UINT status; +UINT old_preempt; +#endif + + + /* Inform user. */ + printf("Running Thread Multi-Level Preemption Threshold Test................ "); + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */ + + /* Wakeup Thread 1. It has a higher-priority but should be blocked by + preemption threshold. */ + status = tx_thread_resume(&thread_1); + + /* Check status and make sure the other run counters are proper. */ + if ((status != TX_SUCCESS) || (thread_1_counter) || (thread_2_counter) || + (thread_3_counter) || (thread_4_counter)) + { + + /* Thread Preempt Threshold error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + + /* Resume thread 2 which will preempt this thread. */ + status = tx_thread_resume(&thread_2); + + /* Check for good status and proper run counters. All other threads except for + thread 1 should have executed. */ + if ((status != TX_SUCCESS) || (thread_1_counter) || (thread_2_counter != 1) || + (thread_3_counter != 1) || (thread_4_counter != 1)) + { + + /* Thread Preempt Threshold error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Set preemption threshold low enough to allow thread 1 to execute. */ + status = tx_thread_preemption_change(&thread_0, ((TX_MAX_PRIORITIES/2)+1), &old_preempt); + + /* Check for good status and proper run counters. All other threads except for + thread 1 should have executed. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1) || + (thread_3_counter != 1) || (thread_4_counter != 1) || + (_tx_thread_preempt_disable)) + { + + /* Thread Preempt Threshold error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Set preemption threshold to keep new test threads from running. */ + status = tx_thread_preemption_change(&thread_0, 17, &old_preempt); + + /* Now wakup the lowest priority preemption-threshold thread. */ + status += tx_thread_resume(&thread_30_29); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Thread Preempt Threshold error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + + /* Now, self suspend. */ + status = tx_thread_suspend(&thread_0); + + /* Check to make sure all the preemption-threshold threads ran. */ + if ((thread_1_0_counter != 1) || + (thread_2_1_counter != 1) || + (thread_3_2_counter != 1) || + (thread_4_3_counter != 1) || + (thread_6_5_counter != 1) || + (thread_8_7_counter != 1) || + (thread_10_9_counter != 1) || + (thread_12_11_counter != 1) || + (thread_14_13_counter != 1) || + (thread_16_15_counter != 1) || + (thread_18_17_counter != 1) || + (thread_20_19_counter != 1) || + (thread_22_21_counter != 1) || + (thread_24_23_counter != 1) || + (thread_26_25_counter != 1) || + (thread_28_27_counter != 1) || + (thread_30_29_counter != 1)) + { + + /* Thread Preempt Threshold error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + +#endif + + /* Successful Thread Suspend non-current thread test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD + +static void thread_1_entry(ULONG thread_input) +{ + + thread_1_counter++; +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; + + /* Resume thread 3 which will not preempt because of thread 2's preemption + threshold. */ + status = tx_thread_resume(&thread_3); + + /* Resume thread 2a which will not preempt this thread because it is at + the same priority. */ + status += tx_thread_resume(&thread_2a); + + /* Check status and run counters. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_3_counter) || + (thread_4_counter)) + return; + + /* Resume thread 4 which will preempt. We should get back here before thread + three runs because of preemption threshold. */ + status = tx_thread_resume(&thread_4); + + /* Check status and run counters. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_3_counter) || + (thread_4_counter != 1)) + return; + + /* Relinquish to the other thread at this priority level. This should + clear the preemption threshold condition and allow thread 3 to run. */ + tx_thread_relinquish(); + + /* Check status and run counters. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_2a_counter != 1) || + (thread_3_counter != 1) || (thread_4_counter != 1)) + return; + + /* If all is okay, increment thread 2's counter. */ + thread_2_counter++; +} + + +static void thread_2a_entry(ULONG thread_input) +{ + + if (thread_3_counter == 1) + thread_2a_counter++; +} + + +static void thread_3_entry(ULONG thread_input) +{ + + thread_3_counter++; +} + + +static void thread_4_entry(ULONG thread_input) +{ + + thread_4_counter++; +} + + + +static void timer_0_entry(ULONG id) +{ + + /* Pretend like a preemption occurred on a thread priority of 1 with preemption-threshold set to 0. */ + _tx_thread_preempted_maps[0] = _tx_thread_preempted_maps[0] | 2; + + /* Set the thread's preemption threshold as well. */ + thread_1_0.tx_thread_preempt_threshold = 0; + + /* Increment timer 0 counter. */ + timer_0_counter++; +} + + +static void thread_1_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Activate the timer to force a priority 0 thread to interrupt. */ + status = tx_timer_activate(&timer_0); + + /* Loop to wait until timer 0 runs. */ + while (timer_0_counter == 0) + { + } + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_1_0_counter++; + } +} + + +static void thread_2_1_entry(ULONG thread_input) +{ + + /* Increment this thread's counter. */ + thread_2_1_counter++; +} + + +static void thread_3_2_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_1_0); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_3_2_counter++; + } +} + + +static void thread_4_3_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_2_1); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_4_3_counter++; + } +} + + +static void thread_6_5_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_4_3); + + /* In this particular case, we have two different preemptions to make + sure we exercise all the code. */ + + /* Now resume next highest priority thread. */ + status = tx_thread_resume(&thread_3_2); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_6_5_counter++; + } +} + + +static void thread_8_7_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_6_5); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_8_7_counter++; + } +} + + +static void thread_10_9_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_8_7); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_10_9_counter++; + } +} + +static void thread_12_11_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_10_9); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_12_11_counter++; + } +} + + +static void thread_14_13_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_12_11); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_14_13_counter++; + } +} + + +static void thread_16_15_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_14_13); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_16_15_counter++; + } +} + + +static void thread_18_17_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_16_15); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_18_17_counter++; + } +} + + +static void thread_20_19_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_18_17); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_20_19_counter++; + } +} + + +static void thread_22_21_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_20_19); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_22_21_counter++; + } +} + + +static void thread_24_23_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_22_21); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_24_23_counter++; + } +} + +static void thread_26_25_entry(ULONG thread_input)\ +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_24_23); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_26_25_counter++; + } +} + +static void thread_28_27_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_26_25); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_28_27_counter++; + } +} + +static void thread_30_29_entry(ULONG thread_input) +{ + +UINT status; + + + /* Resume next highest priority thread. */ + status = tx_thread_resume(&thread_28_27); + + /* Check for good status. */ + if (status == TX_SUCCESS) + { + + /* Increment this thread's counter. */ + thread_30_29_counter++; + } + + /* Resume thread_0. */ + tx_thread_resume(&thread_0); +} + + +#endif diff --git a/test/smp/regression/threadx_thread_multiple_non_current_test.c b/test/smp/regression/threadx_thread_multiple_non_current_test.c new file mode 100644 index 00000000..51212b3b --- /dev/null +++ b/test/smp/regression/threadx_thread_multiple_non_current_test.c @@ -0,0 +1,222 @@ +/* This test is designed to see if multiple non-current threads can be suspended. + The order the suspension and resumption occurs makes sure everything is working + right. Thread execution should remain predictable even after suspension and + resumption of threads within a priority group. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_multiple_non_current_suspension_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Non-Current Suspend Test............................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Non-Current Suspend Test............................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Non-Current Suspend Test............................. ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Non-Current Suspend Test............................. ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Non-Current Suspend Test............................. ERROR #5\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Inform user. */ + printf("Running Thread Non-Current Suspend Test............................. "); + + /* Wakeup all other threads at same priority. */ + status = tx_thread_resume(&thread_1); + status += tx_thread_resume(&thread_2); + + /* Check for good status. */ + if (status != TX_SUCCESS) + { + + /* Thread Suspend error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Wakeup thread with preempt. */ + status = tx_thread_resume(&thread_3); + + /* Check for good status and proper counters. */ + if ((status != TX_SUCCESS) || (thread_3_counter != 1) || (thread_1_counter) || + (thread_2_counter) || (thread_4_counter)) + { + + /* Thread Suspend error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Suspend thread 1. */ + status = tx_thread_suspend(&thread_1); + + /* Resume thread 4. */ + status += tx_thread_resume(&thread_4); + + /* Check for good status and proper counters. */ + if ((status != TX_SUCCESS) || (thread_3_counter != 1) || (thread_1_counter) || + (thread_2_counter) || (thread_4_counter)) + { + + /* Thread Suspend error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Relinquish to thread 2 and 4 before we get back. */ + tx_thread_relinquish(); + + /* Check for good status and proper counters. */ + if ((status != TX_SUCCESS) || (thread_3_counter != 1) || (thread_1_counter) || + (thread_2_counter != 1) || (thread_4_counter != 1)) + { + + /* Thread Suspend error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Successful Thread Suspend non-current thread test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +static void thread_1_entry(ULONG thread_input) +{ + + thread_1_counter++; +} + +static void thread_2_entry(ULONG thread_input) +{ + if (thread_4_counter == 0) + thread_2_counter++; +} + +static void thread_3_entry(ULONG thread_input) +{ + + thread_3_counter++; +} + +static void thread_4_entry(ULONG thread_input) +{ + + if (thread_2_counter == 1) + thread_4_counter++; +} + diff --git a/test/smp/regression/threadx_thread_multiple_sleep_test.c b/test/smp/regression/threadx_thread_multiple_sleep_test.c new file mode 100644 index 00000000..9a876295 --- /dev/null +++ b/test/smp/regression/threadx_thread_multiple_sleep_test.c @@ -0,0 +1,184 @@ +/* This test is designed to test multiple threads sleeping for 33 ticks. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; +//static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_multiple_sleep_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 3, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 3, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 3, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, 3, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #4\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Sleep for a couple ticks. */ + tx_thread_sleep(33); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 1 counter. */ + thread_1_counter++; + + /* Sleep for a couple ticks. */ + tx_thread_sleep(33); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 0 counter. */ + thread_2_counter++; + + /* Sleep for a couple ticks. */ + tx_thread_sleep(33); + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + + + /* Inform user. */ + printf("Running Thread Multiple Thread Sleep for 33 Test.................... "); + + /* Clear the tick count. */ + tx_time_set(0); + + /* Sleep for 100 ticks (+1 in case tick before threads 0,1,2 have run). */ + tx_thread_sleep(101); + + /* Determine if the sleep was accurate. */ + if ((thread_0_counter == 4) && (thread_1_counter == 4) && + (thread_2_counter == 4)) + { + + /* Successful Multiple Sleep test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } + else + { + + /* Thread Multiple Sleep error. */ + printf("ERROR #5\n"); + test_control_return(1); + } +} + diff --git a/test/smp/regression/threadx_thread_multiple_suspension_test.c b/test/smp/regression/threadx_thread_multiple_suspension_test.c new file mode 100644 index 00000000..0e4e5c06 --- /dev/null +++ b/test/smp/regression/threadx_thread_multiple_suspension_test.c @@ -0,0 +1,432 @@ +/* This test is designed to see if multiple threads can be created and suspend. + The order the suspension and resumption occurs makes sure everything is working + right. All the counters should increment at the same rate. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + +static unsigned long thread_5_counter = 0; +static TX_THREAD thread_5; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_multiple_suspension_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + /* Create thread 0. */ + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 13, 13, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #1\n"); + test_control_return(1); + } + + /* Create thread 1. */ + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + (TX_MAX_PRIORITIES/2), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #2\n"); + test_control_return(1); + } + + /* Create thread 2. */ + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + (TX_MAX_PRIORITIES/2), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #3\n"); + test_control_return(1); + } + + /* Create thread 3. */ + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + (TX_MAX_PRIORITIES/2), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #4\n"); + test_control_return(1); + } + + /* Create thread 4. */ + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #5\n"); + test_control_return(1); + } + + /* Create thread 5. Make this thread non-preemptable for the range of priorities here... */ + status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + (TX_MAX_PRIORITIES-1), 13, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Suspend/Resume Test.................. ERROR #6\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Suspend this thread... */ + tx_thread_suspend(&thread_0); + + /* Resume thread 5... */ + tx_thread_resume(&thread_5); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 1 counter. */ + thread_1_counter++; + + /* Suspend this thread. */ + tx_thread_suspend(&thread_1); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 2 counter. */ + thread_2_counter++; + + /* Suspend this thread. */ + tx_thread_suspend(&thread_2); + } +} + +static void thread_3_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 3 counter. */ + thread_3_counter++; + + /* Suspend this thread. */ + tx_thread_suspend(&thread_3); + } +} + +static void thread_4_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 4 counter. */ + thread_4_counter++; + + /* Suspend this thread. */ + tx_thread_suspend(&thread_4); + } +} + +static void thread_5_entry(ULONG thread_input) +{ + +UINT status; + + /* Inform user. */ + printf("Running Thread Multiple Thread Suspend/Resume Test.................. "); + + /* Determine if all the other threads are in a suspended state. */ + if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) || + (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) || + (thread_4.tx_thread_state != TX_SUSPENDED)) + { + + /* Thread Suspend error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Make sure that each thread has run once. */ + if ((thread_0_counter != 1) || (thread_1_counter != 1) || + (thread_2_counter != 1) || (thread_3_counter != 1) || + (thread_4_counter != 1)) + { + + /* Thread Suspend error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Resume all of the threads. */ + status = tx_thread_resume(&thread_0); + + /* Determine if all the other threads are in the proper state. */ + if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_SUSPENDED) || + (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) || + (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS)) + { + + /* Thread Suspend error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Make sure that each thread has run once. */ + if ((thread_0_counter != 1) || (thread_1_counter != 1) || + (thread_2_counter != 1) || (thread_3_counter != 1) || + (thread_4_counter != 1)) + { + + /* Thread Suspend error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + status = tx_thread_resume(&thread_1); + + /* Determine if all the other threads are in the proper state. */ + if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_READY) || + (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) || + (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS)) + { + + /* Thread Suspend error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Make sure that each thread has run once. */ + if ((thread_0_counter != 1) || (thread_1_counter != 1) || + (thread_2_counter != 1) || (thread_3_counter != 1) || + (thread_4_counter != 1)) + { + + /* Thread Suspend error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + status = tx_thread_resume(&thread_2); + + /* Determine if all the other threads are in the proper state. */ + if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_READY) || + (thread_2.tx_thread_state != TX_READY) || (thread_3.tx_thread_state != TX_SUSPENDED) || + (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS)) + { + + /* Thread Suspend error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Make sure that each thread has run once. */ + if ((thread_0_counter != 1) || (thread_1_counter != 1) || + (thread_2_counter != 1) || (thread_3_counter != 1) || + (thread_4_counter != 1)) + { + + /* Thread Suspend error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + status = tx_thread_resume(&thread_3); + + /* Determine if all the other threads are in the proper state. */ + if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_READY) || + (thread_2.tx_thread_state != TX_READY) || (thread_3.tx_thread_state != TX_READY) || + (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS)) + { + + /* Thread Suspend error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Make sure that each thread has run once. */ + if ((thread_0_counter != 1) || (thread_1_counter != 1) || + (thread_2_counter != 1) || (thread_3_counter != 1) || + (thread_4_counter != 1)) + { + + /* Thread Suspend error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + status = tx_thread_resume(&thread_4); + + /* Determine if all the other threads are in the proper state. */ + if ((thread_0.tx_thread_state != TX_READY) || (thread_1.tx_thread_state != TX_READY) || + (thread_2.tx_thread_state != TX_READY) || (thread_3.tx_thread_state != TX_READY) || + (thread_4.tx_thread_state != TX_READY) || (status != TX_SUCCESS)) + { + + /* Thread Suspend error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Make sure that each thread has run once. */ + if ((thread_0_counter != 1) || (thread_1_counter != 1) || + (thread_2_counter != 1) || (thread_3_counter != 1) || + (thread_4_counter != 1)) + { + + /* Thread Suspend error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Relinquish to allow other threads to run. */ + tx_thread_relinquish(); + + /* Determine if all the other threads are in a suspended state. */ + if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) || + (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) || + (thread_4.tx_thread_state != TX_SUSPENDED)) + { + + /* Thread Suspend error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Make sure that each thread has run twice. */ + if ((thread_0_counter != 2) || (thread_1_counter != 2) || + (thread_2_counter != 2) || (thread_3_counter != 2) || + (thread_4_counter != 2)) + { + + /* Thread Suspend error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Suspend a thread that is already suspended. */ + status = tx_thread_suspend(&thread_4); + + /* Check for error condition. */ + if (status != TX_SUCCESS) + { + /* Thread Suspend error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + else + { + + /* Increment thread 5 counter. */ + thread_5_counter++; + + /* Successful Thread Suspend test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + diff --git a/test/smp/regression/threadx_thread_multiple_time_slice_test.c b/test/smp/regression/threadx_thread_multiple_time_slice_test.c new file mode 100644 index 00000000..6e1f61fd --- /dev/null +++ b/test/smp/regression/threadx_thread_multiple_time_slice_test.c @@ -0,0 +1,269 @@ +/* This test is designed to see if two threads can be created and execute with a time-slice. + Thread 7 should run twice as long because it has more of a time-slice. */ + +#include +#include "tx_api.h" + +static volatile unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static volatile unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; +static volatile unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD +static volatile unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; +static volatile unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; +#endif + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +#endif + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_multiple_time_slice_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 2, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 4, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #2\n"); + test_control_return(1); + } + + /* Create control thread. */ + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #3\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD + + /* Create threads with preemption-threshold and time-slice, such and make sure time-slice is defeated by + preemption-threshold. */ + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 17, 2, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, 4, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Multiple Thread Time-Slice Test...................... ERROR #5\n"); + test_control_return(1); + } +#endif +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Call thread identify for Win32 test case. */ + tx_thread_identify(); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 1 counter. */ + thread_1_counter++; + + /* Call thread identify for Win32 test case. */ + tx_thread_identify(); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +unsigned long counter_sum; +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD +UINT status; +#endif + + + /* Inform user. */ + printf("Running Thread Multiple Thread Time-Slice Test...................... "); + + /* Sleep for some multiple of 6. */ + tx_thread_sleep(48); + + /* Increment thread 2 counter. */ + thread_2_counter++; + + /* Compute the delta. Should be twice as much, but some test environments (Windows/Linux) are + not as good in terms of real time processing. */ + counter_sum = thread_0_counter; + counter_sum = counter_sum + (thread_0_counter/4); + if (thread_1_counter <= counter_sum) + { + + /* Thread Time-slice error. */ + printf("ERROR #6\n"); + test_control_return(1); + } +#ifdef TX_DISABLE_PREEMPTION_THRESHOLD + else + { + /* Successful Thread Time-slice test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +#else + /* Now suspend threads 0 and 1 so we can let 3 and 4 run. */ + status = tx_thread_suspend(&thread_0); + status += tx_thread_suspend(&thread_1); + + /* Check status. */ + if (status) + { + /* Thread Time-slice error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Now sleep and see if thread 4 ever runs. */ + tx_thread_sleep(4); + + /* Determine if thread 3 ran and thread 4 didn't. */ + if ((thread_3_counter) && (thread_4_counter == 0)) + { + /* Successful Thread Time-slice test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } + else + { + + /* Thread Time-slice error. */ + printf("ERROR #8\n"); + test_control_return(1); + } +#endif +} + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD + +/* Define the test threads. */ + +static void thread_3_entry(ULONG thread_input) +{ + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 3 counter. */ + thread_3_counter++; + + /* Call thread identify for Win32 test case. */ + tx_thread_identify(); + } +} + + +static void thread_4_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* We should never get here! */ + + /* Increment thread 4 counter. */ + thread_4_counter++; + + /* Call thread identify for Win32 test case. */ + tx_thread_identify(); + } +} +#endif + diff --git a/test/smp/regression/threadx_thread_preemptable_suspension_test.c b/test/smp/regression/threadx_thread_preemptable_suspension_test.c new file mode 100644 index 00000000..b1c1bc52 --- /dev/null +++ b/test/smp/regression/threadx_thread_preemptable_suspension_test.c @@ -0,0 +1,416 @@ +/* This test is designed to see if multiple threads can be created and suspended. + The order the suspension and resumption occurs makes sure everything is working right. + All the counters should increment at the same rate. This test differs from test 4 in + that thread 5 is preemptable. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + +static unsigned long thread_5_counter = 0; +static TX_THREAD thread_5; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_preemptable_suspension_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + /* Create thread 0. */ + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 13, 13, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #1\n"); + test_control_return(1); + } + + /* Create thread 1. */ + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #2\n"); + test_control_return(1); + } + + /* Create thread 2. */ + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #3\n"); + test_control_return(1); + } + + /* Create thread 3. */ + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #4\n"); + test_control_return(1); + } + + /* Create thread 4. */ + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #5\n"); + test_control_return(1); + } + + /* Create thread 5. Make this thread fully preemptable... */ + status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Suspend/Resume W/Preemption Test..................... ERROR #6\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Suspend this thread... */ + tx_thread_suspend(&thread_0); + + /* Resume thread 5... */ + tx_thread_resume(&thread_5); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 1 counter. */ + thread_1_counter++; + + /* Suspend this thread. */ + tx_thread_suspend(&thread_1); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 2 counter. */ + thread_2_counter++; + + /* Suspend this thread. */ + tx_thread_suspend(&thread_2); + } +} + +static void thread_3_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 3 counter. */ + thread_3_counter++; + + /* Suspend this thread. */ + tx_thread_suspend(&thread_3); + } +} + +static void thread_4_entry(ULONG thread_input) +{ + + + /* Enter into a forever loop. */ + while(1) + { + + /* Increment thread 4 counter. */ + thread_4_counter++; + + /* Suspend this thread. */ + tx_thread_suspend(&thread_4); + } +} + +static void thread_5_entry(ULONG thread_input) +{ + +UINT status; + + /* Inform user. */ + printf("Running Thread Suspend/Resume W/Preemption Test..................... "); + + /* Determine if all the other threads are in a suspended state. */ + if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) || + (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) || + (thread_4.tx_thread_state != TX_SUSPENDED)) + { + + /* Thread Suspend error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Make sure that each thread has run once. */ + if ((thread_0_counter != 1) || (thread_1_counter != 1) || + (thread_2_counter != 1) || (thread_3_counter != 1) || + (thread_4_counter != 1)) + { + + /* Thread Suspend error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Resume all of the threads. */ + status = tx_thread_resume(&thread_0); + + /* Determine if all the other threads are in the proper state. */ + if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) || + (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) || + (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS)) + { + + /* Thread Suspend error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Make sure that each thread has run the proper amount. */ + if ((thread_0_counter != 2) || (thread_1_counter != 1) || + (thread_2_counter != 1) || (thread_3_counter != 1) || + (thread_4_counter != 1)) + { + + /* Thread Suspend error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + status = tx_thread_resume(&thread_1); + + /* Determine if all the other threads are in the proper state. */ + if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) || + (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) || + (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS)) + { + + /* Thread Suspend error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Make sure that each thread has run the proper amount. */ + if ((thread_0_counter != 2) || (thread_1_counter != 2) || + (thread_2_counter != 1) || (thread_3_counter != 1) || + (thread_4_counter != 1)) + { + + /* Thread Suspend error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + status = tx_thread_resume(&thread_2); + + /* Determine if all the other threads are in the proper state. */ + if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) || + (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) || + (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS)) + { + + /* Thread Suspend error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Make sure that each thread has the proper amount. */ + if ((thread_0_counter != 2) || (thread_1_counter != 2) || + (thread_2_counter != 2) || (thread_3_counter != 1) || + (thread_4_counter != 1)) + { + + /* Thread Suspend error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + status = tx_thread_resume(&thread_3); + + /* Determine if all the other threads are in the proper state. */ + if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) || + (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) || + (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS)) + { + + /* Thread Suspend error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Make sure that each thread has run the proper amount. */ + if ((thread_0_counter != 2) || (thread_1_counter != 2) || + (thread_2_counter != 2) || (thread_3_counter != 2) || + (thread_4_counter != 1)) + { + + /* Thread Suspend error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + status = tx_thread_resume(&thread_4); + + /* Determine if all the other threads are in the proper state. */ + if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) || + (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) || + (thread_4.tx_thread_state != TX_SUSPENDED) || (status != TX_SUCCESS)) + { + + /* Thread Suspend error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Make sure that each thread has run once. */ + if ((thread_0_counter != 2) || (thread_1_counter != 2) || + (thread_2_counter != 2) || (thread_3_counter != 2) || + (thread_4_counter != 2)) + { + + /* Thread Suspend error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Relinquish - this should not do anything! */ + tx_thread_relinquish(); + + /* Determine if all the other threads are in a suspended state. */ + if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_1.tx_thread_state != TX_SUSPENDED) || + (thread_2.tx_thread_state != TX_SUSPENDED) || (thread_3.tx_thread_state != TX_SUSPENDED) || + (thread_4.tx_thread_state != TX_SUSPENDED)) + { + + /* Thread Suspend error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Make sure that each thread has run twice. */ + if ((thread_0_counter != 2) || (thread_1_counter != 2) || + (thread_2_counter != 2) || (thread_3_counter != 2) || + (thread_4_counter != 2)) + { + + /* Thread Suspend error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Increment thread 5 counter. */ + thread_5_counter++; + + /* Successful Thread Suspend test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} diff --git a/test/smp/regression/threadx_thread_preemption_change_test.c b/test/smp/regression/threadx_thread_preemption_change_test.c new file mode 100644 index 00000000..a16b2633 --- /dev/null +++ b/test/smp/regression/threadx_thread_preemption_change_test.c @@ -0,0 +1,379 @@ +/* This test is designed to test the change preemption service call. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" +#include "tx_initialize.h" + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD +static unsigned long thread_0_counter = 0; +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static TX_MUTEX mutex_0; +#endif + +static TX_THREAD thread_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_preemption_change_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 15, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Preemption Change Test............................... ERROR #1\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */ + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Preemption Change Test............................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 14, 14, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Preemption Change Test............................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_mutex_create(&mutex_0, "mutex 0", TX_INHERIT); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Preemption Change Test............................... ERROR #4\n"); + test_control_return(1); + } +#endif +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD +UINT old_threshold; +UINT status; +UINT i; +#endif + + + /* Inform user. */ + printf("Running Thread Preemption Change Test............................... "); + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */ + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Resume thread 1, which has a higher priority. Preemption is disabled + though so thread 1 should not run yet. */ + status = tx_thread_resume(&thread_1); + + /* Check status and run counters of other threads. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_2_counter != 0)) + { + + /* Thread error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Change the preemption-threshold such that thread 1 doesn't run yet... just for code coverage. */ + status = tx_thread_preemption_change(&thread_0, 15, &old_threshold); + + /* Change the preemption threshold. This should cause thread 1 to execute! */ + status += tx_thread_preemption_change(&thread_0, 16, &old_threshold); + + /* Check status and run counters of other threads. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) || + (old_threshold != 15)) + { + + /* Thread error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Change the preemption threshold of another thread. */ + status = tx_thread_preemption_change(&thread_2, 11, &old_threshold); + + /* Check status and run counters of other threads. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) || + (old_threshold != 14)) + { + + /* Thread error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Change the preemption threshold back to 15. */ + status = tx_thread_preemption_change(&thread_0, 15, &old_threshold); + + /* Check status and run counters of other threads. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) || + (old_threshold != 16)) + { + + /* Thread error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Resume thread 2. This should preempt because it is priority 14 and the + current preemption threshold is 15. */ + status = tx_thread_resume(&thread_2); + + /* Check status and run counters of other threads. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1)) + { + + /* Thread error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* At this point, we are going to loop through preemption changes that result in + preemption. */ + for (i = 0; i < (TX_THREAD_EXECUTE_LOG_SIZE*3); i++) + { + + /* Change the preemption threshold back to 14. */ + status = tx_thread_preemption_change(&thread_0, 14, &old_threshold); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Thread error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Resume thread 2 again. */ + status = tx_thread_resume(&thread_2); + + /* Check status an thread 2 run counter. */ + if ((status != TX_SUCCESS) && (thread_2_counter != (i+1))) + { + + /* Thread error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Change the preemption threshold back to 15 to allow thread 2 to run. */ + status = tx_thread_preemption_change(&thread_0, 15, &old_threshold); + + /* Check status an thread 2 run counter. */ + if ((status != TX_SUCCESS) && (thread_2_counter != (i+2))) + { + + /* Thread error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + } + + /* Change the priority of threads 0 and 1. */ + status = tx_thread_priority_change(&thread_0, 7, &old_threshold); + status += tx_thread_priority_change(&thread_1, 5, &old_threshold); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Thread error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Change the preemption-threshold of this thread. */ + status = tx_thread_preemption_change(&thread_0, 0, &old_threshold); + + /* Check status. */ + if ((status != TX_SUCCESS) || (old_threshold != 7)) + { + + /* Thread error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Get the mutex that has priority inheritance. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Thread error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Resume thread 1 so that it can suspend on the mutex and automatically raise its priority. */ + tx_thread_resume(&thread_1); + + /* Self suspend so that thread 1 and run. */ + tx_thread_suspend(&thread_0); + + /* Restore the preemption-threshold of this thread. */ + status = tx_thread_preemption_change(&thread_0, old_threshold, &old_threshold); + + /* Check status. */ + if ((status != TX_SUCCESS) || (old_threshold != 0) || (thread_0.tx_thread_priority != 5) || (thread_0.tx_thread_preempt_threshold != 5)) + { + + /* Thread error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Ensure thread 0's entries in these lists were removed. */ + if (_tx_thread_preempted_maps[0] != 0 || + _tx_thread_preemption_threshold_list[5] != TX_NULL) + { + + /* Thread error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Let thread 1 run again so it can release the mutex and undo the priority inheritance. */ + status = tx_mutex_put(&mutex_0); + + /* Check status. */ + if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 7) || (thread_0.tx_thread_preempt_threshold != 7)) + { + + /* Thread error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Test direct call to the thread preemption change routine with a threshold greater than the current priority. */ + status = _tx_thread_preemption_change(&thread_0, 8, &old_threshold); + + /* Check status. */ + if (status != TX_THRESH_ERROR) + { + + /* Thread error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + +#endif + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + +} + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD +static void thread_1_entry(ULONG thread_input) +{ + +UINT old_threshold; + + /* Hit branch in _tx_thread_preemption_change where preemption-threshold is being disabled + but the thread doesn't have preemption-threshold. */ + tx_thread_preemption_change(&thread_1, 15, &old_threshold); + + /* Self suspend after initial run. */ + tx_thread_suspend(&thread_1); + + /* Increment the thread counter. */ + thread_1_counter++; + + /* Self suspend. */ + tx_thread_suspend(&thread_1); + + /* Resume thread 0. */ + tx_thread_resume(&thread_0); + + /* Get the mutex, which will cause suspension. */ + tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Release the mutex. */ + tx_mutex_put(&mutex_0); +} + + +static void thread_2_entry(ULONG thread_input) +{ + + while(1) + { + + /* Increment thread counter. */ + thread_2_counter++; + + /* Self suspend. */ + tx_thread_suspend(&thread_2); + } +} +#endif diff --git a/test/smp/regression/threadx_thread_priority_change.c b/test/smp/regression/threadx_thread_priority_change.c new file mode 100644 index 00000000..af65c5e0 --- /dev/null +++ b/test/smp/regression/threadx_thread_priority_change.c @@ -0,0 +1,544 @@ +/* This test is designed to test the change priority service call. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static TX_THREAD thread_3; +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_4; +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_5; +static unsigned long thread_5_counter = 0; +extern UINT priority_change_extension_selection; + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); + + + +extern unsigned long _tx_thread_priority_map; + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + +/* Prototype for internal function. */ +VOID _tx_thread_smp_simple_priority_change(TX_THREAD *thread_ptr,UINT new_priority); + + +/* This test routine is used to get a thread of a non ready state. */ +void suspend_thread(void) +{ + +TX_INTERRUPT_SAVE_AREA + +TX_THREAD *thread_ptr; + + + /* Setup the thread pointer. */ + thread_ptr = &thread_0; + + /* Disable interrupts. */ + TX_DISABLE + + /* Set the state to suspended. */ + thread_ptr -> tx_thread_state = TX_SUSPENDED; + +#ifdef TX_NOT_INTERRUPTABLE + + /* Call actual non-interruptable thread suspension routine. */ + _tx_thread_system_ni_suspend(thread_ptr, ((ULONG) 0)); + + /* Restore interrupts. */ + TX_RESTORE +#else + + /* Set the suspending flag. */ + thread_ptr -> tx_thread_suspending = TX_TRUE; + + /* Setup for no timeout period. */ + thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks = ((ULONG) 0); + + /* Temporarily disable preemption. */ + _tx_thread_preempt_disable++; + + /* Restore interrupts. */ + TX_RESTORE + + /* Call actual thread suspension routine. */ + _tx_thread_system_suspend(thread_ptr); +#endif +} + + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + +UINT saved_preempt_disable; + +#ifndef TX_NOT_INTERRUPTABLE + + /* Determine if we have the interrupt condition we are looking for. */ + if ((thread_3.tx_thread_priority == 6) && + (thread_3.tx_thread_state == TX_READY) && + (_tx_thread_priority_list[6] != &thread_3) && + (thread_3_counter > 100)) + { + + /* Save the preempt disable flag. */ + saved_preempt_disable = _tx_thread_preempt_disable; + + /* Clear the preempt disable flag to ensure the API works correctly. */ + _tx_thread_preempt_disable = 0; + + /* Suspend the thread to generate the condition. */ + tx_thread_suspend(&thread_3); + + /* Restore the preempt disable flag. */ + _tx_thread_preempt_disable = saved_preempt_disable; + + /* Done trying to generate this test condition. */ + test_isr_dispatch = TX_NULL; + } +#else + + /* Can't get the interrupt inside the code wit TX_NOT_INTERRUPTABLE defined, so simply stop after thread_3_counter > 100. */ + if (thread_3_counter > 100) + { + + /* Done trying to generate this test condition. */ + test_isr_dispatch = TX_NULL; + } +#endif +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_priority_change_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Priority Change Test................................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 22, 22, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Priority Change Test................................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 30, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 5, 5, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 6, 6, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + status += tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 15, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Priority Change Test................................. ERROR #3\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +TX_INTERRUPT_SAVE_AREA + +//ULONG current_time; +UINT old_threshold; +UINT old_priority; +UINT status; +TX_THREAD *temp_thread; + + + /* Inform user. */ + printf("Running Thread Priority Change Test................................. "); + + /* Resume thread 3. */ + tx_thread_resume(&thread_3); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Change priority to 22, to match that of the next highest priority ready thread. + This is to test the update of the priority list when a thread is moved to a + priority with already ready threads. */ + status = tx_thread_priority_change(&thread_0, 22, &old_priority); + + /* Check status, return priority, and run count of other thread. */ + if ((status != TX_SUCCESS) || (old_priority != 16) || (thread_1_counter != 0)) + { + + /* Thread error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Restore original priority. */ + tx_thread_priority_change(&thread_0, old_priority, &old_priority); + + /* See if we can change priority of this thread. */ + status = tx_thread_priority_change(&thread_0, 7, &old_priority); + + /* Check status, return priority, and run count of other thread. */ + if ((status != TX_SUCCESS) || (old_priority != 16) || (thread_1_counter != 0)) + { + + /* Thread error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* See if we can change priority of another ready thread. */ + status = tx_thread_priority_change(&thread_1, 21, &old_priority); + + /* Check status, return priority, and run count of other thread. */ + if ((status != TX_SUCCESS) || (old_priority != 22) || (thread_1_counter != 0)) + { + + /* Thread error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* See if we can cause preemption by lowering this thread's priority. */ + status = tx_thread_priority_change(&thread_0, 22, &old_priority); + + /* Check status, return priority, and run count of other thread. */ + if ((status != TX_SUCCESS) || (old_priority != 7) || (thread_1_counter != 1)) + { + + /* Thread error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Thread 1 should have run already... Raise this threads priority + back up. */ + status = tx_thread_priority_change(&thread_0, 8, &old_priority); + + /* Check status, return priority, and run count of other thread. */ + if ((status != TX_SUCCESS) || (old_priority != 22) || (thread_1_counter != 1)) + { + + /* Thread error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* See if we can change the priority of a suspended thread. */ + status = tx_thread_priority_change(&thread_1, 19, &old_priority); + + /* Check status, return priority, and run count of other thread. */ + if ((status != TX_SUCCESS) || (old_priority != 21) || (thread_1_counter != 1)) + { + + /* Thread error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Resume the suspended thread so it is in a ready condition. */ + status = tx_thread_resume(&thread_1); + + /* Check status, return priority, and run count of other thread. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1)) + { + + /* Thread error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Should not have run yet. Raise its priority to 8 still should not run yet! */ + status = tx_thread_priority_change(&thread_1, 8, &old_priority); + + /* Check status, return priority, and run count of other thread. */ + if ((status != TX_SUCCESS) || (old_priority != 19) || (thread_1_counter != 1)) + { + + /* Thread error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Raise its priority to 7, now it should run. */ + status = tx_thread_priority_change(&thread_1, 7, &old_priority); + + /* Check status, return priority, and run count of other thread. */ + if ((status != TX_SUCCESS) || (old_priority != 8) || (thread_1_counter != 2) || (thread_2_counter != 0)) + { + + /* Thread error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Now thread 1 should be suspended. Let's change thread 0's priority and make sure thread 2 doesn't run yet! */ + status = tx_thread_priority_change(&thread_0, 7, &old_priority); + + /* Check status, return priority, and run count of other thread. */ + if ((status != TX_SUCCESS) || (old_priority != 8) || (thread_1_counter != 2) || (thread_2_counter != 0)) + { + + /* Thread error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Now resume thread 1, it won't run because it's priority is less than this thread. */ + status = tx_thread_resume(&thread_1); + + /* Change the priority of thread 1 - the non executing thread to test that path. */ + status += tx_thread_priority_change(&thread_1, 23, &old_priority); + + /* Check status, return priority, and run count of other thread. */ + if ((status != TX_SUCCESS) || (old_priority != 7) || (thread_1_counter != 2) || (thread_2_counter != 0)) + { + + /* Thread error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_PREEMPTION_THRESHOLD + /* Now setup the preemption-threshold for thread 1. */ + status = tx_thread_preemption_change(&thread_1, 14, &old_threshold); + + /* Check status, return priority, and run count of other thread. */ + if ((status != TX_SUCCESS) || (old_threshold != 23) || (thread_1_counter != 2) || (thread_2_counter != 0)) + { + + /* Thread error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Resume a higher priority preemption-threshold thread. */ + status = tx_thread_resume(&thread_5); + + /* Now lower this thread's priority. */ + status += tx_thread_priority_change(&thread_0, 15, &old_priority); + + /* Check status, return priority, and run count of other thread. */ + if ((status != TX_SUCCESS) || (old_priority != 7) || (thread_1_counter != 2) || (thread_2_counter != 0) || (thread_5_counter != 0)) + { + + /* Thread error. */ + printf("ERROR #15\n"); + test_control_return(1); + } +#endif + + /* Change to a higher priority. */ + tx_thread_priority_change(&thread_0, 7, &old_priority); + + /* Disable interrupts. */ + TX_DISABLE + + /* Simulate a call from inside of mutex put, but doing it here makes life easier. */ + _tx_thread_preempt_disable++; + + /* Suspend thread 0. */ + suspend_thread(); + + /* Resume thread 0. */ + tx_thread_resume(&thread_0); + + /* Change priority to get avoid the reset of the priority list. */ + tx_thread_priority_change(&thread_0, 16, &old_priority); + + /* Move the priority back so we have some room to test. */ + tx_thread_priority_change(&thread_0, 7, &old_priority); + + /* Now create the invalid core index situation. */ + priority_change_extension_selection = 1; + tx_thread_priority_change(&thread_0, 8, &old_priority); + thread_0.tx_thread_smp_core_mapped = 0; + + /* Now fiddle with the original priority to satisfy that branch. */ + priority_change_extension_selection = 2; + tx_thread_priority_change(&thread_0, 9, &old_priority); + _tx_thread_execute_ptr[0] = &thread_0; + + /* Create the condition where original pt thread is same as the current thread. */ + temp_thread = _tx_thread_preemption__threshold_scheduled; + priority_change_extension_selection = 3; + tx_thread_priority_change(&thread_0, 15, &old_priority); + _tx_thread_preemption__threshold_scheduled = temp_thread; + + /* Move the thread back to a higher priority. */ + tx_thread_priority_change(&thread_0, 7, &old_priority); + + /* Create the condition where the new thread is NULL. */ + temp_thread = _tx_thread_preemption__threshold_scheduled; + priority_change_extension_selection = 4; + tx_thread_priority_change(&thread_0, 15, &old_priority); + _tx_thread_preemption__threshold_scheduled = temp_thread; + + /* Decrement the preempt disable count. */ + _tx_thread_preempt_disable--; + + /* Restore interrupts. */ + TX_RESTORE + + /* Hit branch in _tx_thread_smp_simple_priority_change such that the + new priority is less than the inheritance priority. */ + thread_0.tx_thread_inherit_priority = 0; + _tx_thread_smp_simple_priority_change(&thread_0, 16); + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +static void thread_1_entry(ULONG thread_input) +{ + + while(1) + { + + /* Increment the thread counter. */ + thread_1_counter++; + + /* Suspend self and wait for upper thread to resume. */ + tx_thread_suspend(&thread_1); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + + while(1) + { + + /* This thread should never run! */ + + /* Increment the thread counter. */ + thread_2_counter++; + + /* Self suspend. */ + tx_thread_suspend(&thread_2); + } +} + + +static void thread_3_entry(ULONG thread_input) +{ + +UINT old_priority; +UINT loop; + + + /* Resume threads 4. */ + tx_thread_resume(&thread_4); + + /* Setup the ISR. */ + test_isr_dispatch = test_isr; + do + { + + loop = rand() % 100; + while (loop--) + { + thread_3_counter++; + } + + /* Raise priority of thread 3 for code coverage. */ + tx_thread_priority_change(&thread_3, 6, &old_priority); + tx_thread_priority_change(&thread_3, 5, &old_priority); + + /* Check to see if thread 4 has run... it should not have executed + yet. If it does, set the thread_1_counter to indicate an error! */ + if (thread_4_counter) + thread_1_counter++; + + } while (test_isr_dispatch); +} + + +static void thread_4_entry(ULONG thread_input) +{ + thread_4_counter++; +} + + +static void thread_5_entry(ULONG thread_input) +{ + thread_5_counter++; +} + + diff --git a/test/smp/regression/threadx_thread_relinquish_test.c b/test/smp/regression/threadx_thread_relinquish_test.c new file mode 100644 index 00000000..2a48717b --- /dev/null +++ b/test/smp/regression/threadx_thread_relinquish_test.c @@ -0,0 +1,459 @@ +/* This test is designed to see if multiple threads can be created and relinquish control between them. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static unsigned long thread_3_counter = 0; +static TX_THREAD thread_3; + +static unsigned long thread_4_counter = 0; +static TX_THREAD thread_4; + +static unsigned long thread_5_counter = 0; +static TX_THREAD thread_5; + +static unsigned long thread_6_counter = 0; +static TX_THREAD thread_6; + +static unsigned long thread_7_counter = 0; +static TX_THREAD thread_7; + +static unsigned long thread_8_counter = 0; +static TX_THREAD thread_8; + +static unsigned long thread_9_counter = 0; +static TX_THREAD thread_9; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_4_entry(ULONG thread_input); +static void thread_5_entry(ULONG thread_input); +static void thread_6_entry(ULONG thread_input); +static void thread_7_entry(ULONG thread_input); +static void thread_8_entry(ULONG thread_input); +static void thread_9_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_relinquish_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + /* Create thread 0. */ + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Relinquish Test...................................... ERROR #1\n"); + test_control_return(1); + } + + /* Create thread 1. */ + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Relinquish Test...................................... ERROR #2\n"); + test_control_return(1); + } + + /* Create thread 2. */ + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Relinquish Test...................................... ERROR #3\n"); + test_control_return(1); + } + + /* Create thread 3. */ + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Relinquish Test...................................... ERROR #4\n"); + test_control_return(1); + } + + /* Create thread 4. */ + status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Relinquish Test...................................... ERROR #5\n"); + test_control_return(1); + } + + /* Create thread 5. */ + status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 15, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Relinquish Test...................................... ERROR #6\n"); + test_control_return(1); + } + + /* Create thread 6. */ + status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Relinquish Test...................................... ERROR #7\n"); + test_control_return(1); + } + + /* Create thread 7. */ + status = tx_thread_create(&thread_7, "thread 7", thread_7_entry, 7, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Relinquish Test...................................... ERROR #8\n"); + test_control_return(1); + } + + /* Create thread 8. */ + status = tx_thread_create(&thread_8, "thread 8", thread_8_entry, 8, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Relinquish Test...................................... ERROR #9\n"); + test_control_return(1); + } + + /* Create thread 9. */ + status = tx_thread_create(&thread_9, "thread 9", thread_9_entry, 9, + pointer, TEST_STACK_SIZE_PRINTF, + 31, 31, 1, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Relinquish Test...................................... ERROR #10\n"); + test_control_return(1); + } +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + /* Check for correct input value and execution of other threads. */ + if ((thread_input != 0) || (thread_1_counter) || (thread_2_counter) || + (thread_3_counter)) + return; + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Relinquish to other thread(s). */ + tx_thread_relinquish(); +} + + +static void thread_1_entry(ULONG thread_input) +{ + + /* Check for correct input value and execution of other threads. */ + if ((thread_input != 1) || (thread_0_counter != 1) || (thread_2_counter) || + (thread_3_counter)) + return; + + /* Increment thread 1 counter. */ + thread_1_counter++; + + /* Relinquish to other thread(s). */ + tx_thread_relinquish(); +} + + +static void thread_2_entry(ULONG thread_input) +{ + + /* Check for correct input value and execution of other threads. */ + if ((thread_input != 2) || (thread_0_counter != 1) || (thread_1_counter != 1) || + (thread_3_counter)) + return; + + /* Increment thread 2 counter. */ + thread_2_counter++; + + /* Relinquish to other thread(s). */ + tx_thread_relinquish(); +} + + +static void thread_3_entry(ULONG thread_input) +{ + +UINT status; +UINT old_threshold; +UINT old_priority; + + + /* Inform user. */ + printf("Running Thread Relinquish Test...................................... "); + + /* Check for correct input value and execution of other threads. */ + if ((thread_input != 3) || (thread_0_counter != 1) || (thread_1_counter != 1) || + (thread_2_counter != 1) || (thread_0.tx_thread_state != TX_READY) || + (thread_1.tx_thread_state != TX_READY) || (thread_2.tx_thread_state != TX_READY)) + { + + /* Thread Relinquish error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Increment thread 3 counter. */ + thread_3_counter++; + + /* Immediate response relinquish. */ + tx_thread_relinquish(); + + /* All other threads should be completed now. */ + if ((thread_0.tx_thread_state != TX_COMPLETED) || (thread_1.tx_thread_state != TX_COMPLETED) || + (thread_2.tx_thread_state != TX_COMPLETED)) + { + + /* Thread Relinquish error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Execute immediate response relinquish. */ + tx_thread_relinquish(); + + /* Move to the lowest default priority. */ + status = tx_thread_priority_change(&thread_3, 31, &old_priority); + + /* Temporarily make enable preemption-threshold with this thread. */ + status += tx_thread_preemption_change(&thread_3, 3, &old_threshold); + + /* Execute immediate response, bypassing the error checking. */ + _tx_thread_preemption__threshold_scheduled = TX_NULL; + _tx_thread_relinquish(); + + /* Restore the preemtion-threshold and priority. */ + status += tx_thread_preemption_change(&thread_3, old_threshold, &old_threshold); + + /* Enable all cores for all threads. */ + status += tx_thread_smp_core_exclude(&thread_4, 0); + status += tx_thread_smp_core_exclude(&thread_5, 0); + status += tx_thread_smp_core_exclude(&thread_6, 0); + status += tx_thread_smp_core_exclude(&thread_7, 0); + status += tx_thread_smp_core_exclude(&thread_8, 0); + status += tx_thread_smp_core_exclude(&thread_9, 0); + + /* Now lets resume threads 4 through 9. Thread 5 has preemption-threshold set which will excercise + the preemption-threshold logic. */ + status += tx_thread_resume(&thread_4); + status += tx_thread_resume(&thread_5); + status += tx_thread_resume(&thread_6); + status += tx_thread_resume(&thread_7); + status += tx_thread_resume(&thread_8); + status += tx_thread_resume(&thread_9); + + /* Now relinquish to let these other threads run. */ + tx_thread_relinquish(); + + /* Sleep for 20 ticks to test the paths. */ + tx_thread_sleep(20); + + /* Now see if the results are as expected. */ + if (status != TX_SUCCESS) + { + + /* Thread Relinquish error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Successful thread relinquish test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_4_entry(ULONG thread_input) +{ + + /* Loop to test relinquish. */ + while(1) + { + + /* Increment thread 2 counter. */ + thread_4_counter++; + + /* Relinquish to other thread(s). */ + tx_thread_relinquish(); + } +} + + +static void thread_5_entry(ULONG thread_input) +{ + + + /* Loop to test relinquish. */ + while(1) + { + + /* Increment thread 2 counter. */ + thread_5_counter++; + + /* Relinquish to other thread(s). */ + tx_thread_relinquish(); + } +} + + +static void thread_6_entry(ULONG thread_input) +{ + + + /* Loop to test relinquish. */ + while(1) + { + + /* Increment thread 2 counter. */ + thread_6_counter++; + + /* Relinquish to other thread(s). */ + tx_thread_relinquish(); + } +} + + +static void thread_7_entry(ULONG thread_input) +{ + + + /* Loop to test relinquish. */ + while(1) + { + + /* Increment thread 2 counter. */ + thread_7_counter++; + + /* Relinquish to other thread(s). */ + tx_thread_relinquish(); + } +} + + +static void thread_8_entry(ULONG thread_input) +{ + + + /* Loop to test relinquish. */ + while(1) + { + + /* Increment thread 2 counter. */ + thread_8_counter++; + + /* Relinquish to other thread(s). */ + tx_thread_relinquish(); + } +} + + +static void thread_9_entry(ULONG thread_input) +{ + + + /* Loop to test relinquish. */ + while(1) + { + + /* Increment thread 2 counter. */ + thread_9_counter++; + + /* Relinquish to other thread(s). */ + tx_thread_relinquish(); + } +} + + diff --git a/test/smp/regression/threadx_thread_reset_test.c b/test/smp/regression/threadx_thread_reset_test.c new file mode 100644 index 00000000..ff3531a5 --- /dev/null +++ b/test/smp/regression/threadx_thread_reset_test.c @@ -0,0 +1,248 @@ +/* This test is designed to test the tx_thread_reset function. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" + + +static unsigned long thread_0_counter = 0; +static unsigned long thread_0_enter = 0; +static unsigned long thread_0_exit = 0; +static unsigned long thread_1_counter = 0; +static unsigned long thread_2_counter = 0; + + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; + + +/* Define task prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void entry_exit_notify(TX_THREAD *thread_ptr, UINT type) +{ + + /* Check for the appropriate thread. */ + if (thread_ptr != &thread_0) + return; + + /* Check for type. */ + if (type == TX_THREAD_ENTRY) + thread_0_enter++; + else if (type == TX_THREAD_EXIT) + thread_0_exit++; +} + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_reset_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Setup the notify call to test that logic. */ + status += tx_thread_entry_exit_notify(&thread_0, entry_exit_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Reset Test........................................... ERROR #1\n"); + test_control_return(1); + } + +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Thread Reset Test........................................... ERROR #2\n"); + test_control_return(1); + } + +#endif + + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Reset Test........................................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Reset Test........................................... ERROR #4\n"); + test_control_return(1); + } +} + + + +/* Define the test thread. */ + +static void thread_0_entry(ULONG thread_input) +{ + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Fall through to the return in order to place the thread in a finished + state. */ +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Thread Reset Test........................................... "); + + /* Increment thread 1 counter. */ + thread_1_counter++; + + /* Attempt to delete thread 2, which is in the wrong stat for deleting. */ + status = tx_thread_delete(&thread_2); + + /* Check for the proper status. */ + if (status != TX_DELETE_ERROR) + { + + /* Thread delete error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Determine if the first Thread has run and if it's current state is + finished. */ + if ((thread_0.tx_thread_state != TX_COMPLETED) || (thread_0_counter != 1) || +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + (thread_0_enter != 1) || (thread_0_exit != 1) || (thread_2_counter != 0)) +#else + (thread_0_enter != 0) || (thread_0_exit != 0) || (thread_2_counter != 0)) +#endif + { + + /* Thread reset error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Call thread reset on thread 2, which should result in an error. */ + status = tx_thread_reset(&thread_2); + + /* Check for proper status. */ + if (status != TX_NOT_DONE) + { + + /* Thread reset error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Now call the thread reset function on thread 0. */ + status = tx_thread_reset(&thread_0); + + /* Determine if the first Thread has been reset but not executed. */ + if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_0_counter != 1) || +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + (thread_0_enter != 1) || (thread_0_exit != 1) || (thread_2_counter != 0)) +#else + (thread_0_enter != 0) || (thread_0_exit != 0) || (thread_2_counter != 0)) +#endif + { + + /* Thread reset error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Terminate thread 0. */ + status = tx_thread_terminate(&thread_0); + status += tx_thread_reset(&thread_0); + + + /* Now resume thread 0 to let it run. */ + status += tx_thread_resume(&thread_0); + + /* Determine if the first Thread has run and if it's current state is + finished. */ + if ((thread_0.tx_thread_state != TX_COMPLETED) || (thread_0_counter != 2) || +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + (thread_0_enter != 2) || (thread_0_exit != 3) || (thread_2_counter != 0)) +#else + (thread_0_enter != 0) || (thread_0_exit != 0) || (thread_2_counter != 0)) +#endif + { + + /* Thread reset error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + else + { + + + /* Successful thread finish test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + + /* Increment thread 2 counter. */ + thread_2_counter++; + + /* Fall through to the return in order to place the thread in a finished + state. */ +} diff --git a/test/smp/regression/threadx_thread_simple_sleep_non_clear_test.c b/test/smp/regression/threadx_thread_simple_sleep_non_clear_test.c new file mode 100644 index 00000000..5713e41d --- /dev/null +++ b/test/smp/regression/threadx_thread_simple_sleep_non_clear_test.c @@ -0,0 +1,90 @@ +/* This test is designed to test a simple sleep for 18 ticks, with something in the + remaining field of the thread control block. */ + +#include +#include "tx_api.h" + +//static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_simple_sleep_non_clear_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Place a 1 in the thread control block to simulate a control block created in + random memory. */ + thread_0.tx_thread_timer.tx_timer_internal_re_initialize_ticks = 1; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 3, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Sleep with non-zero TX_THREAD........................ ERROR #1\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + + /* Inform user. */ + printf("Running Thread Sleep with non-zero TX_THREAD........................ "); + + /* Clear the tick count. */ + tx_time_set(0); + + /* Sleep for 18 ticks. */ + tx_thread_sleep(9); + tx_thread_sleep(9); + + /* Determine if the sleep was accurate. */ + if ((tx_time_get() == 18) || + (tx_time_get() == 19)) + { + + /* Successful Simple Sleep test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } + else + { + + /* Thread Simple Sleep error. */ + printf("ERROR #2\n"); + test_control_return(1); + } +} + diff --git a/test/smp/regression/threadx_thread_simple_sleep_test.c b/test/smp/regression/threadx_thread_simple_sleep_test.c new file mode 100644 index 00000000..b87bd82d --- /dev/null +++ b/test/smp/regression/threadx_thread_simple_sleep_test.c @@ -0,0 +1,85 @@ +/* This test is designed to test a simple sleep for 18 ticks. */ + +#include +#include "tx_api.h" + +//static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_simple_sleep_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 3, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Simple Sleep for 18 Ticks Test....................... ERROR #1\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + + /* Inform user. */ + printf("Running Thread Simple Sleep for 18 Ticks Test....................... "); + + /* Clear the tick count. */ + tx_time_set(0); + + /* Sleep for 18 ticks. */ + tx_thread_sleep(18); + + /* Determine if the sleep was accurate. */ + if ((tx_time_get() == 18) || + (tx_time_get() == 19)) + { + + /* Successful Simple Sleep test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } + else + { + + /* Thread Simple Sleep error. */ + printf("ERROR #2\n"); + test_control_return(1); + } +} + diff --git a/test/smp/regression/threadx_thread_simple_suspend_test.c b/test/smp/regression/threadx_thread_simple_suspend_test.c new file mode 100644 index 00000000..52215a75 --- /dev/null +++ b/test/smp/regression/threadx_thread_simple_suspend_test.c @@ -0,0 +1,116 @@ +/* This test is designed to see if a thread can successfully suspend itself in a single + thread system. This also tests a thread created that is not automatically enabled. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static TX_THREAD thread_1; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_simple_supsend_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Simple Suspend Test.................................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Simple Suspend Test.................................. ERROR #2\n"); + test_control_return(1); + } +} + + + +/* Define the test thread. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Resume the test control thread. */ + status = tx_thread_resume(&thread_1); + + /* Check status. */ + if (status != TX_SUCCESS) + return; + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Suspend the running thread. */ + tx_thread_suspend(&thread_0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + + /* Inform user. */ + printf("Running Thread Simple Suspend Test.................................. "); + + /* The other thread should be in a suspended state now. */ + if ((thread_0.tx_thread_state != TX_SUSPENDED) || (thread_0_counter != 1)) + { + + /* Thread Suspend error. */ + printf("ERROR #3\n"); + test_control_return(1); + } + else + { + + /* Successful Thread Suspend test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + diff --git a/test/smp/regression/threadx_thread_sleep_for_100ticks_test.c b/test/smp/regression/threadx_thread_sleep_for_100ticks_test.c new file mode 100644 index 00000000..69eadbc6 --- /dev/null +++ b/test/smp/regression/threadx_thread_sleep_for_100ticks_test.c @@ -0,0 +1,435 @@ +/* This test is designed to test a simple sleep for 100 ticks. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" +#include "tx_timer.h" + +//#define DEBUG + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + + +static TX_THREAD thread_0; + +static int error = 0; + +static int isr_count = 0; + +#ifdef TEST_INTERRUPT_CONDITION +#ifndef TX_NOT_INTERRUPTABLE + +#if defined(TX_WIN32_MEMORY_SIZE) || defined(TX_LINUX_MEMORY_SIZE) +/* Use larger array size when running on Win32 test platform because of greater speed. */ +#define ARRAY_SIZE 100 +#else +#define ARRAY_SIZE 10 +#endif + + +static UINT isr_test_suspend_interrupt = TX_TRUE; +static UINT isr_test_suspend_interrupted_condition = TX_FALSE; +static ULONG min_loop_count; +static ULONG max_loop_count; +static TX_SEMAPHORE test_semaphore; +static ULONG loop_count; +static volatile ULONG count; +static volatile ULONG destination = 0; +static ULONG array_delay[ARRAY_SIZE]; +static ULONG start_time; +static ULONG lower_bound; +static ULONG upper_bound; +static ULONG current_itterations; +#ifdef DEBUG_1 +static ULONG last_loop_count; +#endif +static ULONG delay_function(void) +{ + +ULONG accumulator; +ULONG i; + + for (i = 0; i < ARRAY_SIZE; i++) + array_delay[i] = i; + + for (i = 0; i < ARRAY_SIZE-4; i++) + { + array_delay[i] = (array_delay[i+1] * array_delay[i+2]) * (array_delay[i+3] * array_delay[i+4]); + } + + accumulator = 0; + for (i = 0; i < ARRAY_SIZE; i++) + accumulator = accumulator + array_delay[i]; + + return(accumulator); +} + +#endif +#endif + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + +UINT status; + +#ifdef TEST_INTERRUPT_CONDITION +#ifndef TX_NOT_INTERRUPTABLE +ULONG i; + + /* Determine if we are in calibration mode. */ + if ((loop_count) && (loop_count != 0xFFFFFFFF)) + { + if (loop_count < min_loop_count) + min_loop_count = loop_count; + if (loop_count > max_loop_count) + max_loop_count = loop_count; + + lower_bound = loop_count - 1; + upper_bound = loop_count + 1; + if (lower_bound < min_loop_count) + lower_bound = min_loop_count; + if (upper_bound > max_loop_count) + lower_bound = max_loop_count; + + if ((current_itterations < lower_bound) || (current_itterations > upper_bound)) + current_itterations = lower_bound; + +#ifdef DEBUG_1 + /* Last loop count. */ + last_loop_count = loop_count; +#endif + + /* Reset the loop count to all ones! */ + loop_count = 0xFFFFFFFF; + } + count++; + for (i = 0; i < (count%32); i++) + destination++; + + /* Determine if the ISR is in the mode to wakeup the thread suspending with a timeout. */ + if (isr_test_suspend_interrupt) + { + + /* Determine if the thread is suspended on the semaphore... */ + if (thread_0.tx_thread_state == TX_SEMAPHORE_SUSP) + { + + /* Determine if the test condition is present... */ + if ((_tx_thread_preempt_disable) && + (thread_0.tx_thread_timer.tx_timer_internal_list_head == TX_NULL)) + { + + /* Set the flag showing the condition is present. */ + isr_test_suspend_interrupted_condition = TX_TRUE; + + /* All done with the test. */ + isr_test_suspend_interrupt = TX_FALSE; + } + + /* Post to the semaphore to wakeup the thread. */ + tx_semaphore_put(&test_semaphore); + } + + return; + } +#endif +#endif + + /* Increment the ISR count. */ + isr_count++; + + /* Call sleep from ISR to check for error! */ + status = tx_thread_sleep(100); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + + error = 1; + } + + /* End the ISR. */ + test_isr_dispatch = TX_NULL; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_sleep_for_100ticks_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 3, TX_AUTO_START); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Sleep for 100 Ticks Test............................. ERROR #1\n"); + test_control_return(1); + } + +#ifdef TEST_INTERRUPT_CONDITION +#ifndef TX_NOT_INTERRUPTABLE + + status = tx_semaphore_create(&test_semaphore, "test semaphore", 0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Sleep for 100 Ticks Test............................. ERROR #2\n"); + test_control_return(1); + } + + min_loop_count = 0xFFFFFFFF; + max_loop_count = 0; + loop_count = 0xFFFFFFFF; + current_itterations = 0; +#ifdef DEBUG_1 + last_loop_count = 0x0; +#endif +#endif +#endif +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +#ifdef TEST_INTERRUPT_CONDITION +#ifndef TX_NOT_INTERRUPTABLE +ULONG i; +volatile ULONG value = 0; +#endif +#endif + + /* Inform user. */ + printf("Running Thread Sleep for 100 Ticks Test............................. "); + + /* Call sleep with an expiration of 0 and test error code. */ + status = tx_thread_sleep(0); + + /* Check error code. */ + if (status != TX_SUCCESS) + { + + /* Thread Simple Sleep error. */ + printf("ERROR #3\n"); + test_control_return(1); + } + +#ifdef TEST_INTERRUPT_CONDITION +#ifndef TX_NOT_INTERRUPTABLE + + + isr_test_suspend_interrupt = TX_TRUE; + isr_test_suspend_interrupted_condition = TX_FALSE; +#endif +#endif + + /* Setup the test ISR. */ + test_isr_dispatch = test_isr; + +#ifdef TEST_INTERRUPT_CONDITION +#ifndef TX_NOT_INTERRUPTABLE + + /* Callibrate the loop count from thread sleep. */ + for (i = 0; i < 180; i++) + { + + /* Sleep to get a fresh time. */ + tx_thread_sleep(1); + + /* Set the loop count to 0 and start counting.... */ + loop_count = 0; + start_time = _tx_timer_system_clock; + do + { + + /* Call delay function. */ + delay_function(); + loop_count++; + } while (start_time == _tx_timer_system_clock); + + /* Wait to reset the loop count. */ + tx_thread_sleep(1); + } + +#if 1 + /* Setup the lower and upper bounds. */ + lower_bound = min_loop_count; + if (lower_bound > 5) + lower_bound = lower_bound - 5; + upper_bound = max_loop_count + 5; +#else + /* Setup the lower and upper bounds. */ + lower_bound = min_loop_count; + upper_bound = max_loop_count; +#endif + + current_itterations = lower_bound; +#ifdef DEBUG + i = 0; +#endif + while (isr_test_suspend_interrupted_condition != TX_TRUE) + { + + /* Sleep to get a frest timer slot. */ + tx_thread_sleep(1); + + /* Loop to delay to next interrupt. */ + loop_count = 0; + start_time = _tx_timer_system_clock; + do + { + /* Call delay function. */ + delay_function(); + loop_count++; + } while (loop_count < current_itterations); + + /* Check for a timer interrupt... if so, just skip the semaphore get. */ + if (start_time != _tx_timer_system_clock) + continue; + + /* Suspend on the semaphore for 20 ticks... */ + tx_semaphore_get(&test_semaphore, 20); + + /* Adjust the current itterations. */ + current_itterations++; + if (current_itterations > upper_bound) + { + if (lower_bound > min_loop_count) + lower_bound--; + if (upper_bound < max_loop_count) + upper_bound++; + current_itterations = lower_bound; + } + + /* Set the tick count simply to use value. */ + tx_time_set(value); +#ifdef DEBUG + /* Debug block. */ + i++; + if ((i % 180) == 0) + { + printf("*** update ***\n"); + if (loop_count == 0xFFFFFFFF) + printf("loop count: NA\n"); + else + printf("loop count: %lu\n", loop_count); + printf("current: %lu\n", current_itterations); + printf("last loop count: %lu\n", last_loop_count); + printf("minimum: %lu\n", min_loop_count); + printf("maximum: %lu\n", max_loop_count); + printf("lower bound: %lu\n", lower_bound); + printf("upper bound: %lu\n", upper_bound); + printf("count: %lu\n", i); + } +#endif + } + +#ifdef DEBUG + /* Debug block */ + printf("*** final ***\n"); + if (loop_count == 0xFFFFFFFF) + printf("loop count: NA\n"); + else + printf("loop count: %lu\n", loop_count); + printf("current: %lu\n", current_itterations); + printf("last loop count: %lu\n", last_loop_count); + printf("minimum: %lu\n", min_loop_count); + printf("maximum: %lu\n", max_loop_count); + printf("lower bound: %lu\n", lower_bound); + printf("upper bound: %lu\n", upper_bound); + printf("count: %lu\n", i); +#endif + + /* Clear the tick count. */ + tx_time_set(0); + + /* Sleep for 100 ticks. */ + tx_thread_sleep(100); + + /* Check for error. */ + if (tx_time_get() < 100) + { + + /* Thread Simple Sleep error. */ + printf("ERROR #4\n"); + test_control_return(1); + } +#endif +#endif + + /* Clear the tick count. */ + tx_time_set(0); + + + /* Sleep for 100 ticks. */ + status = tx_thread_sleep(100); + + /* Determine if the sleep was accurate. */ + if ((status != TX_SUCCESS) || (tx_time_get() < 100) || + (tx_time_get() > 101)) + { + + /* Thread Simple Sleep error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Check to make sure the ISR happened and the proper return value was present. */ + if ((isr_count == 0) || (error)) + { + + /* Thread Simple Sleep error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + else + { + + /* Successful Simple Sleep test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + diff --git a/test/smp/regression/threadx_thread_sleep_terminate_test.c b/test/smp/regression/threadx_thread_sleep_terminate_test.c new file mode 100644 index 00000000..871fc6e2 --- /dev/null +++ b/test/smp/regression/threadx_thread_sleep_terminate_test.c @@ -0,0 +1,187 @@ +/* This test is designed to test thread termination of a thread in a sleep condition. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static unsigned long thread_1_counter = 0; +static unsigned long thread_1_enter = 0; +static unsigned long thread_1_exit = 0; +static TX_THREAD thread_1; + +extern UINT _tx_thread_preempt_disable; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + + +static void entry_exit_notify(TX_THREAD *thread_ptr, UINT type) +{ + + /* Check for the appropriate thread. */ + if (thread_ptr != &thread_1) + return; + + /* Check for type. */ + if (type == TX_THREAD_ENTRY) + thread_1_enter++; + else if (type == TX_THREAD_EXIT) + thread_1_exit++; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_sleep_terminate_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Suspend Terminate Test............................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Suspend Terminate Test............................... ERROR #2\n"); + test_control_return(1); + } + + /* Setup the notify call to test that logic. */ + status += tx_thread_entry_exit_notify(&thread_1, entry_exit_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Suspend Terminate Test............................... ERROR #3\n"); + test_control_return(1); + } + +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Thread Suspend Terminate Test............................... ERROR #4\n"); + test_control_return(1); + } + +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Thread Suspend Terminate Test............................... "); + + /* Increment run counter. */ + thread_0_counter++; + + /* Sleep to allow lower-priority thread 1 to run. */ + tx_thread_sleep(5); + + /* Now terminate thread 1. */ + status = tx_thread_terminate(&thread_1); + + /* Check status. */ + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (_tx_thread_preempt_disable)) + { + + /* Terminate error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Now try to suspend a terminated thread. */ + status = tx_thread_suspend(&thread_1); + + /* Check status. */ + if (status != TX_SUSPEND_ERROR) + { + + /* Suspend error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + + while(1) + { + + /* Increment run counter. */ + thread_1_counter++; + + /* Suspend thread 1. */ + status = tx_thread_sleep(100); + + /* Check status. */ + if (status != TX_SUCCESS) + { + thread_1_counter = 0; /* Make an error! */ + return; + } + } +} + + diff --git a/test/smp/regression/threadx_thread_stack_checking_test.c b/test/smp/regression/threadx_thread_stack_checking_test.c new file mode 100644 index 00000000..3ffe3841 --- /dev/null +++ b/test/smp/regression/threadx_thread_stack_checking_test.c @@ -0,0 +1,224 @@ +/* This test is for the thread stack checking services. */ + +#include +#include "tx_api.h" + + +/* Prototype for direct call. */ + +VOID _tx_thread_stack_analyze(TX_THREAD *thread_ptr); + + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; +static CHAR *thread_2_stack_start; +static UINT stack_error = 0; + + +/* Define task prototypes. */ + +static void thread_0_entry(ULONG task_input); +static void thread_1_entry(ULONG task_input); +static void thread_2_entry(ULONG task_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define the stack checking error handler. */ + +void stack_error_handler(TX_THREAD *thread_ptr) +{ + + /* Check for the right thread. */ + if (thread_ptr == &thread_2) + stack_error = 1; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_stack_checking_application_define(void *first_unused_memory) +#endif +{ + +INT status; +CHAR *pointer; + + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Stack Checking Test.................................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Stack Checking Test.................................. ERROR #2\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, TX_NO_TIME_SLICE, TX_DONT_START); + thread_2_stack_start = pointer; + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Stack Checking Test.................................. ERROR #3\n"); + test_control_return(1); + } + + /* Register the stack checking handler. */ + status = tx_thread_stack_error_notify(stack_error_handler); + +#ifdef TX_ENABLE_STACK_CHECKING + /* Check for status. */ + if (status != TX_SUCCESS) +#else + if (status != TX_FEATURE_NOT_ENABLED) +#endif + + { + + printf("Running Thread Stack Checking Test.................................. ERROR #4\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Inform user of success getting to this test. */ + printf("Running Thread Stack Checking Test.................................. "); + + /* Resume thread 1 to get the stack checking to take place. */ + status = tx_thread_resume(&thread_1); + + /* Suspend to allow thread 1 to run. */ + tx_thread_suspend(&thread_0); + + /* Terminate thread 1. */ + status = tx_thread_terminate(&thread_1); + + /* Check error code. */ +#ifdef TX_ENABLE_STACK_CHECKING + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) || (stack_error != 1)) +#else + if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0) || (stack_error != 0)) +#endif + { + + /* Thread error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + else + { + + /* Success! */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +TX_THREAD fake_thread; + + /* Call stack analyze with a NULL pointer. */ + _tx_thread_stack_analyze(TX_NULL); + + /* Call the stack analyze with a fake stack just to test that path. */ + fake_thread.tx_thread_id = 0; + _tx_thread_stack_analyze(&fake_thread); + + /* Call the stack analyze with a NULL stack pointer. */ + fake_thread.tx_thread_id = ((ULONG) 0x54485244); + fake_thread.tx_thread_stack_start = TX_NULL; + _tx_thread_stack_analyze(&fake_thread); + + /* Call the stack analyze with a NULL highest stack pointer. */ + fake_thread.tx_thread_id = ((ULONG) 0x54485244); + fake_thread.tx_thread_stack_start = (void *) 0x1000; + fake_thread.tx_thread_stack_highest_ptr = TX_NULL; + _tx_thread_stack_analyze(&fake_thread); + + /* Clear the pattern in thread 2's stack. */ + TX_MEMSET(thread_2_stack_start, (CHAR) 0x11, TEST_STACK_SIZE_PRINTF); + + /* Resume thread 2, which should cause the stack error to occur. */ + tx_thread_resume(&thread_2); + + /* Suspend thread 2. */ + tx_thread_suspend(&thread_2); + + /* Increment thread 1 counter. */ + thread_1_counter++; + + /* Now, deregister the stack error handler and get into a spin condition. We will then + want to terminate thread 1 from thread 0 when it awakes! */ + tx_thread_stack_error_notify(TX_NULL); + + /* Now resume thread 2 again to cause the stack error! */ + tx_thread_resume(&thread_2); + + /* Now suspend thread 2 again. */ + tx_thread_suspend(&thread_2); + + /* Resume thread 0. */ + tx_thread_resume(&thread_0); +} + + +static void thread_2_entry(ULONG thread_input) +{ + + /* Increment thread 1 counter. */ + thread_2_counter++; +} diff --git a/test/smp/regression/threadx_thread_terminate_delete_test.c b/test/smp/regression/threadx_thread_terminate_delete_test.c new file mode 100644 index 00000000..dbe919f3 --- /dev/null +++ b/test/smp/regression/threadx_thread_terminate_delete_test.c @@ -0,0 +1,341 @@ +/* This test is designed to test thread terminate (self, and other), thread delete, + and thread identify services. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static unsigned long thread_1_enter = 0; +static unsigned long thread_1_exit = 0; +static TX_THREAD thread_1; + +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_2; + +static TX_THREAD thread_3; +static unsigned long thread_3_enter = 0; +static unsigned long thread_3_exit = 0; + + +static TX_SEMAPHORE semaphore_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void entry_exit_notify(TX_THREAD *thread_ptr, UINT type) +{ + + /* Check for the appropriate thread. */ + if (thread_ptr != &thread_1) + return; + + /* Check for type. */ + if (type == TX_THREAD_ENTRY) + thread_1_enter++; + else if (type == TX_THREAD_EXIT) + thread_1_exit++; +} + + +static void entry_exit_notify3(TX_THREAD *thread_ptr, UINT type) +{ + + /* Check for the appropriate thread. */ + if (thread_ptr != &thread_3) + return; + + /* Check for type. */ + if (type == TX_THREAD_ENTRY) + thread_3_enter++; + else if (type == TX_THREAD_EXIT) + thread_3_exit++; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_terminate_delete_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Terminate and Delete Test............................ ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Terminate and Delete Test............................ ERROR #2\n"); + test_control_return(1); + } + + /* Setup the notify call to test that logic. */ + status = tx_thread_entry_exit_notify(&thread_1, entry_exit_notify); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Terminate and Delete Test............................ ERROR #3\n"); + test_control_return(1); + } + +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Thread Terminate and Delete Test............................ ERROR #4\n"); + test_control_return(1); + } + + +#endif + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Terminate and Delete Test............................ ERROR #5\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3, + pointer, TEST_STACK_SIZE_PRINTF, + 12, 12, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Terminate and Delete Test............................ ERROR #6\n"); + test_control_return(1); + } + + /* Setup the notify call to test that logic. */ + status = tx_thread_entry_exit_notify(&thread_3, entry_exit_notify3); + +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Terminate and Delete Test............................ ERROR #7\n"); + test_control_return(1); + } + +#else + + /* Check for status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Thread Terminate and Delete Test............................ ERROR #8\n"); + test_control_return(1); + } + +#endif + + + /* Create a semaphore for thread 3 to suspend on. */ + status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Terminate and Delete Test............................ ERROR #9\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Thread Terminate and Delete Test............................ "); + + /* Let other threads execute. */ + tx_thread_relinquish(); + + /* Make sure thread 1 is terminated and thread 2 is suspended. */ + if ((thread_1.tx_thread_state != TX_TERMINATED) || +#ifndef TX_DISABLE_NOTIFY_CALLBACKS + (thread_1_enter != 1) || (thread_1_exit != 1) || +#else + (thread_1_enter != 0) || (thread_1_exit != 0) || +#endif + (thread_2.tx_thread_state != TX_SUSPENDED)) + { + + /* Thread error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* At this point, terminate thread 2 which should be in a suspended state + right now. */ + status = tx_thread_terminate(&thread_2); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Thread error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Delete thread 1 (thread 1 alread terminated) and 2. */ + status = tx_thread_delete(&thread_2); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Thread error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + status = tx_thread_delete(&thread_1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Thread error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* At this point, terminate thread 3 which should be in a suspended state + on the semaphore right now. */ + status = tx_thread_terminate(&thread_3); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Thread error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Delete thread 3. */ + status = tx_thread_delete(&thread_3); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Thread error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +static void thread_1_entry(ULONG thread_input) +{ + + /* Test identity. */ + if (tx_thread_identify() != &thread_1) + return; + + /* Increment the thread counter. */ + thread_1_counter++; + + /* Terminate self. */ + tx_thread_terminate(&thread_1); +} + +static void thread_2_entry(ULONG thread_input) +{ + + /* Test identity. */ + if (tx_thread_identify() != &thread_2) + return; + + /* Increment thread counter. */ + thread_2_counter++; + + /* Suspend thread. */ + tx_thread_suspend(&thread_2); +} + + +static void thread_3_entry(ULONG thread_input) +{ + + /* Get the semaphore with wait forever! */ + tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + /* Increment thread counter. */ + thread_2_counter++; +} + diff --git a/test/smp/regression/threadx_thread_time_slice_change_test.c b/test/smp/regression/threadx_thread_time_slice_change_test.c new file mode 100644 index 00000000..8ee7df3b --- /dev/null +++ b/test/smp/regression/threadx_thread_time_slice_change_test.c @@ -0,0 +1,149 @@ +/* This test is designed to test the change time-slice service call. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +extern unsigned long _tx_timer_time_slice; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_time_slice_change_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Time-Slice Change Test............................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 22, 22, 200, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Time-Slice Change Test............................... ERROR #2\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG old_time_slice = 0; + + + /* Inform user. */ + printf("Running Thread Time-Slice Change Test............................... "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Change the time-slice of other thread. */ + status = tx_thread_time_slice_change(&thread_1, 33, &old_time_slice); + + /* Check status and the time sice of specified thread. */ + if ((status != TX_SUCCESS) || (old_time_slice != 200) || (thread_1.tx_thread_new_time_slice != 33)) + { + + /* Thread error. */ + printf("ERROR #3\n"); + test_control_return(1); + } + + /* Sleep to get a fresh timer. */ + tx_thread_sleep(1); + + /* Change the time-slice of this thread. */ + status = tx_thread_time_slice_change(&thread_0, 66, &old_time_slice); + + /* Check status and the time sice of specified thread. */ + if ((status != TX_SUCCESS) || (old_time_slice != 100) || (thread_0.tx_thread_new_time_slice != 66) || + (_tx_timer_time_slice != 66)) + { + + /* Thread error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Change the time-slice of this thread. */ + status = tx_thread_time_slice_change(&thread_1, 2, &old_time_slice); + + /* Sleep for 8 ticks just to allow thread 1 to run and time-slice with no other thread ready. */ + tx_thread_sleep(8); + + if (status != TX_SUCCESS) + { + + /* Thread error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + + while(1) + { + + /* Identify. */ + tx_thread_identify(); + + /* Increment the thread counter. */ + thread_1_counter++; + } +} + diff --git a/test/smp/regression/threadx_thread_wait_abort_and_isr_test.c b/test/smp/regression/threadx_thread_wait_abort_and_isr_test.c new file mode 100644 index 00000000..073151ac --- /dev/null +++ b/test/smp/regression/threadx_thread_wait_abort_and_isr_test.c @@ -0,0 +1,272 @@ +/* This test is designed to test for simultaneous thread suspension lifting AND thread wait abort calls. */ + +#include +#include "tx_api.h" +#include "tx_timer.h" + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + +static unsigned long timer_0_counter = 0; +static TX_TIMER timer_0; + + +static unsigned long semaphore_put_counter = 0; +static unsigned long condition_count = 0; + +static TX_SEMAPHORE semaphore_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void timer_0_entry(ULONG timer_input); + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Define the external reference for the preempt disable flag. */ + +extern volatile UINT _tx_thread_preempt_disable; + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +static void isr_entry(void) +{ + +UINT status; +static volatile UINT miss_count = 0; + + + /* Attempt to sleep from a timer in order to test the error logic. */ + status = tx_thread_sleep(1); + + /* Check for proper error status. */ + if (status != TX_CALLER_ERROR) + { + + /* Blow up the test to force an error. */ + condition_count = 10000000; + semaphore_put_counter = 0xFFFF0000; + } + + /* Determine if the interrupt occurred when the preempt disable flag was set. */ + if (_tx_thread_preempt_disable) + { + + /* Yes this is the condition we are looking for, increment the test condition counter. */ + condition_count++; + } + + /* + It is possible for this test to get into a resonance condition in which + the ISR never occurs while preemption is disabled (especially if the + ISR is installed in the periodic timer interrupt handler, which is + conveniently available). Detect this condition and break out of it by + perturbing the duration of this ISR a pseudo-random amount of time. + */ + else if (++miss_count > 100) + for (miss_count = _tx_timer_system_clock % 100; miss_count != 0; --miss_count); + + /* Put the semaphore to wakeup thread 0. */ + status = tx_semaphore_put(&semaphore_0); + + /* Increment the semaphore counter. */ + if (status == TX_SUCCESS) + semaphore_put_counter++; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_wait_abort_and_isr_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Wait Abort and ISR Resume Test....................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 17, 17, 100, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Wait Abort and ISR Resume Test....................... ERROR #2\n"); + test_control_return(1); + } + + /* Create semaphore - consumer producer semaphore. */ + status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Wait Abort and ISR Resume Test....................... ERROR #3\n"); + test_control_return(1); + } + + /* Create a timer to ensure a context save is called for every interrupt. */ + status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 1, TX_AUTO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Wait Abort and ISR Resume Test....................... ERROR #4\n"); + test_control_return(1); + } + + /* Clear the condition count variable. */ + condition_count = 0; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Setup ISR for this test. */ + test_isr_dispatch = isr_entry; + + /* Inform user. */ + printf("Running Thread Wait Abort and ISR Resume Test....................... "); + + /* Loop to exploit the probability window inside tx_thread_wait_abort. */ + while (condition_count < 20) + { + + /* Suspend on the semaphore that is going to be set via the ISR. */ + status = tx_semaphore_get(&semaphore_0, (thread_0_counter % 5) + 1); + + /* Determine if we have an unexpected result. */ + if ((status != TX_SUCCESS) && (status != TX_WAIT_ABORTED)) + { + + /* Test error! */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Check for the preempt disable flag being set. */ + if (_tx_thread_preempt_disable) + { + + /* Test error! */ + printf("ERROR #6\n"); + test_control_return(2); + } + + /* Determine if we really got the semaphore. */ + if (status == TX_SUCCESS) + { + + /* Increment the thread count. */ + thread_0_counter++; + +#ifdef TX_NOT_INTERRUPTABLE + + /* Determine if we have a non-interruptable build of ThreadX. If so, just + get out of this loop after 100 passes. */ + + if (thread_0_counter >= 100) + break; +#endif + + } + } + + /* Clear ISR dispatch. */ + test_isr_dispatch = TX_NULL; + +#ifdef TX_NOT_INTERRUPTABLE + /* At this point, check to see if we got all the semaphores! */ + if ((thread_0_counter != (semaphore_put_counter - semaphore_0.tx_semaphore_count)) || + (condition_count != 0)) +#else + /* At this point, check to see if we got all the semaphores! */ + if (thread_0_counter != (semaphore_put_counter - semaphore_0.tx_semaphore_count)) +#endif + { + + /* Test error! */ + printf("ERROR #7\n"); + test_control_return(3); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + /* Loop forever! */ + while(1) + { + + + /* Abort the suspension on the semaphore in thread 0. */ + tx_thread_wait_abort(&thread_0); + + /* Increment the thread counter. */ + thread_1_counter++; + + /* Let thread 0 run again! */ + tx_thread_relinquish(); + } +} + + +static void timer_0_entry(ULONG input) +{ + timer_0_counter++; +} + diff --git a/test/smp/regression/threadx_thread_wait_abort_test.c b/test/smp/regression/threadx_thread_wait_abort_test.c new file mode 100644 index 00000000..a2e8e42d --- /dev/null +++ b/test/smp/regression/threadx_thread_wait_abort_test.c @@ -0,0 +1,138 @@ +/* This test is designed to test thread wait abort. */ + +#include +#include "tx_api.h" + +//static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long thread_1_counter = 0; +static TX_THREAD thread_1; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_thread_wait_abort_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Wait Abort Test...................................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Thread Wait Abort Test...................................... ERROR #2\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Inform user. */ + printf("Running Thread Wait Abort Test...................................... "); + + /* Let other thread run. */ + tx_thread_resume(&thread_1); + + /* Make sure thread 1 is sleeping. */ + if (thread_1.tx_thread_state != TX_SLEEP) + { + + /* Thread error. */ + printf("ERROR #3\n"); + test_control_return(1); + } + + /* At this point, call tx_thread_wait_abort to abort the sleep in thread1. */ + status = tx_thread_wait_abort(&thread_1); + + /* Check for status. */ + if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_SUSPENDED)) + { + + /* Thread error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Sleep for a long long time. */ + status = tx_thread_sleep(1000000000); + + /* Check for the proper status. */ + if (status != TX_WAIT_ABORTED) + { + + /* Thread error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Increment the thread counter. */ + thread_1_counter++; + + /* Suspend self. */ + tx_thread_suspend(&thread_1); +} + diff --git a/test/smp/regression/threadx_time_get_set_test.c b/test/smp/regression/threadx_time_get_set_test.c new file mode 100644 index 00000000..486294e9 --- /dev/null +++ b/test/smp/regression/threadx_time_get_set_test.c @@ -0,0 +1,109 @@ +/* This test is designed to test simple tx_time_get and set services. */ + +#include +#include "tx_api.h" +#include "tx_timer.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_time_get_set_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 3, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Time Simple Get/Set Test.................................... ERROR #1\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG current_time; + + + /* Inform user. */ + printf("Running Time Simple Get/Set Test.................................... "); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Sleep for 1 tick to get a fresh timer. */ + tx_thread_sleep(1); + + /* Set time to 0. */ + tx_time_set(0); + + /* Sleep for a couple ticks. */ + tx_thread_sleep(35); + + /* Pickup the current time. */ + /* Call internal function to cover this function. */ + current_time = _tx_time_get(); + + /* Check Current time. It should be 35. */ + if (current_time != 35) + { + + /* System time error. */ + printf("ERROR #2\n"); + test_control_return(1); + } + + /* Set the new time. */ + tx_time_set(7); + + /* Check the new time. */ + if (tx_time_get() != 7) + { + + /* System time error. */ + printf("ERROR #3\n"); + test_control_return(1); + } + else + { + + /* Successful time test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + diff --git a/test/smp/regression/threadx_timer_activate_deactivate_test.c b/test/smp/regression/threadx_timer_activate_deactivate_test.c new file mode 100644 index 00000000..a238ea33 --- /dev/null +++ b/test/smp/regression/threadx_timer_activate_deactivate_test.c @@ -0,0 +1,268 @@ +/* This test is designed to test application timer activation/deactivation services + from threads and the activation routines. */ + +#include +#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 **) ¤t_list_head; + current_list_head = (struct TX_TIMER_INTERNAL_STRUCT **) &(timer_2.tx_timer_internal); + timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = TX_TIMER_ENTRIES*2; + timer_2.tx_timer_internal.tx_timer_internal_active_next = &(timer_2.tx_timer_internal); + status = tx_timer_deactivate(&timer_2); + + /* Check for error. */ + if ((status != TX_SUCCESS) || (timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks != TX_TIMER_ENTRIES)) + { + + /* Application timer error. */ + printf("ERROR #8a\n"); + test_control_return(1); + } + + + /* Sleep for twice the expiration time to make sure the timer + doesn't automatically reschedule. */ + tx_thread_sleep(47); + + /* Check for an error. */ + + /* At this point the timer counter should still be 1. */ + if (timer_0_counter != 1) + { + + /* Application timer activate/deactivate error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + else + { + + /* Application Timer test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void timer_0_expiration(ULONG timer_input) +{ + + +UINT status; + + + /* Attempt to sleep from a timer in order to test the error logic. */ + status = tx_thread_sleep(1); + + /* Check for proper error status. */ + if (status == TX_CALLER_ERROR) + { + + /* Process timer expiration. */ + timer_0_counter++; + + /* Deactivate the timer from the expiration routine. */ + tx_timer_deactivate(&timer_0); + } +} + + diff --git a/test/smp/regression/threadx_timer_deactivate_accuracy_test.c b/test/smp/regression/threadx_timer_deactivate_accuracy_test.c new file mode 100644 index 00000000..6af4bde4 --- /dev/null +++ b/test/smp/regression/threadx_timer_deactivate_accuracy_test.c @@ -0,0 +1,286 @@ +/* This test is designed to test application timer activation/deactivation services + from threads... Make sure the remaining ticks are being saved/restored properly. */ + +#include +#include "tx_api.h" + +//static unsigned long expected_time; +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long timer_0_counter = 0; +static TX_TIMER timer_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void timer_0_expiration(ULONG timer_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_timer_deactivate_accuracy_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 3, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Activation/Deactivation Accuracy Test................. ERROR #1\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234, + 29, 31, TX_NO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Activation/Deactivation Accuracy Test................. ERROR #2\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Inform user. */ + printf("Running Timer Activation/Deactivation Accuracy Test................. "); + + /* Sleep so we have to handle the wrap condition. */ + tx_thread_sleep(10); + + /* Activate the timer. */ + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #3\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(2); + + /* Deactivate and activate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(3); + + /* Deactivate and activate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(4); + + /* Deactivate and activate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(5); + + /* Deactivate and activate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(6); + + /* Deactivate and activate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(7); + + /* Deactivate and activate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if ((status != TX_SUCCESS) || (timer_0_counter)) + { + + /* Application timer error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(2); + + /* At this point the timer should have ran! */ + status = tx_timer_deactivate(&timer_0); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Check for status. */ + if ((status != TX_SUCCESS) || (timer_0_counter != 1)) + { + + /* Application timer error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + else + { + + /* Successful Re-activate test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void timer_0_expiration(ULONG timer_input) +{ + + + /* Process timer expiration. */ + timer_0_counter++; +} + diff --git a/test/smp/regression/threadx_timer_information_test.c b/test/smp/regression/threadx_timer_information_test.c new file mode 100644 index 00000000..4dbc3c9b --- /dev/null +++ b/test/smp/regression/threadx_timer_information_test.c @@ -0,0 +1,538 @@ +/* This test is designed to test timer information services. */ + +#include +#include "tx_api.h" +#include "tx_timer.h" + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long timer_0_counter = 0; +static TX_TIMER timer_0; + +static unsigned long timer_1_counter = 0; +static TX_TIMER timer_1; + + +static TX_TIMER timer_2; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void timer_0_expiration(ULONG timer_input); +static void timer_1_expiration(ULONG timer_input); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_timer_information_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 3, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Information Test...................................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234, + 1, 18, TX_AUTO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Information Test...................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234, + 1000, 1000, TX_AUTO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Information Test...................................... ERROR #3\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT interrupt_status; +CHAR *name; +UINT active; +ULONG remaining_ticks; +ULONG reschedule_ticks; +TX_TIMER *next_timer; +ULONG activates; +ULONG reactivates; +ULONG deactivates; +ULONG expirations; +ULONG expiration_adjusts; +TX_TIMER_INTERNAL **list_head; + + + /* Inform user. */ + printf("Running Timer Information Test...................................... "); + + /* Sleep for a couple ticks. */ + tx_thread_sleep(19); + + /* Check for an error. */ + if (timer_0_counter != 2) + { + + /* Application timer error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + /* Deactivate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Sleep again. */ + tx_thread_sleep(19); + + /* Check for an error. */ + if (timer_0_counter != 2) + { + + /* Application timer error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Modify the timer. */ + status = tx_timer_change(&timer_0, 100, 1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Clear the system time. */ + tx_time_set(0); + + /* Activate the timer. */ + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Sleep for 120. */ + tx_thread_sleep(120); + + /* Check the counters to make sure everything is where it should be. */ + if ((timer_0_counter != 23) || (tx_time_get() != 120)) + { + + /* Application timer error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Get the timer information. */ + status = tx_timer_info_get(&timer_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &next_timer); + status += tx_timer_info_get(&timer_0, &name, &active, &remaining_ticks, &reschedule_ticks, &next_timer); + + /* Check for successful completion. */ + if ((status != TX_SUCCESS) || (active != TX_TRUE) || (remaining_ticks != 1) || (reschedule_ticks != 1) || (next_timer != &timer_1)) + { + + /* Application timer error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Now, deactivate timer 0 to get another path through the info get service. */ + status = tx_timer_deactivate(&timer_0); + status += tx_timer_info_get(&timer_0, &name, &active, &remaining_ticks, &reschedule_ticks, &next_timer); + + /* Check for successful completion. */ + if ((status != TX_SUCCESS) || (active != TX_FALSE) || (remaining_ticks != 1) || (reschedule_ticks != 1) || (next_timer != &timer_1)) + { + + /* Application timer error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Change timer 0 to a large value and get the information again. */ + status = tx_timer_change(&timer_0, 100, 200); + status += tx_timer_activate(&timer_0); + + status += tx_timer_info_get(&timer_0, &name, &active, &remaining_ticks, &reschedule_ticks, &next_timer); + + /* Check for successful completion. */ + if ((status != TX_SUCCESS) || (active != TX_TRUE) || (remaining_ticks != 100) || (reschedule_ticks != 200) || (next_timer != &timer_1)) + { + + /* Application timer error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + +#ifdef TX_TIMER_ENABLE_PERFORMANCE_INFO + + /* Check for NULL pointer. */ + status = _tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for error. */ + if (status != TX_PTR_ERROR) + { + + /* Application timer error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Now get the performance information. */ + status = tx_timer_performance_info_get(&timer_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_timer_performance_info_get(&timer_0, &activates, &reactivates, &deactivates, &expirations, &expiration_adjusts); + + /* Check for successful completion. */ + if ((status != TX_SUCCESS) || (activates != timer_0.tx_timer_performance_activate_count) || (reactivates != timer_0.tx_timer_performance_reactivate_count) || + (deactivates != timer_0.tx_timer_performance_deactivate_count) || (expirations != timer_0.tx_timer_performance_expiration_count) || (expiration_adjusts != timer_0.tx_timer_performance__expiration_adjust_count)) + { + + /* Application timer error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Now get the system performance information. */ + status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + status += tx_timer_performance_system_info_get(&activates, &reactivates, &deactivates, &expirations, &expiration_adjusts); + + /* Check for successful completion. */ + if ((status != TX_SUCCESS) || (activates != _tx_timer_performance_activate_count) || (reactivates != _tx_timer_performance_reactivate_count) || + (deactivates != _tx_timer_performance_deactivate_count) || (expirations != _tx_timer_performance_expiration_count) || (expiration_adjusts != _tx_timer_performance__expiration_adjust_count)) + { + + /* Application timer error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + +#else + + /* Now get the performance information. */ + status = tx_timer_performance_info_get(&timer_0, &activates, &reactivates, &deactivates, &expirations, &expiration_adjusts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Application timer error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Now get the performance information. */ + status = tx_timer_performance_info_get(TX_NULL, &activates, &reactivates, &deactivates, &expirations, &expiration_adjusts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Application timer error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Now get the performance information. */ + status = tx_timer_performance_info_get(TX_NULL, TX_NULL, &reactivates, &deactivates, &expirations, &expiration_adjusts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Application timer error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Now get the performance information. */ + status = tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &deactivates, &expirations, &expiration_adjusts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Application timer error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Now get the performance information. */ + status = tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &expirations, &expiration_adjusts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Application timer error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Now get the performance information. */ + status = tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &expiration_adjusts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Application timer error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + /* Now get the performance information. */ + status = tx_timer_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Application timer error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Now get the system performance information. */ + status = tx_timer_performance_system_info_get(&activates, &reactivates, &deactivates, &expirations, &expiration_adjusts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Application timer error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Now get the system performance information. */ + status = tx_timer_performance_system_info_get(TX_NULL, &reactivates, &deactivates, &expirations, &expiration_adjusts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Application timer error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Now get the system performance information. */ + status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, &deactivates, &expirations, &expiration_adjusts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Application timer error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + + /* Now get the system performance information. */ + status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &expirations, &expiration_adjusts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Application timer error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Now get the system performance information. */ + status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &expiration_adjusts); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Application timer error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Now get the system performance information. */ + status = tx_timer_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check for error. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Application timer error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + +#endif + + /* Test timer that is in the process of expiration - on temporary "expired" list. */ + TX_MEMSET(&timer_2, 0, (sizeof(TX_TIMER))); + + /* Setup fake timer and test for no-reactivate condition. */ + timer_2.tx_timer_id = TX_TIMER_ID; + timer_2.tx_timer_internal.tx_timer_internal_list_head = (TX_TIMER_INTERNAL **) &list_head; + list_head = (struct TX_TIMER_INTERNAL_STRUCT **) &(timer_2.tx_timer_internal); + timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = 10; + status = tx_timer_info_get(&timer_2, TX_NULL, TX_NULL, &remaining_ticks, &reschedule_ticks, TX_NULL); + + /* Check for error. */ + if ((status != TX_SUCCESS) || (remaining_ticks != 0) || (reschedule_ticks != 0)) + { + + /* Application timer error. */ + printf("ERROR #28a\n"); + test_control_return(1); + } + + /* Setup fake timer and test for reactivate condition - on temporary "expired" list. */ + timer_2.tx_timer_id = TX_TIMER_ID; + timer_2.tx_timer_internal.tx_timer_internal_list_head = (TX_TIMER_INTERNAL **) &list_head; + list_head = (struct TX_TIMER_INTERNAL_STRUCT **) &(timer_2.tx_timer_internal); + timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = TX_TIMER_ENTRIES * 2; + status = tx_timer_info_get(&timer_2, TX_NULL, TX_NULL, &remaining_ticks, &reschedule_ticks, TX_NULL); + + /* Check for error. */ + if ((status != TX_SUCCESS) || (remaining_ticks != TX_TIMER_ENTRIES) || (reschedule_ticks != 0)) + { + + /* Application timer error. */ + printf("ERROR #28a\n"); + test_control_return(1); + } + + + /* Lockout interrupts. */ + interrupt_status = tx_interrupt_control(TX_INT_DISABLE); + + /* Setup fake timer and test for reactivate condition - current timer. */ + timer_2.tx_timer_id = TX_TIMER_ID; + timer_2.tx_timer_internal.tx_timer_internal_list_head = (TX_TIMER_INTERNAL **) &list_head; + list_head = (struct TX_TIMER_INTERNAL_STRUCT **) &(timer_2.tx_timer_internal); + timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = 13; + _tx_timer_expired_timer_ptr = &timer_2.tx_timer_internal; + status = tx_timer_info_get(&timer_2, TX_NULL, TX_NULL, &remaining_ticks, &reschedule_ticks, TX_NULL); + _tx_timer_expired_timer_ptr = TX_NULL; + + /* Restore interrupts. */ + tx_interrupt_control(interrupt_status); + + /* Check for error. */ + if ((status != TX_SUCCESS) || (remaining_ticks != 0) || (reschedule_ticks != 0)) + { + + /* Application timer error. */ + printf("ERROR #28b\n"); + test_control_return(1); + } + + + /* Delete the timer... that are currently active and on the same expiration + list! */ + status = tx_timer_deactivate(&timer_0); + status += tx_timer_deactivate(&timer_1); + status += tx_timer_change(&timer_0, 100, 200); + status += tx_timer_change(&timer_1, 100, 200); + status += tx_timer_activate(&timer_0); + status += tx_timer_activate(&timer_1); + status += tx_timer_delete(&timer_0); + status += tx_timer_delete(&timer_1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + else + { + + /* Successful Multiple Sleep test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void timer_0_expiration(ULONG timer_input) +{ + + + /* Process timer expiration. */ + timer_0_counter++; +} + + +static void timer_1_expiration(ULONG timer_input) +{ + + + /* Process timer expiration. */ + timer_1_counter++; +} diff --git a/test/smp/regression/threadx_timer_large_timer_accuracy_test.c b/test/smp/regression/threadx_timer_large_timer_accuracy_test.c new file mode 100644 index 00000000..dde97fe4 --- /dev/null +++ b/test/smp/regression/threadx_timer_large_timer_accuracy_test.c @@ -0,0 +1,286 @@ +/* This test is designed to test application timer activation/deactivation services + from threads... To make sure large timer expirations are being saved/restored properly. */ + +#include +#include "tx_api.h" + +//static unsigned long expected_time; +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long timer_0_counter = 0; +static TX_TIMER timer_0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void timer_0_expiration(ULONG timer_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_timer_large_timer_accuracy_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 3, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Large Timer Activate Accuracy Test.................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234, + 100, 31, TX_NO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Large Timer Activate Accuracy Test.................... ERROR #2\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Inform user. */ + printf("Running Timer Large Timer Activate Accuracy Test.................... "); + + /* Sleep so we have to handle the wrap condition. */ + tx_thread_sleep(10); + + /* Activate the timer. */ + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #3\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(20); + + /* Deactivate and activate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(35); + + /* Deactivate and activate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(2); + + /* Deactivate and activate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(1); + + /* Deactivate and activate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(2); + + /* Deactivate and activate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(5); + + /* Deactivate and activate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if ((status != TX_SUCCESS) || (timer_0_counter)) + { + + /* Application timer error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Sleep */ + tx_thread_sleep(35); + + /* At this point the timer should have ran! */ + status = tx_timer_deactivate(&timer_0); + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Check for status. */ + if ((status != TX_SUCCESS) || (timer_0_counter != 1)) + { + + /* Application timer error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + else + { + + /* Successful Re-activate test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void timer_0_expiration(ULONG timer_input) +{ + + + /* Process timer expiration. */ + timer_0_counter++; +} + diff --git a/test/smp/regression/threadx_timer_multiple_accuracy_test.c b/test/smp/regression/threadx_timer_multiple_accuracy_test.c new file mode 100644 index 00000000..a7be91e2 --- /dev/null +++ b/test/smp/regression/threadx_timer_multiple_accuracy_test.c @@ -0,0 +1,186 @@ +/* This test is designed to test the accuracy of three free running timers. */ + +#include +#include "tx_api.h" + +//static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long timer_0_counter = 0; +static TX_TIMER timer_0; +static unsigned long timer_1_counter = 0; +static TX_TIMER timer_1; +static unsigned long timer_2_counter = 0; +static TX_TIMER timer_2; + + +/* Define prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void timer_0_expiration(ULONG timer_input); +static void timer_1_expiration(ULONG timer_input); +static void timer_2_expiration(ULONG timer_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_timer_multiple_accuracy_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 3, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Multiple Timer Accuracy Test.......................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234, + 1, 1, TX_NO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Multiple Timer Accuracy Test.......................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234, + 2, 2, TX_NO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Multiple Timer Accuracy Test.......................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_2, "timer 2", timer_2_expiration, 0x1234, + 3, 3, TX_NO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Multiple Timer Accuracy Test.......................... ERROR #4\n"); + test_control_return(1); + } +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Inform user. */ + printf("Running Timer Multiple Timer Accuracy Test.......................... "); + + /* Sleep to get a fresh timer. */ + tx_thread_sleep(1); + + /* Activate all the timers. */ + status = tx_timer_activate(&timer_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_1); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_2); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Sleep for a some ticks. */ + tx_thread_sleep(300); + + /* Insure that each timer ran twice. */ + if ((timer_0_counter != 300) || (timer_1_counter != 150) || + (timer_2_counter != 100)) + { + + /* Application timer error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + else + { + + /* Successful timer test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void timer_0_expiration(ULONG timer_input) +{ + + + /* Process timer expiration. */ + timer_0_counter++; +} + +static void timer_1_expiration(ULONG timer_input) +{ + + + /* Process timer expiration. */ + timer_1_counter++; +} + +static void timer_2_expiration(ULONG timer_input) +{ + + + /* Process timer expiration. */ + timer_2_counter++; +} + diff --git a/test/smp/regression/threadx_timer_multiple_test.c b/test/smp/regression/threadx_timer_multiple_test.c new file mode 100644 index 00000000..3f02d5a7 --- /dev/null +++ b/test/smp/regression/threadx_timer_multiple_test.c @@ -0,0 +1,349 @@ +/* This test is designed to test a simple application timer services, + including create, activate, deactivate, change, and delete with multiple timers. */ + +#include +#include "tx_api.h" + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; + +static unsigned long timer_0_counter = 0; +static TX_TIMER timer_0; +static unsigned long timer_1_counter = 0; +static TX_TIMER timer_1; +static unsigned long timer_2_counter = 0; +static TX_TIMER timer_2; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void timer_0_expiration(ULONG timer_input); +static void timer_1_expiration(ULONG timer_input); +static void timer_2_expiration(ULONG timer_input); + + +/* Prototype for test control return. */ +void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_timer_multiple_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 3, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Multiple Timer Test................................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234, + 100, 200, TX_AUTO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Multiple Timer Test................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234, + 100, 200, TX_AUTO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Multiple Timer Test................................... ERROR #3\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_2, "timer 2", timer_2_expiration, 0x1234, + 100, 200, TX_AUTO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Multiple Timer Test................................... ERROR #4\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Inform user. */ + printf("Running Timer Multiple Timer Test................................... "); + + /* Sleep for a couple ticks. */ + tx_thread_sleep(301); + + /* Insure that each timer ran twice. */ + if ((timer_0_counter != 2) || (timer_1_counter != 2) || + (timer_2_counter != 2)) + { + + /* Application timer error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Deactivate the timers. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + status = tx_timer_deactivate(&timer_1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + status = tx_timer_deactivate(&timer_2); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Sleep again. */ + tx_thread_sleep(100); + + /* Insure that each timer haven't run again. */ + if ((timer_0_counter != 2) || (timer_1_counter != 2) || + (timer_2_counter != 2)) + { + + /* Application timer error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Modify the timer. */ + status = tx_timer_change(&timer_0, 100, 1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + status = tx_timer_change(&timer_1, 100, 2); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + status = tx_timer_change(&timer_2, 100, 3); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Activate the timer. */ + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + status = tx_timer_activate(&timer_2); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Sleep for 200. */ + tx_thread_sleep(200); + + /* Insure that each timer haven't run again. */ + if ((timer_0_counter != 103) || (timer_1_counter != 53) || + (timer_2_counter != 36)) + { + + /* Application timer error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Deactivate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + status = tx_timer_deactivate(&timer_1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + status = tx_timer_deactivate(&timer_2); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Delete the timer. */ + status = tx_timer_delete(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + status = tx_timer_delete(&timer_2); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + status = tx_timer_delete(&timer_1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Successful Multiple timer test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void timer_0_expiration(ULONG timer_input) +{ + + + /* Process timer expiration. */ + timer_0_counter++; +} + +static void timer_1_expiration(ULONG timer_input) +{ + + + /* Process timer expiration. */ + timer_1_counter++; +} + +static void timer_2_expiration(ULONG timer_input) +{ + + + /* Process timer expiration. */ + timer_2_counter++; +} + diff --git a/test/smp/regression/threadx_timer_simple_test.c b/test/smp/regression/threadx_timer_simple_test.c new file mode 100644 index 00000000..ec3ff235 --- /dev/null +++ b/test/smp/regression/threadx_timer_simple_test.c @@ -0,0 +1,830 @@ +/* This test is designed to test a simple application timer services, including create, + activate, deactivate, change, and delete. */ + +#include +#include "tx_api.h" +#include "tx_timer.h" + +typedef struct TIMER_MEMORY_TEST_STRUCT +{ + ULONG first; + ULONG second; + TX_TIMER timer; + ULONG next_to_last; + ULONG last; + +} TIMER_MEMORY_TEST; + +static TIMER_MEMORY_TEST timer_memory; + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Define external reference to status from timer create during initialization. */ + +extern UINT test_timer_create_init; + + +static unsigned long thread_0_counter = 0; +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static unsigned long timer_0_counter = 0; +static TX_TIMER timer_0; + +static unsigned long timer_1_counter = 0; +static TX_TIMER timer_1; + +static TX_TIMER timer_2; +static TX_TIMER timer_3; + +static unsigned long error = 0; +static unsigned long timer_executed = 0; +static unsigned long isr_executed = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void timer_0_expiration(ULONG timer_input); +static void timer_1_expiration(ULONG timer_input); + +UINT _txe_timer_create(TX_TIMER *timer_ptr, CHAR *name_ptr, + VOID (*expiration_function)(ULONG), ULONG expiration_input, + ULONG initial_ticks, ULONG reschedule_ticks, UINT auto_activate, UINT timer_control_block_size); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define the timer for this test. */ + +static void timer_entry(ULONG i) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +UINT status; + + + /* Determine if the timer was able to be created durning initialization. */ + if (test_timer_create_init != TX_SUCCESS) + { + + /* Error! */ + error++; + } + + /* Attempt to delete a timer from a timer. */ + status = tx_timer_delete(&timer_0); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to create a timer from a timer. */ + status = tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234, + 1, 18, TX_AUTO_ACTIVATE); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + +#ifndef TX_TIMER_PROCESS_IN_ISR + /* Just to test another path, set this timer expired variable. */ + if (timer_executed == 0) + _tx_timer_expired = 1; +#endif + + timer_executed = 1; +#endif +} + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + +#ifndef TX_DISABLE_ERROR_CHECKING + +UINT status; + + /* Attempt to delete a timer from an ISR. */ + status = tx_timer_delete(&timer_0); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + /* Attempt to create a timer from an ISR. */ + status = tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234, + 1, 18, TX_AUTO_ACTIVATE); + + /* Check status. */ + if (status != TX_CALLER_ERROR) + { + + /* Error! */ + error++; + } + + isr_executed = 1; +#endif +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_timer_simple_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + /* Put first available memory address into a character pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, 3, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 18, 18, 3, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Simple Test........................................... ERROR #1\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234, + 1, 18, TX_AUTO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Simple Test........................................... ERROR #2\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234, + 1000, 1000, TX_AUTO_ACTIVATE); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Timer Simple Test........................................... ERROR #3\n"); + test_control_return(1); + } + +#ifndef TX_TIMER_PROCESS_IN_ISR + + /* Call the timer thread entry function with a bad ID to test another path. */ + _tx_timer_thread_entry(0); +#endif + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT tx_interrupt_save; +UINT status; +ULONG exclusion_map; + + + /* Inform user. */ + printf("Running Timer Simple Test........................................... "); + + /* Perform timer memory test. */ + timer_memory.first = 0x11223344; + timer_memory.second = 0x55667788; + timer_memory.next_to_last = 0x99aabbcc; + timer_memory.last = 0xddeeff00; + + /* Create the timer. */ + status = tx_timer_create(&timer_memory.timer, "timer memory", timer_0_expiration, 0x1234, + 1000000, 100000, TX_NO_ACTIVATE); + tx_timer_delete(&timer_memory.timer); + + /* Check for status. */ + if ((status != TX_SUCCESS) || + (timer_memory.first != 0x11223344) || + (timer_memory.second != 0x55667788) || + (timer_memory.next_to_last != 0x99aabbcc) || + (timer_memory.last != 0xddeeff00)) + { + + /* Memory overwrite error. */ + printf("ERROR #4\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Attempt to activate a non-timer. */ + status = tx_timer_activate(TX_NULL); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #5\n"); + test_control_return(1); + } + + /* Attempt to activate a non-created timer. */ + timer_2.tx_timer_id = 0; + status = tx_timer_activate(&timer_2); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #6\n"); + test_control_return(1); + } + + /* Attempt to activate a timer with a 0 expiration. */ + timer_2.tx_timer_id = ((ULONG) 0x4154494D); + timer_2.tx_timer_internal.tx_timer_internal_list_head = TX_NULL; + timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = 0; + status = tx_timer_activate(&timer_2); + + /* Check status. */ + if (status != TX_ACTIVATE_ERROR) + { + + /* Application timer error. */ + printf("ERROR #7\n"); + test_control_return(1); + } + + + /* Attempt to activate a timer with a wait forever expiration. */ + timer_2.tx_timer_id = ((ULONG) 0x4154494D); + timer_2.tx_timer_internal.tx_timer_internal_list_head = TX_NULL; + timer_2.tx_timer_internal.tx_timer_internal_remaining_ticks = TX_WAIT_FOREVER; + status = tx_timer_activate(&timer_2); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #8\n"); + test_control_return(1); + } + + timer_2.tx_timer_id = 0; + + /* Attempt to deactivate a non-timer. */ + status = tx_timer_deactivate(TX_NULL); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to deactivate a non-created timer. */ + timer_2.tx_timer_id = 0; + status = tx_timer_deactivate(&timer_2); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #10\n"); + test_control_return(1); + } + + /* Attempt to change a non-timer. */ + status = tx_timer_change(TX_NULL, 1, 1); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #11\n"); + test_control_return(1); + } + + /* Attempt to change a non-created timer. */ + timer_2.tx_timer_id = 0; + status = tx_timer_change(&timer_2, 1, 1); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Attempt to change a timer with a 0 initial ticks. */ + status = tx_timer_change(&timer_0, 0, 1); + + /* Check status. */ + if (status != TX_TICK_ERROR) + { + + /* Application timer error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + + /* Attempt to delete a non-time. */ + status = tx_timer_delete(TX_NULL); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #14\n"); + test_control_return(1); + } + + /* Attempt to delete a non-created time. */ + timer_2.tx_timer_id = 0; + status = tx_timer_delete(&timer_2); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Attempt to get info from a non-timer. */ + status = tx_timer_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + + /* Attempt to get info from a non-created timer. */ + timer_2.tx_timer_id = 0; + status = tx_timer_info_get(&timer_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #17\n"); + test_control_return(1); + } + + /* Attempt to create a timer with a NULL pointer. */ + status = tx_timer_create(TX_NULL, "timer 0", timer_0_expiration, 0x1234, + 1, 18, TX_AUTO_ACTIVATE); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Attempt to create a timer with a bad control block size. */ + status = _txe_timer_create(&timer_3, "timer 3", timer_0_expiration, 0x1234, + 1, 18, TX_AUTO_ACTIVATE, (sizeof(TX_TIMER)+1)); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + + /* Attempt to create a timer that has already been created. */ + status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234, + 1, 18, TX_AUTO_ACTIVATE); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #20\n"); + test_control_return(1); + } + + /* Attempt to create a timer with an invalid number of initial ticks. */ + status = tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234, + 0, 18, TX_AUTO_ACTIVATE); + + /* Check status. */ + if (status != TX_TICK_ERROR) + { + + /* Application timer error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + /* Attempt to create a timer with an invalid activation. */ + status = tx_timer_create(&timer_2, "timer 2", timer_0_expiration, 0x1234, + 1, 18, TX_AUTO_ACTIVATE+3999); + + /* Check status. */ + if (status != TX_ACTIVATE_ERROR) + { + + /* Application timer error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + +#endif + + /* Sleep for a couple ticks. */ + tx_thread_sleep(19); + + /* Check for an error. */ + if (timer_0_counter != 2) + { + + /* Application timer error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Deactivate the timer. */ + status = tx_timer_deactivate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Sleep again. */ + tx_thread_sleep(19); + + /* Check for an error. */ + if (timer_0_counter != 2) + { + + /* Application timer error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + + /* Modify the timer. */ + status = tx_timer_change(&timer_0, 100, 1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + /* Clear the system time. */ + tx_time_set(0); + + /* Activate the timer. */ + status = tx_timer_activate(&timer_0); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #27\n"); + test_control_return(1); + } + + /* Sleep for 120. */ + tx_thread_sleep(120); + + /* Check the counters to make sure everything is where it should be. */ + if ((timer_0_counter != 23) || (tx_time_get() != 120)) + { + + /* Application timer error. */ + printf("ERROR #28\n"); + test_control_return(1); + } + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Delete the timer... that are currently active and on the same expiration + list! */ + status = tx_timer_deactivate(&timer_0); + status += tx_timer_deactivate(&timer_1); + status += tx_timer_change(&timer_0, 100, 100); + status += tx_timer_change(&timer_1, 100, 100); + status += tx_timer_activate(&timer_0); + status += tx_timer_activate(&timer_1); + status += tx_timer_delete(&timer_0); + status += tx_timer_delete(&timer_1); + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #29\n"); + test_control_return(1); + } + +#ifndef TX_DISABLE_ERROR_CHECKING + + /* Create a timer for the test. */ + tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE); + + /* Setup the ISR. */ + test_isr_dispatch = test_isr; + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Resume thread 1 to take an interrupt on top of it. */ + tx_thread_resume(&thread_1); + + /* Sleep for a bit... */ + tx_thread_sleep(3); + + /* Clear the ISR. */ + test_isr_dispatch = TX_NULL; + + /* Test for error. */ + if ((error) || (timer_executed != 1) || (isr_executed != 1)) + { + + /* Thread error. */ + printf("ERROR #30\n"); + test_control_return(1); + } + + /* Deactivate and delete timer 0. */ + status = tx_timer_deactivate(&timer_0); + status += tx_timer_delete(&timer_0); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #31\n"); + test_control_return(1); + } + +#endif + + /* Check for ISR errors. */ + if (error) + { + + /* Thread error. */ + printf("ERROR #32\n"); + test_control_return(1); + } + + /* Test the SMP timer exclusion get routines with bad values. */ + status = tx_timer_smp_core_exclude_get(TX_NULL, TX_NULL); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #33\n"); + test_control_return(1); + } + + status = tx_timer_smp_core_exclude_get(&timer_0, TX_NULL); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #34\n"); + test_control_return(1); + } + + /* Test the SMP timer exclusion set routines with bad values. */ + status = tx_timer_smp_core_exclude(TX_NULL, 0); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #35\n"); + test_control_return(1); + } + + status = tx_timer_smp_core_exclude(&timer_0, 0); + + /* Check status. */ + if (status != TX_TIMER_ERROR) + { + + /* Application timer error. */ + printf("ERROR #36\n"); + test_control_return(1); + } + + /* Create two timers and exclude them from core 0. */ + status = tx_timer_create(&timer_0, "timer 0", timer_0_expiration, 0x1234, + 10, 10, TX_NO_ACTIVATE); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #37\n"); + test_control_return(1); + } + + status = tx_timer_create(&timer_1, "timer 1", timer_1_expiration, 0x1234, + 10, 10, TX_NO_ACTIVATE); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #38\n"); + test_control_return(1); + } + + /* Now test the exclusion get with a valid timer, but with a NULL destination. */ + status = tx_timer_smp_core_exclude_get(&timer_0, TX_NULL); + + /* Check status. */ + if (status != TX_PTR_ERROR) + { + + /* Application timer error. */ + printf("ERROR #39\n"); + test_control_return(1); + } + + /* Now exclude the processing of each timer from executing on core 0. */ + status = tx_timer_smp_core_exclude(&timer_0, 0x1); + status += tx_timer_smp_core_exclude(&timer_1, 0x1); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #40\n"); + test_control_return(1); + } + + /* Now test the exclusion get with a valid timer. */ + status = tx_timer_smp_core_exclude_get(&timer_0, &exclusion_map); + + /* Check status. */ + if ((status != TX_SUCCESS) || (exclusion_map != 0x1)) + { + + /* Application timer error. */ + printf("ERROR #41\n"); + test_control_return(1); + } + + /* Clear the timer counters. */ + timer_0_counter = 0; + timer_1_counter = 0; + + /* Sleep for one tick to get a new timer period. */ + tx_thread_sleep(1); + + /* Now activate both timers and immediately deactivate timer 1 so we test the system deactivate path. */ + status += tx_timer_activate(&timer_0); + status = tx_timer_activate(&timer_1); + tx_interrupt_save = _tx_thread_smp_protect(); + _tx_timer_system_deactivate(&timer_1.tx_timer_internal); + _tx_thread_smp_unprotect(tx_interrupt_save); + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Application timer error. */ + printf("ERROR #42\n"); + test_control_return(1); + } + + /* Now sleep for 20 ticks to ensure the timer works when excluded from core 0. */ + tx_thread_sleep(20); + + /* Deactivate timer 0. */ + status = tx_timer_deactivate(&timer_0); + + /* Delete both timers. */ + status += tx_timer_delete(&timer_0); + status += tx_timer_delete(&timer_1); + + /* Check status. */ + if ((status != TX_SUCCESS) || (timer_0_counter == 0) || (timer_1_counter != 0)) + { + + /* Application timer error. */ + printf("ERROR #43\n"); + test_control_return(1); + } + else + { + + /* Successful simple timer test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + + while(1) + { + + tx_thread_relinquish(); + } +} + +static void timer_0_expiration(ULONG timer_input) +{ + + + /* Process timer expiration. */ + timer_0_counter++; +} + + +static void timer_1_expiration(ULONG timer_input) +{ + + /* Process timer expiration. */ + timer_1_counter++; +} diff --git a/test/smp/regression/threadx_trace_basic_test.c b/test/smp/regression/threadx_trace_basic_test.c new file mode 100644 index 00000000..c6bc9be4 --- /dev/null +++ b/test/smp/regression/threadx_trace_basic_test.c @@ -0,0 +1,824 @@ +/* This test is designed to test trace functionality in ThreadX. */ + +#include +#include "tx_api.h" +#include "tx_thread.h" +#define TX_SOURCE_CODE +#include "tx_trace.h" + +//#define FILE_DUMP + +#ifdef __linux__ +#define TX_WIN32_MEMORY_SIZE TX_LINUX_MEMORY_SIZE +#define _tx_win32_critical_section _tx_linux_mutex +#define tx_win32_critical_section_nested_count tx_linux_mutex_nested_count +#endif /* __linux__ */ + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + +extern UINT _tx_trace_interrupt_control(UINT new_posture); +extern VOID _tx_trace_object_register(UCHAR object_type, VOID *object_ptr, CHAR *object_name, ULONG parameter_1, ULONG parameter_2); +extern VOID _tx_trace_object_unregister(VOID *object_ptr); + +static unsigned long thread_0_counter = 0; +static unsigned long thread_1_counter = 0; +static unsigned long thread_2_counter = 0; +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; + +static TX_TIMER timer_0; + +static TX_BLOCK_POOL block_pool_0; +static TX_BYTE_POOL byte_pool_0; +static TX_EVENT_FLAGS_GROUP group_0; +static TX_MUTEX mutex_0; +static TX_QUEUE queue_0; +static TX_SEMAPHORE semaphore_0; + +/* Define a bunch of semaphores for loading up the trace buffer. */ + +static TX_SEMAPHORE semaphore_1; +static TX_SEMAPHORE semaphore_2; +static TX_SEMAPHORE semaphore_3; +static TX_SEMAPHORE semaphore_4; +static TX_SEMAPHORE semaphore_5; +static TX_SEMAPHORE semaphore_6; +static TX_SEMAPHORE semaphore_7; +static TX_SEMAPHORE semaphore_8; +static TX_SEMAPHORE semaphore_9; +static TX_SEMAPHORE semaphore_10; +static TX_SEMAPHORE semaphore_11; +static TX_SEMAPHORE semaphore_12; +static TX_SEMAPHORE semaphore_13; +static TX_SEMAPHORE semaphore_14; +static TX_SEMAPHORE semaphore_15; +static TX_SEMAPHORE semaphore_16; + + +static unsigned long error = 0; +static unsigned long full_buffer = 0; +static void *save_pointer; + +#if TX_WIN32_MEMORY_SIZE + +static FILE *trace_dump_file; +static CHAR trace_dump_file_name[]= "tracedump000.trx"; + +#endif + + +/* Define task prototypes. */ + +static void thread_0_entry(ULONG task_input); +static void thread_1_entry(ULONG task_input); +static void thread_2_entry(ULONG task_input); + + +/* Define the trace buffer. */ +UCHAR trace_buffer[16384]; + + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); +UINT _tx_thread_interrupt_control(UINT new_posture); + + +void trace_dump(void) +{ + +#if FILE_DUMP + +/* Win32 automatic dump! */ +UINT old_interrupt; + + + /* Disable interrupts. */ + old_interrupt = _tx_thread_smp_protect(); + + /* If win32, we can actually dump the file! */ + trace_dump_file = fopen(trace_dump_file_name, "wb+"); + + fwrite(trace_buffer, 1, sizeof(trace_buffer), trace_dump_file); + + fclose(trace_dump_file); + + /* Restore interrupts. */ + _tx_thread_smp_unprotect(old_interrupt); + + /* Prepare for next file dump. */ + trace_dump_file_name[11]++; + if (trace_dump_file_name[11] > '9') + { + trace_dump_file_name[11] = '0'; + trace_dump_file_name[10]++; + + if (trace_dump_file_name[10] > '9') + { + trace_dump_file_name[10] = '0'; + trace_dump_file_name[9]++; + + if (trace_dump_file_name[9] > '9') + trace_dump_file_name[9] = '0'; + } + } + +#endif + +} + + +/* Define the timer for this test. */ + +static void timer_entry(ULONG i) +{ + + /* Resume thread 1. */ + tx_thread_resume(&thread_1); +} + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + + if ((_tx_thread_smp_protection.tx_thread_smp_protect_in_force != 1) || + (_tx_win32_critical_section.tx_win32_critical_section_nested_count > 1)) + { + + /* Make ISR entry event. */ + tx_trace_isr_enter_insert(2); + } + else + { + + /* Make ISR entry event. */ + tx_trace_isr_enter_insert(1); + } + + /* Resume thread 2. */ + tx_thread_resume(&thread_2); + + /* Make ISR entry event. */ + tx_trace_isr_exit_insert(1); + + /* Make ISR entry event. */ + tx_trace_isr_enter_insert(0); + + /* Make ISR entry event. */ + tx_trace_isr_exit_insert(0); + +} + + +/* Define the trace buffer full notify function. */ + +static VOID trace_buffer_full(void *ptr) +{ + + /* Dump trace file! */ + trace_dump(); + + full_buffer++; +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void threadx_trace_basic_application_define(void *first_unused_memory) +#endif +{ + +INT status; +CHAR *pointer; + + + /* Setup a pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Adjust it forward just to make sure there is some space for the test below. */ + pointer = pointer + 200; + + /* Create a bunch of objects before being enabled. */ + + /* Create a timer for the test. */ + save_pointer = (void *) pointer; + tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 2, 2, TX_AUTO_ACTIVATE); + tx_block_pool_create(&block_pool_0, "block pool 0", 20, pointer, 100); + pointer = pointer + 100; + tx_byte_pool_create(&byte_pool_0, "byte pool 0", pointer, 1000); + pointer = pointer + 1000; + tx_event_flags_create(&group_0, "event flags group 0"); + tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + tx_queue_create(&queue_0, "queue 0", 16, pointer, 400); + pointer = pointer + 400; + tx_semaphore_create(&semaphore_0, "semaphore 0", 1); + + /* Enable event tracing. */ + _tx_trace_initialize(); + status = tx_trace_enable(trace_buffer, sizeof(trace_buffer), 16); + +#ifdef TX_ENABLE_EVENT_TRACE + + /* Check status. */ + if (status != TX_SUCCESS) + { + + printf("Running Trace Basic Test............................................ ERROR #1\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("Running Trace Basic Test............................................ ERROR #2\n"); + test_control_return(1); + } +#endif + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, TEST_STACK_SIZE_PRINTF, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Trace Basic Test............................................ ERROR #3\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, TEST_STACK_SIZE_PRINTF, + 15, 15, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Trace Basic Test............................................ ERROR #4\n"); + test_control_return(1); + } + + status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, TEST_STACK_SIZE_PRINTF, + 14, 14, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + TEST_STACK_SIZE_PRINTF; + + /* Check for status. */ + if (status != TX_SUCCESS) + { + + printf("Running Trace Basic Test............................................ ERROR #5\n"); + test_control_return(1); + } +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT old_interrupt; +CHAR *pointer; +TX_INTERRUPT_SAVE_AREA +ULONG object; + + /* Coverage for build without TraceX enabled. */ + tx_interrupt_save = _tx_trace_interrupt_control(TX_INT_DISABLE); + _tx_trace_interrupt_control(tx_interrupt_save); +#ifndef TX_ENABLE_EVENT_TRACE + _tx_trace_object_register(0, TX_NULL, TX_NULL, 0, 0); + _tx_trace_object_register(1, TX_NULL, TX_NULL, 0, 0); + _tx_trace_object_register(1, &object, TX_NULL, 0, 0); + _tx_trace_object_register(1, &object, "fake name", 0, 0); + _tx_trace_object_register(1, &object, "fake name", 1, 0); +#endif + _tx_trace_object_register(1, &object, "fake name", 1, 1); + _tx_trace_object_unregister(TX_NULL); + _tx_trace_object_unregister(&object); + + + /* Increment thread 0 counter. */ + thread_0_counter++; + + /* Inform user of success getting to this test. */ + printf("Running Trace Basic Test............................................ "); + + /* Delete the additional objects. */ + tx_timer_delete(&timer_0); + tx_block_pool_delete(&block_pool_0); + tx_byte_pool_delete(&byte_pool_0); + tx_event_flags_delete(&group_0); + tx_mutex_delete(&mutex_0); + tx_queue_delete(&queue_0); + tx_semaphore_delete(&semaphore_0); + + /* Create all the semaphores. */ + tx_semaphore_create(&semaphore_1, "semaphore 1", 1); + tx_semaphore_create(&semaphore_2, "semaphore 2", 1); + tx_semaphore_create(&semaphore_3, "semaphore 3", 1); + tx_semaphore_create(&semaphore_4, "semaphore 4", 1); + tx_semaphore_create(&semaphore_5, "semaphore 5", 1); + tx_semaphore_create(&semaphore_6, "semaphore 6", 1); + tx_semaphore_create(&semaphore_7, "semaphore 7", 1); + tx_semaphore_create(&semaphore_8, "semaphore 8", 1); + tx_semaphore_create(&semaphore_9, "semaphore 9", 1); + tx_semaphore_create(&semaphore_10, "semaphore 10", 1); + tx_semaphore_create(&semaphore_11, "semaphore 11", 1); + tx_semaphore_create(&semaphore_12, "semaphore 12", 1); + tx_semaphore_create(&semaphore_13, "semaphore 13", 1); + tx_semaphore_create(&semaphore_14, "semaphore 14", 1); + tx_semaphore_create(&semaphore_15, "semaphore 15", 1); + tx_semaphore_create(&semaphore_16, "semaphore 16", 1); + + /* Delete them all. */ + tx_semaphore_delete(&semaphore_1); + tx_semaphore_delete(&semaphore_2); + tx_semaphore_delete(&semaphore_3); + tx_semaphore_delete(&semaphore_4); + tx_semaphore_delete(&semaphore_5); + tx_semaphore_delete(&semaphore_6); + tx_semaphore_delete(&semaphore_7); + tx_semaphore_delete(&semaphore_8); + tx_semaphore_delete(&semaphore_9); + tx_semaphore_delete(&semaphore_10); + tx_semaphore_delete(&semaphore_11); + tx_semaphore_delete(&semaphore_12); + tx_semaphore_delete(&semaphore_13); + tx_semaphore_delete(&semaphore_14); + tx_semaphore_delete(&semaphore_15); + tx_semaphore_delete(&semaphore_16); + + /* Create one over again. */ + tx_semaphore_create(&semaphore_1, "semaphore 1", 1); + + /* Now, create them all again. */ + pointer = (CHAR *) save_pointer; + tx_block_pool_create(&block_pool_0, "block pool 0", 20, pointer, 100); + pointer = pointer + 100; + tx_byte_pool_create(&byte_pool_0, "byte pool 0", pointer, 1000); + pointer = pointer + 1000; + tx_event_flags_create(&group_0, "event flags group 0"); + tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + tx_queue_create(&queue_0, "queue 0", 16, pointer, 400); + pointer = pointer + 400; + tx_semaphore_create(&semaphore_0, "semaphore 0", 1); + + /* Attempt to enable event tracing again. */ + status = tx_trace_enable(trace_buffer, sizeof(trace_buffer), 8); + +#ifdef TX_ENABLE_EVENT_TRACE + + /* Check status. */ + if (status != TX_NOT_DONE) + { + + printf("ERROR #6\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("ERROR #7\n"); + test_control_return(1); + } + + /* Attempt to enable event tracing again. */ + status = tx_trace_enable(TX_NULL, 0, 8); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("ERROR #8\n"); + test_control_return(1); + } + + /* Attempt to enable event tracing again. */ + status = tx_trace_enable(TX_NULL, 1, 0); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("ERROR #9\n"); + test_control_return(1); + } + + /* Attempt to enable event tracing again. */ + status = tx_trace_enable(TX_NULL, 1, 8); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + printf("ERROR #10\n"); + test_control_return(1); + } + +#endif + + /* Filter all events. */ + status = tx_trace_event_filter(TX_TRACE_ALL_EVENTS); + +#ifdef TX_ENABLE_EVENT_TRACE + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Trace error. */ + printf("ERROR #11\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #12\n"); + test_control_return(1); + } + + /* Filter all events. */ + status = tx_trace_event_filter(0); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #13\n"); + test_control_return(1); + } + +#endif + + /* Unfilter all events. */ + status = tx_trace_event_unfilter(TX_TRACE_ALL_EVENTS); + +#ifdef TX_ENABLE_EVENT_TRACE + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Trace error. */ + printf("ERROR #14\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #15\n"); + test_control_return(1); + } + + /* Unfilter all events. */ + status = tx_trace_event_unfilter(0); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #16\n"); + test_control_return(1); + } + +#endif + + /* Register the trace buffer full notification routine. */ + status = tx_trace_buffer_full_notify(trace_buffer_full); + +#ifdef TX_ENABLE_EVENT_TRACE + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Trace error. */ + printf("ERROR #17\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #18\n"); + test_control_return(1); + } + + /* Check the NULL path with trace disabled. */ + status = tx_trace_buffer_full_notify(TX_NULL); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #19\n"); + test_control_return(1); + } + +#endif + + /* Create a timer for the test. */ + tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 2, 2, TX_AUTO_ACTIVATE); + + /* Setup the ISR. */ + test_isr_dispatch = test_isr; + + while (full_buffer < 40) + { + +if ((_tx_thread_smp_protection.tx_thread_smp_protect_in_force != 0) || + (_tx_win32_critical_section.tx_win32_critical_section_nested_count != 0)) + test_isr_dispatch = test_isr; + + if (full_buffer < 20) + { + + /* Disable interrupts. */ + old_interrupt = tx_interrupt_control(TX_INT_DISABLE); + +if ((_tx_thread_smp_protection.tx_thread_smp_protect_in_force != 0) || + (_tx_win32_critical_section.tx_win32_critical_section_nested_count != 1)) + test_isr_dispatch = test_isr; + + /* Restore interrupts. */ + tx_interrupt_control(old_interrupt); + +if ((_tx_thread_smp_protection.tx_thread_smp_protect_in_force != 0) || + (_tx_win32_critical_section.tx_win32_critical_section_nested_count != 0)) + test_isr_dispatch = test_isr; + } + + /* Insert user event. */ + status = tx_trace_user_event_insert(1027, 1, 2, 3, 4); + +if ((_tx_thread_smp_protection.tx_thread_smp_protect_in_force != 0) || + (_tx_win32_critical_section.tx_win32_critical_section_nested_count != 0)) + test_isr_dispatch = test_isr; + + +#ifdef TX_ENABLE_EVENT_TRACE + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Trace error. */ + printf("ERROR #20\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #21\n"); + test_control_return(1); + } + + /* Insert user event. */ + status = tx_trace_user_event_insert(0, 1, 2, 3, 4); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #22\n"); + test_control_return(1); + } + + /* Insert user event. */ + status = tx_trace_user_event_insert(0, 0, 2, 3, 4); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #23\n"); + test_control_return(1); + } + + /* Insert user event. */ + status = tx_trace_user_event_insert(0, 0, 0, 3, 4); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #24\n"); + test_control_return(1); + } + + /* Insert user event. */ + status = tx_trace_user_event_insert(0, 0, 0, 0, 4); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #25\n"); + test_control_return(1); + } + + /* Insert user event. */ + status = tx_trace_user_event_insert(0, 0, 0, 0, 0); + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #26\n"); + test_control_return(1); + } + + break; +#endif + } + + /* Clear the ISR. */ + test_isr_dispatch = TX_NULL; + + /* Disable the trace buffer. */ + status = tx_trace_disable(); + +#ifdef TX_ENABLE_EVENT_TRACE + + /* Check status. */ + if (status != TX_SUCCESS) + { + + /* Trace error. */ + printf("ERROR #27\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #28\n"); + test_control_return(1); + } +#endif + + /* Attempt to disable again, just to get the TX_NOT_DONE error code. */ + status = tx_trace_disable(); + +#ifdef TX_ENABLE_EVENT_TRACE + + /* Check status. */ + if (status != TX_NOT_DONE) + { + + /* Trace error. */ + printf("ERROR #29\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #30\n"); + test_control_return(1); + } +#endif + + /* Attempt to enable event tracing with a bogus size. */ + status = tx_trace_enable(trace_buffer, 1, 8); + +#ifdef TX_ENABLE_EVENT_TRACE + + /* Check status. */ + if (status != TX_SIZE_ERROR) + { + + /* Trace error. */ + printf("ERROR #31\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #32\n"); + test_control_return(1); + } +#endif + + + /* Attempt to make an user event when tracing is not enabled. */ + status = tx_trace_user_event_insert(1027, 1, 2, 3, 4); + +#ifdef TX_ENABLE_EVENT_TRACE + + /* Check status. */ + if (status != TX_NOT_DONE) + { + + /* Trace error. */ + printf("ERROR #33\n"); + test_control_return(1); + } +#else + + /* Check status. */ + if (status != TX_FEATURE_NOT_ENABLED) + { + + /* Trace error. */ + printf("ERROR #34\n"); + test_control_return(1); + } +#endif + + + /* Check status. */ + if (error) + { + + /* Trace error. */ + printf("ERROR #35\n"); + test_control_return(1); + } + else + { + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG task_input) +{ + + while(1) + { + + thread_1_counter++; + tx_thread_suspend(&thread_1); + } +} + + + +static void thread_2_entry(ULONG task_input) +{ + + while(1) + { + + thread_2_counter++; + tx_thread_suspend(&thread_2); + } +} diff --git a/test/tx/cmake/CMakeLists.txt b/test/tx/cmake/CMakeLists.txt new file mode 100644 index 00000000..02e2a41b --- /dev/null +++ b/test/tx/cmake/CMakeLists.txt @@ -0,0 +1,73 @@ +cmake_minimum_required(VERSION 3.13 FATAL_ERROR) +cmake_policy(SET CMP0054 NEW) +cmake_policy(SET CMP0057 NEW) + +project(threadx_test LANGUAGES C) + +# Set build configurations +set(BUILD_CONFIGURATIONS default_build_coverage disable_notify_callbacks_build + stack_checking_build trace_build) +set(CMAKE_CONFIGURATION_TYPES + ${BUILD_CONFIGURATIONS} + CACHE STRING "list of supported configuration types" FORCE) +set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + ${CMAKE_CONFIGURATION_TYPES}) +list(GET CMAKE_CONFIGURATION_TYPES 0 BUILD_TYPE) +if((NOT CMAKE_BUILD_TYPE) OR (NOT ("${CMAKE_BUILD_TYPE}" IN_LIST + CMAKE_CONFIGURATION_TYPES))) + set(CMAKE_BUILD_TYPE + "${BUILD_TYPE}" + CACHE STRING "Build Type of the project" FORCE) +endif() + +message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") +message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.") +set(default_build_coverage "") +set(disable_notify_callbacks_build -DTX_DISABLE_NOTIFY_CALLBACKS) +set(stack_checking_build -DTX_ENABLE_STACK_CHECKING) +set(trace_build -DTX_ENABLE_EVENT_TRACE) + +add_compile_options( + -m32 + -std=c99 + -ggdb + -g3 + -gdwarf-2 + -fdiagnostics-color + -Werror + -DTX_REGRESSION_TEST + -DTEST_STACK_SIZE_PRINTF=4096 + ${${CMAKE_BUILD_TYPE}}) +add_link_options(-m32) + +enable_testing() + +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../../.. threadx) +add_subdirectory(regression) +add_subdirectory(samples) + +# Coverage +if(CMAKE_BUILD_TYPE MATCHES ".*_coverage") + target_compile_options(threadx PRIVATE -fprofile-arcs -ftest-coverage) + target_link_options(threadx PRIVATE -fprofile-arcs -ftest-coverage) +endif() + +target_compile_options( + threadx + PRIVATE -Werror + -Wall + -Wextra + -pedantic + -fmessage-length=0 + -fsigned-char + -ffunction-sections + -fdata-sections + -Wunused + -Wuninitialized + -Wmissing-declarations + -Wconversion + -Wpointer-arith + # -Wshadow + -Wlogical-op + -Waggregate-return + -Wfloat-equal) diff --git a/test/tx/cmake/coverage.sh b/test/tx/cmake/coverage.sh new file mode 100755 index 00000000..ae2c7a4b --- /dev/null +++ b/test/tx/cmake/coverage.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -e + +cd $(dirname $0) +mkdir -p coverage_report/$1 +gcovr --object-directory=build/$1/threadx/CMakeFiles/threadx.dir/common/src -r build/$1 -f ../../../common/src --xml-pretty --output coverage_report/$1.xml +gcovr --object-directory=build/$1/threadx/CMakeFiles/threadx.dir/common/src -r build/$1 -f ../../../common/src --html --html-details --output coverage_report/$1/index.html diff --git a/test/tx/cmake/regression/CMakeLists.txt b/test/tx/cmake/regression/CMakeLists.txt new file mode 100644 index 00000000..160f9e29 --- /dev/null +++ b/test/tx/cmake/regression/CMakeLists.txt @@ -0,0 +1,121 @@ +cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR) +cmake_policy(SET CMP0057 NEW) + +project(regression_test LANGUAGES C) + +set(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../regression) + +set(regression_test_cases + ${SOURCE_DIR}/threadx_block_memory_basic_test.c + ${SOURCE_DIR}/threadx_block_memory_error_detection_test.c + ${SOURCE_DIR}/threadx_block_memory_information_test.c + ${SOURCE_DIR}/threadx_block_memory_prioritize_test.c + ${SOURCE_DIR}/threadx_block_memory_suspension_test.c + ${SOURCE_DIR}/threadx_block_memory_suspension_timeout_test.c + ${SOURCE_DIR}/threadx_block_memory_thread_terminate_test.c + ${SOURCE_DIR}/threadx_byte_memory_basic_test.c + ${SOURCE_DIR}/threadx_byte_memory_information_test.c + ${SOURCE_DIR}/threadx_byte_memory_prioritize_test.c + ${SOURCE_DIR}/threadx_byte_memory_suspension_test.c + ${SOURCE_DIR}/threadx_byte_memory_suspension_timeout_test.c + ${SOURCE_DIR}/threadx_byte_memory_thread_contention_test.c + ${SOURCE_DIR}/threadx_byte_memory_thread_terminate_test.c + ${SOURCE_DIR}/threadx_event_flag_basic_test.c + ${SOURCE_DIR}/threadx_event_flag_information_test.c + ${SOURCE_DIR}/threadx_event_flag_isr_set_clear_test.c + ${SOURCE_DIR}/threadx_event_flag_isr_wait_abort_test.c + ${SOURCE_DIR}/threadx_event_flag_single_thread_terminate_test.c + ${SOURCE_DIR}/threadx_event_flag_suspension_consume_test.c + ${SOURCE_DIR}/threadx_event_flag_suspension_different_bits_consume_test.c + ${SOURCE_DIR}/threadx_event_flag_suspension_different_bits_test.c + ${SOURCE_DIR}/threadx_event_flag_suspension_test.c + ${SOURCE_DIR}/threadx_event_flag_suspension_timeout_test.c + ${SOURCE_DIR}/threadx_event_flag_thread_terminate_test.c + ${SOURCE_DIR}/threadx_interrupt_control_test.c + ${SOURCE_DIR}/threadx_mutex_basic_test.c + ${SOURCE_DIR}/threadx_mutex_delete_test.c + ${SOURCE_DIR}/threadx_mutex_information_test.c + ${SOURCE_DIR}/threadx_mutex_nested_priority_inheritance_test.c + ${SOURCE_DIR}/threadx_mutex_no_preemption_test.c + ${SOURCE_DIR}/threadx_mutex_preemption_test.c + ${SOURCE_DIR}/threadx_mutex_priority_inheritance_test.c + ${SOURCE_DIR}/threadx_mutex_proritize_test.c + ${SOURCE_DIR}/threadx_mutex_suspension_timeout_test.c + ${SOURCE_DIR}/threadx_mutex_thread_terminate_test.c + ${SOURCE_DIR}/threadx_queue_basic_eight_word_test.c + ${SOURCE_DIR}/threadx_queue_basic_four_word_test.c + ${SOURCE_DIR}/threadx_queue_basic_one_word_test.c + ${SOURCE_DIR}/threadx_queue_basic_sixteen_word_test.c + ${SOURCE_DIR}/threadx_queue_basic_two_word_test.c + ${SOURCE_DIR}/threadx_queue_empty_suspension_test.c + ${SOURCE_DIR}/threadx_queue_flush_no_suspension_test.c + ${SOURCE_DIR}/threadx_queue_flush_test.c + ${SOURCE_DIR}/threadx_queue_front_send_test.c + ${SOURCE_DIR}/threadx_queue_full_suspension_test.c + ${SOURCE_DIR}/threadx_queue_information_test.c + ${SOURCE_DIR}/threadx_queue_prioritize.c + ${SOURCE_DIR}/threadx_queue_suspension_timeout_test.c + ${SOURCE_DIR}/threadx_queue_thread_terminate_test.c + ${SOURCE_DIR}/threadx_semaphore_basic_test.c + ${SOURCE_DIR}/threadx_semaphore_ceiling_put_test.c + ${SOURCE_DIR}/threadx_semaphore_delete_test.c + ${SOURCE_DIR}/threadx_semaphore_information_test.c + ${SOURCE_DIR}/threadx_semaphore_non_preemption_test.c + ${SOURCE_DIR}/threadx_semaphore_preemption_test.c + ${SOURCE_DIR}/threadx_semaphore_prioritize.c + ${SOURCE_DIR}/threadx_semaphore_thread_terminate_test.c + ${SOURCE_DIR}/threadx_semaphore_timeout_test.c + ${SOURCE_DIR}/threadx_thread_basic_execution_test.c + ${SOURCE_DIR}/threadx_thread_basic_time_slice_test.c + ${SOURCE_DIR}/threadx_thread_completed_test.c + ${SOURCE_DIR}/threadx_thread_create_preemption_threshold_test.c + ${SOURCE_DIR}/threadx_thread_delayed_suspension_test.c + ${SOURCE_DIR}/threadx_thread_information_test.c + ${SOURCE_DIR}/threadx_thread_multi_level_preemption_threshold_test.c + ${SOURCE_DIR}/threadx_thread_multiple_non_current_test.c + ${SOURCE_DIR}/threadx_thread_multiple_sleep_test.c + ${SOURCE_DIR}/threadx_thread_multiple_suspension_test.c + ${SOURCE_DIR}/threadx_thread_multiple_time_slice_test.c + ${SOURCE_DIR}/threadx_thread_preemptable_suspension_test.c + ${SOURCE_DIR}/threadx_thread_preemption_change_test.c + ${SOURCE_DIR}/threadx_thread_priority_change.c + ${SOURCE_DIR}/threadx_thread_relinquish_test.c + ${SOURCE_DIR}/threadx_thread_reset_test.c + ${SOURCE_DIR}/threadx_thread_simple_sleep_non_clear_test.c + ${SOURCE_DIR}/threadx_thread_simple_sleep_test.c + ${SOURCE_DIR}/threadx_thread_simple_suspend_test.c + ${SOURCE_DIR}/threadx_thread_sleep_for_100ticks_test.c + ${SOURCE_DIR}/threadx_thread_sleep_terminate_test.c + ${SOURCE_DIR}/threadx_thread_stack_checking_test.c + ${SOURCE_DIR}/threadx_thread_terminate_delete_test.c + ${SOURCE_DIR}/threadx_thread_time_slice_change_test.c + ${SOURCE_DIR}/threadx_thread_wait_abort_and_isr_test.c + ${SOURCE_DIR}/threadx_thread_wait_abort_test.c + ${SOURCE_DIR}/threadx_time_get_set_test.c + ${SOURCE_DIR}/threadx_timer_activate_deactivate_test.c + ${SOURCE_DIR}/threadx_timer_deactivate_accuracy_test.c + ${SOURCE_DIR}/threadx_timer_information_test.c + ${SOURCE_DIR}/threadx_timer_large_timer_accuracy_test.c + ${SOURCE_DIR}/threadx_timer_multiple_accuracy_test.c + ${SOURCE_DIR}/threadx_timer_multiple_test.c + ${SOURCE_DIR}/threadx_timer_simple_test.c + ${SOURCE_DIR}/threadx_trace_basic_test.c + ${SOURCE_DIR}/threadx_initialize_kernel_setup_test.c) + +add_custom_command( + OUTPUT ${SOURCE_DIR}/tx_initialize_low_level.c + COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/generate_test_file.sh + COMMENT "Generating tx_initialize_low_level.c for test") + +add_library(test_utility ${SOURCE_DIR}/tx_initialize_low_level.c + ${SOURCE_DIR}/testcontrol.c) +target_link_libraries(test_utility PUBLIC azrtos::threadx) +target_compile_definitions(test_utility PUBLIC CTEST BATCH_TEST + TEST_STACK_SIZE_PRINTF=4096) + +foreach(test_case ${regression_test_cases}) + get_filename_component(test_name ${test_case} NAME_WE) + add_executable(${test_name} ${test_case}) + target_link_libraries(${test_name} PRIVATE test_utility) + add_test(${CMAKE_BUILD_TYPE}::${test_name} ${test_name}) +endforeach() diff --git a/test/tx/cmake/regression/generate_test_file.sh b/test/tx/cmake/regression/generate_test_file.sh new file mode 100755 index 00000000..ac0a70fa --- /dev/null +++ b/test/tx/cmake/regression/generate_test_file.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +dst=$(dirname $0)/../../regression/tx_initialize_low_level.c +src=$(dirname $0)/../../../../ports/linux/gnu/src/tx_initialize_low_level.c + +line=`sed -n '/_tx_linux_timer_interrupt/=' $src | tail -n 1` +sed "${line}iVOID test_interrupt_dispatch(VOID);" $src > tmp1 +line=`sed -n '/_tx_timer_interrupt/=' $src | tail -n 1` +sed "${line}itest_interrupt_dispatch();" tmp1 > $dst +rm tmp1 \ No newline at end of file diff --git a/test/tx/cmake/run.sh b/test/tx/cmake/run.sh new file mode 120000 index 00000000..d2f7f7df --- /dev/null +++ b/test/tx/cmake/run.sh @@ -0,0 +1 @@ +../../../tools/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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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, ¤t_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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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, ¤t_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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 **) ¤t_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 +#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 +#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 +#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 +#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 +#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 +#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 +#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); + } +} From 5f430f22e2c00f2c079c91f48c9e2a0fc0bbbf47 Mon Sep 17 00:00:00 2001 From: Tiejun Zhou Date: Tue, 11 Apr 2023 07:36:09 +0000 Subject: [PATCH 2/2] Add Azure DevOps pipelines for ThreadX test --- .pipelines/smp.yml | 59 +++++++++++++++++++++++++++++++++++++++++++ .pipelines/tx.yml | 59 +++++++++++++++++++++++++++++++++++++++++++ scripts/install.sh | 22 ++++++++++++++++ scripts/sdl_check.sh | 19 ++++++++++++++ test/smp/cmake/run.sh | 2 +- test/tx/cmake/run.sh | 2 +- 6 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 .pipelines/smp.yml create mode 100644 .pipelines/tx.yml create mode 100755 scripts/install.sh create mode 100755 scripts/sdl_check.sh diff --git a/.pipelines/smp.yml b/.pipelines/smp.yml new file mode 100644 index 00000000..c60ae672 --- /dev/null +++ b/.pipelines/smp.yml @@ -0,0 +1,59 @@ +trigger: +- master + +pr: +- master + +pool: + vmImage: "ubuntu-22.04" + +steps: + - bash: sudo $(Build.SourcesDirectory)/scripts/install.sh + displayName: 'Install softwares' + env: + INDEX_URL: $(INDEX_URL) + + - task: Bash@3 + displayName: 'SDL check' + inputs: + filePath: '$(Build.SourcesDirectory)/scripts/sdl_check.sh' + + - task: Bash@3 + displayName: 'Build SMP' + inputs: + filePath: '$(Build.SourcesDirectory)/scripts/build_smp.sh' + + - task: Bash@3 + displayName: 'Test SMP' + inputs: + filePath: '$(Build.SourcesDirectory)/scripts/test_smp.sh' + + - task: PublishTestResults@2 + condition: succeededOrFailed() + displayName: 'Test SMP (PublishTestResults)' + inputs: + testResultsFormat: 'cTest' + testResultsFiles: '*/Testing/**/*.xml' + searchFolder: '$(Build.SourcesDirectory)/test/smp/cmake/build' + testRunTitle: 'SMP-Tests' + buildConfiguration: 'Release' + + - task: CopyFiles@2 + condition: succeededOrFailed() + displayName: 'Test SMP (PublishTestReports)' + inputs: + SourceFolder: '$(Build.SourcesDirectory)/test/smp/cmake' + Contents: | + build/*.txt + build/*/Testing/**/*.xml + coverage_report/**/* + TargetFolder: '$(ob_outputDirectory)/test_reports_SMP' + + - task: PublishCodeCoverageResults@1 + condition: succeededOrFailed() + displayName: 'Test SMP (PublishCodeCoverageResults)' + inputs: + codeCoverageTool: 'Cobertura' + summaryFileLocation: '$(Build.SourcesDirectory)/test/smp/cmake/coverage_report/default_build_coverage.xml' + pathToSources: '$(Build.SourcesDirectory)/test/smp/cmake' + reportDirectory: '$(Build.SourcesDirectory)/test/smp/cmake/coverage_report/default_build_coverage' diff --git a/.pipelines/tx.yml b/.pipelines/tx.yml new file mode 100644 index 00000000..b9319d2e --- /dev/null +++ b/.pipelines/tx.yml @@ -0,0 +1,59 @@ +trigger: +- master + +pr: +- master + +pool: + vmImage: "ubuntu-22.04" + +steps: + - bash: sudo $(Build.SourcesDirectory)/scripts/install.sh + displayName: 'Install softwares' + env: + INDEX_URL: $(INDEX_URL) + + - task: Bash@3 + displayName: 'SDL check' + inputs: + filePath: '$(Build.SourcesDirectory)/scripts/sdl_check.sh' + + - task: Bash@3 + displayName: 'Build TX' + inputs: + filePath: '$(Build.SourcesDirectory)/scripts/build_tx.sh' + + - task: Bash@3 + displayName: 'Test TX' + inputs: + filePath: '$(Build.SourcesDirectory)/scripts/test_tx.sh' + + - task: PublishTestResults@2 + condition: succeededOrFailed() + displayName: 'Test TX (PublishTestResults)' + inputs: + testResultsFormat: 'cTest' + testResultsFiles: '*/Testing/**/*.xml' + searchFolder: '$(Build.SourcesDirectory)/test/tx/cmake/build' + testRunTitle: 'TX-Tests' + buildConfiguration: 'Release' + + - task: CopyFiles@2 + condition: succeededOrFailed() + displayName: 'Test TX (PublishTestReports)' + inputs: + SourceFolder: '$(Build.SourcesDirectory)/test/tx/cmake' + Contents: | + build/*.txt + build/*/Testing/**/*.xml + coverage_report/**/* + TargetFolder: '$(ob_outputDirectory)/test_reports_TX' + + - task: PublishCodeCoverageResults@1 + condition: succeededOrFailed() + displayName: 'Test TX (PublishCodeCoverageResults)' + inputs: + codeCoverageTool: 'Cobertura' + summaryFileLocation: '$(Build.SourcesDirectory)/test/tx/cmake/coverage_report/default_build_coverage.xml' + pathToSources: '$(Build.SourcesDirectory)/test/tx/cmake' + reportDirectory: '$(Build.SourcesDirectory)/test/tx/cmake/coverage_report/default_build_coverage' diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 00000000..5435f4fc --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# +# Install necessary softwares for Ubuntu. + +apt-get update +apt-get install -y \ + gcc-multilib \ + git \ + g++ \ + python3-pip \ + ninja-build \ + unifdef \ + p7zip-full \ + tofrodos \ + gawk \ + cmake \ + software-properties-common + +python3 -m pip install --upgrade pip +pip3 install artifacts-keyring +pip3 install gcovr==4.1 $INDEX_URL + diff --git a/scripts/sdl_check.sh b/scripts/sdl_check.sh new file mode 100755 index 00000000..77eeb5ce --- /dev/null +++ b/scripts/sdl_check.sh @@ -0,0 +1,19 @@ +# !/bin/bash +dir_list="common common_smp common_modules ports ports_module ports_smp samples" +exclude_list="-path TX" +file_list=$(find $dir_list \( $exclude_list \) -prune -o -type f -name '*.[ch]' -print) +cd $(dirname `realpath $0`)/.. +echo "Checking for unexpected usage of memcpy..." +echo "" +echo "Excluding:" +echo $exclude_list | grep -P "[^\s]*/[^\s]*" -o +echo "" +echo "Result:" +grep -i "memcpy(" -i $file_list -n | grep -i "use case of .* is verified" -v +if [ "$?" -eq "1" ]; +then + echo "CLEAN" + exit 0 +else + exit 1 +fi \ No newline at end of file diff --git a/test/smp/cmake/run.sh b/test/smp/cmake/run.sh index d2f7f7df..429ff2bd 120000 --- a/test/smp/cmake/run.sh +++ b/test/smp/cmake/run.sh @@ -1 +1 @@ -../../../tools/cmake_bootstrap.sh \ No newline at end of file +../../../scripts/cmake_bootstrap.sh \ No newline at end of file diff --git a/test/tx/cmake/run.sh b/test/tx/cmake/run.sh index d2f7f7df..429ff2bd 120000 --- a/test/tx/cmake/run.sh +++ b/test/tx/cmake/run.sh @@ -1 +1 @@ -../../../tools/cmake_bootstrap.sh \ No newline at end of file +../../../scripts/cmake_bootstrap.sh \ No newline at end of file