mirror of
https://github.com/azure-rtos/threadx
synced 2025-01-30 08:02:57 +08:00
Release ThreadX regression system
This commit is contained in:
parent
ac3b6b326c
commit
ebeb02b958
4
.devcontainer/devcontainer.json
Normal file
4
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"image": "tizho/azurertos-regression",
|
||||
"runArgs": [ "--cap-add=NET_ADMIN"]
|
||||
}
|
2
scripts/build_smp.sh
Executable file
2
scripts/build_smp.sh
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
$(dirname `realpath $0`)/../test/smp/cmake/run.sh build all
|
2
scripts/build_tx.sh
Executable file
2
scripts/build_tx.sh
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
$(dirname `realpath $0`)/../test/tx/cmake/run.sh build all
|
120
scripts/cmake_bootstrap.sh
Executable file
120
scripts/cmake_bootstrap.sh
Executable file
@ -0,0 +1,120 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
function help() {
|
||||
echo "Usage: $0 [build|test] [all|<build_configuration> <build_configuration>...]"
|
||||
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
|
3
scripts/test_smp.sh
Executable file
3
scripts/test_smp.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
CTEST_PARALLEL_LEVEL=4 $(dirname `realpath $0`)/../test/smp/cmake/run.sh test all
|
3
scripts/test_tx.sh
Executable file
3
scripts/test_tx.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
CTEST_PARALLEL_LEVEL=4 $(dirname `realpath $0`)/../test/tx/cmake/run.sh test all
|
2
test/.gitignore
vendored
Normal file
2
test/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
tx_initialize_low_level.c
|
||||
coverage_report/
|
76
test/smp/cmake/CMakeLists.txt
Normal file
76
test/smp/cmake/CMakeLists.txt
Normal file
@ -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)
|
9
test/smp/cmake/coverage.sh
Executable file
9
test/smp/cmake/coverage.sh
Executable file
@ -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
|
133
test/smp/cmake/regression/CMakeLists.txt
Normal file
133
test/smp/cmake/regression/CMakeLists.txt
Normal file
@ -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()
|
10
test/smp/cmake/regression/generate_test_file.sh
Executable file
10
test/smp/cmake/regression/generate_test_file.sh
Executable file
@ -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
|
1
test/smp/cmake/run.sh
Symbolic link
1
test/smp/cmake/run.sh
Symbolic link
@ -0,0 +1 @@
|
||||
../../../tools/cmake_bootstrap.sh
|
15
test/smp/cmake/samples/CMakeLists.txt
Normal file
15
test/smp/cmake/samples/CMakeLists.txt
Normal file
@ -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()
|
22
test/smp/cmake/samples/fake.c
Normal file
22
test/smp/cmake/samples/fake.c
Normal file
@ -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;
|
60
test/smp/cmake/threadx_smp/CMakeLists.txt
Normal file
60
test/smp/cmake/threadx_smp/CMakeLists.txt
Normal file
@ -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)
|
220
test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt
Normal file
220
test/smp/cmake/threadx_smp/common_smp/CMakeLists.txt
Normal file
@ -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
|
||||
)
|
||||
|
@ -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")
|
1609
test/smp/regression/testcontrol.c
Normal file
1609
test/smp/regression/testcontrol.c
Normal file
File diff suppressed because it is too large
Load Diff
568
test/smp/regression/threadx_block_memory_basic_test.c
Normal file
568
test/smp/regression/threadx_block_memory_basic_test.c
Normal file
@ -0,0 +1,568 @@
|
||||
/* This test is designed to test simple memory block pool creation, deletion, and
|
||||
allocates and releases. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
typedef struct BLOCK_MEMORY_TEST_STRUCT
|
||||
{
|
||||
ULONG first;
|
||||
ULONG second;
|
||||
TX_BLOCK_POOL pool;
|
||||
ULONG first_middle;
|
||||
ULONG second_middle;
|
||||
ULONG pool_area[2048/sizeof(ULONG)];
|
||||
ULONG next_to_last;
|
||||
ULONG last;
|
||||
|
||||
} BLOCK_MEMORY_TEST;
|
||||
|
||||
static BLOCK_MEMORY_TEST block_memory;
|
||||
|
||||
|
||||
/* Define external reference for status of block pool create from initialization. */
|
||||
|
||||
extern UINT test_block_pool_create_init;
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
|
||||
static TX_BLOCK_POOL pool_0;
|
||||
static TX_BLOCK_POOL pool_1;
|
||||
static TX_BLOCK_POOL pool_2;
|
||||
static TX_BLOCK_POOL pool_3;
|
||||
|
||||
static TX_TIMER timer_0;
|
||||
|
||||
|
||||
static unsigned long error = 0;
|
||||
static unsigned long timer_executed = 0;
|
||||
static unsigned long isr_executed = 0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Prototype direct call to block pool core service. */
|
||||
|
||||
UINT _tx_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size,
|
||||
VOID *pool_start, ULONG pool_size);
|
||||
|
||||
|
||||
|
||||
/* Define the timer for this test. */
|
||||
|
||||
static void timer_entry(ULONG i)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Determine if calling block pool create from initialization was successful. */
|
||||
if (test_block_pool_create_init != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to create a block pool from a timer. */
|
||||
pointer = (CHAR *) 0x30000;
|
||||
status = tx_block_pool_create(&pool_3, "pool 3", 100, pointer, 320);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to delete a block pool. */
|
||||
status = tx_block_pool_delete(&pool_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
timer_executed = 1;
|
||||
|
||||
/* Attempt to allocate a block with suspension from a timer. */
|
||||
status = tx_block_allocate(&pool_0, (void **) &pointer, 10);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
CHAR *pointer;
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Attempt to Allocate block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to create a block pool from an ISR. */
|
||||
status = tx_block_pool_create(&pool_3, "pool 3", 100, (void *) 0x100000, 320);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to delete a pool from an ISR. */
|
||||
status = tx_block_pool_delete(&pool_0);
|
||||
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
isr_executed = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_block_memory_basic_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Basic Functionality Test....................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
18, 18, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Basic Functionality Test....................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create block pools 0 and 1. */
|
||||
status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
|
||||
pointer = pointer + 320;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Basic Functionality Test....................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_block_pool_create(&pool_1, "pool 1", 100, pointer, 320);
|
||||
pointer = pointer + 320;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Basic Functionality Test....................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Check the no-blocks path. */
|
||||
status = _tx_block_pool_create(&pool_2, "pool 2", 100, pointer, 50);
|
||||
pointer = pointer + 320;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SIZE_ERROR)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Basic Functionality Test....................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer_1;
|
||||
CHAR *pointer_2;
|
||||
CHAR *pointer_3;
|
||||
CHAR *pointer_4;
|
||||
INT i;
|
||||
unsigned long fake_block[20];
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Block Memory Basic Functionality Test....................... ");
|
||||
|
||||
/* Perform block memory test. */
|
||||
block_memory.first = 0x11223344;
|
||||
block_memory.second = 0x55667788;
|
||||
block_memory.first_middle = 0x21314151;
|
||||
block_memory.second_middle= 0x61718191;
|
||||
block_memory.next_to_last = 0x99aabbcc;
|
||||
block_memory.last = 0xddeeff00;
|
||||
|
||||
/* Create the block pool. */
|
||||
status = tx_block_pool_create(&block_memory.pool, "pool memory", 16, &block_memory.pool_area[0], (2048*sizeof(ULONG))/sizeof(ULONG));
|
||||
tx_block_pool_delete(&block_memory.pool);
|
||||
|
||||
/* Check for status. */
|
||||
if ((status != TX_SUCCESS) ||
|
||||
(block_memory.first != 0x11223344) ||
|
||||
(block_memory.second != 0x55667788) ||
|
||||
(block_memory.first_middle != 0x21314151) ||
|
||||
(block_memory.second_middle != 0x61718191) ||
|
||||
(block_memory.next_to_last != 0x99aabbcc) ||
|
||||
(block_memory.last != 0xddeeff00))
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Try to release a non-block. */
|
||||
fake_block[0] = 0;
|
||||
fake_block[1] = 0;
|
||||
status = tx_block_release(&fake_block[2]);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Try to release a block that points to a non-pool. */
|
||||
fake_block[0] = 0;
|
||||
fake_block[1] = (unsigned long) &fake_block[0];
|
||||
status = tx_block_release(&fake_block[2]);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate first block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Allocate second block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Allocate third block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Attempt to allocate fourth block from the pool. This should fail because
|
||||
there should be no more blocks in the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_MEMORY)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR ##12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the memory of all of the allocated blocks. */
|
||||
for (i =0; i < 100; i++)
|
||||
{
|
||||
pointer_1[i] = (CHAR) 0xFF;
|
||||
pointer_2[i] = (CHAR) 0xFF;
|
||||
pointer_3[i] = (CHAR) 0xFF;
|
||||
}
|
||||
|
||||
/* Now release each of the blocks. */
|
||||
status = tx_block_release(pointer_1);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Release the second block. */
|
||||
status = tx_block_release(pointer_2);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Release the third block. */
|
||||
status = tx_block_release(pointer_3);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Allocate each block again to make sure everything still
|
||||
works. The block addresses should come out in reverse
|
||||
order, because a released block is placed at the head of
|
||||
the list. */
|
||||
|
||||
/* Allocate first block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Allocate second block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Allocate third block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Attempt to allocate fourth block from the pool. This should fail because
|
||||
there should be no more blocks in the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_MEMORY)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Create a timer for the test. */
|
||||
tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
|
||||
|
||||
/* Setup the ISR. */
|
||||
test_isr_dispatch = test_isr;
|
||||
|
||||
/* Sleep for a bit... */
|
||||
tx_thread_sleep(3);
|
||||
|
||||
/* Now resume the background thread. */
|
||||
tx_thread_resume(&thread_1);
|
||||
|
||||
/* Sleep for a bit... */
|
||||
tx_thread_sleep(3);
|
||||
|
||||
/* Clear the ISR. */
|
||||
test_isr_dispatch = TX_NULL;
|
||||
|
||||
/* Test for error. */
|
||||
if ((error) || (timer_executed != 1) || (isr_executed != 1))
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Delete both block pools. */
|
||||
status = tx_block_pool_delete(&pool_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_block_pool_delete(&pool_1);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (error))
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
387
test/smp/regression/threadx_block_memory_error_detection_test.c
Normal file
387
test/smp/regression/threadx_block_memory_error_detection_test.c
Normal file
@ -0,0 +1,387 @@
|
||||
/* This test is designed to test error detection for simple memory block operations. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
|
||||
static TX_BLOCK_POOL pool_0;
|
||||
static TX_BLOCK_POOL pool_1;
|
||||
static TX_BLOCK_POOL pool_2;
|
||||
static CHAR *pointer;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
UINT _txe_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size,
|
||||
VOID *pool_start, ULONG pool_size, UINT pool_control_block_size);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_block_memory_error_detection_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
INT status;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Create block pool 0. */
|
||||
status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
|
||||
pointer = pointer + 320;
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING /* skip this test and pretend it passed */
|
||||
|
||||
/* Create block pool again to get pool_ptr error. */
|
||||
status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
|
||||
if (status != TX_POOL_ERROR)
|
||||
return;
|
||||
|
||||
/* Create block pool with NULL pointer. */
|
||||
status = tx_block_pool_create(TX_NULL, "pool 0", 100, pointer, 320);
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Error Detection Test........................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create block pool pointer if NULL start. */
|
||||
status = tx_block_pool_create(&pool_1, "pool 0", 100, NULL, 320);
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Error Detection Test........................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create block pool pointer with invalid size. */
|
||||
status = tx_block_pool_create(&pool_1, "pool 0", 100, pointer, 100);
|
||||
if (status != TX_SIZE_ERROR)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Error Detection Test........................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt of allocate block with NULL dest. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) TX_NULL, TX_NO_WAIT);
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Error Detection Test........................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Delete null pointer. */
|
||||
status = tx_block_pool_delete(TX_NULL);
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Error Detection Test........................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif /* TX_DISABLE_ERROR_CHECKING */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
UINT status;
|
||||
CHAR *pointer_1;
|
||||
CHAR *pointer_2;
|
||||
CHAR *pointer_3;
|
||||
CHAR *pointer_4;
|
||||
INT i;
|
||||
#endif
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Block Memory Error Detection Test........................... ");
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING /* skip this test and pretend it passed */
|
||||
|
||||
status = tx_block_pool_create(&pool_1, "pool 1", 100, pointer, 320);
|
||||
pointer = pointer + 320;
|
||||
|
||||
/* Attempt to create a pool with an invalid size. */
|
||||
status = _txe_block_pool_create(&pool_2, "pool 2", 100, pointer, 320, 777777);
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Allocate with a NULL destination pointer. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) TX_NULL, TX_NO_WAIT);
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Allocate with a NULL pool pointer. */
|
||||
status = tx_block_allocate(TX_NULL, (VOID **) TX_NULL, TX_NO_WAIT);
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Allocate with bad pool pointer. */
|
||||
pool_2.tx_block_pool_id = 0;
|
||||
status = tx_block_allocate(&pool_2, (VOID **) TX_NULL, TX_NO_WAIT);
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Release bad pool ptr. */
|
||||
status = tx_block_release(TX_NULL);
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Allocate first block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Allocate second block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Allocate third block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Attempt to allocate fourth block from the pool. This should fail because
|
||||
there should be no more blocks in the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_MEMORY)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the memory of all of the allocated blocks. */
|
||||
for (i =0; i < 100; i++)
|
||||
{
|
||||
pointer_1[i] = (CHAR) 0xFF;
|
||||
pointer_2[i] = (CHAR) 0xFF;
|
||||
pointer_3[i] = (CHAR) 0xFF;
|
||||
}
|
||||
|
||||
/* Now release each of the blocks. */
|
||||
status = tx_block_release(pointer_1);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Release the second block. */
|
||||
status = tx_block_release(pointer_2);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Release the third block. */
|
||||
status = tx_block_release(pointer_3);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Allocate each block again to make sure everything still
|
||||
works. The block addresses should come out in reverse
|
||||
order, because a released block is placed at the head of
|
||||
the list. */
|
||||
|
||||
/* Allocate first block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Allocate second block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Allocate third block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Attempt to allocate fourth block from the pool. This should fail because
|
||||
there should be no more blocks in the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_4, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_MEMORY)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Delete both block pools. */
|
||||
status = tx_block_pool_delete(&pool_0);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_block_pool_delete(&pool_1);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to delete again. */
|
||||
status = tx_block_pool_delete(&pool_1);
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
thread_0_counter++;
|
||||
|
||||
#endif /* TX_DISABLE_ERROR_CHECKING */
|
||||
|
||||
/* All is good! */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
713
test/smp/regression/threadx_block_memory_information_test.c
Normal file
713
test/smp/regression/threadx_block_memory_information_test.c
Normal file
@ -0,0 +1,713 @@
|
||||
/* This test is designed to test block memory information services. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_block_pool.h"
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Define the external reference for the preempt disable flag. */
|
||||
|
||||
extern volatile UINT _tx_thread_preempt_disable;
|
||||
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
static unsigned long thread_4_counter = 0;
|
||||
static TX_THREAD thread_4;
|
||||
|
||||
static unsigned long thread_5_counter = 0;
|
||||
static TX_THREAD thread_5;
|
||||
|
||||
static unsigned long thread_6_counter = 0;
|
||||
static TX_THREAD thread_6;
|
||||
|
||||
static TX_BLOCK_POOL block_pool_0;
|
||||
static TX_BLOCK_POOL block_pool_2;
|
||||
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
static TX_BLOCK_POOL block_pool_1;
|
||||
#endif
|
||||
|
||||
static int test_status;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
static void thread_5_entry(ULONG thread_input);
|
||||
static void thread_6_entry(ULONG thread_input);
|
||||
|
||||
/* Direct core function to bypass the error checking shell. */
|
||||
UINT _tx_block_pool_info_get(TX_BLOCK_POOL *pool_ptr, CHAR **name, ULONG *available_blocks,
|
||||
ULONG *total_blocks, TX_THREAD **first_suspended,
|
||||
ULONG *suspended_count, TX_BLOCK_POOL **next_pool);
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* Determine if the test case we are looking for is present. */
|
||||
if ((_tx_thread_preempt_disable) && (test_status == 1))
|
||||
{
|
||||
|
||||
/* Abort the wait of thread 3. */
|
||||
tx_thread_wait_abort(&thread_3);
|
||||
|
||||
/* End the ISR processing. */
|
||||
test_status = 2;
|
||||
test_isr_dispatch = TX_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_block_memory_information_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Information Test............................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Information Test............................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Information Test............................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
3, 3, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Information Test............................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
4, 4, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Information Test............................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
5, 5, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Information Test............................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
6, 6, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Information Test............................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the block_pool with one block. */
|
||||
status = tx_block_pool_create(&block_pool_0, "block_pool 0", 30, pointer, 40);
|
||||
pointer = pointer + 40;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Information Test............................... ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
CHAR *name;
|
||||
ULONG available;
|
||||
ULONG total_blocks;
|
||||
TX_THREAD *first_suspended;
|
||||
ULONG suspended_count;
|
||||
TX_BLOCK_POOL *next_pool;
|
||||
ULONG allocates;
|
||||
ULONG releases;
|
||||
ULONG suspensions;
|
||||
ULONG timeouts;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Block Memory Information Test............................... ");
|
||||
|
||||
/* Allocate the one block. */
|
||||
tx_block_allocate(&block_pool_0, &pointer, TX_NO_WAIT);
|
||||
|
||||
/* Nothing to do here, but check prioritization with no suspended threads. */
|
||||
status = tx_block_pool_prioritize(&block_pool_0);
|
||||
|
||||
/* Check for an error condition. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get both threads suspended. */
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Make sure thread 1 and 2 are suspended on the block_pool. */
|
||||
if ((thread_1.tx_thread_state != TX_BLOCK_MEMORY) || (thread_2.tx_thread_state != TX_BLOCK_MEMORY) ||
|
||||
(block_pool_0.tx_block_pool_suspension_list != &thread_1))
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Prioritize the block pool suspension list. */
|
||||
status = tx_block_pool_prioritize(&block_pool_0);
|
||||
|
||||
/* Check status and make sure thread 1 is terminated. */
|
||||
if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_2))
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point we are going to get more than 2 threads suspended. */
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
tx_thread_resume(&thread_3);
|
||||
tx_thread_resume(&thread_4);
|
||||
tx_thread_resume(&thread_5);
|
||||
tx_thread_resume(&thread_6);
|
||||
|
||||
/* Prioritize the block pool suspension list. */
|
||||
status = tx_block_pool_prioritize(&block_pool_0);
|
||||
|
||||
/* Check status and make sure thread 3 is at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_3))
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now loop to test the interrupt of the prioritize loop logic. */
|
||||
test_status = 1;
|
||||
test_isr_dispatch = test_isr;
|
||||
do
|
||||
{
|
||||
|
||||
/* Prioritize the block pool suspension list. */
|
||||
status = tx_block_pool_prioritize(&block_pool_0);
|
||||
|
||||
/* Check status and make sure thread 1 is terminated. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
} while (test_status == 1);
|
||||
|
||||
/* Now determine if thread 4 is at the front of the list... It should be! */
|
||||
if (block_pool_0.tx_block_pool_suspension_list != &thread_4)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Test the NULL pointer on the info get call. */
|
||||
status = tx_block_pool_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Test the non-thread pointer on the info get call. */
|
||||
block_pool_2.tx_block_pool_id = 0;
|
||||
status = tx_block_pool_info_get(&block_pool_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Now use the information services in order to test them. */
|
||||
status = tx_block_pool_info_get(&block_pool_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
status += tx_block_pool_info_get(&block_pool_0, &name, &available, &total_blocks, &first_suspended, &suspended_count, &next_pool);
|
||||
|
||||
/* Check for an error condition. */
|
||||
if ((status) || (available != block_pool_0.tx_block_pool_available) || (total_blocks != block_pool_0.tx_block_pool_total) ||
|
||||
(first_suspended != &thread_4) || (suspended_count != block_pool_0.tx_block_pool_suspended_count) || (next_pool != &block_pool_0))
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Call the core block pool info get function with a NULL pointer. */
|
||||
status = _tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Call the core block pool info get function with a non-initialized pool. */
|
||||
status = _tx_block_pool_performance_info_get(&block_pool_1, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the pool performance information. */
|
||||
status = tx_block_pool_performance_info_get(&block_pool_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
status += tx_block_pool_performance_info_get(&block_pool_0, &allocates, &releases, &suspensions, &timeouts);
|
||||
|
||||
/* Check for an error condition. */
|
||||
if ((status) || (allocates != block_pool_0.tx_block_pool_performance_allocate_count) ||
|
||||
(releases != block_pool_0.tx_block_pool_performance_release_count) ||
|
||||
(suspensions != block_pool_0.tx_block_pool_performance_suspension_count) ||
|
||||
(timeouts != block_pool_0.tx_block_pool_performance_timeout_count))
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system pool performance information. */
|
||||
status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
status += tx_block_pool_performance_system_info_get(&allocates, &releases, &suspensions, &timeouts);
|
||||
|
||||
/* Check for an error condition. */
|
||||
if ((status) || (allocates != _tx_block_pool_performance_allocate_count) || (releases != _tx_block_pool_performance_release_count) ||
|
||||
(suspensions != _tx_block_pool_performance_suspension_count) || (timeouts != _tx_block_pool_performance_timeout_count))
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Call the block pool performance info get function. */
|
||||
status = tx_block_pool_performance_info_get(&block_pool_0, &allocates, &releases, &suspensions, &timeouts);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Call the block pool performance info get function. */
|
||||
status = tx_block_pool_performance_info_get(TX_NULL, &allocates, &releases, &suspensions, &timeouts);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Call the block pool performance info get function. */
|
||||
status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, &releases, &suspensions, &timeouts);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Call the block pool performance info get function. */
|
||||
status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Call the block pool performance info get function. */
|
||||
status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #26\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Call the block pool performance info get function. */
|
||||
status = tx_block_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #27\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system pool performance information. */
|
||||
status = tx_block_pool_performance_system_info_get(&allocates, &releases, &suspensions, &timeouts);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #28\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system pool performance information. */
|
||||
status = tx_block_pool_performance_system_info_get(TX_NULL, &releases, &suspensions, &timeouts);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #29\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system pool performance information. */
|
||||
status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #30\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system pool performance information. */
|
||||
status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #31\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system pool performance information. */
|
||||
status = tx_block_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check for the proper error code. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #32\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get block from pool. */
|
||||
status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get block from pool. */
|
||||
status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get block from pool. */
|
||||
status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_3_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get block from pool. */
|
||||
status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_4_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get block from pool. */
|
||||
status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_6_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get block from pool. */
|
||||
status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_6_counter++;
|
||||
}
|
||||
}
|
||||
|
500
test/smp/regression/threadx_block_memory_prioritize_test.c
Normal file
500
test/smp/regression/threadx_block_memory_prioritize_test.c
Normal file
@ -0,0 +1,500 @@
|
||||
/* This test is designed to test block memory pool prioritize. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Define the external reference for the preempt disable flag. */
|
||||
|
||||
extern volatile UINT _tx_thread_preempt_disable;
|
||||
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
static unsigned long thread_4_counter = 0;
|
||||
static TX_THREAD thread_4;
|
||||
|
||||
static unsigned long thread_5_counter = 0;
|
||||
static TX_THREAD thread_5;
|
||||
|
||||
static unsigned long thread_6_counter = 0;
|
||||
static TX_THREAD thread_6;
|
||||
|
||||
static TX_BLOCK_POOL block_pool_0;
|
||||
static TX_BLOCK_POOL block_pool_1;
|
||||
|
||||
|
||||
static int test_status;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
static void thread_5_entry(ULONG thread_input);
|
||||
static void thread_6_entry(ULONG thread_input);
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* Determine if the test case we are looking for is present. */
|
||||
if ((_tx_thread_preempt_disable) && (test_status == 1))
|
||||
{
|
||||
|
||||
/* Determine if thread 3 is at the front of the suspension list. */
|
||||
if (block_pool_0.tx_block_pool_suspension_list == &thread_3)
|
||||
{
|
||||
|
||||
/* Abort the wait of thread 3. */
|
||||
tx_thread_wait_abort(&thread_3);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Abort the wait of thread 5. */
|
||||
tx_thread_wait_abort(&thread_5);
|
||||
|
||||
/* End the ISR processing. */
|
||||
test_status = 2;
|
||||
test_isr_dispatch = TX_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_block_memory_prioritize_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Prioritize Test................................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Prioritize Test................................ ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Prioritize Test................................ ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
3, 3, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Prioritize Test................................ ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
4, 4, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Prioritize Test................................ ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
5, 5, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Prioritize Test................................ ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
6, 6, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Prioritize Test................................ ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the block_pool with one block. */
|
||||
status = tx_block_pool_create(&block_pool_0, "block_pool 0", 30, pointer, 40);
|
||||
pointer = pointer + 40;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Prioritize Test................................ ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Block Memory Prioritize Test................................ ");
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Attempt to prioritize with a NULL pointer. */
|
||||
status = tx_block_pool_prioritize(TX_NULL);
|
||||
|
||||
/* Check for an error condition. */
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to prioritize with a bad pool pointer. */
|
||||
block_pool_1.tx_block_pool_id = 0;
|
||||
status = tx_block_pool_prioritize(&block_pool_1);
|
||||
|
||||
/* Check for an error condition. */
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allocate the one block. */
|
||||
tx_block_allocate(&block_pool_0, &pointer, TX_NO_WAIT);
|
||||
|
||||
/* Nothing to do here, but check prioritization with no suspended threads. */
|
||||
status = tx_block_pool_prioritize(&block_pool_0);
|
||||
|
||||
/* Check for an error condition. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get both threads suspended. */
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Make sure thread 1 and 2 are suspended on the block_pool. */
|
||||
if ((thread_1.tx_thread_state != TX_BLOCK_MEMORY) || (thread_2.tx_thread_state != TX_BLOCK_MEMORY) ||
|
||||
(block_pool_0.tx_block_pool_suspension_list != &thread_1))
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Prioritize the block pool suspension list. */
|
||||
status = tx_block_pool_prioritize(&block_pool_0);
|
||||
|
||||
/* Check status and make sure thread 2 is at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_2))
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Call block pool prioritize again to test the don't-do-anything path in tx_block_pool_prioritize. */
|
||||
status += tx_block_pool_prioritize(&block_pool_0);
|
||||
|
||||
/* At this point we are going to get more than 2 threads suspended. */
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
tx_thread_resume(&thread_3);
|
||||
tx_thread_resume(&thread_4);
|
||||
tx_thread_resume(&thread_5);
|
||||
tx_thread_resume(&thread_6);
|
||||
|
||||
/* Prioritize the block pool suspension list. */
|
||||
status = tx_block_pool_prioritize(&block_pool_0);
|
||||
|
||||
/* Check status and make sure thread 3 is at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (block_pool_0.tx_block_pool_suspension_list != &thread_3))
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now loop to test the interrupt of the prioritize loop logic. */
|
||||
test_status = 1;
|
||||
test_isr_dispatch = test_isr;
|
||||
do
|
||||
{
|
||||
|
||||
/* Prioritize the block pool suspension list. */
|
||||
status = tx_block_pool_prioritize(&block_pool_0);
|
||||
|
||||
/* Check status and make sure thread 1 is terminated. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
} while (test_status == 1);
|
||||
|
||||
/* Now determine if thread 4 is at the front of the list... It should be! */
|
||||
if (block_pool_0.tx_block_pool_suspension_list != &thread_4)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get block from pool. */
|
||||
status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get block from pool. */
|
||||
status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get block from pool. */
|
||||
status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_3_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get block from pool. */
|
||||
status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_4_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get block from pool. */
|
||||
status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_6_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get block from pool. */
|
||||
status = tx_block_allocate(&block_pool_0, &pointer, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_6_counter++;
|
||||
}
|
||||
}
|
311
test/smp/regression/threadx_block_memory_suspension_test.c
Normal file
311
test/smp/regression/threadx_block_memory_suspension_test.c
Normal file
@ -0,0 +1,311 @@
|
||||
/* This test is designed to test suspension on memory block pools. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static TX_BLOCK_POOL pool_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_block_memory_suspension_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Suspension Test................................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Suspension Test................................ ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Suspension Test................................ ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create block pool. */
|
||||
status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
|
||||
pointer = pointer + 320;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Suspension Test................................ ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer_1;
|
||||
CHAR *pointer_2;
|
||||
CHAR *pointer_3;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Block Memory Suspension Test................................ ");
|
||||
|
||||
/* Increment the run counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Allocate all blocks from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
|
||||
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Get the last block. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Let the other thread suspend on the pool. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Now release the block to lift the suspension on the other thread. */
|
||||
status = tx_block_release(pointer_3);
|
||||
|
||||
/* Check status and run counter. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 0))
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Let the other thread run again. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Check the run counter of the other thread. */
|
||||
if (thread_1_counter != 1)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point the other thread has run and there is one block free. */
|
||||
|
||||
/* Get the last block again. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Resume the second thread. */
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Let both threads suspend on the block pool via relinquish. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Now release the block. */
|
||||
status = tx_block_release(pointer_3);
|
||||
|
||||
/* Check status and run counter. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 0))
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Let thread 1 release the block. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Let thread 2 get the block and release the block. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Check status and run counter. */
|
||||
if ((thread_1_counter != 3) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer_1;
|
||||
|
||||
|
||||
/* Attempt to get a block from the pool. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Allocate a block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_WAIT_FOREVER);
|
||||
|
||||
/* Determine if the allocate was successful. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Release the block. */
|
||||
tx_block_release(pointer_1);
|
||||
|
||||
/* Switch back to other thread. */
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer_1;
|
||||
|
||||
|
||||
/* Attempt to get a block from the pool. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Allocate a block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_WAIT_FOREVER);
|
||||
|
||||
/* Determine if the allocate was successful. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Release the block. */
|
||||
tx_block_release(pointer_1);
|
||||
|
||||
/* Switch back to other thread. */
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,212 @@
|
||||
/* This test is designed to test timeouts on suspension on memory block pools. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
|
||||
static TX_BLOCK_POOL pool_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_block_memory_suspension_timeout_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Suspension Timeout Test........................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Suspension Timeout Test........................ ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Suspension Timeout Test........................ ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create block pool. */
|
||||
status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
|
||||
pointer = pointer + 320;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Suspension Timeout Test........................ ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer_1;
|
||||
CHAR *pointer_2;
|
||||
CHAR *pointer_3;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Block Memory Suspension Timeout Test........................ ");
|
||||
|
||||
/* Allocate all blocks from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
|
||||
status += tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
|
||||
status += tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Sleep for 64 ticks to allow the other thread 6 timeouts on the block
|
||||
pool. */
|
||||
tx_thread_sleep(64);
|
||||
|
||||
/* Incrment the run counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Check the counter of the other thread. */
|
||||
if ((thread_1_counter != 6) || (thread_2_counter != 3))
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer_1;
|
||||
|
||||
|
||||
/* Attempt to get a block from the pool. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Allocate a block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, 10);
|
||||
|
||||
/* Determine if the allocate was successful. */
|
||||
if (status != TX_NO_MEMORY)
|
||||
return;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer_1;
|
||||
|
||||
|
||||
/* Delay so we get some single suspension timeouts as well. */
|
||||
tx_thread_sleep(32);
|
||||
|
||||
/* Attempt to get a block from the pool. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Allocate a block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, 10);
|
||||
|
||||
/* Determine if the allocate was successful. */
|
||||
if (status != TX_NO_MEMORY)
|
||||
return;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
}
|
||||
|
185
test/smp/regression/threadx_block_memory_thread_terminate_test.c
Normal file
185
test/smp/regression/threadx_block_memory_thread_terminate_test.c
Normal file
@ -0,0 +1,185 @@
|
||||
/* This test is designed to test thread termination on a thread suspended on a block
|
||||
memory pool. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
|
||||
static TX_BLOCK_POOL pool_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_block_memory_thread_terminate_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Thread Terminate Test.......................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Thread Terminate Test.......................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create block pool. */
|
||||
status = tx_block_pool_create(&pool_0, "pool 0", 100, pointer, 320);
|
||||
pointer = pointer + 320;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Block Memory Thread Terminate Test.......................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer_1;
|
||||
CHAR *pointer_2;
|
||||
CHAR *pointer_3;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Block Memory Thread Terminate Test.......................... ");
|
||||
|
||||
/* Allocate all blocks from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, TX_NO_WAIT);
|
||||
status += tx_block_allocate(&pool_0, (VOID **) &pointer_2, TX_NO_WAIT);
|
||||
status += tx_block_allocate(&pool_0, (VOID **) &pointer_3, TX_NO_WAIT);
|
||||
|
||||
/* Increment the run counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
|
||||
TX_MEMSET(pointer_2, (CHAR) 0xEF, 100);
|
||||
TX_MEMSET(pointer_3, (CHAR) 0xEF, 100);
|
||||
|
||||
|
||||
/* Let other thread suspend on block pool. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Terminate the other thread. */
|
||||
status = tx_thread_terminate(&thread_1);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_TERMINATED) ||
|
||||
(thread_1_counter != 0))
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Release all the blocks. */
|
||||
status = tx_block_release(pointer_1);
|
||||
status += tx_block_release(pointer_2);
|
||||
status += tx_block_release(pointer_3);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_TERMINATED) ||
|
||||
(thread_1_counter != 0))
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer_1;
|
||||
|
||||
|
||||
/* Attempt to get a block from the pool. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Allocate a block from the pool. */
|
||||
status = tx_block_allocate(&pool_0, (VOID **) &pointer_1, 10);
|
||||
|
||||
/* Determine if the allocate was successful. */
|
||||
if (status != TX_NO_MEMORY)
|
||||
return;
|
||||
|
||||
/* Set all the memory of the blocks. */
|
||||
TX_MEMSET(pointer_1, (CHAR) 0xEF, 100);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
1064
test/smp/regression/threadx_byte_memory_basic_test.c
Normal file
1064
test/smp/regression/threadx_byte_memory_basic_test.c
Normal file
File diff suppressed because it is too large
Load Diff
784
test/smp/regression/threadx_byte_memory_information_test.c
Normal file
784
test/smp/regression/threadx_byte_memory_information_test.c
Normal file
@ -0,0 +1,784 @@
|
||||
/* This test is designed to test byte memory information. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_byte_pool.h"
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Define the external reference for the preempt disable flag. */
|
||||
|
||||
extern volatile UINT _tx_thread_preempt_disable;
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
static unsigned long thread_4_counter = 0;
|
||||
static TX_THREAD thread_4;
|
||||
|
||||
static unsigned long thread_5_counter = 0;
|
||||
static TX_THREAD thread_5;
|
||||
|
||||
static unsigned long thread_6_counter = 0;
|
||||
static TX_THREAD thread_6;
|
||||
|
||||
static TX_BYTE_POOL byte_pool_0;
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
static TX_BYTE_POOL byte_pool_1;
|
||||
#endif
|
||||
static TX_BYTE_POOL byte_pool_2;
|
||||
|
||||
static int test_status;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
static void thread_5_entry(ULONG thread_input);
|
||||
static void thread_6_entry(ULONG thread_input);
|
||||
|
||||
UINT _tx_byte_pool_performance_info_get(TX_BYTE_POOL *pool_ptr, ULONG *allocates, ULONG *releases,
|
||||
ULONG *fragments_searched, ULONG *merges, ULONG *splits, ULONG *suspensions, ULONG *timeouts);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* Determine if the test case we are looking for is present. */
|
||||
if ((_tx_thread_preempt_disable) && (test_status == 1))
|
||||
{
|
||||
|
||||
/* Abort the wait of thread 3. */
|
||||
tx_thread_wait_abort(&thread_3);
|
||||
|
||||
/* End the ISR processing. */
|
||||
test_status = 2;
|
||||
test_isr_dispatch = TX_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_byte_memory_information_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Information Test................................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Information Test................................ ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Information Test................................ ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
3, 3, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Information Test................................ ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
4, 4, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Information Test................................ ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
5, 5, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Information Test................................ ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
6, 6, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Information Test................................ ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the byte_pool with one byte. */
|
||||
status = tx_byte_pool_create(&byte_pool_0, "byte_pool 0", pointer, 100);
|
||||
pointer = pointer + 100;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Information Test................................ ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
CHAR *name;
|
||||
ULONG available;
|
||||
ULONG fragments;
|
||||
TX_THREAD *first_suspended;
|
||||
ULONG suspended_count;
|
||||
TX_BYTE_POOL *next_pool;
|
||||
ULONG allocates;
|
||||
ULONG releases;
|
||||
ULONG fragments_searched;
|
||||
ULONG merges;
|
||||
ULONG splits;
|
||||
ULONG suspensions;
|
||||
ULONG timeouts;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Byte Memory Information Test................................ ");
|
||||
|
||||
/* Allocate the one byte. */
|
||||
tx_byte_allocate(&byte_pool_0, &pointer, 80, TX_NO_WAIT);
|
||||
|
||||
/* Nothing to do here, but check prioritization with no suspended threads. */
|
||||
status = tx_byte_pool_prioritize(&byte_pool_0);
|
||||
|
||||
/* Check status and make sure thread 1 is terminated. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Make sure thread 1 and 2 are suspended on the byte_pool. */
|
||||
if ((thread_1.tx_thread_state != TX_BYTE_MEMORY) || (thread_2.tx_thread_state != TX_BYTE_MEMORY) ||
|
||||
(byte_pool_0.tx_byte_pool_suspension_list != &thread_1))
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Prioritize the byte pool suspension list. */
|
||||
status = tx_byte_pool_prioritize(&byte_pool_0);
|
||||
|
||||
/* Check status and make sure thread 2 is now at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_2))
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point we are going to get more than 2 threads suspended. */
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
tx_thread_resume(&thread_3);
|
||||
tx_thread_resume(&thread_4);
|
||||
tx_thread_resume(&thread_5);
|
||||
tx_thread_resume(&thread_6);
|
||||
|
||||
/* Prioritize the byte pool suspension list. */
|
||||
status = tx_byte_pool_prioritize(&byte_pool_0);
|
||||
|
||||
/* Check status and make sure thread 3 is now at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_3))
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now loop to test the interrupt of the prioritize loop logic. */
|
||||
test_status = 1;
|
||||
test_isr_dispatch = test_isr;
|
||||
do
|
||||
{
|
||||
|
||||
/* Prioritize the byte pool suspension list. */
|
||||
status = tx_byte_pool_prioritize(&byte_pool_0);
|
||||
|
||||
/* Check status and make sure thread 1 is terminated. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
} while (test_status == 1);
|
||||
|
||||
/* Check status and make sure thread 3 is now at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_4))
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Call byte pool info with a NULL pointer. */
|
||||
status = tx_byte_pool_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Call byte pool info with an non-created pool pointer. */
|
||||
byte_pool_2.tx_byte_pool_id = 0;
|
||||
status = tx_byte_pool_info_get(&byte_pool_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get the byte pool information. */
|
||||
status = tx_byte_pool_info_get(&byte_pool_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
status += tx_byte_pool_info_get(&byte_pool_0, &name, &available, &fragments, &first_suspended, &suspended_count, &next_pool);
|
||||
|
||||
/* Check the status. */
|
||||
if ((status != TX_SUCCESS) || (available != byte_pool_0.tx_byte_pool_available) || (fragments != byte_pool_0.tx_byte_pool_fragments) ||
|
||||
(first_suspended != &thread_4) || (suspended_count != byte_pool_0.tx_byte_pool_suspended_count) || (next_pool != &byte_pool_0))
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Get the byte pool performance information. */
|
||||
status = tx_byte_pool_performance_info_get(TX_NULL, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool performance information. */
|
||||
status = tx_byte_pool_performance_info_get(&byte_pool_1, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool performance information. */
|
||||
status = tx_byte_pool_performance_info_get(&byte_pool_0, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if ((status != TX_SUCCESS) || (allocates != byte_pool_0.tx_byte_pool_performance_allocate_count) || (releases != byte_pool_0.tx_byte_pool_performance_release_count) ||
|
||||
(fragments_searched != byte_pool_0.tx_byte_pool_performance_search_count) || (merges != byte_pool_0.tx_byte_pool_performance_merge_count) ||
|
||||
(splits != byte_pool_0.tx_byte_pool_performance_split_count) || (suspensions != byte_pool_0.tx_byte_pool_performance_suspension_count) ||
|
||||
(timeouts != byte_pool_0.tx_byte_pool_performance_timeout_count))
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool system performance information. */
|
||||
status = tx_byte_pool_performance_system_info_get(&allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if ((status != TX_SUCCESS) || (allocates != _tx_byte_pool_performance_allocate_count) || (releases != _tx_byte_pool_performance_release_count) ||
|
||||
(fragments_searched != _tx_byte_pool_performance_search_count) || (merges != _tx_byte_pool_performance_merge_count) ||
|
||||
(splits != _tx_byte_pool_performance_split_count) || (suspensions != _tx_byte_pool_performance_suspension_count) ||
|
||||
(timeouts != _tx_byte_pool_performance_timeout_count))
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Get the byte pool performance information. */
|
||||
status = tx_byte_pool_performance_info_get(&byte_pool_0, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool performance information. */
|
||||
status = tx_byte_pool_performance_info_get(TX_NULL, &allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool performance information. */
|
||||
status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool performance information. */
|
||||
status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool performance information. */
|
||||
status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &merges, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #26\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool performance information. */
|
||||
status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #27\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool performance information. */
|
||||
status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #28\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool performance information. */
|
||||
status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #29\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool performance information. */
|
||||
status = tx_byte_pool_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #30\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool system performance information. */
|
||||
status = tx_byte_pool_performance_system_info_get(&allocates, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #31\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool system performance information. */
|
||||
status = tx_byte_pool_performance_system_info_get(TX_NULL, &releases, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #32\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool system performance information. */
|
||||
status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, &fragments_searched, &merges, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #33\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool system performance information. */
|
||||
status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &merges, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #34\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool system performance information. */
|
||||
status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &splits, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #35\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool system performance information. */
|
||||
status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #36\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool system performance information. */
|
||||
status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #37\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the byte pool system performance information. */
|
||||
status = tx_byte_pool_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #38\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get byte from pool. */
|
||||
status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get byte from pool. */
|
||||
status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get byte from pool. */
|
||||
status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_3_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get byte from pool. */
|
||||
status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_4_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get byte from pool. */
|
||||
status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_6_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get byte from pool. */
|
||||
status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_6_counter++;
|
||||
}
|
||||
}
|
498
test/smp/regression/threadx_byte_memory_prioritize_test.c
Normal file
498
test/smp/regression/threadx_byte_memory_prioritize_test.c
Normal file
@ -0,0 +1,498 @@
|
||||
/* This test is designed to test byte memory prioritize. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Define the external reference for the preempt disable flag. */
|
||||
|
||||
extern volatile UINT _tx_thread_preempt_disable;
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
static unsigned long thread_4_counter = 0;
|
||||
static TX_THREAD thread_4;
|
||||
|
||||
static unsigned long thread_5_counter = 0;
|
||||
static TX_THREAD thread_5;
|
||||
|
||||
static unsigned long thread_6_counter = 0;
|
||||
static TX_THREAD thread_6;
|
||||
|
||||
static TX_BYTE_POOL byte_pool_0;
|
||||
static TX_BYTE_POOL byte_pool_1;
|
||||
|
||||
static int test_status;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
static void thread_5_entry(ULONG thread_input);
|
||||
static void thread_6_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* Determine if the test case we are looking for is present. */
|
||||
if ((_tx_thread_preempt_disable) && (test_status == 1))
|
||||
{
|
||||
|
||||
/* Determine if thread 3 is at the front of the suspension list. */
|
||||
if (byte_pool_0.tx_byte_pool_suspension_list == &thread_3)
|
||||
{
|
||||
|
||||
/* Abort the wait of thread 3. */
|
||||
tx_thread_wait_abort(&thread_3);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Abort the wait of thread 5. */
|
||||
tx_thread_wait_abort(&thread_5);
|
||||
|
||||
/* End the ISR processing. */
|
||||
test_status = 2;
|
||||
test_isr_dispatch = TX_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_byte_memory_prioritize_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Prioritize Test................................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Prioritize Test................................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Prioritize Test................................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
3, 3, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Prioritize Test................................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
4, 4, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Prioritize Test................................. ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
5, 5, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Prioritize Test................................. ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
6, 6, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Prioritize Test................................. ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the byte_pool with one byte. */
|
||||
status = tx_byte_pool_create(&byte_pool_0, "byte_pool 0", pointer, 100);
|
||||
pointer = pointer + 100;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Prioritize Test................................. ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Byte Memory Prioritize Test................................. ");
|
||||
|
||||
/* Allocate the one byte. */
|
||||
tx_byte_allocate(&byte_pool_0, &pointer, 80, TX_NO_WAIT);
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Call byte pool prioritize with a NULL pointer. */
|
||||
status = tx_byte_pool_prioritize(TX_NULL);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Call byte pool info with an non-created pool pointer. */
|
||||
byte_pool_1.tx_byte_pool_id = 0;
|
||||
status = tx_byte_pool_prioritize(&byte_pool_1);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_POOL_ERROR)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Nothing to do here, but check prioritization with no suspended threads. */
|
||||
status = tx_byte_pool_prioritize(&byte_pool_0);
|
||||
|
||||
/* Check status and make sure thread 1 is terminated. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Make sure thread 1 and 2 are suspended on the byte_pool. */
|
||||
if ((thread_1.tx_thread_state != TX_BYTE_MEMORY) || (thread_2.tx_thread_state != TX_BYTE_MEMORY) ||
|
||||
(byte_pool_0.tx_byte_pool_suspension_list != &thread_1))
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Prioritize the byte pool suspension list. */
|
||||
status = tx_byte_pool_prioritize(&byte_pool_0);
|
||||
|
||||
/* Check status and make sure thread 2 is now at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_2))
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Call byte pool prioritize again to test the don't-do-anything path in tx_byte_pool_prioritize. */
|
||||
status += tx_byte_pool_prioritize(&byte_pool_0);
|
||||
|
||||
/* At this point we are going to get more than 2 threads suspended. */
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
tx_thread_resume(&thread_3);
|
||||
tx_thread_resume(&thread_4);
|
||||
tx_thread_resume(&thread_5);
|
||||
tx_thread_resume(&thread_6);
|
||||
|
||||
/* Prioritize the byte pool suspension list. */
|
||||
status = tx_byte_pool_prioritize(&byte_pool_0);
|
||||
|
||||
/* Check status and make sure thread 3 is now at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_3))
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now loop to test the interrupt of the prioritize loop logic. */
|
||||
test_status = 1;
|
||||
test_isr_dispatch = test_isr;
|
||||
do
|
||||
{
|
||||
|
||||
/* Prioritize the byte pool suspension list. */
|
||||
status = tx_byte_pool_prioritize(&byte_pool_0);
|
||||
|
||||
/* Check status and make sure thread 1 is terminated. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
} while (test_status == 1);
|
||||
|
||||
/* Check status and make sure thread 3 is now at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (byte_pool_0.tx_byte_pool_suspension_list != &thread_4))
|
||||
{
|
||||
|
||||
/* Byte Pool error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get byte from pool. */
|
||||
status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get byte from pool. */
|
||||
status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get byte from pool. */
|
||||
status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_3_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get byte from pool. */
|
||||
status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_4_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get byte from pool. */
|
||||
status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_6_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
VOID *pointer;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get byte from pool. */
|
||||
status = tx_byte_allocate(&byte_pool_0, &pointer, 25, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_6_counter++;
|
||||
}
|
||||
}
|
||||
|
391
test/smp/regression/threadx_byte_memory_suspension_test.c
Normal file
391
test/smp/regression/threadx_byte_memory_suspension_test.c
Normal file
@ -0,0 +1,391 @@
|
||||
/* This test is designed to test suspension on a memory byte pool. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
|
||||
static TX_BYTE_POOL pool_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
|
||||
|
||||
|
||||
#ifndef TX_MANUAL_TEST
|
||||
|
||||
/* Define test flags for automated test. */
|
||||
|
||||
extern TEST_FLAG threadx_byte_allocate_loop_test;
|
||||
extern TEST_FLAG threadx_byte_release_loop_test;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void abort_and_resume_byte_allocating_thread(void)
|
||||
{
|
||||
|
||||
UCHAR *search_ptr;
|
||||
|
||||
/* Adjust the search pointer to avoid the search pointer change for this test. */
|
||||
search_ptr = pool_0.tx_byte_pool_search;
|
||||
while (search_ptr >= pool_0.tx_byte_pool_search)
|
||||
|
||||
{
|
||||
search_ptr = *((UCHAR **) ((VOID *) search_ptr));
|
||||
}
|
||||
pool_0.tx_byte_pool_search = search_ptr;
|
||||
|
||||
tx_thread_wait_abort(&thread_3);
|
||||
tx_thread_resume(&thread_3);
|
||||
}
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_byte_memory_suspension_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Suspension Test................................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Suspension Test................................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Suspension Test................................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create byte pool 0. */
|
||||
status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
|
||||
pointer = pointer + 108;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Suspension Test................................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Byte Memory Suspension Test................................. ");
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Allocate memory from the pool. Only one block of this size will fit. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Let other thread suspend on byte pool. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Now release the blocks. */
|
||||
status = tx_byte_release(pointer);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) && (thread_1_counter == 0))
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Let other thread run again. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Check to make sure thread 1 has now run. */
|
||||
if (thread_1_counter != 1)
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now allocate the memory again. Only one block of this size will fit. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume the second thread. */
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Now relinquish to let both thread 1 and 2 suspend. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* At this point both threads should be suspended on the byte pool. */
|
||||
|
||||
/* Release the memory again. */
|
||||
status = tx_byte_release(pointer);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now relinquish to get the other threads to run once. */
|
||||
tx_thread_relinquish();
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* At this point both threads 1 and 2 are suspended on the byte pool again. */
|
||||
if ((thread_1_counter != 3) && (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now allocate the memory again. Only one block of this size will fit. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #10a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 3 to get it suspended on the the pool. */
|
||||
tx_thread_resume(&thread_3);
|
||||
|
||||
#ifdef TX_MANUAL_TEST
|
||||
|
||||
/* Set BP hear. Now release the memory and step into the code. After byte search issue IRQ2 mannually, which will
|
||||
make thread 3 abort the first request and make another request of a different size. This is the path we are trying
|
||||
to generate in the test. */
|
||||
status = tx_byte_release(pointer);
|
||||
#else
|
||||
|
||||
/* Set the flag that will make thread 3 abort the first request and make another request of a different size. This tests the memory size change path
|
||||
in the byte release loop logic. */
|
||||
threadx_byte_release_loop_test = 1;
|
||||
status = tx_byte_release(pointer);
|
||||
|
||||
#endif
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #10b\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Allocate memory from the pool. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Now release each of the blocks. */
|
||||
status = tx_byte_release(pointer);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Let thread 0 run again. */
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Allocate memory from the pool. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Now release each of the blocks. */
|
||||
status = tx_byte_release(pointer);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Let thread 0 run again. */
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* Allocate memory from the pool. */
|
||||
tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
|
||||
|
||||
#ifdef TX_MANUAL_TEST
|
||||
|
||||
/* Set BP here and manually clear the owner after one failed byte search just to test the loop
|
||||
construct in tx_byte_allocate.c. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 90, TX_WAIT_FOREVER);
|
||||
#else
|
||||
|
||||
/* Set the flag that clears the pool owner after one failed byte search to test the loop
|
||||
construct processing in tx_byte_allocate.c. */
|
||||
threadx_byte_allocate_loop_test = 1;
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 90, TX_WAIT_FOREVER);
|
||||
#endif
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_3_counter++;
|
||||
|
||||
/* Now release the block. */
|
||||
status = tx_byte_release(pointer);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* suspend this thread. */
|
||||
tx_thread_suspend(&thread_3);
|
||||
}
|
||||
}
|
@ -0,0 +1,196 @@
|
||||
/* This test is designed to test suspension timeout on a memory byte pool. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
|
||||
static TX_BYTE_POOL pool_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_byte_memory_suspension_timeout_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Suspension Timeout Test......................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Suspension Timeout Test......................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Suspension Timeout Test......................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create byte pool 0. */
|
||||
status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
|
||||
pointer = pointer + 108;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Suspension Timeout Test......................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Byte Memory Suspension Timeout Test......................... ");
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Allocate memory from the pool. Only one block of this size will fit. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 0))
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Sleep to allow the other thread to suspend and timeout on the memory
|
||||
pool once. */
|
||||
tx_thread_sleep(64);
|
||||
|
||||
/* Check the counter of the other thread. */
|
||||
if ((thread_1_counter != 6) || (thread_2_counter != 3))
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Allocate memory from the pool - with timeout. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, 10);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_MEMORY)
|
||||
return;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Delay so we get some single suspension timeouts as well. */
|
||||
tx_thread_sleep(32);
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Allocate memory from the pool - with timeout. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, 10);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_MEMORY)
|
||||
return;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
}
|
255
test/smp/regression/threadx_byte_memory_thread_contention_test.c
Normal file
255
test/smp/regression/threadx_byte_memory_thread_contention_test.c
Normal file
@ -0,0 +1,255 @@
|
||||
/* This test is designed to test contention of two threads on a single
|
||||
memory byte pool. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
static unsigned long initial_pool_size;
|
||||
|
||||
|
||||
static TX_BYTE_POOL pool_0;
|
||||
|
||||
|
||||
static int test_done;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_byte_memory_thread_contention_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 1, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Thread Contention Test.......................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 1, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Thread Contention Test.......................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 1, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Thread Contention Test.......................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create byte pool 0. */
|
||||
status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
|
||||
pointer = pointer + 108;
|
||||
|
||||
/* Save off the intial pool size. */
|
||||
initial_pool_size = pool_0.tx_byte_pool_available;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Thread Contention Test.......................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the test done flag to false. */
|
||||
test_done = TX_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Byte Memory Thread Contention Test.......................... ");
|
||||
|
||||
/* Set time to 0. */
|
||||
tx_time_set(0);
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Allocate memory from the pool. This size will cause merge activity
|
||||
because the search pointer will sit in this large block about half
|
||||
the time. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Fill the memory. */
|
||||
TX_MEMSET(pointer, (CHAR) 0xEF, 60);
|
||||
|
||||
/* Now release the block. */
|
||||
status = tx_byte_release(pointer);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Check the time. */
|
||||
if (tx_time_get() > 1280)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
}
|
||||
|
||||
/* Set the done flag. */
|
||||
test_done = TX_TRUE;
|
||||
|
||||
/* Sleep to let the other threads finish up! */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Determine if we all all the original memory and that thread 1
|
||||
is in the proper place. */
|
||||
if (pool_0.tx_byte_pool_available != initial_pool_size)
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
while(test_done == TX_FALSE)
|
||||
{
|
||||
|
||||
/* Allocate memory from the pool. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 30, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Fill the memory. */
|
||||
TX_MEMSET(pointer, (CHAR) 0xEF, 30);
|
||||
|
||||
/* Now release the block. */
|
||||
status = tx_byte_release(pointer);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
while(test_done == TX_FALSE)
|
||||
{
|
||||
|
||||
/* Allocate memory from the pool. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 12, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Fill the memory. */
|
||||
TX_MEMSET(pointer, (CHAR) 0xEF, 12);
|
||||
|
||||
/* Now release the block. */
|
||||
status = tx_byte_release(pointer);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
}
|
177
test/smp/regression/threadx_byte_memory_thread_terminate_test.c
Normal file
177
test/smp/regression/threadx_byte_memory_thread_terminate_test.c
Normal file
@ -0,0 +1,177 @@
|
||||
/* This test is designed to test termination on thread suspended on memory byte pool. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
|
||||
static TX_BYTE_POOL pool_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_byte_memory_thread_terminate_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Thread Terminate Test........................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Thread Terminate Test........................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create byte pools 0 and 1. */
|
||||
status = tx_byte_pool_create(&pool_0, "pool 0", pointer, 108);
|
||||
pointer = pointer + 108;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Byte Memory Thread Terminate Test........................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Byte Memory Thread Terminate Test........................... ");
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Allocate memory from the pool. Only one block of this size will fit. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Let other thread suspend on byte pool. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Terminate the other thread. */
|
||||
status = tx_thread_terminate(&thread_1);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Release block back. */
|
||||
status = tx_byte_release(pointer);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Allocate memory from the pool. Only one block of this size will fit. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 0))
|
||||
{
|
||||
|
||||
/* Byte memory error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Allocate memory from the pool. */
|
||||
status = tx_byte_allocate(&pool_0, (VOID **) &pointer, 60, TX_WAIT_FOREVER);
|
||||
|
||||
/* Should never get here! */
|
||||
if (status != TX_NO_MEMORY)
|
||||
return;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
743
test/smp/regression/threadx_event_flag_basic_test.c
Normal file
743
test/smp/regression/threadx_event_flag_basic_test.c
Normal file
@ -0,0 +1,743 @@
|
||||
/* This test is designed to test simple event flag group creation, deletion, gets and
|
||||
sets. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
typedef struct EVENT_FLAG_MEMORY_TEST_STRUCT
|
||||
{
|
||||
ULONG first;
|
||||
ULONG second;
|
||||
TX_EVENT_FLAGS_GROUP event_flags;
|
||||
ULONG next_to_last;
|
||||
ULONG last;
|
||||
|
||||
} EVENT_FLAG_MEMORY_TEST;
|
||||
|
||||
static EVENT_FLAG_MEMORY_TEST event_flag_memory;
|
||||
|
||||
|
||||
/* Define external reference to the event flag create call from initialization. */
|
||||
|
||||
extern UINT test_event_flags_from_init;
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
static TX_TIMER timer_0;
|
||||
|
||||
static unsigned long error = 0;
|
||||
static unsigned long timer_executed = 0;
|
||||
static unsigned long isr_executed = 0;
|
||||
|
||||
static TX_EVENT_FLAGS_GROUP group_0;
|
||||
static TX_EVENT_FLAGS_GROUP group_1;
|
||||
static TX_EVENT_FLAGS_GROUP group_2;
|
||||
static TX_EVENT_FLAGS_GROUP group_3;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
UINT _txe_event_flags_create(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name_ptr, UINT event_control_block_size);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
|
||||
{
|
||||
|
||||
/* Not necessary to do anything in this function. */
|
||||
}
|
||||
|
||||
|
||||
/* Define the timer for this test. */
|
||||
|
||||
static void timer_entry(ULONG i)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
UINT status;
|
||||
ULONG actual_events;
|
||||
|
||||
|
||||
/* Determine if calling event flag create from initialization was successful. */
|
||||
if (test_event_flags_from_init != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to create an event flag group from a timer. */
|
||||
status = tx_event_flags_create(&group_2, "group 2");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Try to delete an event flags group from a timer. */
|
||||
status = tx_event_flags_delete(&group_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Get events with suspendsion from a timer. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, 14, &actual_events, 100);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
timer_executed = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
UINT status;
|
||||
ULONG actual_events;
|
||||
|
||||
|
||||
/* Attempt to create an event flag group from an ISR. */
|
||||
status = tx_event_flags_create(&group_2, "group 2");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to delete an event flags group from an ISR. */
|
||||
status = tx_event_flags_delete(&group_0);
|
||||
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Get events with suspendsion from an ISR. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, 14, &actual_events, 100);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
|
||||
isr_executed = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_event_flag_basic_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
INT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Basic Test....................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
18, 18, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Basic Test....................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create event flag group 0 and 1. */
|
||||
status = tx_event_flags_create(&group_0, "group 0");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Basic Test....................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_event_flags_create(&group_1, "group 1");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Basic Test....................................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the event set notify function. */
|
||||
status = tx_event_flags_set_notify(&group_0, event_set_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Basic Test....................................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Basic Test....................................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Un-register the event set notify function. */
|
||||
status = tx_event_flags_set_notify(&group_0, TX_NULL);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Basic Test....................................... ERROR #5a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Basic Test....................................... ERROR #6a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_events;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Event Flag Basic Test....................................... ");
|
||||
|
||||
/* Perform event flag memory test. */
|
||||
event_flag_memory.first = 0x11223344;
|
||||
event_flag_memory.second = 0x55667788;
|
||||
event_flag_memory.next_to_last = 0x99aabbcc;
|
||||
event_flag_memory.last = 0xddeeff00;
|
||||
|
||||
/* Create the event flag group. */
|
||||
status = tx_event_flags_create(&event_flag_memory.event_flags, "group memory");
|
||||
tx_event_flags_delete(&event_flag_memory.event_flags);
|
||||
|
||||
/* Check for status. */
|
||||
if ((status != TX_SUCCESS) ||
|
||||
(event_flag_memory.first != 0x11223344) ||
|
||||
(event_flag_memory.second != 0x55667788) ||
|
||||
(event_flag_memory.next_to_last != 0x99aabbcc) ||
|
||||
(event_flag_memory.last != 0xddeeff00))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Event flags should be created now. */
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Try to create with a NULL pointer. */
|
||||
status = tx_event_flags_create(TX_NULL, "group 0");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_GROUP_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Try to create with a bad size. */
|
||||
status = _txe_event_flags_create(&group_3, "group 3", (sizeof(TX_EVENT_FLAGS_GROUP)+1));
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_GROUP_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Try to create an already created group. */
|
||||
status = tx_event_flags_create(&group_0, "group 0");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_GROUP_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Delete with a NULL pointer. */
|
||||
status = tx_event_flags_delete(TX_NULL);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_GROUP_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Delete with a non-created pointer. */
|
||||
group_2.tx_event_flags_group_id = 0;
|
||||
status = tx_event_flags_delete(&group_2);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_GROUP_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get events with a null group pointer. */
|
||||
status = tx_event_flags_get(TX_NULL, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_GROUP_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get events with a non-created group pointer. */
|
||||
group_2.tx_event_flags_group_id = 0;
|
||||
status = tx_event_flags_get(&group_2, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_GROUP_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get events with a null flags retun pointer. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, TX_NULL, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get events with a bad option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, 14, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_OPTION_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set evetns with a NULL group pointer. */
|
||||
status = tx_event_flags_set(TX_NULL, 0x80008000, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_GROUP_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set events with a non-created group pointer. */
|
||||
group_2.tx_event_flags_group_id = 0;
|
||||
status = tx_event_flags_set(&group_2, 0x80008000, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_GROUP_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set events with a bad option. */
|
||||
status = tx_event_flags_set(&group_0, 0x80008000, 14);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_OPTION_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to register the event set notify function with a NULL group pointer. */
|
||||
status = tx_event_flags_set_notify(TX_NULL, event_set_notify);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_GROUP_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to register the event set notify function with a non-created group pointer. */
|
||||
group_2.tx_event_flags_group_id = 0;
|
||||
status = tx_event_flags_set_notify(&group_2, event_set_notify);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_GROUP_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Attempt to get events from an empty event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from an empty event flag group. OR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from an empty event flag group. AND CLEAR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from an empty event flag group. OR CLEAR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the necessary events. */
|
||||
status = tx_event_flags_set(&group_0, 0x80008000, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #26\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Just for fun, clear bit 15. */
|
||||
status = tx_event_flags_set(&group_0, 0x80000000, TX_AND);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #27\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set bit 15 again. */
|
||||
status = tx_event_flags_set(&group_0, 0x00008000, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #28\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now attemp to retrieve events... */
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #29\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from event flag group. OR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #30\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from event flag group. AND CLEAR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #31\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from an empty event flag group. OR CLEAR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #32\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Put event flags back in the group. */
|
||||
|
||||
/* Set the necessary events. */
|
||||
status = tx_event_flags_set(&group_0, 0x80008000, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #33\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from event flag group. OR CLEAR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x00008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #34\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from event flag group. OR CLEAR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #35\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Create a timer for the test. */
|
||||
tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
|
||||
|
||||
/* Setup the ISR. */
|
||||
test_isr_dispatch = test_isr;
|
||||
|
||||
/* Sleep for a bit... */
|
||||
tx_thread_sleep(3);
|
||||
|
||||
/* Now resume thread 1. */
|
||||
tx_thread_resume(&thread_1);
|
||||
|
||||
/* Sleep for a bit... */
|
||||
tx_thread_sleep(3);
|
||||
|
||||
/* Clear the ISR. */
|
||||
test_isr_dispatch = TX_NULL;
|
||||
|
||||
/* Test for error. */
|
||||
if ((error) || (timer_executed != 1) || (isr_executed != 1))
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #36\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Delete both event flag groups. */
|
||||
status = tx_event_flags_delete(&group_0);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #37\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_event_flags_delete(&group_1);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #38\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
|
562
test/smp/regression/threadx_event_flag_information_test.c
Normal file
562
test/smp/regression/threadx_event_flag_information_test.c
Normal file
@ -0,0 +1,562 @@
|
||||
/* This test is designed to test the event flag group information gathering services. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_event_flags.h"
|
||||
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
|
||||
static TX_EVENT_FLAGS_GROUP group_0;
|
||||
static TX_EVENT_FLAGS_GROUP group_1;
|
||||
static TX_EVENT_FLAGS_GROUP group_2;
|
||||
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
|
||||
UINT _tx_event_flags_performance_info_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG *sets, ULONG *gets,
|
||||
ULONG *suspensions, ULONG *timeouts);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
|
||||
{
|
||||
|
||||
/* Not necessary to do anything in this function. */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_event_flag_information_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
INT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Information Test................................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create event flag group 0 and 1. */
|
||||
status = tx_event_flags_create(&group_0, "group 0");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Information Test................................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_event_flags_create(&group_1, "group 1");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Information Test................................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the event set notify function. */
|
||||
status = tx_event_flags_set_notify(&group_0, event_set_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Information Test................................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Information Test................................. ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_events;
|
||||
CHAR *name;
|
||||
ULONG current_flags;
|
||||
TX_THREAD *first_suspended;
|
||||
ULONG suspended_count;
|
||||
TX_EVENT_FLAGS_GROUP *next_group;
|
||||
ULONG sets;
|
||||
ULONG gets;
|
||||
ULONG suspensions;
|
||||
ULONG timeouts;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Event Flag Information Test................................. ");
|
||||
|
||||
/* Event flags should be created now. */
|
||||
|
||||
/* Attempt to get events from an empty event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from an empty event flag group. OR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from an empty event flag group. AND CLEAR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from an empty event flag group. OR CLEAR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the necessary events. */
|
||||
status = tx_event_flags_set(&group_0, 0x80008000, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Just for fun, clear bit 15. */
|
||||
status = tx_event_flags_set(&group_0, 0x80000000, TX_AND);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set bit 15 again. */
|
||||
status = tx_event_flags_set(&group_0, 0x00008000, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now attemp to retrieve events... */
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from event flag group. OR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_OR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from event flag group. AND CLEAR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from an empty event flag group. OR CLEAR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Put event flags back in the group. */
|
||||
|
||||
/* Set the necessary events. */
|
||||
status = tx_event_flags_set(&group_0, 0x80008000, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from event flag group. OR CLEAR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x00008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x80008000UL))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get events from event flag group. OR CLEAR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_OR_CLEAR, &actual_events, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Get information with a NULL pointer. */
|
||||
status = tx_event_flags_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_GROUP_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get information from a non-created group. */
|
||||
group_2.tx_event_flags_group_id = 0;
|
||||
status = tx_event_flags_info_get(&group_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_GROUP_ERROR)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Get information about the event flag group. */
|
||||
status = tx_event_flags_info_get(&group_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
status += tx_event_flags_info_get(&group_0, &name, ¤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);
|
||||
}
|
||||
}
|
358
test/smp/regression/threadx_event_flag_isr_set_clear_test.c
Normal file
358
test/smp/regression/threadx_event_flag_isr_set_clear_test.c
Normal file
@ -0,0 +1,358 @@
|
||||
/* This test is designed to test for simultaneous thread event flag set AND ISR event flag set and clear. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h"
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static unsigned long timer_0_counter = 0;
|
||||
static TX_TIMER timer_0;
|
||||
|
||||
static unsigned long event_flags_set_counter = 0;
|
||||
static unsigned long condition_count = 0;
|
||||
|
||||
static TX_EVENT_FLAGS_GROUP event_flags_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void timer_0_entry(ULONG timer_input);
|
||||
|
||||
|
||||
static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
|
||||
{
|
||||
|
||||
/* Not necessary to do anything in this function. */
|
||||
}
|
||||
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual;
|
||||
static volatile UINT miss_count = 0;
|
||||
|
||||
|
||||
/* Determine if the interrupt occurred when the preempt disable flag was set. */
|
||||
if (_tx_thread_preempt_disable)
|
||||
{
|
||||
|
||||
/* Yes this is the condition we are looking for, increment the test condition counter. */
|
||||
condition_count++;
|
||||
}
|
||||
|
||||
/*
|
||||
It is possible for this test to get into a resonance condition in which
|
||||
the ISR never occurs while preemption is disabled (especially if the
|
||||
ISR is installed in the periodic timer interrupt handler, which is
|
||||
conveniently available). Detect this condition and break out of it by
|
||||
perturbing the duration of this ISR a pseudo-random amount of time.
|
||||
*/
|
||||
else if (++miss_count > 100)
|
||||
{
|
||||
for (miss_count = _tx_timer_system_clock % 100; miss_count != 0; --miss_count);
|
||||
}
|
||||
|
||||
if (((event_flags_0.tx_event_flags_group_current & 0x3) == 0) &&
|
||||
(event_flags_0.tx_event_flags_group_suspended_count == 2))
|
||||
{
|
||||
|
||||
/* Put the event_flags to wakeup thread 0. */
|
||||
status = tx_event_flags_set(&event_flags_0, 0x3, TX_OR);
|
||||
|
||||
/* Clear the same flags immediately. */
|
||||
status += tx_event_flags_set(&event_flags_0, 0xFFFFFFFC, TX_AND);
|
||||
|
||||
/* Setup some event flags just so we can clear them. */
|
||||
status += tx_event_flags_set(&event_flags_0, 0x30000, TX_OR);
|
||||
|
||||
/* Clear the same flags immediately. */
|
||||
status += tx_event_flags_set(&event_flags_0, 0xFFFEFFFF, TX_AND);
|
||||
|
||||
/* Clear the same flags immediately. */
|
||||
status += tx_event_flags_set(&event_flags_0, 0xFFFDFFFC, TX_AND);
|
||||
|
||||
/* Check for an error. */
|
||||
if (status)
|
||||
return;
|
||||
|
||||
/* Get the events from an ISR. */
|
||||
status = tx_event_flags_get(&event_flags_0, 0x30000, TX_OR, &actual, TX_NO_WAIT);
|
||||
|
||||
/* Check to make sure this results in an error. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
return;
|
||||
|
||||
/* Do a set and a get consume from an ISR. */
|
||||
status = tx_event_flags_set(&event_flags_0, 0x000000C0, TX_OR);
|
||||
|
||||
status += tx_event_flags_get(&event_flags_0, 0x00000080, TX_OR, &actual, TX_NO_WAIT);
|
||||
|
||||
status += tx_event_flags_get(&event_flags_0, 0x000000C0, TX_OR_CLEAR, &actual, TX_NO_WAIT);
|
||||
|
||||
/* Increment the event_flags counter. */
|
||||
if ((status == TX_SUCCESS) && (actual == 0xC4))
|
||||
{
|
||||
event_flags_set_counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_event_flag_isr_set_clear_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create event flags group. */
|
||||
status = tx_event_flags_create(&event_flags_0, "event_flags 0");
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a timer to ensure a context save is called for every interrupt. */
|
||||
status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the event set notify function. */
|
||||
status = tx_event_flags_set_notify(&event_flags_0, event_set_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Set/Clear from ISR Test.......................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Event Flag Set/Clear from ISR Test.......................... ");
|
||||
|
||||
/* Setup the test ISR. */
|
||||
test_isr_dispatch = test_isr;
|
||||
|
||||
/* Loop to exploit the probability window inside tx_event_flags_set call. */
|
||||
while (condition_count < 40)
|
||||
{
|
||||
|
||||
/* Suspend on the event_flags that is going to be set via the ISR. */
|
||||
status = tx_event_flags_get(&event_flags_0, 2, TX_OR_CLEAR, &actual, 4);
|
||||
|
||||
/* Determine if we have an unexpected result. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Check for the preempt disable flag being set. */
|
||||
if (_tx_thread_preempt_disable)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(2);
|
||||
}
|
||||
|
||||
/* Determine if we really got the event_flags. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment the thread count. */
|
||||
thread_0_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup the test ISR. */
|
||||
test_isr_dispatch = TX_NULL;
|
||||
|
||||
/* Let the other threads run once more... */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* At this point, check to see if we got all the event_flagss! */
|
||||
if ((thread_0_counter != event_flags_set_counter) ||
|
||||
(thread_1_counter != event_flags_set_counter))
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual;
|
||||
|
||||
|
||||
/* Loop to exploit the probability window inside tx_event_flags_set call. */
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* Suspend on the event_flags that is going to be set via the ISR. */
|
||||
status = tx_event_flags_get(&event_flags_0, 1, TX_OR_CLEAR, &actual, 4);
|
||||
|
||||
/* Determine if we have an unexpected result. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Set event flags - not the one needed by threads 0 and 1. */
|
||||
tx_event_flags_set(&event_flags_0, 0x4, TX_OR);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Let thread 0 run again! */
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void timer_0_entry(ULONG input)
|
||||
{
|
||||
timer_0_counter++;
|
||||
}
|
||||
|
||||
|
330
test/smp/regression/threadx_event_flag_isr_wait_abort_test.c
Normal file
330
test/smp/regression/threadx_event_flag_isr_wait_abort_test.c
Normal file
@ -0,0 +1,330 @@
|
||||
/* This test is designed to test for wait abort from an ISR. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h"
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static unsigned long timer_0_counter = 0;
|
||||
static TX_TIMER timer_0;
|
||||
|
||||
static unsigned long event_flags_wait_abort_counter = 0;
|
||||
static unsigned long condition_count = 0;
|
||||
|
||||
static TX_EVENT_FLAGS_GROUP event_flags_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void timer_0_entry(ULONG timer_input);
|
||||
|
||||
|
||||
static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
|
||||
{
|
||||
|
||||
/* Not necessary to do anything in this function. */
|
||||
}
|
||||
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
static volatile UINT miss_count = 0;
|
||||
|
||||
|
||||
/* Determine if the interrupt occurred when the preempt disable flag was set. */
|
||||
if (_tx_thread_preempt_disable)
|
||||
{
|
||||
|
||||
/* Yes this is the condition we are looking for, increment the test condition counter. */
|
||||
condition_count++;
|
||||
}
|
||||
|
||||
/*
|
||||
It is possible for this test to get into a resonance condition in which
|
||||
the ISR never occurs while preemption is disabled (especially if the
|
||||
ISR is installed in the periodic timer interrupt handler, which is
|
||||
conveniently available). Detect this condition and break out of it by
|
||||
perturbing the duration of this ISR a pseudo-random amount of time.
|
||||
*/
|
||||
else if (++miss_count > 100)
|
||||
{
|
||||
for (miss_count = _tx_timer_system_clock % 100; miss_count != 0; --miss_count);
|
||||
}
|
||||
|
||||
if (((event_flags_0.tx_event_flags_group_current & 0x3) == 0) &&
|
||||
(event_flags_0.tx_event_flags_group_suspended_count == 2))
|
||||
{
|
||||
|
||||
/* Set event flags - not the one needed by threads 0 and 1. */
|
||||
status = tx_event_flags_set(&event_flags_0, 0x4, TX_OR);
|
||||
|
||||
/* Abort the threads 1 and 2. */
|
||||
status += tx_thread_wait_abort(&thread_0);
|
||||
status += tx_thread_wait_abort(&thread_1);
|
||||
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
event_flags_wait_abort_counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_event_flag_isr_wait_abort_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create event flags group. */
|
||||
status = tx_event_flags_create(&event_flags_0, "event_flags 0");
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a timer to ensure a context save is called for every interrupt. */
|
||||
status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the event set notify function. */
|
||||
status = tx_event_flags_set_notify(&event_flags_0, event_set_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Wait Abort from ISR Test......................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Event Flag Wait Abort from ISR Test......................... ");
|
||||
|
||||
/* Setup the test ISR. */
|
||||
test_isr_dispatch = test_isr;
|
||||
|
||||
/* Loop to exploit the probability window inside tx_event_flags_set call. */
|
||||
while (condition_count < 40)
|
||||
{
|
||||
|
||||
/* Suspend on the event_flags that is going to be set via the ISR. */
|
||||
status = tx_event_flags_get(&event_flags_0, 2, TX_OR_CLEAR, &actual, 4);
|
||||
|
||||
/* Determine if we have an unexpected result. */
|
||||
if (status != TX_WAIT_ABORTED)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Check for the preempt disable flag being set. */
|
||||
if (_tx_thread_preempt_disable)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(2);
|
||||
}
|
||||
|
||||
/* Determine if we really got the event_flags. */
|
||||
if (status == TX_WAIT_ABORTED)
|
||||
{
|
||||
|
||||
/* Increment the thread count. */
|
||||
thread_0_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup the test ISR. */
|
||||
test_isr_dispatch = TX_NULL;
|
||||
|
||||
/* Let the other threads run once more... */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* At this point, check to see if we got all the event_flagss! */
|
||||
if ((thread_0_counter != event_flags_wait_abort_counter) ||
|
||||
(thread_1_counter != event_flags_wait_abort_counter))
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual;
|
||||
|
||||
|
||||
/* Loop to exploit the probability window inside tx_event_flags_set call. */
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* Suspend on the event_flags that is going to be set via the ISR. */
|
||||
status = tx_event_flags_get(&event_flags_0, 1, TX_OR_CLEAR, &actual, 4);
|
||||
|
||||
/* Determine if we have an unexpected result. */
|
||||
if (status != TX_WAIT_ABORTED)
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Set event flags - not the one needed by threads 0 and 1. */
|
||||
tx_event_flags_set(&event_flags_0, 0x4, TX_OR);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Let thread 0 run again! */
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void timer_0_entry(ULONG input)
|
||||
{
|
||||
timer_0_counter++;
|
||||
}
|
@ -0,0 +1,331 @@
|
||||
/* This test is designed to test event flag suspension with a single suspended thread
|
||||
being terminated at the same priority level. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
|
||||
extern UINT _tx_thread_preempt_disable;
|
||||
|
||||
static TX_EVENT_FLAGS_GROUP group_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
|
||||
{
|
||||
|
||||
/* Not necessary to do anything in this function. */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_event_flag_single_thread_terminate_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Single Thread Terminate Test..................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
18, 18, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Single Thread Terminate Test..................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
18, 18, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Single Thread Terminate Test..................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create event flag group 0. */
|
||||
status = tx_event_flags_create(&group_0, "group 0");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Single Thread Terminate Test..................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the event set notify function. */
|
||||
status = tx_event_flags_set_notify(&group_0, event_set_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Single Thread Terminate Test..................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Single Thread Terminate Test..................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Event Flag Single Thread Terminate Test..................... ");
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Sleep to allow lower-priority thread 1 to run. */
|
||||
tx_thread_sleep(5);
|
||||
|
||||
/* Resume Thread 2. */
|
||||
status = tx_thread_resume(&thread_2);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now terminate thread 1. */
|
||||
status = tx_thread_terminate(&thread_1);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now sleep to allow Thread 2 to run. */
|
||||
tx_thread_sleep(5);
|
||||
|
||||
/* Set only one of the event flags needed. */
|
||||
status = tx_event_flags_set(&group_0, 0x00080000, TX_OR);
|
||||
|
||||
/* Now sleep to allow thread 2 to run. */
|
||||
tx_thread_sleep(5);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) && (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the other event flag needed. */
|
||||
status = tx_event_flags_set(&group_0, 0x00800000, TX_OR);
|
||||
|
||||
/* Now sleep to allow thread 2 to run. */
|
||||
tx_thread_sleep(5);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) && (thread_2_counter != 2))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point, thread 2 is suspended on the flags again. Or some flags that are
|
||||
not needed. */
|
||||
|
||||
/* Set an event flag that is not needed. */
|
||||
status = tx_event_flags_set(&group_0, 0x00000001, TX_OR);
|
||||
|
||||
/* Now sleep to allow thread 2 to run. */
|
||||
tx_thread_sleep(5);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) && (thread_2_counter != 2))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set an event flag that is needed. */
|
||||
status = tx_event_flags_set(&group_0, 0x00080001, TX_OR);
|
||||
|
||||
/* Now sleep to allow thread 2 to run. */
|
||||
tx_thread_sleep(5);
|
||||
|
||||
/* Check status and run counters. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 3) ||
|
||||
(_tx_thread_preempt_disable))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Terminate thread 2. */
|
||||
status = tx_thread_terminate(&thread_2);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (thread_2_counter != 3))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Self suspend thread. */
|
||||
status = tx_thread_suspend(&thread_1);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
thread_1_counter = 0; /* Make an error! */
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x000880000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. OR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x000880000, TX_OR_CLEAR, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x000880000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
281
test/smp/regression/threadx_event_flag_suspension_consume_test.c
Normal file
281
test/smp/regression/threadx_event_flag_suspension_consume_test.c
Normal file
@ -0,0 +1,281 @@
|
||||
/* This test is designed to test event flag suspension and resumption of two threads
|
||||
waiting on the same event flag set with the consumption. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
|
||||
static TX_EVENT_FLAGS_GROUP group_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
|
||||
{
|
||||
|
||||
/* Not necessary to do anything in this function. */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_event_flag_suspension_consume_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension/Consumption Test...................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension/Consumption Test...................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension/Consumption Test...................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension/Consumption Test...................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create event flag group 0. */
|
||||
status = tx_event_flags_create(&group_0, "group 0");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension/Consumption Test...................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the event set notify function. */
|
||||
status = tx_event_flags_set_notify(&group_0, event_set_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension/Consumption Test...................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension/Consumption Test...................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG event_flag = 1;
|
||||
int i;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Event Flag Suspension/Consumption Test...................... ");
|
||||
|
||||
/* Set all event flags. */
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Set event flag. */
|
||||
status = tx_event_flags_set(&group_0, event_flag, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Check the thread counters... */
|
||||
if ((i < 31) && ((thread_1_counter != 1) || (thread_2_counter != 1) || (thread_3_counter != 1)))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
if ((i == 31) && ((thread_1_counter != 2) || (thread_2_counter != 2) || (thread_3_counter != 2)))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Shift event flag up one bit. */
|
||||
event_flag = event_flag << 1;
|
||||
|
||||
/* Check for 0. */
|
||||
if (event_flag == 0)
|
||||
event_flag = 1;
|
||||
}
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
//ULONG event_flag = 1;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
//ULONG event_flag = 1;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
//ULONG event_flag = 1;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_3_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,224 @@
|
||||
/* This test is designed to test event flag suspension and resumption of two threads
|
||||
waiting on different event flags with consumption. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
|
||||
static TX_EVENT_FLAGS_GROUP group_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
|
||||
{
|
||||
|
||||
/* Not necessary to do anything in this function. */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_event_flag_suspension_different_bits_consume_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
INT status;
|
||||
CHAR *pointer;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create event flag group 0. */
|
||||
status = tx_event_flags_create(&group_0, "group 0");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the event set notify function. */
|
||||
status = tx_event_flags_set_notify(&group_0, event_set_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Event Flag Suspension/Consumption Unique Bit Test........... ");
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Set event flag. */
|
||||
status = tx_event_flags_set(&group_0, 0x80000000, TX_OR);
|
||||
|
||||
/* Check status and run counters. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 2) ||
|
||||
(thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set event flag. */
|
||||
status = tx_event_flags_set(&group_0, 0x00008000, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 2) ||
|
||||
(thread_2_counter != 2))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80000000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
//ULONG event_flag = 1;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x00008000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x00008000UL))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,230 @@
|
||||
/* This test is designed to test event flag suspension and resumption of two threads
|
||||
waiting on different event flags. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
|
||||
static TX_EVENT_FLAGS_GROUP group_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
|
||||
{
|
||||
|
||||
/* Not necessary to do anything in this function. */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_event_flag_suspension_different_bits_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
INT status;
|
||||
CHAR *pointer;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create event flag group 0. */
|
||||
status = tx_event_flags_create(&group_0, "group 0");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the event set notify function. */
|
||||
status = tx_event_flags_set_notify(&group_0, event_set_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Unique Bit Test....................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Event Flag Suspension Unique Bit Test....................... ");
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Set event flag. */
|
||||
status = tx_event_flags_set(&group_0, 0x80000000, TX_OR);
|
||||
|
||||
/* Check status and run counters. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 2) ||
|
||||
(thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set event flag. */
|
||||
status = tx_event_flags_set(&group_0, 0x00008000, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 2) ||
|
||||
(thread_2_counter != 2))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80000000, TX_AND, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x80000000UL))
|
||||
return;
|
||||
|
||||
/* Clear the event flags. */
|
||||
tx_event_flags_set(&group_0, 0x7FFFFFFF, TX_AND);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
//ULONG event_flag = 1;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x00008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x00008000UL))
|
||||
return;
|
||||
|
||||
/* Clear the event flags. */
|
||||
tx_event_flags_set(&group_0, 0xFFFF7FFF, TX_AND);
|
||||
}
|
||||
}
|
||||
|
349
test/smp/regression/threadx_event_flag_suspension_test.c
Normal file
349
test/smp/regression/threadx_event_flag_suspension_test.c
Normal file
@ -0,0 +1,349 @@
|
||||
/* This test is designed to test event flag suspension and resumption of three threads
|
||||
waiting on the same event flag set. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
static unsigned long thread_4_counter = 0;
|
||||
static TX_THREAD thread_4;
|
||||
|
||||
|
||||
static TX_EVENT_FLAGS_GROUP group_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
|
||||
{
|
||||
|
||||
/* Not necessary to do anything in this function. */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_event_flag_suspension_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Same Bit Test......................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Same Bit Test......................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Same Bit Test......................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Same Bit Test......................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Same Bit Test......................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create event flag group 0. */
|
||||
status = tx_event_flags_create(&group_0, "group 0");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Same Bit Test......................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the event set notify function. */
|
||||
status = tx_event_flags_set_notify(&group_0, event_set_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Same Bit Test......................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Same Bit Test......................... ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG event_flag = 1;
|
||||
int i;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Event Flag Suspension Same Bit Test......................... ");
|
||||
|
||||
/* Set all event flags. */
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Set event flag. */
|
||||
status = tx_event_flags_set(&group_0, event_flag, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Check the thread counters... */
|
||||
if ((i < 31) && ((thread_1_counter != 1) || (thread_2_counter != 1) || (thread_3_counter != 1)))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
if ((i == 31) && ((thread_1_counter != 2) || (thread_2_counter != 2) || (thread_3_counter != 2)))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Shift event flag up one bit. */
|
||||
event_flag = event_flag << 1;
|
||||
|
||||
/* Check for 0. */
|
||||
if (event_flag == 0)
|
||||
event_flag = 1;
|
||||
}
|
||||
|
||||
/* Set the event flags to 0. */
|
||||
status = tx_event_flags_set(&group_0, 0x0, TX_AND);
|
||||
|
||||
/* Resume thread 4 so it can suspend on the event flag group too. */
|
||||
status += tx_thread_resume(&thread_4);
|
||||
|
||||
/* Determine if there was an error. */
|
||||
if ((status != TX_SUCCESS) || (thread_4_counter != 1))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now set the event flag that only thread 4 is waiting on to ensure that we are not satisfying the first thread on the list. */
|
||||
status = tx_event_flags_set(&group_0, 0x1, TX_OR);
|
||||
|
||||
/* Determine if there was an error. */
|
||||
if ((status != TX_SUCCESS) || (thread_4_counter != 2))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
//ULONG event_flag = 1;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
|
||||
return;
|
||||
|
||||
/* Clear the event flags. */
|
||||
tx_event_flags_set(&group_0, 0, TX_AND);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
//ULONG event_flag = 1;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
//ULONG event_flag = 1;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_3_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80008000, TX_AND, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0xFFFFFFFFUL))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_4_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. OR option. */
|
||||
status = tx_event_flags_get(&group_0, 0x00000001, TX_OR_CLEAR, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_events != 0x1UL))
|
||||
return;
|
||||
}
|
||||
}
|
266
test/smp/regression/threadx_event_flag_suspension_timeout_test.c
Normal file
266
test/smp/regression/threadx_event_flag_suspension_timeout_test.c
Normal file
@ -0,0 +1,266 @@
|
||||
/* This test is designed to test event flag suspension timeout processing. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
|
||||
static TX_EVENT_FLAGS_GROUP group_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
|
||||
{
|
||||
|
||||
/* Not necessary to do anything in this function. */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_event_flag_suspension_timeout_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Timeout Test.......................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
18, 18, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Timeout Test.......................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Timeout Test.......................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create event flag group 0. */
|
||||
status = tx_event_flags_create(&group_0, "group 0");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Timeout Test.......................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the event set notify function. */
|
||||
status = tx_event_flags_set_notify(&group_0, event_set_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Timeout Test.......................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Suspension Timeout Test.......................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG actual_events;
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Event Flag Suspension Timeout Test.......................... ");
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Set event flag 0. */
|
||||
tx_event_flags_set(&group_0, 0x00000001, TX_OR);
|
||||
|
||||
/* Resume thread 3. */
|
||||
tx_thread_resume(&thread_3);
|
||||
tx_thread_sleep(1); /* Thread 3 should now be suspended on group 0. */
|
||||
tx_event_flags_set(&group_0, 0x00000002, TX_OR);
|
||||
|
||||
/* Start everything on a new timer. */
|
||||
tx_thread_sleep(2);
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
tx_thread_sleep(1);
|
||||
status = tx_event_flags_get(&group_0, 0x00000001, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check the status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #6a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Sleep for 63 ticks. */
|
||||
tx_thread_sleep(63);
|
||||
|
||||
/* Check the run counters. */
|
||||
if ((thread_1_counter != 33) || (thread_2_counter != 13))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_events;
|
||||
|
||||
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80000000, TX_AND_CLEAR, &actual_events, 2);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
//ULONG event_flag = 1;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x00008000, TX_AND_CLEAR, &actual_events, 5);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
//ULONG event_flag = 1;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_3_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x00000002, TX_AND, &actual_events, 5);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
return;
|
||||
}
|
||||
}
|
234
test/smp/regression/threadx_event_flag_thread_terminate_test.c
Normal file
234
test/smp/regression/threadx_event_flag_thread_terminate_test.c
Normal file
@ -0,0 +1,234 @@
|
||||
/* This test is designed to test event flag suspension with the suspended threads
|
||||
being terminated. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
|
||||
static TX_EVENT_FLAGS_GROUP group_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void event_set_notify(TX_EVENT_FLAGS_GROUP *group)
|
||||
{
|
||||
|
||||
/* Not necessary to do anything in this function. */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_event_flag_thread_terminate_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Thread Terminate Test............................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Thread Terminate Test............................ ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Thread Terminate Test............................ ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create event flag group 0. */
|
||||
status = tx_event_flags_create(&group_0, "group 0");
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Thread Terminate Test............................ ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the event set notify function. */
|
||||
status = tx_event_flags_set_notify(&group_0, event_set_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Thread Terminate Test............................ ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Event Flag Thread Terminate Test............................ ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Event Flag Thread Terminate Test............................ ");
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Terminate thread 2. */
|
||||
status = tx_thread_terminate(&thread_2);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Terminate thread 1. */
|
||||
status = tx_thread_terminate(&thread_1);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set event flags to make sure no threads are suspended. */
|
||||
status = tx_event_flags_set(&group_0, 0xFFFFFFFF, TX_OR);
|
||||
|
||||
/* Check status and run counters. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Event flag error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x80000000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
//ULONG event_flag = 1;
|
||||
ULONG actual_events;
|
||||
|
||||
/* Wait for event flags. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Attempt to get events from event flag group. AND option. */
|
||||
status = tx_event_flags_get(&group_0, 0x00008000, TX_AND_CLEAR, &actual_events, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_EVENTS)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
83
test/smp/regression/threadx_initialize_kernel_setup_test.c
Normal file
83
test/smp/regression/threadx_initialize_kernel_setup_test.c
Normal file
@ -0,0 +1,83 @@
|
||||
/* This test is designed to test kernel setup functionality in ThreadX. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_initialize.h"
|
||||
#include "tx_thread.h"
|
||||
|
||||
|
||||
TEST_FLAG test_forced_mutex_timeout;
|
||||
TEST_FLAG threadx_mutex_suspension_put_test;
|
||||
TEST_FLAG threadx_mutex_suspension_priority_test;
|
||||
TEST_FLAG threadx_byte_allocate_loop_test;
|
||||
TEST_FLAG test_initialize_flag;
|
||||
TEST_FLAG threadx_byte_release_loop_test;
|
||||
TEST_FLAG test_stack_analyze_flag;
|
||||
|
||||
|
||||
/* Define the test control global variables. */
|
||||
|
||||
ULONG test_control_return_status;
|
||||
ULONG test_control_successful_tests;
|
||||
ULONG test_control_failed_tests;
|
||||
ULONG test_control_system_errors;
|
||||
|
||||
UINT test_mutex_from_init;
|
||||
UINT test_semaphore_from_init;
|
||||
UINT test_queue_from_init;
|
||||
UINT test_event_flags_from_init;
|
||||
UINT test_byte_pool_create_init;
|
||||
UINT test_block_pool_create_init;
|
||||
UINT test_timer_create_init;
|
||||
UINT mutex_priority_change_extension_selection;
|
||||
UINT priority_change_extension_selection;
|
||||
|
||||
|
||||
__attribute__((weak)) void abort_all_threads_suspended_on_mutex(void)
|
||||
{
|
||||
}
|
||||
|
||||
__attribute__((weak)) void suspend_lowest_priority(void)
|
||||
{
|
||||
}
|
||||
|
||||
__attribute__((weak)) void abort_and_resume_byte_allocating_thread(void)
|
||||
{
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
/* Setup the ThreadX kernel. */
|
||||
_tx_initialize_kernel_setup();
|
||||
|
||||
if (_tx_thread_system_state == TX_INITIALIZE_ALMOST_DONE)
|
||||
{
|
||||
printf("Running Initialize Kernel Setup Test................................ SUCCESS!\n");
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Running Initialize Kernel Setup Test................................ ERROR!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void test_application_define(void *first_unused_memory){}
|
||||
void tx_application_define(void *first_unused_memory){}
|
||||
|
||||
|
||||
#ifndef TX_TIMER_PROCESS_IN_ISR
|
||||
|
||||
/* Define the deletion of the system timer thread. */
|
||||
|
||||
extern TX_THREAD _tx_timer_thread;
|
||||
TEST_FLAG threadx_delete_timer_thread;
|
||||
void delete_timer_thread(void)
|
||||
{
|
||||
|
||||
_tx_thread_terminate(&_tx_timer_thread);
|
||||
_tx_thread_delete(&_tx_timer_thread);
|
||||
}
|
||||
|
||||
#endif
|
94
test/smp/regression/threadx_interrupt_control_test.c
Normal file
94
test/smp/regression/threadx_interrupt_control_test.c
Normal file
@ -0,0 +1,94 @@
|
||||
/* This test is designed to test the interrupt control service call avaialbe to the
|
||||
application. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_interrupt_control_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Interrupt Control Test...................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT saved_interrupt_posture;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Interrupt Control Test...................................... ");
|
||||
|
||||
/* Lockout interrupts. */
|
||||
saved_interrupt_posture = tx_interrupt_control(TX_INT_DISABLE);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
saved_interrupt_posture = tx_interrupt_control(saved_interrupt_posture);
|
||||
|
||||
/* Sleep to make sure interrupts now work. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Check to make sure the returned interrupt type works. */
|
||||
if (saved_interrupt_posture != TX_INT_DISABLE)
|
||||
{
|
||||
|
||||
/* Interrupt control error. */
|
||||
printf("ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
767
test/smp/regression/threadx_mutex_basic_test.c
Normal file
767
test/smp/regression/threadx_mutex_basic_test.c
Normal file
@ -0,0 +1,767 @@
|
||||
/* This test is designed to test the mutex create/delete and immediate
|
||||
return gets and puts. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_mutex.h"
|
||||
|
||||
|
||||
typedef struct MUTEX_MEMORY_TEST_STRUCT
|
||||
{
|
||||
ULONG first;
|
||||
ULONG second;
|
||||
TX_MUTEX mutex;
|
||||
ULONG next_to_last;
|
||||
ULONG last;
|
||||
|
||||
} MUTEX_MEMORY_TEST;
|
||||
|
||||
static MUTEX_MEMORY_TEST mutex_memory;
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
static TX_THREAD thread_2;
|
||||
static TX_THREAD thread_3;
|
||||
static TX_THREAD thread_4;
|
||||
|
||||
static TX_MUTEX mutex_0;
|
||||
static TX_MUTEX mutex_1;
|
||||
static TX_MUTEX mutex_2;
|
||||
static TX_MUTEX mutex_3;
|
||||
static TX_MUTEX mutex_4;
|
||||
static TX_MUTEX mutex_5;
|
||||
static TX_MUTEX mutex_6;
|
||||
static TX_MUTEX mutex_7;
|
||||
static TX_MUTEX mutex_8;
|
||||
|
||||
static TX_TIMER timer_0;
|
||||
|
||||
|
||||
static unsigned long error = 0;
|
||||
static unsigned long timer_executed = 0;
|
||||
static unsigned long isr_executed = 0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
|
||||
UINT _txe_mutex_create(TX_MUTEX *mutex_ptr, CHAR *name_ptr, UINT inherit, UINT mutex_control_block_size);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the timer for this test. */
|
||||
|
||||
static void timer_entry(ULONG i)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Attempt to create a mutex from a timer. */
|
||||
status = tx_mutex_create(&mutex_4, "mutex 4", TX_NO_INHERIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to delete a mutex from a timer. */
|
||||
status = tx_mutex_delete(&mutex_2);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to get from mutex from a timer with suspension. */
|
||||
status = tx_mutex_get(&mutex_2, 100);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
timer_executed = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Attempt to create a mutex from an ISR. */
|
||||
status = tx_mutex_create(&mutex_4, "mutex 4", TX_NO_INHERIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to delete a mutex from an ISR. */
|
||||
status = tx_mutex_delete(&mutex_2);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to get from mutex from an ISR with suspension. */
|
||||
status = tx_mutex_get(&mutex_2, 100);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to get from mutex from an ISR without suspension. */
|
||||
status = tx_mutex_get(&mutex_2, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to put a mutex from an ISR. */
|
||||
status = tx_mutex_put(&mutex_2);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
isr_executed = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_mutex_basic_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
|
||||
status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
status += tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
status += tx_thread_create(&thread_4, "thread 4", thread_4_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Basic Test............................................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a mutex. */
|
||||
status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Basic Test............................................ ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create another mutex. */
|
||||
status = tx_mutex_create(&mutex_1, "mutex 1", TX_NO_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Basic Test............................................ ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create another mutex. */
|
||||
status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Basic Test............................................ ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create another mutex. */
|
||||
status = tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Basic Test............................................ ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create another mutex. */
|
||||
status = tx_mutex_create(&mutex_8, "mutex 8", TX_NO_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Basic Test............................................ ERROR #5a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Mutex Basic Test............................................ ");
|
||||
|
||||
/* Perform mutex memory test. */
|
||||
mutex_memory.first = 0x11223344;
|
||||
mutex_memory.second = 0x55667788;
|
||||
mutex_memory.next_to_last = 0x99aabbcc;
|
||||
mutex_memory.last = 0xddeeff00;
|
||||
|
||||
/* Create the semaphore. */
|
||||
status = tx_mutex_create(&mutex_memory.mutex, "mutex memory", TX_INHERIT);
|
||||
tx_mutex_delete(&mutex_memory.mutex);
|
||||
|
||||
/* Check for status. */
|
||||
if ((status != TX_SUCCESS) ||
|
||||
(mutex_memory.first != 0x11223344) ||
|
||||
(mutex_memory.second != 0x55667788) ||
|
||||
(mutex_memory.next_to_last != 0x99aabbcc) ||
|
||||
(mutex_memory.last != 0xddeeff00))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Attempt to create a mutex with a NULL pointer. */
|
||||
status = tx_mutex_create(TX_NULL, "mutex 2", TX_INHERIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_MUTEX_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a mutex with a bad size. */
|
||||
status = _txe_mutex_create(&mutex_5, "mutex 5", TX_INHERIT, (sizeof(TX_MUTEX)+1));
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_MUTEX_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a mutex that has already been created. */
|
||||
status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_MUTEX_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a mutex with a bad inheritance option. */
|
||||
status = tx_mutex_create(&mutex_4, "mutex 4", 14);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_INHERIT_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to delete a mutex with a NULL pointer. */
|
||||
status = tx_mutex_delete(TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_MUTEX_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to delete a non-created mutex. */
|
||||
mutex_4.tx_mutex_id = 0;
|
||||
status = tx_mutex_delete(&mutex_4);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_MUTEX_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get a mutex with a NULL pointer. */
|
||||
status = tx_mutex_get(TX_NULL, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_MUTEX_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get a non-created mutex. */
|
||||
mutex_4.tx_mutex_id = 0;
|
||||
status = tx_mutex_get(&mutex_4, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_MUTEX_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to put a NULL mutex. */
|
||||
status = tx_mutex_put(TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_MUTEX_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to put a non-created mutex. */
|
||||
mutex_4.tx_mutex_id = 0;
|
||||
status = tx_mutex_put(&mutex_4);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_MUTEX_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Attempt to get from mutex that is available. Should be successful! */
|
||||
status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get the same mutex again. Should be successful! */
|
||||
status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Put the mutex. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_ownership_count != 1))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Put the mutex again. Should be successful! */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) != (mutex_0.tx_mutex_owner != TX_NULL))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to allow other thread to get the mutex. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Attempt to get the mutex. Should be unsuccessful. */
|
||||
status = tx_mutex_get(&mutex_1, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NOT_AVAILABLE)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish again so that the other thread can release it. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Delete mutex. */
|
||||
status = tx_mutex_delete(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_mutex_delete(&mutex_1);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get a priority inheritance mutex. */
|
||||
status = tx_mutex_get(&mutex_2, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get another priority inheritance mutex. */
|
||||
status = tx_mutex_get(&mutex_3, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Create a timer for the test. */
|
||||
tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
|
||||
|
||||
/* Setup the ISR. */
|
||||
test_isr_dispatch = test_isr;
|
||||
|
||||
/* Sleep for a bit... */
|
||||
tx_thread_sleep(3);
|
||||
|
||||
/* Wakeup thread 2 to get the ISR to take place on top of the thread. */
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Sleep for a bit... */
|
||||
tx_thread_sleep(3);
|
||||
|
||||
/* Clear the ISR. */
|
||||
test_isr_dispatch = TX_NULL;
|
||||
|
||||
/* Test for error. */
|
||||
if ((error) || (timer_executed != 1) || (isr_executed != 1))
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #26\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Release mutex multiple times. */
|
||||
status = tx_mutex_put(&mutex_2);
|
||||
status += tx_mutex_put(&mutex_2);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NOT_OWNED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #27\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to release a mutex that is not owned. */
|
||||
status = _tx_mutex_put(&mutex_2);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NOT_OWNED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #28\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Delete mutex. */
|
||||
status = tx_mutex_delete(&mutex_2);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #29\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get mutex 8. */
|
||||
status = tx_mutex_get(&mutex_8, TX_WAIT_FOREVER);
|
||||
|
||||
/* Start thread 3 and 4. */
|
||||
status += tx_thread_resume(&thread_3);
|
||||
status += tx_thread_resume(&thread_4);
|
||||
|
||||
/* Sleep to let thread 3 suspend on the mutex. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Now, put the mutex to give it to thread 3. */
|
||||
status += tx_mutex_put(&mutex_8);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #29a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_mutex_delete(&mutex_3);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #30\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Increment thread 1 counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Attempt to get from mutex that is available. Should be successful! */
|
||||
status = tx_mutex_get(&mutex_1, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #31\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Let other thread run again. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Release mutex! */
|
||||
status = tx_mutex_put(&mutex_1);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #32\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create and obtain a couple mutexes so the thread completion can release them. */
|
||||
status = tx_mutex_create(&mutex_6, "mutex 6", TX_NO_INHERIT);
|
||||
status += tx_mutex_create(&mutex_7, "mutex 7", TX_NO_INHERIT);
|
||||
status += tx_mutex_get(&mutex_6, TX_NO_WAIT);
|
||||
status += tx_mutex_get(&mutex_7, TX_NO_WAIT);
|
||||
status += tx_mutex_get(&mutex_6, TX_NO_WAIT);
|
||||
status += tx_mutex_get(&mutex_7, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #33\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_mutex_get(&mutex_8, TX_WAIT_FOREVER);
|
||||
tx_mutex_put(&mutex_8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_mutex_get(&mutex_8, TX_WAIT_FOREVER);
|
||||
tx_mutex_put(&mutex_8);
|
||||
}
|
||||
}
|
194
test/smp/regression/threadx_mutex_delete_test.c
Normal file
194
test/smp/regression/threadx_mutex_delete_test.c
Normal file
@ -0,0 +1,194 @@
|
||||
/* This test is designed to test the mutex suspension and mutex delete with
|
||||
suspended threads. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
|
||||
static TX_MUTEX mutex_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_mutex_delete_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Delete Test........................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Delete Test........................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Delete Test........................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a mutex. */
|
||||
status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Delete Test........................................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Mutex Delete Test........................................... ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Grab the mutex so it is owned by this thread. */
|
||||
status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to let other threads run. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Other threads should now be suspended on the mutex. */
|
||||
|
||||
/* Delete the mutex to test it out! */
|
||||
status = tx_mutex_delete(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to allow other threads to run again before we return. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Now check the run counter of each thread. */
|
||||
if ((thread_1_counter != 1) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_DELETED)
|
||||
thread_1_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_DELETED)
|
||||
thread_2_counter++;
|
||||
}
|
592
test/smp/regression/threadx_mutex_information_test.c
Normal file
592
test/smp/regression/threadx_mutex_information_test.c
Normal file
@ -0,0 +1,592 @@
|
||||
/* This test is designed to test the mutex information services. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_mutex.h"
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static TX_MUTEX mutex_0;
|
||||
static TX_MUTEX mutex_1;
|
||||
static TX_MUTEX mutex_2;
|
||||
static TX_MUTEX mutex_3;
|
||||
static TX_MUTEX mutex_4;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
UINT _tx_mutex_performance_info_get(TX_MUTEX *mutex_ptr, ULONG *puts, ULONG *gets,
|
||||
ULONG *suspensions, ULONG *timeouts, ULONG *inversions, ULONG *inheritances);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_mutex_information_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Information Test...................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a mutex. */
|
||||
status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Information Test...................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create another mutex. */
|
||||
status = tx_mutex_create(&mutex_1, "mutex 1", TX_NO_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Information Test...................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create another mutex. */
|
||||
status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Information Test...................................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create another mutex. */
|
||||
status = tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Information Test...................................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *name;
|
||||
ULONG count;
|
||||
TX_THREAD *owner;
|
||||
TX_THREAD *first_suspended;
|
||||
ULONG suspended_count;
|
||||
TX_MUTEX *next_mutex;
|
||||
ULONG puts;
|
||||
ULONG gets;
|
||||
ULONG suspensions;
|
||||
ULONG timeouts;
|
||||
ULONG inversions;
|
||||
ULONG inheritances;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Mutex Information Test...................................... ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Attempt to get from mutex that is available. Should be successful! */
|
||||
status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get the same mutex again. Should be successful! */
|
||||
status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Put the mutex. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_ownership_count != 1))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Put the mutex again. Should be successful! */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to allow other thread to get the mutex. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Attempt to get the mutex. Should be unsuccessful. */
|
||||
status = tx_mutex_get(&mutex_1, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NOT_AVAILABLE)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish again so that the other thread can release it. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Delete mutex. */
|
||||
status = tx_mutex_delete(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_mutex_delete(&mutex_1);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get a priority inheritance mutex. */
|
||||
status = tx_mutex_get(&mutex_2, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get another priority inheritance mutex. */
|
||||
status = tx_mutex_get(&mutex_3, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Attempt to get mutex info with a NULL pointer. */
|
||||
status = tx_mutex_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_MUTEX_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get mutex info from a non-created mutex. */
|
||||
mutex_4.tx_mutex_id = 0;
|
||||
status = tx_mutex_info_get(&mutex_4, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_MUTEX_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get mutex information. */
|
||||
status = tx_mutex_info_get(&mutex_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
status += tx_mutex_info_get(&mutex_2, &name, &count, &owner, &first_suspended, &suspended_count, &next_mutex);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (count != mutex_2.tx_mutex_ownership_count) || (owner != mutex_2.tx_mutex_owner) ||
|
||||
(first_suspended != mutex_2.tx_mutex_suspension_list) || (suspended_count != mutex_2.tx_mutex_suspended_count) || (next_mutex != mutex_2.tx_mutex_created_next))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifdef TX_MUTEX_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Call with NULL pointer. */
|
||||
status = _tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the performance inforamtion. */
|
||||
status = tx_mutex_performance_info_get(&mutex_2, &puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (puts != mutex_2.tx_mutex_performance_put_count) || (gets != mutex_2.tx_mutex_performance_get_count) ||
|
||||
(suspensions != mutex_2.tx_mutex_performance_suspension_count) || (timeouts != mutex_2.tx_mutex_performance_timeout_count) ||
|
||||
(inversions != mutex_2.tx_mutex_performance_priority_inversion_count) || (inheritances != mutex_2.tx_mutex_performance__priority_inheritance_count))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system performance inforamtion. */
|
||||
status = tx_mutex_performance_system_info_get(&puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (puts != _tx_mutex_performance_put_count) || (gets != _tx_mutex_performance_get_count) ||
|
||||
(suspensions != _tx_mutex_performance_suspension_count) || (timeouts != _tx_mutex_performance_timeout_count) ||
|
||||
(inversions != _tx_mutex_performance_priority_inversion_count) || (inheritances != _tx_mutex_performance__priority_inheritance_count))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Now get the performance inforamtion. */
|
||||
status = tx_mutex_performance_info_get(&mutex_2, &puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the performance inforamtion. */
|
||||
status = tx_mutex_performance_info_get(TX_NULL, &puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the performance inforamtion. */
|
||||
status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, &gets, &suspensions, &timeouts, &inversions, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the performance inforamtion. */
|
||||
status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &suspensions, &timeouts, &inversions, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the performance inforamtion. */
|
||||
status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts, &inversions, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the performance inforamtion. */
|
||||
status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inversions, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #26\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the performance inforamtion. */
|
||||
status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #27\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the performance inforamtion. */
|
||||
status = tx_mutex_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #28\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system performance inforamtion. */
|
||||
status = tx_mutex_performance_system_info_get(&puts, &gets, &suspensions, &timeouts, &inversions, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #29\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system performance inforamtion. */
|
||||
status = tx_mutex_performance_system_info_get(TX_NULL, &gets, &suspensions, &timeouts, &inversions, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #30\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system performance inforamtion. */
|
||||
status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, &suspensions, &timeouts, &inversions, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #31\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system performance inforamtion. */
|
||||
status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &timeouts, &inversions, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #32\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system performance inforamtion. */
|
||||
status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inversions, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #33\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system performance inforamtion. */
|
||||
status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &inheritances);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #34\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now get the system performance inforamtion. */
|
||||
status = tx_mutex_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #35\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Delete mutex. */
|
||||
status = tx_mutex_delete(&mutex_2);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #36\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_mutex_delete(&mutex_3);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #37\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Increment thread 1 counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Attempt to get from mutex that is available. Should be successful! */
|
||||
status = tx_mutex_get(&mutex_1, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #38\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Let other thread run again. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Release mutex! */
|
||||
status = tx_mutex_put(&mutex_1);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #39\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
@ -0,0 +1,701 @@
|
||||
/* This test is designed to test multiple mutex priority inheritance situations. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
#define DEMO_STACK_SIZE TEST_STACK_SIZE_PRINTF
|
||||
|
||||
|
||||
/* Define the ThreadX object control blocks... */
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
static TX_THREAD thread_1;
|
||||
static TX_THREAD thread_2;
|
||||
static TX_THREAD thread_3;
|
||||
static TX_THREAD thread_4;
|
||||
static TX_THREAD thread_5;
|
||||
static TX_THREAD thread_6;
|
||||
|
||||
static TX_MUTEX mutex_0;
|
||||
static TX_MUTEX mutex_1;
|
||||
static TX_MUTEX mutex_2;
|
||||
static TX_MUTEX mutex_3;
|
||||
|
||||
|
||||
/* Define the counters used in the demo application... */
|
||||
|
||||
static ULONG thread_0_counter;
|
||||
static ULONG thread_1_counter;
|
||||
static ULONG thread_2_counter;
|
||||
static ULONG thread_3_counter;
|
||||
static ULONG thread_4_counter;
|
||||
static ULONG thread_5_counter;
|
||||
static ULONG thread_6_counter;
|
||||
#endif
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
static void thread_5_entry(ULONG thread_input);
|
||||
static void thread_6_entry(ULONG thread_input);
|
||||
#endif
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_mutex_nested_priority_inheritance_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
CHAR *pointer;
|
||||
UINT status;
|
||||
|
||||
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Create thread. */
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
pointer = pointer + DEMO_STACK_SIZE;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
|
||||
/* Create thread. */
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + DEMO_STACK_SIZE;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create thread. */
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
4, 4, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + DEMO_STACK_SIZE;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create thread. */
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
30, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
pointer = pointer + DEMO_STACK_SIZE;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create thread. */
|
||||
status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
4, 4, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + DEMO_STACK_SIZE;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create thread. */
|
||||
status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + DEMO_STACK_SIZE;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4b\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create thread. */
|
||||
status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
30, 30, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + DEMO_STACK_SIZE;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #4c\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the mutexes. */
|
||||
status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
status += tx_mutex_create(&mutex_1, "mutex 1", TX_INHERIT);
|
||||
status += tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
|
||||
status += tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Nested Priority Inheritance Test...................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
#ifdef TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
|
||||
/* Preemption threshold is not enabled, skip this test. */
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Mutex Nested Priority Inheritance Test...................... SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
|
||||
#else
|
||||
|
||||
UINT test_case = 0;
|
||||
UINT loop_count = 0;
|
||||
UINT priority;
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Mutex Nested Priority Inheritance Test...................... ");
|
||||
|
||||
/* Get the mutex that will be owned always.... */
|
||||
tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
|
||||
|
||||
while(loop_count++ < 50)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
|
||||
tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
|
||||
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Suspend this thread. */
|
||||
tx_thread_suspend(&thread_0);
|
||||
|
||||
/* Resume thread thread 3. */
|
||||
tx_thread_resume(&thread_3);
|
||||
|
||||
/* Thread priority should be 4. */
|
||||
if (thread_0.tx_thread_priority != 4)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Release the mutexes... Depending on the order they are released should dictate
|
||||
the thread's returned to priority. */
|
||||
if (test_case == 0)
|
||||
{
|
||||
|
||||
|
||||
tx_mutex_put(&mutex_2);
|
||||
|
||||
/* Priority should now be returned to priority 8. */
|
||||
if (thread_0.tx_thread_priority != 8)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(2);
|
||||
}
|
||||
|
||||
tx_mutex_put(&mutex_1);
|
||||
|
||||
/* Priority should now be returned to priority 15. */
|
||||
if (thread_0.tx_thread_priority != 15)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(3);
|
||||
}
|
||||
|
||||
tx_mutex_put(&mutex_0);
|
||||
|
||||
/* No change. */
|
||||
if (thread_0.tx_thread_priority != 15)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(4);
|
||||
}
|
||||
}
|
||||
else if (test_case == 1)
|
||||
{
|
||||
|
||||
priority = thread_0.tx_thread_priority;
|
||||
tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Should have no change in priority since nothing was inherited for this mutex. */
|
||||
if (thread_0.tx_thread_priority != priority)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(4);
|
||||
}
|
||||
|
||||
tx_mutex_put(&mutex_1);
|
||||
|
||||
/* Should not do anything since mutex 2 elevated to a higher priority. */
|
||||
if (thread_0.tx_thread_priority != priority)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(5);
|
||||
}
|
||||
|
||||
tx_mutex_put(&mutex_2);
|
||||
|
||||
/* Should go back to priority 15. */
|
||||
if (thread_0.tx_thread_priority != 15)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(6);
|
||||
}
|
||||
}
|
||||
else if (test_case == 2)
|
||||
{
|
||||
|
||||
tx_mutex_put(&mutex_2);
|
||||
|
||||
/* Should go back to priority 8. */
|
||||
if (thread_0.tx_thread_priority != 8)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(7);
|
||||
}
|
||||
|
||||
tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Should not do anything. */
|
||||
if (thread_0.tx_thread_priority != 8)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(8);
|
||||
}
|
||||
|
||||
tx_mutex_put(&mutex_1);
|
||||
|
||||
/* Should go back to priority 15. */
|
||||
if (thread_0.tx_thread_priority != 15)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(9);
|
||||
}
|
||||
}
|
||||
else if (test_case == 3)
|
||||
{
|
||||
|
||||
priority = thread_0.tx_thread_priority;
|
||||
tx_mutex_put(&mutex_1);
|
||||
|
||||
/* Should not do anything since mutex 2 is still owned. */
|
||||
if (thread_0.tx_thread_priority != priority)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(10);
|
||||
}
|
||||
|
||||
tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Should not do anything. */
|
||||
if (thread_0.tx_thread_priority != priority)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(11);
|
||||
}
|
||||
|
||||
tx_mutex_put(&mutex_2);
|
||||
|
||||
/* Should finally go back to priority 15. */
|
||||
if (thread_0.tx_thread_priority != 15)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(12);
|
||||
}
|
||||
}
|
||||
else if (test_case == 4)
|
||||
{
|
||||
|
||||
priority = thread_0.tx_thread_priority;
|
||||
tx_mutex_put(&mutex_1);
|
||||
|
||||
/* Should not do anything since mutex 2 is still owned. */
|
||||
if (thread_0.tx_thread_priority != priority)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(13);
|
||||
}
|
||||
|
||||
tx_mutex_put(&mutex_2);
|
||||
|
||||
/* Should reurn us back to priority 15. */
|
||||
if (thread_0.tx_thread_priority != 15)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(14);
|
||||
}
|
||||
|
||||
tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Should not do anything. */
|
||||
if (thread_0.tx_thread_priority != 15)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(15);
|
||||
}
|
||||
}
|
||||
else if (test_case == 5)
|
||||
{
|
||||
|
||||
priority = thread_0.tx_thread_priority;
|
||||
tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Should not do anything since mutex 2 is still owned. */
|
||||
if (thread_0.tx_thread_priority != priority)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(16);
|
||||
}
|
||||
|
||||
tx_mutex_put(&mutex_2);
|
||||
|
||||
/* Should reurn us back to priority 8. */
|
||||
if (thread_0.tx_thread_priority != 8)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(17);
|
||||
}
|
||||
|
||||
tx_mutex_put(&mutex_1);
|
||||
|
||||
/* Should return us back to priority 15. */
|
||||
if (thread_0.tx_thread_priority != 15)
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(18);
|
||||
}
|
||||
}
|
||||
|
||||
test_case++;
|
||||
if (test_case > 5)
|
||||
test_case = 0;
|
||||
}
|
||||
|
||||
/* Check for thread 3 running... this should not happen! */
|
||||
if (thread_3_counter != 50)
|
||||
{
|
||||
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(19);
|
||||
}
|
||||
|
||||
/* At this point, mutex 3 owned by this thread. */
|
||||
|
||||
/* Resume thread 6, lowest priority thread. */
|
||||
status = tx_thread_resume(&thread_6);
|
||||
|
||||
/* Check for an error. */
|
||||
if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 15) || (thread_6_counter != 0))
|
||||
{
|
||||
|
||||
printf("ERROR #27\n");
|
||||
test_control_return(19);
|
||||
}
|
||||
|
||||
/* Now resume thread 4. */
|
||||
status = tx_thread_resume(&thread_4);
|
||||
|
||||
/* Check for an error. */
|
||||
if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 4) || (thread_6_counter != 0))
|
||||
{
|
||||
|
||||
printf("ERROR #28\n");
|
||||
test_control_return(19);
|
||||
}
|
||||
|
||||
/* Now resume thread 5. */
|
||||
status = tx_thread_resume(&thread_5);
|
||||
|
||||
/* Check for an error. */
|
||||
if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 2) || (thread_6_counter != 0))
|
||||
{
|
||||
|
||||
printf("ERROR #29\n");
|
||||
test_control_return(19);
|
||||
}
|
||||
|
||||
/* Sleep to let thread 6 run, which is lower priority. */
|
||||
tx_thread_sleep(1);
|
||||
|
||||
/* Now release the mutex. */
|
||||
status = tx_mutex_put(&mutex_3);
|
||||
|
||||
/* Check for an error. */
|
||||
if ((status != TX_SUCCESS) || (thread_0.tx_thread_priority != 15) || (thread_6_counter != 0) || (thread_4_counter != 1) || (thread_5_counter != 1))
|
||||
{
|
||||
|
||||
printf("ERROR #30\n");
|
||||
test_control_return(19);
|
||||
}
|
||||
|
||||
/* Sleep to let thread 6 run and release the mutex. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
|
||||
/* If we get here the test was successful! */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT old_priority;
|
||||
UINT old_threshold;
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Update the thread priority and thread preemption-threshold of thread 0. */
|
||||
tx_thread_priority_change(&thread_0, 15, &old_priority);
|
||||
tx_thread_preemption_change(&thread_0, 14, &old_threshold);
|
||||
|
||||
/* Get mutex. */
|
||||
tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
|
||||
tx_mutex_put(&mutex_1);
|
||||
|
||||
tx_thread_suspend(&thread_1);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Update the thread priority and thread preemption-threshold of thread 0. */
|
||||
tx_thread_priority_change(&thread_0, 15, &old_priority);
|
||||
tx_thread_preemption_change(&thread_0, 8, &old_threshold);
|
||||
|
||||
/* Get mutex. */
|
||||
tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
|
||||
tx_mutex_put(&mutex_1);
|
||||
|
||||
tx_thread_suspend(&thread_1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT old_priority;
|
||||
UINT old_threshold;
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Update the thread priority and thread preemption-threshold of thread 0. */
|
||||
tx_thread_priority_change(&thread_0, 15, &old_priority);
|
||||
tx_thread_preemption_change(&thread_0, 14, &old_threshold);
|
||||
|
||||
/* Get mutex. */
|
||||
tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
|
||||
tx_mutex_put(&mutex_2);
|
||||
|
||||
tx_thread_suspend(&thread_2);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Update the thread priority and thread preemption-threshold of thread 0. */
|
||||
tx_thread_priority_change(&thread_0, 15, &old_priority);
|
||||
tx_thread_preemption_change(&thread_0, 8, &old_threshold);
|
||||
|
||||
/* Get mutex. */
|
||||
tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
|
||||
tx_mutex_put(&mutex_2);
|
||||
|
||||
tx_thread_suspend(&thread_2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Resume thread 0. */
|
||||
tx_thread_resume(&thread_0);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_3_counter++;
|
||||
|
||||
/* Suspend this thread. */
|
||||
tx_thread_suspend(&thread_3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Get priority inherit mutex. */
|
||||
tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_4_counter++;
|
||||
|
||||
/* Release the priority inherit mutex. */
|
||||
tx_mutex_put(&mutex_3);
|
||||
|
||||
/* Suspend this thread. */
|
||||
tx_thread_suspend(&thread_4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Get priority inherit mutex. */
|
||||
tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
|
||||
/* Release the priority inherit mutex. */
|
||||
tx_mutex_put(&mutex_3);
|
||||
|
||||
/* Suspend this thread. */
|
||||
tx_thread_suspend(&thread_5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_6_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Get priority inherit mutex. */
|
||||
tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_6_counter++;
|
||||
|
||||
/* Release the priority inherit mutex. */
|
||||
tx_mutex_put(&mutex_3);
|
||||
|
||||
/* Suspend this thread. */
|
||||
tx_thread_suspend(&thread_6);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
173
test/smp/regression/threadx_mutex_no_preemption_test.c
Normal file
173
test/smp/regression/threadx_mutex_no_preemption_test.c
Normal file
@ -0,0 +1,173 @@
|
||||
/* This test is designed to test the mutex suspension and another thread resuming the
|
||||
same priority thread by doing a mutex put. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
|
||||
static TX_MUTEX mutex_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_mutext_no_preemption_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Put with No Preemption Test........................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Put with No Preemption Test........................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a mutex. */
|
||||
status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Put with No Preemption Test........................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Mutex Put with No Preemption Test........................... ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Get the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to make the other thread suspend on the mutex. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Make sure the other thread has run. */
|
||||
if (thread_1_counter != 1)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Put the mutex, this should resume the other thread
|
||||
but not preempt this thread. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check the status and the run counter of the other thread. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 1))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to allow the other thread to run. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Make sure the other thread has run. */
|
||||
if (thread_1_counter != 2)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Increment thread run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_1_counter++;
|
||||
}
|
||||
|
161
test/smp/regression/threadx_mutex_preemption_test.c
Normal file
161
test/smp/regression/threadx_mutex_preemption_test.c
Normal file
@ -0,0 +1,161 @@
|
||||
/* This test is designed to test the mutex suspension and another thread resuming the
|
||||
higher priority thread by doing a mutex put. Higher-priority thread should preempt. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
|
||||
static TX_MUTEX mutex_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_mutex_preemption_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Put with Preemption Test.............................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Put with Preemption Test.............................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a mutex. */
|
||||
status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Put with Preemption Test.............................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Mutex Put with Preemption Test.............................. ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Get the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now resume the higher priority thread to cause suspension. */
|
||||
tx_thread_resume(&thread_1);
|
||||
|
||||
/* The other thread should now be suspended on the mutex. */
|
||||
if (thread_1_counter != 1)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Release the mutex, this should cause the other thread
|
||||
to preempt. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status and run counter of other thread. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 2))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Increment thread run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_1_counter++;
|
||||
}
|
||||
|
607
test/smp/regression/threadx_mutex_priority_inheritance_test.c
Normal file
607
test/smp/regression/threadx_mutex_priority_inheritance_test.c
Normal file
@ -0,0 +1,607 @@
|
||||
/* This test is designed to test the mutex suspension and priority inheritance with another
|
||||
thread resuming the higher priority thread by doing a mutex put. Higher-priority thread should preempt. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
static unsigned long thread_4_counter = 0;
|
||||
static TX_THREAD thread_4;
|
||||
|
||||
static unsigned long thread_5_counter = 0;
|
||||
static TX_THREAD thread_5;
|
||||
|
||||
static unsigned long thread_6_counter = 0;
|
||||
static TX_THREAD thread_6;
|
||||
|
||||
static unsigned long thread_7_counter = 0;
|
||||
static TX_THREAD thread_7;
|
||||
|
||||
static TX_MUTEX mutex_0;
|
||||
static TX_MUTEX mutex_1;
|
||||
static TX_MUTEX mutex_2;
|
||||
static TX_MUTEX mutex_3;
|
||||
|
||||
|
||||
extern UINT test_mutex_from_init;
|
||||
extern TEST_FLAG test_forced_mutex_timeout;
|
||||
|
||||
|
||||
VOID _tx_mutex_priority_change(TX_THREAD *thread_ptr, UINT priority, UINT threshold);
|
||||
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
static void thread_5_entry(ULONG thread_input);
|
||||
static void thread_6_entry(ULONG thread_input);
|
||||
static void thread_7_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_mutex_priority_inheritance_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Test for an error creating/using a mutex from initialization. */
|
||||
if (test_mutex_from_init != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Priority Inheritance Test............................. ERROR #0\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Priority Inheritance Test............................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Priority Inheritance Test............................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
14, 14, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Priority Inheritance Test............................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a high-priority thread that will get all the priority inheritance mutexes and return from
|
||||
it's entry function in order to test the auto delete feature. */
|
||||
status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
10, 10, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Priority Inheritance Test............................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a higher-priority thread that is used to get thread 4 into a priority inheritance state. */
|
||||
status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
8, 8, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Priority Inheritance Test............................. ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Create a higher-priority thread that is used to suspend on priority inheritance mutex 3. */
|
||||
status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
6, 6, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Priority Inheritance Test............................. ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Create a higher-priority thread that is used to suspend on priority inheritance mutex 3. */
|
||||
status = tx_thread_create(&thread_7, "thread 7", thread_7_entry, 7,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
7, 7, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Priority Inheritance Test............................. ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a mutex. */
|
||||
status = tx_mutex_create(&mutex_0, "mutex 0", TX_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Priority Inheritance Test............................. ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create another mutex. */
|
||||
status = tx_mutex_create(&mutex_1, "mutex 1", TX_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Priority Inheritance Test............................. ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create another mutex. */
|
||||
status = tx_mutex_create(&mutex_2, "mutex 2", TX_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Priority Inheritance Test............................. ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create another mutex. */
|
||||
status = tx_mutex_create(&mutex_3, "mutex 3", TX_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Priority Inheritance Test............................. ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Drive one path of the internal mutex priority change routine directly for code coverage. */
|
||||
thread_3.tx_thread_user_priority = 1;
|
||||
thread_3.tx_thread_user_preempt_threshold = 1;
|
||||
thread_3.tx_thread_state = 4;
|
||||
_tx_mutex_priority_change(&thread_3, 3, 3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Mutex Priority Inheritance Test............................. ");
|
||||
|
||||
/* Resume thread 4 to test the automatic release of the mutexes. */
|
||||
tx_thread_resume(&thread_4);
|
||||
|
||||
/* Determine if thread 4 was able to get the mutexes before completion... and
|
||||
have its original priority restored after the priority inheritance. */
|
||||
if ((thread_4_counter != 1) || (thread_5_counter != 1) || (thread_4.tx_thread_priority != 10) ||
|
||||
(thread_4.tx_thread_inherit_priority != TX_MAX_PRIORITIES))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Get all the mutexex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
|
||||
status += tx_mutex_get(&mutex_1, TX_NO_WAIT);
|
||||
status += tx_mutex_get(&mutex_2, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Release mutex 2 to be compatible with original test. */
|
||||
tx_mutex_put(&mutex_2);
|
||||
|
||||
/* Now resume the higher priority thread to cause suspension. */
|
||||
tx_thread_resume(&thread_1);
|
||||
|
||||
/* The other thread should now be suspended on the mutex. */
|
||||
if ((thread_1_counter != 1) || (thread_0.tx_thread_priority != 15))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Release the mutex, this should cause the other thread
|
||||
to preempt. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status and run counter of other thread. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 2) || (thread_0.tx_thread_priority != 16))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point, get the mutex again. */
|
||||
status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now sleep for 20 ticks in order to test the priority inheritance change of a
|
||||
non-ready thread. */
|
||||
tx_thread_sleep(20);
|
||||
|
||||
/* The other thread should now be suspended on the mutex. */
|
||||
if ((thread_1_counter != 3) || (thread_0.tx_thread_priority != 15))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 2 in order to get two threads suspended on the mutex. */
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Now do a mutex put to release both threads suspended on this mutex. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* The other thread should now be suspended on the mutex. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 4) || (thread_2_counter != 2) || (thread_0.tx_thread_priority != 16))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point, get the mutex again. */
|
||||
status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Abort the sleep. */
|
||||
tx_thread_wait_abort(&thread_1);
|
||||
tx_thread_wait_abort(&thread_2);
|
||||
|
||||
/* Now both threads are suspended again on mutex... and then terminate them. */
|
||||
tx_thread_terminate(&thread_1);
|
||||
tx_thread_terminate(&thread_2);
|
||||
|
||||
/* Now do a mutex put to release both threads suspended on this mutex. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* The other thread should now be suspended on the mutex. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 3) || (thread_0.tx_thread_priority != 16))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now test the timeout on the suspension list of a priority inheritance mutex. */
|
||||
|
||||
/* First, obtain priority inheritance mutex 3. */
|
||||
status = tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
|
||||
|
||||
/* Next resume threads 6 and 7 so they will block on trying to get this mutex forever. */
|
||||
status += tx_thread_resume(&thread_7);
|
||||
status += tx_thread_resume(&thread_6);
|
||||
|
||||
/* Now set the flag which will cause the last thread in the suspension list to timeout (abort)
|
||||
resulting in a NULL suspension list and covering that branch condition in tx_mutex_put */
|
||||
test_forced_mutex_timeout = 1;
|
||||
|
||||
/* Perform a mutex put to release the mutex. */
|
||||
status += tx_mutex_put(&mutex_3);
|
||||
|
||||
/* Now check for errors. */
|
||||
#ifndef TX_MISRA_ENABLE
|
||||
#ifndef TX_MANUAL_TEST
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
if ((status != TX_SUCCESS) || (thread_6_counter != 1) || (thread_7_counter != 0))
|
||||
#else
|
||||
if ((status != TX_SUCCESS) || (thread_6_counter != 1))
|
||||
#endif
|
||||
#else
|
||||
if ((status != TX_SUCCESS) || (thread_6_counter != 1))
|
||||
#endif
|
||||
#else
|
||||
if ((status != TX_SUCCESS) || (thread_6_counter != 1))
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment thread run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
status += tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_1_counter++;
|
||||
|
||||
/* Sleep for 10 ticks... to delay. */
|
||||
tx_thread_sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Get mutex to cause additional ownership linked-list processing. */
|
||||
tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment thread run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
status += tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_2_counter++;
|
||||
|
||||
/* Sleep for 10 ticks... to delay. */
|
||||
tx_thread_sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UINT old_priority;
|
||||
|
||||
|
||||
/* Get mutex to cause additional ownership linked-list processing. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
status += tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
|
||||
status += tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
|
||||
status += tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
|
||||
status += tx_mutex_get(&mutex_2, TX_WAIT_FOREVER);
|
||||
|
||||
/* Resume thread 5 to get into priority inheritance. */
|
||||
tx_thread_resume(&thread_5);
|
||||
|
||||
/* Determine if all the mutex gets were successful... and we have
|
||||
inherited priority 8. */
|
||||
if ((status == TX_SUCCESS) && (thread_4.tx_thread_priority == 8))
|
||||
{
|
||||
|
||||
/* Yes, increment the thread counter. */
|
||||
thread_4_counter++;
|
||||
}
|
||||
|
||||
/* Now, attempt to manually set this thread's priority to the same priority. */
|
||||
status = tx_thread_priority_change(&thread_4, 8, &old_priority);
|
||||
|
||||
/* Determine if there is an error. */
|
||||
if ((status != TX_SUCCESS) || (thread_4.tx_thread_user_priority != 8) || (old_priority != 10))
|
||||
{
|
||||
|
||||
/* Clear the counter, which will signal an error to the thread above. */
|
||||
thread_4_counter = 0;
|
||||
}
|
||||
|
||||
/* Now attempt to manually set the same thread priority. */
|
||||
status = tx_thread_priority_change(&thread_4, 8, &old_priority);
|
||||
|
||||
/* Determine if there is an error. */
|
||||
if ((status != TX_SUCCESS) || (thread_4.tx_thread_user_priority != 8) || (old_priority != 8))
|
||||
{
|
||||
|
||||
/* Clear the counter, which will signal an error to the thread above. */
|
||||
thread_4_counter = 0;
|
||||
}
|
||||
|
||||
/* Now restore the original user priority of 10. */
|
||||
status = tx_thread_priority_change(&thread_4, 10, &old_priority);
|
||||
|
||||
/* Determine if there is an error. */
|
||||
if ((status != TX_SUCCESS) || (thread_4.tx_thread_user_priority != 10) || (old_priority != 8))
|
||||
{
|
||||
|
||||
/* Clear the counter, which will signal an error to the thread above. */
|
||||
thread_4_counter = 0;
|
||||
}
|
||||
|
||||
/* Now fall through and make sure the mutex cleanup function
|
||||
releases all the mutexes. */
|
||||
}
|
||||
|
||||
|
||||
static void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Get mutex to cause priority inheritance in thread 4. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Determine if all the mutex gets were successful. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Yes, increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
}
|
||||
|
||||
/* Now fall through and make sure the mutex cleanup function
|
||||
releases all the mutexes. */
|
||||
}
|
||||
|
||||
|
||||
static void thread_6_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Get mutex to cause priority inheritance in thread 0. */
|
||||
status = tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
|
||||
|
||||
/* Determine if all the mutex gets were successful. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Yes, increment the thread counter. */
|
||||
thread_6_counter++;
|
||||
}
|
||||
|
||||
/* Now fall through and make sure the mutex cleanup function
|
||||
releases all the mutexes. */
|
||||
}
|
||||
|
||||
|
||||
static void thread_7_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Get mutex to cause priority inheritance in thread 0. */
|
||||
status = tx_mutex_get(&mutex_3, TX_WAIT_FOREVER);
|
||||
|
||||
/* Determine if all the mutex gets were successful. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Yes, increment the thread counter. */
|
||||
thread_7_counter++;
|
||||
}
|
||||
|
||||
/* Now fall through and make sure the mutex cleanup function
|
||||
releases all the mutexes. */
|
||||
}
|
||||
|
525
test/smp/regression/threadx_mutex_proritize_test.c
Normal file
525
test/smp/regression/threadx_mutex_proritize_test.c
Normal file
@ -0,0 +1,525 @@
|
||||
/* This test is designed to test the mutex suspension prioritization. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Define the external reference for the preempt disable flag. */
|
||||
|
||||
extern volatile UINT _tx_thread_preempt_disable;
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
static unsigned long thread_4_counter = 0;
|
||||
static TX_THREAD thread_4;
|
||||
|
||||
static unsigned long thread_5_counter = 0;
|
||||
static TX_THREAD thread_5;
|
||||
|
||||
static unsigned long thread_6_counter = 0;
|
||||
static TX_THREAD thread_6;
|
||||
|
||||
|
||||
static TX_MUTEX mutex_0;
|
||||
static TX_MUTEX mutex_1;
|
||||
|
||||
static int test_status;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
static void thread_5_entry(ULONG thread_input);
|
||||
static void thread_6_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* Determine if the test case we are looking for is present. */
|
||||
if ((_tx_thread_preempt_disable) && (test_status == 1))
|
||||
{
|
||||
|
||||
/* Determine if thread 3 is at the front of the suspension list. */
|
||||
if (mutex_0.tx_mutex_suspension_list == &thread_3)
|
||||
{
|
||||
|
||||
/* Abort the wait of thread 3. */
|
||||
tx_thread_wait_abort(&thread_3);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Abort the wait of thread 5. */
|
||||
tx_thread_wait_abort(&thread_5);
|
||||
|
||||
/* End the ISR processing. */
|
||||
test_status = 2;
|
||||
test_isr_dispatch = TX_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_mutex_prioritize_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Prioritize Test....................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Prioritize Test....................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
14, 14, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Prioritize Test....................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
3, 3, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Prioritize Test....................................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
4, 4, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Prioritize Test....................................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
5, 5, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Prioritize Test....................................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
6, 6, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Prioritize Test....................................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a mutex. */
|
||||
status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Prioritize Test....................................... ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Mutex Prioritize Test....................................... ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Attempt to prioritize a NULL mutex. */
|
||||
status = tx_mutex_prioritize(TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_MUTEX_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to prioritize a non-created mutex. */
|
||||
mutex_1.tx_mutex_id = 0;
|
||||
status = tx_mutex_prioritize(&mutex_1);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_MUTEX_ERROR)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Prioritize the mutex with no suspended threads! */
|
||||
status = tx_mutex_prioritize(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Grab the mutex so it is owned by this thread. */
|
||||
status = tx_mutex_get(&mutex_0, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume other threads run. */
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Other threads should now be suspended on the mutex. Thread 1 should be
|
||||
in front of thread 2 since it was suspended first. */
|
||||
if (mutex_0.tx_mutex_suspension_list != &thread_1)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Prioritize the mutex to test it out! */
|
||||
status = tx_mutex_prioritize(&mutex_0);
|
||||
|
||||
/* Check status and make sure thread 2 is now at the front of the list. */
|
||||
if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_2))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Prioritize the mutex again to make sure nothing has changed! */
|
||||
status = tx_mutex_prioritize(&mutex_0);
|
||||
|
||||
/* Check status and make sure thread 2 is now at the front of the list. */
|
||||
if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_2))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #14a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point we are going to get more than 2 threads suspended. */
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
tx_thread_resume(&thread_3);
|
||||
tx_thread_resume(&thread_4);
|
||||
tx_thread_resume(&thread_5);
|
||||
tx_thread_resume(&thread_6);
|
||||
|
||||
/* Prioritize the block pool suspension list. */
|
||||
status = tx_mutex_prioritize(&mutex_0);
|
||||
|
||||
/* Check status and make sure thread 3 is at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (mutex_0.tx_mutex_suspension_list != &thread_3))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now loop to test the interrupt of the prioritize loop logic. */
|
||||
test_status = 1;
|
||||
test_isr_dispatch = test_isr;
|
||||
do
|
||||
{
|
||||
|
||||
/* Prioritize the mutex suspension list. */
|
||||
status = tx_mutex_prioritize(&mutex_0);
|
||||
|
||||
/* Check status and make sure thread 1 is terminated. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
} while (test_status == 1);
|
||||
|
||||
/* Now determine if thread 4 is at the front of the list... It should be! */
|
||||
if (mutex_0.tx_mutex_suspension_list != &thread_4)
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Release the mutex. */
|
||||
status += tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_1_counter++;
|
||||
|
||||
/* Self suspend. */
|
||||
tx_thread_suspend(&thread_1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Release the mutex. */
|
||||
status += tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_2_counter++;
|
||||
|
||||
/* Self suspend. */
|
||||
tx_thread_suspend(&thread_2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Release the mutex. */
|
||||
status += tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_3_counter++;
|
||||
|
||||
/* Self suspend. */
|
||||
tx_thread_suspend(&thread_3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Release the mutex. */
|
||||
status += tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_4_counter++;
|
||||
|
||||
/* Self suspend. */
|
||||
tx_thread_suspend(&thread_4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Release the mutex. */
|
||||
status += tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_5_counter++;
|
||||
|
||||
/* Self suspend. */
|
||||
tx_thread_suspend(&thread_5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_6_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Release the mutex. */
|
||||
status += tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_6_counter++;
|
||||
|
||||
/* Self suspend. */
|
||||
tx_thread_suspend(&thread_6);
|
||||
}
|
||||
}
|
||||
|
474
test/smp/regression/threadx_mutex_suspension_timeout_test.c
Normal file
474
test/smp/regression/threadx_mutex_suspension_timeout_test.c
Normal file
@ -0,0 +1,474 @@
|
||||
/* This test is designed to test the mutex suspension and timeout functionality. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_mutex.h"
|
||||
|
||||
|
||||
//static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
static TX_THREAD thread_2;
|
||||
static TX_THREAD thread_3;
|
||||
static TX_THREAD thread_4;
|
||||
static TX_THREAD low_priority;
|
||||
|
||||
|
||||
static TX_MUTEX mutex_0;
|
||||
static TX_MUTEX mutex_1;
|
||||
extern UINT mutex_priority_change_extension_selection;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
static void low_priority_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
extern void test_control_return(UINT status);
|
||||
|
||||
|
||||
#ifndef TX_MANUAL_TEST
|
||||
|
||||
/* Define test flags for automated test. */
|
||||
|
||||
extern TEST_FLAG threadx_mutex_suspension_put_test;
|
||||
extern TEST_FLAG threadx_mutex_suspension_priority_test;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* This test routine is used to get NULL suspension lists in various parts of tx_mutex_put. This is hooked up to IRQ 0 on this simulation and is entered manually at the
|
||||
correct time. */
|
||||
void abort_all_threads_suspended_on_mutex(void)
|
||||
{
|
||||
|
||||
TX_THREAD *thread_ptr;
|
||||
|
||||
thread_ptr = _tx_thread_created_ptr;
|
||||
while (thread_ptr)
|
||||
{
|
||||
if (thread_ptr -> tx_thread_state == TX_MUTEX_SUSP)
|
||||
tx_thread_wait_abort(thread_ptr);
|
||||
|
||||
thread_ptr = thread_ptr -> tx_thread_created_next;
|
||||
if (thread_ptr == _tx_thread_created_ptr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This test routine is used to get a thread of a non ready state into _tx_mutex_change, called froim _tx_mutex_put. This is hooked up to IRQ 1 on this simulation and is entered manually at the
|
||||
correct time. */
|
||||
void suspend_lowest_priority(void)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_THREAD *thread_ptr;
|
||||
|
||||
|
||||
/* Determine which extension to perform... to get to the different error checks in _tx_mutex_priority_change. */
|
||||
if (mutex_priority_change_extension_selection == 0)
|
||||
{
|
||||
|
||||
/* Setup the thread pointer. */
|
||||
thread_ptr = &thread_0;
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Set the state to suspended. */
|
||||
thread_ptr -> tx_thread_state = TX_SUSPENDED;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Call actual non-interruptable thread suspension routine. */
|
||||
_tx_thread_system_ni_suspend(thread_ptr, ((ULONG) 0));
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
#else
|
||||
|
||||
/* Set the suspending flag. */
|
||||
thread_ptr -> tx_thread_suspending = TX_TRUE;
|
||||
|
||||
/* Setup for no timeout period. */
|
||||
thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks = ((ULONG) 0);
|
||||
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Call actual thread suspension routine. */
|
||||
_tx_thread_system_suspend(thread_ptr);
|
||||
#endif
|
||||
}
|
||||
else if (mutex_priority_change_extension_selection == 1)
|
||||
{
|
||||
|
||||
/* Make the mapped core field to be invalid to exercise the error checking branch for core_index. */
|
||||
thread_0.tx_thread_smp_core_mapped = TX_THREAD_SMP_MAX_CORES;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_mutex_suspension_timeout_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
1, 1, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
2, 2, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
3, 3, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
4, 4, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_create(&low_priority, "low priority", low_priority_entry, 30,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
30, 30, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Suspension Timeout Test............................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create mutexes. */
|
||||
status = tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
status += tx_mutex_create(&mutex_1, "mutex 1", TX_INHERIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Suspension Timeout Test............................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the mutex to prevent thread from getting it. */
|
||||
tx_mutex_get(&mutex_0, TX_NO_WAIT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_THREAD *temp_thread;
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Mutex Suspension Timeout Test............................... ");
|
||||
|
||||
/* Sleep for 2 ticks for fresh timer. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Set clock to 0. */
|
||||
tx_time_set(0);
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
status = tx_mutex_get(&mutex_0, 33);
|
||||
|
||||
/* Did we get the right status at the right time? */
|
||||
if ((status != TX_NOT_AVAILABLE) || (tx_time_get() != 33))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the mutex. */
|
||||
status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
|
||||
|
||||
/* Make sure the three higher priority threads suspend on the mutex. */
|
||||
tx_thread_resume(&thread_4);
|
||||
tx_thread_resume(&thread_3);
|
||||
tx_thread_resume(&thread_2);
|
||||
tx_thread_resume(&thread_1);
|
||||
|
||||
|
||||
#ifdef TX_MANUAL_TEST
|
||||
|
||||
/* Set BP hear and step into code and generate appropriate interrupt IRQ 0 by hand right after the prioritize function with interrupts enabled. This is to achieve the empty list branch coverage after the prioritize function. */
|
||||
tx_mutex_put(&mutex_1);
|
||||
#else
|
||||
|
||||
/* Set the flag such that generate the condition wehre the empty list condition is satisfied in the branch coverage. */
|
||||
threadx_mutex_suspension_put_test = 1;
|
||||
tx_mutex_put(&mutex_1);
|
||||
#endif
|
||||
|
||||
/* Now some hand testing for tx_mutex_priority_change. */
|
||||
|
||||
/* Resume the low priority thread. */
|
||||
tx_thread_resume(&low_priority);
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Simulate a call from inside of mutex put, but doing it here makes life easier. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Move the current thread to a lower priority. */
|
||||
_tx_mutex_priority_change(&thread_0, 15);
|
||||
_tx_mutex_priority_change(&thread_0, 16);
|
||||
|
||||
/* Move the lower priority thread to a higher priority. */
|
||||
_tx_mutex_priority_change(&low_priority, 28);
|
||||
_tx_mutex_priority_change(&low_priority, 29);
|
||||
_tx_mutex_priority_change(&low_priority, 30);
|
||||
|
||||
/* Change the priority of the current thread, such that we should have reverse the preemption-threshold issue. */
|
||||
thread_0.tx_thread_user_priority = 30;
|
||||
thread_0.tx_thread_user_preempt_threshold = 30;
|
||||
_tx_mutex_priority_change(&thread_0, 30);
|
||||
|
||||
/* Change to an even lower priority. */
|
||||
thread_0.tx_thread_user_priority = 31;
|
||||
thread_0.tx_thread_user_preempt_threshold = 31;
|
||||
_tx_mutex_priority_change(&thread_0, 31);
|
||||
|
||||
/* Move back to a higher-priority. */
|
||||
thread_0.tx_thread_user_priority = 30;
|
||||
thread_0.tx_thread_user_preempt_threshold = 30;
|
||||
_tx_mutex_priority_change(&thread_0, 16);
|
||||
|
||||
#ifdef TX_MANUAL_TEST
|
||||
|
||||
/* Set BP here and step into code and step through the code until the internal thread resume function returns, then issue an IRQ 1 to cause an ISR to suspend the thread and test the first condition. */
|
||||
_tx_mutex_priority_change(&thread_0, 30);
|
||||
#else
|
||||
|
||||
/* Set the flag to suspend the thread and test the first condition after internal resume is called. */
|
||||
mutex_priority_change_extension_selection = 0;
|
||||
threadx_mutex_suspension_priority_test = 1;
|
||||
_tx_mutex_priority_change(&thread_0, 30);
|
||||
#endif
|
||||
|
||||
/* Resume this thread. */
|
||||
tx_thread_resume(&thread_0);
|
||||
_tx_mutex_priority_change(&thread_0, 16);
|
||||
|
||||
/* Change to an even lower priority. */
|
||||
thread_0.tx_thread_user_priority = 27;
|
||||
thread_0.tx_thread_user_preempt_threshold = 27;
|
||||
_tx_mutex_priority_change(&thread_0, 28);
|
||||
|
||||
/* Setup the low priority thread infromation. */
|
||||
low_priority.tx_thread_user_priority = 30;
|
||||
low_priority.tx_thread_user_preempt_threshold = 29;
|
||||
_tx_mutex_priority_change(&low_priority, 31);
|
||||
|
||||
/* Change to an even lower priority. */
|
||||
thread_0.tx_thread_user_priority = 30;
|
||||
thread_0.tx_thread_user_preempt_threshold = 29;
|
||||
_tx_mutex_priority_change(&thread_0, 26);
|
||||
|
||||
#ifdef TX_MANUAL_TEST
|
||||
|
||||
/* Set BP here and step into code and step through the code until the internal thread resume function returns, and then issue the IRQ that modifies the core mapped. */
|
||||
mutex_priority_change_extension_selection = 1;
|
||||
_tx_mutex_priority_change(&thread_0, 30);
|
||||
thread_0.tx_thread_smp_core_mapped = 0;
|
||||
#else
|
||||
|
||||
/* Set the flag to suspend the thread and test the first condition after internal resume is called. */
|
||||
mutex_priority_change_extension_selection = 1;
|
||||
threadx_mutex_suspension_priority_test = 1;
|
||||
_tx_mutex_priority_change(&thread_0, 30);
|
||||
thread_0.tx_thread_smp_core_mapped = 0;
|
||||
#endif
|
||||
|
||||
/* Move the thread back to priority 28. */
|
||||
_tx_mutex_priority_change(&thread_0, 28);
|
||||
|
||||
#ifdef TX_MANUAL_TEST
|
||||
|
||||
/* Set BP here and step into code and step through the code until the internal thread resume function returns, and then issue the IRQ that modifies the original priority. */
|
||||
mutex_priority_change_extension_selection = 2;
|
||||
_tx_mutex_priority_change(&thread_0, 29);
|
||||
#else
|
||||
|
||||
/* Set the flag to suspend the thread and test the first condition after internal resume is called. */
|
||||
mutex_priority_change_extension_selection = 2;
|
||||
threadx_mutex_suspension_priority_test = 1;
|
||||
_tx_mutex_priority_change(&thread_0, 29);
|
||||
_tx_thread_execute_ptr[0] = &thread_0;
|
||||
#endif
|
||||
|
||||
#ifdef TX_MANUAL_TEST
|
||||
|
||||
/* Set BP here and step into code and step through the code until the internal thread resume function returns, and then issue the IRQ that sets the original_pt_thread to NULL. */
|
||||
mutex_priority_change_extension_selection = 3;
|
||||
_tx_mutex_priority_change(&thread_0, 30);
|
||||
#else
|
||||
|
||||
/* Set the flag to suspend the thread and test the first condition after internal resume is called. */
|
||||
mutex_priority_change_extension_selection = 3;
|
||||
threadx_mutex_suspension_priority_test = 1;
|
||||
_tx_mutex_priority_change(&thread_0, 30);
|
||||
#endif
|
||||
|
||||
#ifdef TX_MANUAL_TEST
|
||||
|
||||
/* Set BP here and step into code and step through the code until the internal thread resume function returns, and then issue the IRQ that sets the _tx_thread_preemption__threshold_scheduled to NULL. */
|
||||
temp_thread = _tx_thread_preemption__threshold_scheduled;
|
||||
mutex_priority_change_extension_selection = 4;
|
||||
_tx_mutex_priority_change(&thread_0, 31);
|
||||
_tx_thread_preemption__threshold_scheduled = temp_thread;
|
||||
#else
|
||||
|
||||
/* Set the flag to suspend the thread and test the first condition after internal resume is called. */
|
||||
temp_thread = _tx_thread_preemption__threshold_scheduled;
|
||||
mutex_priority_change_extension_selection = 4;
|
||||
threadx_mutex_suspension_priority_test = 1;
|
||||
_tx_mutex_priority_change(&thread_0, 31);
|
||||
_tx_thread_preemption__threshold_scheduled = temp_thread;
|
||||
#endif
|
||||
|
||||
/* Just change to same priority to ensure that path is executed. */
|
||||
mutex_priority_change_extension_selection = 0;
|
||||
suspend_lowest_priority();
|
||||
thread_0.tx_thread_user_priority = 31;
|
||||
thread_0.tx_thread_user_preempt_threshold = 30;
|
||||
thread_0.tx_thread_priority = 31;
|
||||
thread_0.tx_thread_preempt_threshold = 30;
|
||||
_tx_mutex_priority_change(&thread_0, 31);
|
||||
thread_0.tx_thread_user_priority = 31;
|
||||
thread_0.tx_thread_user_preempt_threshold = 31;
|
||||
thread_0.tx_thread_priority = 31;
|
||||
thread_0.tx_thread_preempt_threshold = 31;
|
||||
_tx_mutex_priority_change(&thread_0, 31);
|
||||
tx_thread_resume(&thread_0);
|
||||
|
||||
/* Restore the preempt disable flag. */
|
||||
_tx_thread_preempt_disable--;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
|
||||
/* Loop to get the mutex. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Get and release the mutex. */
|
||||
status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
|
||||
if (status == TX_SUCCESS)
|
||||
tx_mutex_put(&mutex_1);
|
||||
tx_thread_suspend(&thread_1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Loop to get the mutex. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Get and release the mutex. */
|
||||
status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
|
||||
if (status == TX_SUCCESS)
|
||||
tx_mutex_put(&mutex_1);
|
||||
tx_thread_suspend(&thread_2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Loop to get the mutex. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Get and release the mutex. */
|
||||
status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
|
||||
if (status == TX_SUCCESS)
|
||||
tx_mutex_put(&mutex_1);
|
||||
tx_thread_suspend(&thread_3);
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Loop to get the mutex. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Get and release the mutex. */
|
||||
status = tx_mutex_get(&mutex_1, TX_WAIT_FOREVER);
|
||||
if (status == TX_SUCCESS)
|
||||
tx_mutex_put(&mutex_1);
|
||||
tx_thread_suspend(&thread_4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void low_priority_entry(ULONG thread_input)
|
||||
{
|
||||
}
|
198
test/smp/regression/threadx_mutex_thread_terminate_test.c
Normal file
198
test/smp/regression/threadx_mutex_thread_terminate_test.c
Normal file
@ -0,0 +1,198 @@
|
||||
/* This test is designed to test thread terminate calls when threads are suspended on
|
||||
a mutex. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
|
||||
static TX_MUTEX mutex_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_mutex_thread_terminate_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Thread Terminate Test................................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Thread Terminate Test................................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Thread Terminate Test................................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a mutex. */
|
||||
status = tx_mutex_create(&mutex_0, "mutex 0", 0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Mutex Thread Terminate Test................................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the mutex. */
|
||||
tx_mutex_get(&mutex_0, TX_NO_WAIT);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Mutex Thread Terminate Test................................. ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Relinquish to let other threads run. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Other threads should now be suspended on the mutex. */
|
||||
if ((thread_1_counter != 1) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Terminate the other threads to make sure the mutex gets
|
||||
cleaned up. */
|
||||
status = tx_thread_terminate(&thread_1);
|
||||
|
||||
/* Check status and run counters of other threads. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Terminate the other thread. */
|
||||
status = tx_thread_terminate(&thread_2);
|
||||
|
||||
/* Relinquish just to make sure. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Check status and run counters of other threads. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Mutex error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
//UINT status;
|
||||
|
||||
/* Increment thread run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
tx_mutex_get(&mutex_0, 33);
|
||||
|
||||
/* Should never get here! */
|
||||
thread_1_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
//UINT status;
|
||||
|
||||
/* Increment thread run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Suspend on the mutex. */
|
||||
tx_mutex_get(&mutex_0, 44);
|
||||
|
||||
/* Should never get here! */
|
||||
thread_2_counter++;
|
||||
}
|
423
test/smp/regression/threadx_queue_basic_eight_word_test.c
Normal file
423
test/smp/regression/threadx_queue_basic_eight_word_test.c
Normal file
@ -0,0 +1,423 @@
|
||||
/* This test is designed to test immediate response queue services including create
|
||||
and delete. This test is for queue sizes of 8 ULONG. Two queues are used one with
|
||||
a capacity of 1 message and another with a capacity of 3 messages. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
static TX_QUEUE queue_1;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_basic_eight_word_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Eight Word Queue Test................................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the queues. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_8_ULONG, pointer, 8*sizeof(ULONG));
|
||||
pointer = pointer + (8*sizeof(ULONG));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Eight Word Queue Test................................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_create(&queue_1, "queue 1", TX_8_ULONG, pointer, 8*3*sizeof(ULONG));
|
||||
pointer = pointer + 8*3*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Eight Word Queue Test................................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG source_message[8];
|
||||
ULONG dest_message[8];
|
||||
ULONG expected_message[8];
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue Eight Word Queue Test................................. ");
|
||||
|
||||
source_message[0] = 0x01234567;
|
||||
source_message[7] = 0x89ABCDEF;
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Place something on queue 0. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) ||
|
||||
(source_message[7] != dest_message[7]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Make sure we can do the same thing again! */
|
||||
source_message[0]++;
|
||||
source_message[7]++;
|
||||
|
||||
/* Place something on queue 0. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) ||
|
||||
(source_message[7] != dest_message[7]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now we need to do the same thing with the queue with three entries. */
|
||||
|
||||
source_message[0]++;
|
||||
source_message[7]++;
|
||||
expected_message[0] = source_message[0];
|
||||
expected_message[7] = source_message[7];
|
||||
|
||||
/* Place something on queue 1. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[7]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[7]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[7]++;
|
||||
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[7] != dest_message[7]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[7]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[7] != dest_message[7]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[7]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[7] != dest_message[7]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[7]++;
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Make sure we can do the same thing again! */
|
||||
|
||||
/* Place something on queue 1. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[7]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[7]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[7]++;
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[7] != dest_message[7]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[7]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[7] != dest_message[7]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[7]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[7] != dest_message[7]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[7]++;
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Delete the queues. */
|
||||
status = tx_queue_delete(&queue_1);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_delete(&queue_0);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
423
test/smp/regression/threadx_queue_basic_four_word_test.c
Normal file
423
test/smp/regression/threadx_queue_basic_four_word_test.c
Normal file
@ -0,0 +1,423 @@
|
||||
/* This test is designed to test immediate response queue services including create
|
||||
and delete. This test is for queue sizes of 4 ULONG. Two queues are used one with
|
||||
a capacity of 1 message and another with a capacity of 3 messages. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
static TX_QUEUE queue_1;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_basic_four_word_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Four Word Test........................................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the queues. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_4_ULONG, pointer, 4*sizeof(ULONG));
|
||||
pointer = pointer + (4*sizeof(ULONG));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Four Word Test........................................ ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_create(&queue_1, "queue 1", TX_4_ULONG, pointer, 4*3*sizeof(ULONG));
|
||||
pointer = pointer + 4*3*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Four Word Test........................................ ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG source_message[4];
|
||||
ULONG dest_message[4];
|
||||
ULONG expected_message[4];
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue Four Word Test........................................ ");
|
||||
|
||||
source_message[0] = 0x01234567;
|
||||
source_message[3] = 0x89ABCDEF;
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Place something on queue 0. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) ||
|
||||
(source_message[3] != dest_message[3]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Make sure we can do the same thing again! */
|
||||
source_message[0]++;
|
||||
source_message[3]++;
|
||||
|
||||
/* Place something on queue 0. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) ||
|
||||
(source_message[3] != dest_message[3]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now we need to do the same thing with the queue with three entries. */
|
||||
|
||||
source_message[0]++;
|
||||
source_message[3]++;
|
||||
expected_message[0] = source_message[0];
|
||||
expected_message[3] = source_message[3];
|
||||
|
||||
/* Place something on queue 1. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[3]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[3]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[3]++;
|
||||
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[3] != dest_message[3]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[3]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[3] != dest_message[3]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[3]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[3] != dest_message[3]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[3]++;
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Make sure we can do the same thing again! */
|
||||
|
||||
/* Place something on queue 1. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[3]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[3]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[3]++;
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[3] != dest_message[3]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[3]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[3] != dest_message[3]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[3]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[3] != dest_message[3]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[3]++;
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Delete the queues. */
|
||||
status = tx_queue_delete(&queue_1);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_delete(&queue_0);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
867
test/smp/regression/threadx_queue_basic_one_word_test.c
Normal file
867
test/smp/regression/threadx_queue_basic_one_word_test.c
Normal file
@ -0,0 +1,867 @@
|
||||
/* This test is designed to test immediate response queue services including create
|
||||
and delete. This test is for queue sizes of 1 ULONG. Two queues are used one with
|
||||
a capacity of 1 message and another with a capacity of 3 messages. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
|
||||
static TX_TIMER timer_0;
|
||||
|
||||
|
||||
static unsigned long error = 0;
|
||||
static unsigned long timer_executed = 0;
|
||||
static unsigned long isr_executed = 0;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
static TX_QUEUE queue_1;
|
||||
static TX_QUEUE queue_2;
|
||||
static TX_QUEUE queue_3;
|
||||
|
||||
|
||||
/* Define the external reference to the status for queue create from initialization. */
|
||||
|
||||
extern UINT test_queue_from_init;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
|
||||
|
||||
UINT _txe_queue_create(TX_QUEUE *queue_ptr, CHAR *name_ptr, UINT message_size,
|
||||
VOID *queue_start, ULONG queue_size, UINT queue_control_block_size);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the timer for this test. */
|
||||
|
||||
static void timer_entry(ULONG i)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
ULONG source = 1234;
|
||||
ULONG destination;
|
||||
|
||||
|
||||
/* Determine if calling queue create from initialization was successful. */
|
||||
if (test_queue_from_init != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to create a queue from a timer. */
|
||||
pointer = (CHAR *) 0x3000;
|
||||
status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, pointer, 3*sizeof(ULONG));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to delete a queue from a timer. */
|
||||
status = tx_queue_delete(&queue_0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to send something with suspension from a timer. */
|
||||
status = tx_queue_front_send(&queue_0, &source, 100);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to send something with suspension from a timer. */
|
||||
status = tx_queue_send(&queue_0, &source, 100);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to receive something with suspension from a timer. */
|
||||
status = tx_queue_receive(&queue_0, &destination, 100);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
|
||||
timer_executed = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
CHAR *pointer;
|
||||
UINT status;
|
||||
ULONG source = 1234;
|
||||
ULONG destination;
|
||||
|
||||
|
||||
/* Attempt to create a queue from an ISR. */
|
||||
pointer = (CHAR *) 0x3000;
|
||||
status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, pointer, 3*sizeof(ULONG));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to delete a queue from an ISR. */
|
||||
status = tx_queue_delete(&queue_0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to send something with suspension from an ISR. */
|
||||
status = tx_queue_front_send(&queue_0, &source, 100);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to send something with suspension from an ISR. */
|
||||
status = tx_queue_send(&queue_0, &source, 100);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to receive something with suspension from an ISR. */
|
||||
status = tx_queue_receive(&queue_0, &destination, 100);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
isr_executed = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_basic_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
18, 18, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue One Word Queue Test................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the queues. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, sizeof(ULONG));
|
||||
pointer = pointer + sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue One Word Queue Test................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_create(&queue_1, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG));
|
||||
pointer = pointer + 3*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue One Word Queue Test................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG source_message = 0x12345678UL;
|
||||
ULONG dest_message;
|
||||
ULONG expected_message;
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
CHAR *pointer;
|
||||
#endif
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue One Word Queue Test................................... ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Attempt to create with NULL queue. */
|
||||
pointer = (CHAR *) 0x3000;
|
||||
status = tx_queue_create(TX_NULL, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create with bad sized queue control block. */
|
||||
status = _txe_queue_create(&queue_3, "queue 3", TX_1_ULONG, pointer, 3*sizeof(ULONG), (sizeof(TX_QUEUE)+1));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create with bad sized message. */
|
||||
status = tx_queue_create(&queue_3, "queue 3", 0, pointer, 3*sizeof(ULONG));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SIZE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a queue that has already been created. */
|
||||
pointer = (CHAR *) 0x3000;
|
||||
status = tx_queue_create(&queue_0, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a queue with an invalid message size. */
|
||||
pointer = (CHAR *) 0x3000;
|
||||
status = tx_queue_create(&queue_2, "queue 2", 47, pointer, 3*sizeof(ULONG));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SIZE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a queue with a NULL queue area. */
|
||||
status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, TX_NULL, 3*sizeof(ULONG));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a queue with a too small queue area. */
|
||||
pointer = (CHAR *) 0x3000;
|
||||
status = tx_queue_create(&queue_2, "queue 2", TX_1_ULONG, pointer, 1);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SIZE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to delete a NULL pointer. */
|
||||
status = tx_queue_delete(TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to delete a non-created queue. */
|
||||
queue_2.tx_queue_id = 0;
|
||||
status = tx_queue_delete(&queue_2);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to flush a NULL pointer. */
|
||||
status = tx_queue_flush(TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to flush a non-created queue. */
|
||||
queue_2.tx_queue_id = 0;
|
||||
status = tx_queue_flush(&queue_2);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to send something to the front of a non-queue. */
|
||||
status = tx_queue_front_send(TX_NULL, &source_message, TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to send something to the front of a non-created queue. */
|
||||
queue_2.tx_queue_id = 0;
|
||||
status = tx_queue_front_send(&queue_2, &source_message, TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to send something with a NULL source pointer. */
|
||||
status = tx_queue_front_send(&queue_0, TX_NULL, TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to send something to a non-queue. */
|
||||
status = tx_queue_send(TX_NULL, &source_message, TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to send something to a non-created queue. */
|
||||
queue_2.tx_queue_id = 0;
|
||||
status = tx_queue_send(&queue_2, &source_message, TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to send something with a NULL source pointer. */
|
||||
status = tx_queue_send(&queue_0, TX_NULL, TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from a non-queue. */
|
||||
status = tx_queue_receive(TX_NULL, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from a non-created queue. */
|
||||
queue_2.tx_queue_id = 0;
|
||||
status = tx_queue_receive(&queue_2, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something to a NULL destination. */
|
||||
status = tx_queue_receive(&queue_0, TX_NULL, TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Place something on queue 0. */
|
||||
status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (source_message != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #26\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #27\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Make sure we can do the same thing again! */
|
||||
source_message++;
|
||||
|
||||
/* Place something on queue 0. */
|
||||
status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #28\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #29\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (source_message != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #30\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #31\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now we need to do the same thing with the queue with three entries. */
|
||||
|
||||
source_message++;
|
||||
expected_message = source_message;
|
||||
|
||||
/* Place something on queue 1. */
|
||||
status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
source_message++;
|
||||
status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
source_message++;
|
||||
status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
source_message++;
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #32\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #33\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message++ != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #34\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message++ != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #35\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message++ != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #36\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #37\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Make sure we can do the same thing again! */
|
||||
|
||||
/* Place something on queue 1. */
|
||||
status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
source_message++;
|
||||
status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
source_message++;
|
||||
status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
source_message++;
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #38\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #39\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message++ != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #40\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message++ != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #41\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message++ != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #42\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #43\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Create a timer for the test. */
|
||||
tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
|
||||
|
||||
/* Setup the ISR. */
|
||||
test_isr_dispatch = test_isr;
|
||||
|
||||
/* Sleep for a bit... */
|
||||
tx_thread_sleep(3);
|
||||
|
||||
/* Resume thread 1 so that we can take an interrupt on top of it. */
|
||||
tx_thread_resume(&thread_1);
|
||||
|
||||
/* Sleep for a bit... */
|
||||
tx_thread_sleep(3);
|
||||
|
||||
/* Clear the ISR. */
|
||||
test_isr_dispatch = TX_NULL;
|
||||
|
||||
/* Test for error. */
|
||||
if ((error) || (timer_executed != 1) || (isr_executed != 1))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #44\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Delete the queues. */
|
||||
status = tx_queue_delete(&queue_1);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #45\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_delete(&queue_0);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #46\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
|
423
test/smp/regression/threadx_queue_basic_sixteen_word_test.c
Normal file
423
test/smp/regression/threadx_queue_basic_sixteen_word_test.c
Normal file
@ -0,0 +1,423 @@
|
||||
/* This test is designed to test immediate response queue services including create
|
||||
and delete. This test is for queue sizes of 16 ULONG. Two queues are used one with
|
||||
a capacity of 1 message and another with a capacity of 3 messages. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
static TX_QUEUE queue_1;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_basic_sixteen_word_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Sixteen Word Test..................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the queues. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_16_ULONG, pointer, 16*sizeof(ULONG));
|
||||
pointer = pointer + (16*sizeof(ULONG));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Sixteen Word Test..................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_create(&queue_1, "queue 1", TX_16_ULONG, pointer, 16*3*sizeof(ULONG));
|
||||
pointer = pointer + 16*3*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Sixteen Word Test..................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG source_message[16];
|
||||
ULONG dest_message[16];
|
||||
ULONG expected_message[16];
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue Sixteen Word Test..................................... ");
|
||||
|
||||
source_message[0] = 0x01234567;
|
||||
source_message[15] = 0x89ABCDEF;
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Place something on queue 0. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) ||
|
||||
(source_message[15] != dest_message[15]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Make sure we can do the same thing again! */
|
||||
source_message[0]++;
|
||||
source_message[15]++;
|
||||
|
||||
/* Place something on queue 0. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) ||
|
||||
(source_message[15] != dest_message[15]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now we need to do the same thing with the queue with three entries. */
|
||||
|
||||
source_message[0]++;
|
||||
source_message[15]++;
|
||||
expected_message[0] = source_message[0];
|
||||
expected_message[15] = source_message[15];
|
||||
|
||||
/* Place something on queue 1. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[15]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[15]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[15]++;
|
||||
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[15] != dest_message[15]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[15]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[15] != dest_message[15]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[15]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[15] != dest_message[15]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[15]++;
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Make sure we can do the same thing again! */
|
||||
|
||||
/* Place something on queue 1. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[15]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[15]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[15]++;
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[15] != dest_message[15]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[15]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[15] != dest_message[15]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[15]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[15] != dest_message[15]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[15]++;
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Delete the queues. */
|
||||
status = tx_queue_delete(&queue_1);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_delete(&queue_0);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
463
test/smp/regression/threadx_queue_basic_two_word_test.c
Normal file
463
test/smp/regression/threadx_queue_basic_two_word_test.c
Normal file
@ -0,0 +1,463 @@
|
||||
/* This test is designed to test immediate response queue services including create
|
||||
and delete. This test is for queue sizes of 2 ULONG. Two queues are used one with
|
||||
a capacity of 1 message and another with a capacity of 3 messages. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
typedef struct QUEUE_MEMORY_TEST_STRUCT
|
||||
{
|
||||
ULONG first;
|
||||
ULONG second;
|
||||
TX_QUEUE queue;
|
||||
ULONG first_middle;
|
||||
ULONG second_middle;
|
||||
ULONG queue_area[2048/sizeof(ULONG)];
|
||||
ULONG next_to_last;
|
||||
ULONG last;
|
||||
|
||||
} QUEUE_MEMORY_TEST;
|
||||
|
||||
static QUEUE_MEMORY_TEST queue_memory;
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
static TX_QUEUE queue_1;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_basic_two_word_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Two Word Test......................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the queues. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 2*sizeof(ULONG));
|
||||
pointer = pointer + (2*sizeof(ULONG));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Two Word Test......................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_create(&queue_1, "queue 1", TX_2_ULONG, pointer, 2*3*sizeof(ULONG));
|
||||
pointer = pointer + 2*3*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Two Word Test......................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG source_message[2];
|
||||
ULONG dest_message[2];
|
||||
ULONG expected_message[2];
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue Two Word Test......................................... ");
|
||||
|
||||
/* Perform queue memory test. */
|
||||
queue_memory.first = 0x11223344;
|
||||
queue_memory.second = 0x55667788;
|
||||
queue_memory.first_middle = 0x21314151;
|
||||
queue_memory.second_middle= 0x61718191;
|
||||
queue_memory.next_to_last = 0x99aabbcc;
|
||||
queue_memory.last = 0xddeeff00;
|
||||
|
||||
/* Create the queue. */
|
||||
status = tx_queue_create(&queue_memory.queue, "queue memory", TX_2_ULONG, &queue_memory.queue_area[0], (2048*sizeof(ULONG))/sizeof(ULONG));
|
||||
tx_queue_delete(&queue_memory.queue);
|
||||
|
||||
/* Check for status. */
|
||||
if ((status != TX_SUCCESS) ||
|
||||
(queue_memory.first != 0x11223344) ||
|
||||
(queue_memory.second != 0x55667788) ||
|
||||
(queue_memory.first_middle != 0x21314151) ||
|
||||
(queue_memory.second_middle != 0x61718191) ||
|
||||
(queue_memory.next_to_last != 0x99aabbcc) ||
|
||||
(queue_memory.last != 0xddeeff00))
|
||||
{
|
||||
/* Queue error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
source_message[0] = 0x01234567;
|
||||
source_message[1] = 0x89ABCDEF;
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Place something on queue 0. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) ||
|
||||
(source_message[1] != dest_message[1]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Make sure we can do the same thing again! */
|
||||
source_message[0]++;
|
||||
source_message[1]++;
|
||||
|
||||
/* Place something on queue 0. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_0, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (source_message[0] != dest_message[0]) ||
|
||||
(source_message[1] != dest_message[1]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_0, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now we need to do the same thing with the queue with three entries. */
|
||||
|
||||
source_message[0]++;
|
||||
source_message[1]++;
|
||||
expected_message[0] = source_message[0];
|
||||
expected_message[1] = source_message[1];
|
||||
|
||||
/* Place something on queue 1. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[1]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[1]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[1]++;
|
||||
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[1] != dest_message[1]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[1]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[1] != dest_message[1]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[1]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[1] != dest_message[1]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[1]++;
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Make sure we can do the same thing again! */
|
||||
|
||||
/* Place something on queue 1. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[1]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[1]++;
|
||||
status += tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
source_message[1]++;
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_1, source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[1] != dest_message[1]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[1]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[1] != dest_message[1]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[1]++;
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message[0] != dest_message[0]) ||
|
||||
(expected_message[1] != dest_message[1]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_message[0]++;
|
||||
expected_message[1]++;
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_1, dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Delete the queues. */
|
||||
status = tx_queue_delete(&queue_1);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_delete(&queue_0);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #26\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
271
test/smp/regression/threadx_queue_empty_suspension_test.c
Normal file
271
test/smp/regression/threadx_queue_empty_suspension_test.c
Normal file
@ -0,0 +1,271 @@
|
||||
/* This test is designed to test empty queue suspension of queue that supports 3 messages
|
||||
that are each 2 ULONG in size. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
static TX_QUEUE queue_1;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void queue_notify(TX_QUEUE *queue_ptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_empty_suspension_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Empty Suspension Test................................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Empty Suspension Test................................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Empty Suspension Test................................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the queue. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
|
||||
pointer = pointer + 3*2*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Empty Suspension Test................................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup queue send notification. */
|
||||
status = tx_queue_send_notify(&queue_0, queue_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Empty Suspension Test................................. ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Queue Empty Suspension Test................................. ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG source_message[2] = {0x12345678, 0};
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue Empty Suspension Test................................. ");
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Attempt to setup notify on a non-queue. */
|
||||
status = tx_queue_send_notify(TX_NULL, queue_notify);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to setup notify on a non-created queue. */
|
||||
queue_1.tx_queue_id = 0;
|
||||
status = tx_queue_send_notify(&queue_1, queue_notify);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Send message that should go directly into the the other thread's
|
||||
destination area! We should also preempt and the queue should
|
||||
be empty by the next time we get around! */
|
||||
status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Check status and run count of other thread - it should have got the
|
||||
message already. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 1))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now resume thread 2 to get another thread suspended on an empty queue. */
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Now send 2 messages to wakeup both threads! */
|
||||
source_message[0]++;
|
||||
status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
|
||||
status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Check status and run count of other thread - it should have got the
|
||||
message already. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 2) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG expected_message[2] = {0x12345678, 0};
|
||||
ULONG dest_message[2];
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Receive message from empty queue with suspension. We should always
|
||||
suspend until thread 0 executes. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG expected_message[2] = {0x12345679, 0};
|
||||
ULONG dest_message[2];
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Receive message from empty queue with suspension. We should always
|
||||
suspend until thread 0 executes. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
}
|
||||
|
216
test/smp/regression/threadx_queue_flush_no_suspension_test.c
Normal file
216
test/smp/regression/threadx_queue_flush_no_suspension_test.c
Normal file
@ -0,0 +1,216 @@
|
||||
/* This test is designed to test the queue flush operation on a queue that has no threads
|
||||
suspended on it. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void queue_notify(TX_QUEUE *queue_ptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_flush_no_suspension_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Flush No Suspension Test.............................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the queue. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
|
||||
pointer = pointer + 3*2*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Flush No Suspension Test.............................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup queue send notification. */
|
||||
status = tx_queue_send_notify(&queue_0, queue_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Flush No Suspension Test.............................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Queue Flush No Suspension Test.............................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG message[2] = {0x12345678, 0};
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue Flush No Suspension Test.............................. ");
|
||||
|
||||
/* Fill up the queue. */
|
||||
status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
|
||||
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Flush queue 0 to make more room. */
|
||||
status = tx_queue_flush(&queue_0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Fill up the queue. */
|
||||
status = tx_queue_send(&queue_0, &message[2], TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_send(&queue_0, &message[2], TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_send(&queue_0, &message[2], TX_NO_WAIT);
|
||||
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Flush queue again to empty and then flush to test on an empty queue. */
|
||||
status = tx_queue_flush(&queue_0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_flush(&queue_0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Success if we get here. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
}
|
||||
|
249
test/smp/regression/threadx_queue_flush_test.c
Normal file
249
test/smp/regression/threadx_queue_flush_test.c
Normal file
@ -0,0 +1,249 @@
|
||||
/* This test is designed to test the queue flush operation on a queue that has two threads
|
||||
suspended on it. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void queue_notify(TX_QUEUE *queue_ptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_flush_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Create the queue. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
|
||||
pointer = pointer + 3*2*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup queue send notification. */
|
||||
status = tx_queue_send_notify(&queue_0, queue_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Queue Flush w/Suspended Threads Test........................ ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG message[2] = {0x12345678, 0};
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue Flush w/Suspended Threads Test........................ ");
|
||||
|
||||
/* Fill up the queue. */
|
||||
status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_send(&queue_0, &message[0], TX_NO_WAIT);
|
||||
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to get other threads suspended on the queue full. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Flush queue 0 which has the threads suspended on it. */
|
||||
status = tx_queue_flush(&queue_0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to let other threads run and finish! */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Determine if the queue flush test was successful. */
|
||||
if ((thread_1_counter == 1) && (thread_2_counter == 1))
|
||||
{
|
||||
|
||||
/* Successful queue flush test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Queue Flush error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
ULONG message[2] = {0x1, 0};
|
||||
|
||||
|
||||
/* Receive message from empty queue. */
|
||||
status = tx_queue_send(&queue_0, &message[0], TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
ULONG message[2] = {0x2, 0};
|
||||
|
||||
|
||||
/* Receive message from empty queue. */
|
||||
status = tx_queue_send(&queue_0, &message[0], TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
|
686
test/smp/regression/threadx_queue_front_send_test.c
Normal file
686
test/smp/regression/threadx_queue_front_send_test.c
Normal file
@ -0,0 +1,686 @@
|
||||
/* This test is designed to test immediate response queue services including queue front send.
|
||||
This test is for queue sizes of 2 ULONG. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
|
||||
|
||||
static unsigned long thread_1a_counter = 0;
|
||||
static TX_THREAD thread_1a;
|
||||
|
||||
static TX_THREAD thread_2a;
|
||||
|
||||
static TX_QUEUE queue_0a;
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_1a_entry(ULONG thread_input);
|
||||
static void thread_2a_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void queue_notify(TX_QUEUE *queue_ptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_front_send_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Front Test............................................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status = tx_thread_create(&thread_1a, "thread 1a", thread_1a_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Front Test............................................ ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status = tx_thread_create(&thread_2a, "thread 2a", thread_2a_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Front Test............................................ ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the queues. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 2*2*sizeof(ULONG));
|
||||
pointer = pointer + 2*2*sizeof(ULONG);
|
||||
status = tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, pointer, 2*1*sizeof(ULONG));
|
||||
pointer = pointer + 2*1*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Front Test............................................ ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup queue send notification. */
|
||||
status = tx_queue_send_notify(&queue_0, queue_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Front Test............................................ ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Queue Front Test............................................ ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG source_message[2] = {0x12345678, 0};
|
||||
ULONG dest_message[2];
|
||||
ULONG temp[2];
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue Front Test............................................ ");
|
||||
|
||||
/* Perform the 1 word queue front send test. */
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Place something on queue 0a. */
|
||||
status = tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #7a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Place a new message on the front of the queue. */
|
||||
temp[0] = 0xF000001;
|
||||
status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #8a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0a. */
|
||||
status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != temp[0]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #9a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0a. */
|
||||
status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != source_message[0]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #10a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive another message from the queue. */
|
||||
status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #11a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point the queue is empty. Resume another thread to
|
||||
suspend on an empty queue. */
|
||||
tx_thread_resume(&thread_1a);
|
||||
|
||||
/* Relinquish to get this thread suspended on the empty queue. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Resume thread 2a to get another thread suspended on the empty queue. */
|
||||
tx_thread_resume(&thread_2a);
|
||||
|
||||
/* Now send something to the front of the queue, which will resume
|
||||
the first waiting thread. */
|
||||
temp[0] = 0xFF00002;
|
||||
status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #12a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now send something to the front of the queue, which will resume
|
||||
the second waiting thread. */
|
||||
temp[0] = 0xFF00002;
|
||||
status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #13a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now relinquish again to let the other thread process the message. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* At this point, the other thread should have placed 2 messages on the queue
|
||||
so we will now send to the front, but without suspension. */
|
||||
temp[0] = 0xFF00003;
|
||||
status = tx_queue_front_send(&queue_0a, &temp[0], TX_NO_WAIT);
|
||||
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #14a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now, we will now send to the front, but with suspension. */
|
||||
temp[0] = 0xFF00003;
|
||||
status = tx_queue_front_send(&queue_0a, &temp[0], TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #15a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now resume thread 2a to get another thread suspended on the queue. */
|
||||
tx_thread_resume(&thread_2a);
|
||||
|
||||
temp[0] = 0xFF00004;
|
||||
status = tx_queue_front_send(&queue_0a, &temp[0], TX_WAIT_FOREVER);
|
||||
|
||||
/* When we get back, the other thread has received all the messages and
|
||||
verified they are in order AND relinquished. */
|
||||
if ((status != TX_SUCCESS) || (thread_1a_counter != 1))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #16a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Perform the multiword queue front send test. */
|
||||
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter = 1;
|
||||
|
||||
/* Reset the source message. */
|
||||
source_message[0] = 0x12345678;
|
||||
source_message[1] = 0;
|
||||
|
||||
/* Place something on queue 0. */
|
||||
status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Place a new message on the front of the queue. */
|
||||
temp[0] = 0xF000001;
|
||||
status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != temp[0]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != source_message[0]))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive another message from the queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point the queue is empty. Resume another thread to
|
||||
suspend on an empty queue. */
|
||||
tx_thread_resume(&thread_1);
|
||||
|
||||
/* Relinquish to get this thread suspended on the empty queue. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Resume thread 2 to get another thread suspended on the empty queue. */
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Now send something to the front of the queue, which will resume
|
||||
the first waiting thread. */
|
||||
temp[0] = 0xFF00002;
|
||||
status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now send something to the front of the queue, which will resume
|
||||
the second waiting thread. */
|
||||
temp[0] = 0xFF00002;
|
||||
status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now relinquish again to let the other thread process the message. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* At this point, the other thread should have placed 2 messages on the queue
|
||||
so we will now send to the front, but without suspension. */
|
||||
temp[0] = 0xFF00003;
|
||||
status = tx_queue_front_send(&queue_0, &temp[0], TX_NO_WAIT);
|
||||
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now, we will now send to the front, but with suspension. */
|
||||
temp[0] = 0xFF00003;
|
||||
status = tx_queue_front_send(&queue_0, &temp[0], TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now resume thread 2 to get another thread suspended on the queue. */
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
temp[0] = 0xFF00004;
|
||||
status = tx_queue_front_send(&queue_0, &temp[0], TX_WAIT_FOREVER);
|
||||
|
||||
/* When we get back, the other thread has received all the messages and
|
||||
verified they are in order AND relinquished. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 1))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG source_message[2] = {0xEE000001, 0};
|
||||
ULONG dest_message[2];
|
||||
|
||||
|
||||
/* First, suspend on an empty queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
/* Determine if the message is good. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00002))
|
||||
return;
|
||||
|
||||
/* Now fill the queue with two messages. */
|
||||
status = tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
|
||||
source_message[0]++;
|
||||
status += tx_queue_front_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Now let thread 0 send to the front of the queue with suspension. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Attempt to receive three messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00003))
|
||||
return;
|
||||
|
||||
/* Attempt to receive three messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000002))
|
||||
return;
|
||||
|
||||
/* Attempt to receive three messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000001))
|
||||
return;
|
||||
|
||||
/* At this point, we are going to fill up the queue again. */
|
||||
source_message[0]++;
|
||||
status = tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
|
||||
source_message[0]++;
|
||||
status += tx_queue_front_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Now let thread 0 send to the front of the queue with suspension. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Attempt to receive four messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00004))
|
||||
return;
|
||||
|
||||
/* Attempt to receive four messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xDD000001))
|
||||
return;
|
||||
|
||||
/* Attempt to receive four messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000004))
|
||||
return;
|
||||
|
||||
/* Attempt to receive three messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000003))
|
||||
return;
|
||||
|
||||
/* Increment this threads counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG source_message[2] = {0xDD000001, 0};
|
||||
ULONG destination_message[2];
|
||||
|
||||
|
||||
/* Receive message. */
|
||||
tx_queue_receive(&queue_0, &destination_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
/* Self suspend. */
|
||||
tx_thread_suspend(&thread_2);
|
||||
|
||||
/* Send another message to the front of the queue. */
|
||||
tx_queue_front_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
|
||||
}
|
||||
|
||||
|
||||
static void thread_1a_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG source_message[2] = {0xEE000001, 0};
|
||||
ULONG dest_message[2];
|
||||
|
||||
|
||||
/* First, suspend on an empty queue. */
|
||||
status = tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
/* Determine if the message is good. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00002))
|
||||
return;
|
||||
|
||||
/* Now fill the queue with two messages. */
|
||||
status = tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
|
||||
source_message[0]++;
|
||||
status += tx_queue_front_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Now let thread 0 send to the front of the queue with suspension. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Attempt to receive three messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00003))
|
||||
return;
|
||||
|
||||
/* Attempt to receive three messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000002))
|
||||
return;
|
||||
|
||||
/* Attempt to receive three messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000001))
|
||||
return;
|
||||
|
||||
/* At this point, we are going to fill up the queue again. */
|
||||
source_message[0]++;
|
||||
status = tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
|
||||
source_message[0]++;
|
||||
status += tx_queue_front_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Now let thread 0 send to the front of the queue with suspension. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Attempt to receive four messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xFF00004))
|
||||
return;
|
||||
|
||||
/* Attempt to receive four messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xDD000001))
|
||||
return;
|
||||
|
||||
/* Attempt to receive four messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000004))
|
||||
return;
|
||||
|
||||
/* Attempt to receive three messages from the queue. */
|
||||
status = tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != 0xEE000003))
|
||||
return;
|
||||
|
||||
/* Increment this threads counter. */
|
||||
thread_1a_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_2a_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG source_message[2] = {0xDD000001, 0};
|
||||
ULONG destination_message[2];
|
||||
|
||||
|
||||
/* Receive message. */
|
||||
tx_queue_receive(&queue_0a, &destination_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
/* Self suspend. */
|
||||
tx_thread_suspend(&thread_2a);
|
||||
|
||||
/* Send another message to the front of the queue. */
|
||||
tx_queue_front_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
|
||||
}
|
368
test/smp/regression/threadx_queue_full_suspension_test.c
Normal file
368
test/smp/regression/threadx_queue_full_suspension_test.c
Normal file
@ -0,0 +1,368 @@
|
||||
/* This test is designed to test queue full suspension of queue that supports 3 messages
|
||||
that are each 2 ULONG in size. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
|
||||
|
||||
static unsigned long thread_1a_counter = 0;
|
||||
static TX_THREAD thread_1a;
|
||||
|
||||
static unsigned long thread_2a_counter = 0;
|
||||
static TX_THREAD thread_2a;
|
||||
|
||||
static TX_QUEUE queue_0a;
|
||||
|
||||
|
||||
static ULONG queue_area[3];
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_1a_entry(ULONG thread_input);
|
||||
static void thread_2a_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void queue_notify(TX_QUEUE *queue_ptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_full_suspension_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Full Suspension Test.................................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_create(&thread_1a, "thread 1a", thread_1a_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Full Suspension Test.................................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_create(&thread_2a, "thread 2a", thread_2a_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Full Suspension Test.................................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the queue. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
|
||||
pointer = pointer + 3*2*sizeof(ULONG);
|
||||
status += tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, pointer, 3*1*sizeof(ULONG));
|
||||
pointer = pointer + 3*1*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Full Suspension Test.................................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup queue send notification. */
|
||||
status = tx_queue_send_notify(&queue_0, queue_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Full Suspension Test.................................. ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Queue Full Suspension Test.................................. ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG source_message[2] = {0x12345678, 0};
|
||||
ULONG dest_message[2];
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue Full Suspension Test.................................. ");
|
||||
|
||||
/* Perform the one word queue version. */
|
||||
|
||||
/* Suspend to get thread 1a to pend on the queue. */
|
||||
tx_thread_suspend(&thread_0);
|
||||
status = tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
|
||||
tx_thread_suspend(&thread_0);
|
||||
tx_thread_resume(&thread_1a);
|
||||
tx_thread_resume(&thread_2a);
|
||||
tx_queue_delete(&queue_0a);
|
||||
status += tx_queue_create(&queue_0a, "queue 0a", TX_1_ULONG, queue_area, sizeof(queue_area));
|
||||
|
||||
|
||||
/* Fill the queue with an initial 3 messages! */
|
||||
status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
|
||||
status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
|
||||
status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
|
||||
/* Receive two of the messages back to put the first received message at the end
|
||||
of the queue. */
|
||||
status += tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
|
||||
status += tx_queue_receive(&queue_0a, &dest_message[0], TX_NO_WAIT);
|
||||
status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
status += tx_queue_send(&queue_0a, &source_message[0], TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
|
||||
/* Check status and run count of other thread. */
|
||||
if ((status != TX_SUCCESS) || (thread_1a_counter != 0))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #6a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Send message that should cause this thread to suspend, until the
|
||||
lower priority thread receives a message. */
|
||||
status = tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status and run count of other thread - it should have got the
|
||||
message already even though its counter is still 0 (it was preempted
|
||||
in the queue receive call. */
|
||||
if ((status != TX_SUCCESS) || (thread_1a_counter != 5) || (thread_2a_counter != 1))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #7a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Perform the two word queue version. */
|
||||
|
||||
/* Reset the source message. */
|
||||
source_message[0] = 0x12345678;
|
||||
source_message[1] = 0;
|
||||
|
||||
/* Resume threads 1 and 2. */
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Fill the queue with an initial 3 messages! */
|
||||
status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
|
||||
status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
|
||||
status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
|
||||
/* Receive two of the messages back to put the first received message at the end
|
||||
of the queue. */
|
||||
status += tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
|
||||
status += tx_queue_receive(&queue_0, &dest_message[0], TX_NO_WAIT);
|
||||
status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
|
||||
/* Check status and run count of other thread. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 0))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Send message that should cause this thread to suspend, until the
|
||||
lower priority thread receives a message. */
|
||||
status = tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status and run count of other thread - it should have got the
|
||||
message already even though its counter is still 0 (it was preempted
|
||||
in the queue receive call. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
ULONG expected_message[2] = {0x12345678, 0};
|
||||
ULONG dest_message[2];
|
||||
UINT old_priority;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Receive messages and suspend. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
|
||||
break;
|
||||
|
||||
/* Change thread 2 priority. */
|
||||
tx_thread_priority_change(&thread_2, 15, &old_priority);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG source_message[2] = {0x1234567C, 0};
|
||||
|
||||
|
||||
/* Send one message to the queue. */
|
||||
tx_queue_send(&queue_0, &source_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_1a_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
ULONG expected_message[2] = {0x12345678, 0};
|
||||
ULONG dest_message[2];
|
||||
UINT old_priority;
|
||||
|
||||
|
||||
/* Receive message and suspend. */
|
||||
status = tx_thread_resume(&thread_0);
|
||||
status += tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER);
|
||||
status += tx_thread_resume(&thread_0);
|
||||
status += tx_thread_suspend(&thread_1a);
|
||||
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]))
|
||||
return;
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Receive messages and suspend. */
|
||||
status = tx_queue_receive(&queue_0a, &dest_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
if ((status != TX_SUCCESS) || (dest_message[0] != expected_message[0]++))
|
||||
break;
|
||||
|
||||
/* Change thread 2a priority. */
|
||||
tx_thread_priority_change(&thread_2a, 15, &old_priority);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1a_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2a_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG source_message[2] = {0x1234567C, 0};
|
||||
|
||||
|
||||
/* Send one message to the queue. */
|
||||
tx_queue_send(&queue_0a, &source_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2a_counter++;
|
||||
}
|
664
test/smp/regression/threadx_queue_information_test.c
Normal file
664
test/smp/regression/threadx_queue_information_test.c
Normal file
@ -0,0 +1,664 @@
|
||||
/* This test is designed to test the queue information services. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_queue.h"
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
static TX_QUEUE queue_1;
|
||||
static TX_QUEUE queue_2;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
|
||||
UINT _tx_queue_performance_info_get(TX_QUEUE *queue_ptr, ULONG *messages_sent, ULONG *messages_received,
|
||||
ULONG *empty_suspensions, ULONG *full_suspensions, ULONG *full_errors, ULONG *timeouts);
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_information_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Information Test...................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the queues. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, sizeof(ULONG));
|
||||
pointer = pointer + sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Information Test...................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_create(&queue_1, "queue 1", TX_1_ULONG, pointer, 3*sizeof(ULONG));
|
||||
pointer = pointer + 3*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Information Test...................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG source_message = 0x12345678UL;
|
||||
ULONG dest_message;
|
||||
ULONG expected_message;
|
||||
CHAR *name;
|
||||
ULONG enqueued;
|
||||
ULONG available_storage;
|
||||
TX_THREAD *first_suspended;
|
||||
ULONG suspended_count;
|
||||
TX_QUEUE *next_queue;
|
||||
ULONG messages_sent;
|
||||
ULONG messages_received;
|
||||
ULONG empty_suspensions;
|
||||
ULONG full_suspensions;
|
||||
ULONG full_errors;
|
||||
ULONG timeouts;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue Information Test...................................... ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Attempt to get info from a non-queue. */
|
||||
status = tx_queue_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get info from a non-created queue. */
|
||||
queue_2.tx_queue_id = 0;
|
||||
status = tx_queue_info_get(&queue_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Place something on queue 0. */
|
||||
status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (source_message != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Make sure we can do the same thing again! */
|
||||
source_message++;
|
||||
|
||||
/* Place something on queue 0. */
|
||||
status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_0, &source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 0. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (source_message != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now we need to do the same thing with the queue with three entries. */
|
||||
|
||||
source_message++;
|
||||
expected_message = source_message;
|
||||
|
||||
/* Place something on queue 1. */
|
||||
status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
source_message++;
|
||||
status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
source_message++;
|
||||
status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
source_message++;
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message++ != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message++ != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message++ != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Make sure we can do the same thing again! */
|
||||
|
||||
/* Place something on queue 1. */
|
||||
status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
source_message++;
|
||||
status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
source_message++;
|
||||
status += tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
source_message++;
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to place something on a full queue. */
|
||||
status = tx_queue_send(&queue_1, &source_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_FULL)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message++ != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message++ != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from queue 1. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be successful and dest_message should equal source. */
|
||||
if ((status != TX_SUCCESS) || (expected_message++ != dest_message))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to receive something from an empty queue. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message, TX_NO_WAIT);
|
||||
|
||||
/* Should be an error. */
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get queue information. */
|
||||
status = tx_queue_info_get(&queue_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
status += tx_queue_info_get(&queue_0, &name, &enqueued, &available_storage, &first_suspended, &suspended_count, &next_queue);
|
||||
|
||||
/* Check for errors. */
|
||||
if ((status != TX_SUCCESS) || (enqueued != queue_0.tx_queue_enqueued) || (available_storage != queue_0.tx_queue_available_storage) ||
|
||||
(first_suspended != queue_0.tx_queue_suspension_list) || (suspended_count != queue_0.tx_queue_suspended_count) ||
|
||||
(next_queue != queue_0.tx_queue_created_next))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifdef TX_QUEUE_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Test null pointer for queue performance info get. */
|
||||
status = _tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #26\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get performance information. */
|
||||
status = tx_queue_performance_info_get(&queue_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
status += tx_queue_performance_info_get(&queue_0, &messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
|
||||
|
||||
/* Check for errors. */
|
||||
if ((status != TX_SUCCESS) || (messages_sent != queue_0.tx_queue_performance_messages_sent_count) || (messages_received != queue_0.tx_queue_performance_messages_received_count) ||
|
||||
(empty_suspensions != queue_0.tx_queue_performance_empty_suspension_count) || (full_suspensions != queue_0.tx_queue_performance_full_suspension_count) ||
|
||||
(full_errors != queue_0.tx_queue_performance_full_error_count) || (timeouts != queue_0.tx_queue_performance_timeout_count))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #27\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get system performance information. */
|
||||
status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
status += tx_queue_performance_system_info_get(&messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
|
||||
|
||||
/* Check for errors. */
|
||||
if ((status != TX_SUCCESS) || (messages_sent != _tx_queue_performance_messages_sent_count) || (messages_received != _tx_queue_performance__messages_received_count) ||
|
||||
(empty_suspensions != _tx_queue_performance_empty_suspension_count) || (full_suspensions != _tx_queue_performance_full_suspension_count) ||
|
||||
(full_errors != _tx_queue_performance_full_error_count) || (timeouts != _tx_queue_performance_timeout_count))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #28\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Get performance information. */
|
||||
status = tx_queue_performance_info_get(&queue_0, &messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #29\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get performance information. */
|
||||
status = tx_queue_performance_info_get(TX_NULL, &messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #30\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get performance information. */
|
||||
status = tx_queue_performance_info_get(TX_NULL, TX_NULL, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #31\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get performance information. */
|
||||
status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #32\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get performance information. */
|
||||
status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &full_suspensions, &full_errors, &timeouts);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #33\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get performance information. */
|
||||
status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &full_errors, &timeouts);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #34\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get performance information. */
|
||||
status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #35\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get performance information. */
|
||||
status = tx_queue_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #36\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get system performance information. */
|
||||
status = tx_queue_performance_system_info_get(&messages_sent, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #37\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get system performance information. */
|
||||
status = tx_queue_performance_system_info_get(TX_NULL, &messages_received, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #38\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get system performance information. */
|
||||
status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, &empty_suspensions, &full_suspensions, &full_errors, &timeouts);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #39\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get system performance information. */
|
||||
status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &full_suspensions, &full_errors, &timeouts);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #40\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get system performance information. */
|
||||
status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &full_errors, &timeouts);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #41\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get system performance information. */
|
||||
status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &timeouts);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #42\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get system performance information. */
|
||||
status = tx_queue_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Should be an error! */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #43\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Delete the queues. */
|
||||
status = tx_queue_delete(&queue_1);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #44\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_delete(&queue_0);
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #45\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
534
test/smp/regression/threadx_queue_prioritize.c
Normal file
534
test/smp/regression/threadx_queue_prioritize.c
Normal file
@ -0,0 +1,534 @@
|
||||
/* This test is designed to test queue prioritize. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Define the external reference for the preempt disable flag. */
|
||||
|
||||
extern volatile UINT _tx_thread_preempt_disable;
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
static unsigned long thread_4_counter = 0;
|
||||
static TX_THREAD thread_4;
|
||||
|
||||
static unsigned long thread_5_counter = 0;
|
||||
static TX_THREAD thread_5;
|
||||
|
||||
static unsigned long thread_6_counter = 0;
|
||||
static TX_THREAD thread_6;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
static TX_QUEUE queue_1;
|
||||
|
||||
|
||||
static int test_status;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
static void thread_5_entry(ULONG thread_input);
|
||||
static void thread_6_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void queue_notify(TX_QUEUE *queue_ptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* Determine if the test case we are looking for is present. */
|
||||
if ((_tx_thread_preempt_disable) && (test_status == 1))
|
||||
{
|
||||
|
||||
/* Determine if thread 3 is at the front of the suspension list. */
|
||||
if (queue_0.tx_queue_suspension_list == &thread_3)
|
||||
{
|
||||
|
||||
/* Abort the wait of thread 3. */
|
||||
tx_thread_wait_abort(&thread_3);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Abort the wait of thread 5. */
|
||||
tx_thread_wait_abort(&thread_5);
|
||||
|
||||
/* End the ISR processing. */
|
||||
test_status = 2;
|
||||
test_isr_dispatch = TX_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_prioritize_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Prioritize Test....................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Prioritize Test....................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Prioritize Test....................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
3, 3, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Prioritize Test....................................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
4, 4, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Prioritize Test....................................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
5, 5, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Prioritize Test....................................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
6, 6, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Prioritize Test....................................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the queue. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, 3*2*sizeof(ULONG));
|
||||
pointer = pointer + 3*2*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Prioritize Test....................................... ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup queue send notification. */
|
||||
status = tx_queue_send_notify(&queue_0, queue_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Prioritize Test....................................... ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Queue Prioritize Test....................................... ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue Prioritize Test....................................... ");
|
||||
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Attempt to prioritize a non-queue. */
|
||||
status = tx_queue_prioritize(TX_NULL);
|
||||
|
||||
/* Check for an error condition. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to prioritize a non-created queue. */
|
||||
queue_1.tx_queue_id = 0;
|
||||
status = tx_queue_prioritize(&queue_1);
|
||||
|
||||
/* Check for an error condition. */
|
||||
if (status != TX_QUEUE_ERROR)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Nothing to do here, but check prioritization with no suspended threads. */
|
||||
status = tx_queue_prioritize(&queue_0);
|
||||
|
||||
/* Check for an error condition. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Make sure thread 1 and 2 are suspended on the queue. */
|
||||
if ((thread_1.tx_thread_state != TX_QUEUE_SUSP) || (thread_2.tx_thread_state != TX_QUEUE_SUSP) ||
|
||||
(queue_0.tx_queue_suspension_list != &thread_1))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Prioritize the queue suspension list. */
|
||||
status = tx_queue_prioritize(&queue_0);
|
||||
|
||||
/* Check status and make sure thread 2 is not at the head of the list. */
|
||||
if ((status != TX_SUCCESS) || (queue_0.tx_queue_suspension_list != &thread_2))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Prioritize the queue suspension list again, but slightly different path because it was previously prioritized. */
|
||||
status = tx_queue_prioritize(&queue_0);
|
||||
|
||||
/* Check status and make sure thread 2 not at the head of the list. */
|
||||
if ((status != TX_SUCCESS) || (queue_0.tx_queue_suspension_list != &thread_2))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point we are going to get more than 2 threads suspended. */
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
tx_thread_resume(&thread_3);
|
||||
tx_thread_resume(&thread_4);
|
||||
tx_thread_resume(&thread_5);
|
||||
tx_thread_resume(&thread_6);
|
||||
|
||||
/* Prioritize the queue suspension list. */
|
||||
status = tx_queue_prioritize(&queue_0);
|
||||
|
||||
/* Check status and make sure thread 3 is at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (queue_0.tx_queue_suspension_list != &thread_3))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now loop to test the interrupt of the prioritize loop logic. */
|
||||
test_status = 1;
|
||||
test_isr_dispatch = test_isr;
|
||||
do
|
||||
{
|
||||
|
||||
/* Prioritize the queue suspension list. */
|
||||
status = tx_queue_prioritize(&queue_0);
|
||||
|
||||
/* Check status and make sure thread 1 is terminated. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Block Pool error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
} while (test_status == 1);
|
||||
|
||||
/* Now determine if thread 4 is at the front of the list... It should be! */
|
||||
if (queue_0.tx_queue_suspension_list != &thread_4)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
ULONG dest_message;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Receive message from empty queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
ULONG dest_message;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Receive message from empty queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
ULONG dest_message;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Receive message from empty queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_3_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
ULONG dest_message;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Receive message from empty queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_4_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
ULONG dest_message;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Receive message from empty queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_6_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
ULONG dest_message;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Receive message from empty queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_6_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
254
test/smp/regression/threadx_queue_suspension_timeout_test.c
Normal file
254
test/smp/regression/threadx_queue_suspension_timeout_test.c
Normal file
@ -0,0 +1,254 @@
|
||||
/* This test is designed to test queue full and empty suspension with timeouts on queues
|
||||
that supports 3 messages that are each 2 ULONG in size. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
//static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static TX_THREAD thread_2;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
static TX_QUEUE queue_1;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void queue_notify(TX_QUEUE *queue_ptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_suspension_timeout_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Suspension Timeout Test............................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Suspension Timeout Test............................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Suspension Timeout Test............................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the queues. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
|
||||
pointer = pointer + 3*2*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Suspension Timeout Test............................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_queue_create(&queue_1, "queue 1", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
|
||||
pointer = pointer + 3*2*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Suspension Timeout Test............................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup queue send notification. */
|
||||
status = tx_queue_send_notify(&queue_0, queue_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Suspension Timeout Test............................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Queue Suspension Timeout Test............................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG source_message[2] = {0x12345678, 0};
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue Suspension Timeout Test............................... ");
|
||||
|
||||
/* Fill the queue with an initial 3 messages! */
|
||||
status = tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
status += tx_queue_send(&queue_0, &source_message[0], TX_NO_WAIT);
|
||||
source_message[0]++;
|
||||
|
||||
/* Check status and run count of other thread. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 0))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Send message to the front of the queue that should cause this thread to suspend. The timeout
|
||||
should cause it to resume with a TX_QUEUE_FULL error code. */
|
||||
status = tx_queue_front_send(&queue_0, &source_message[0], 3);
|
||||
|
||||
if ((status != TX_QUEUE_FULL) || (thread_1_counter != 0) || (thread_2_counter != 0))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #9a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Send message that should cause this thread to suspend. The timeout
|
||||
should cause it to resume with a TX_QUEUE_FULL error code. */
|
||||
status = tx_queue_send(&queue_0, &source_message[0], 32);
|
||||
|
||||
if ((status != TX_QUEUE_FULL) || (thread_1_counter != 1) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
ULONG dest_message[2];
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Receive message from empty queue with suspension and timeout.
|
||||
We should wakeup after the timeout expires with an empty status. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message[0], 20);
|
||||
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
ULONG dest_message[2];
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Receive message from empty queue with suspension and timeout.
|
||||
We should wakeup after the timeout expires with an empty status. */
|
||||
status = tx_queue_receive(&queue_1, &dest_message[0], 20);
|
||||
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
}
|
183
test/smp/regression/threadx_queue_thread_terminate_test.c
Normal file
183
test/smp/regression/threadx_queue_thread_terminate_test.c
Normal file
@ -0,0 +1,183 @@
|
||||
/* This test is designed to test thread terminate when the terminated thread is suspeded
|
||||
on a queue. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static TX_QUEUE queue_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void queue_notify(TX_QUEUE *queue_ptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_queue_thread_terminate_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Thread Terminate Test................................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Thread Terminate Test................................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the queue. */
|
||||
status = tx_queue_create(&queue_0, "queue 0", TX_2_ULONG, pointer, 3*2*sizeof(ULONG));
|
||||
pointer = pointer + 3*2*sizeof(ULONG);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Thread Terminate Test................................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup queue send notification. */
|
||||
status = tx_queue_send_notify(&queue_0, queue_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Queue Thread Terminate Test................................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Queue Thread Terminate Test................................. ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Queue Thread Terminate Test................................. ");
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Make sure thread 1 is suspended on the queue. */
|
||||
if (thread_1.tx_thread_state != TX_QUEUE_SUSP)
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Terminate thread 1 which is suspended on queue 0. */
|
||||
status = tx_thread_terminate(&thread_1);
|
||||
|
||||
/* Check status and make sure thread 1 is terminated. */
|
||||
if ((status != TX_SUCCESS) || (thread_1.tx_thread_state != TX_TERMINATED) ||
|
||||
(thread_1_counter != 0) || (queue_0.tx_queue_suspended_count))
|
||||
{
|
||||
|
||||
/* Queue error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
ULONG dest_message[2];
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Receive message from empty queue. */
|
||||
status = tx_queue_receive(&queue_0, &dest_message[0], TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_QUEUE_EMPTY)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
545
test/smp/regression/threadx_semaphore_basic_test.c
Normal file
545
test/smp/regression/threadx_semaphore_basic_test.c
Normal file
@ -0,0 +1,545 @@
|
||||
/* This test is designed to test the semaphore create/delete and immediate return gets and puts. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
typedef struct SEMAPHORE_MEMORY_TEST_STRUCT
|
||||
{
|
||||
ULONG first;
|
||||
ULONG second;
|
||||
TX_SEMAPHORE semaphore;
|
||||
ULONG next_to_last;
|
||||
ULONG last;
|
||||
|
||||
} SEMAPHORE_MEMORY_TEST;
|
||||
|
||||
static SEMAPHORE_MEMORY_TEST semaphore_memory;
|
||||
|
||||
|
||||
/* Define the external symbol to obtain the status from a create call in initialization. */
|
||||
|
||||
extern UINT test_semaphore_from_init;
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
|
||||
static TX_TIMER timer_0;
|
||||
|
||||
|
||||
static unsigned long error = 0;
|
||||
static unsigned long timer_executed = 0;
|
||||
static unsigned long isr_executed = 0;
|
||||
|
||||
|
||||
static TX_SEMAPHORE semaphore_0;
|
||||
static TX_SEMAPHORE semaphore_1;
|
||||
static TX_SEMAPHORE semaphore_2;
|
||||
static TX_SEMAPHORE semaphore_3;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
|
||||
UINT _txe_semaphore_create(TX_SEMAPHORE *semaphore_ptr, CHAR *name_ptr, ULONG initial_count, UINT semaphore_control_block_size);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the timer for this test. */
|
||||
|
||||
static void timer_entry(ULONG i)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Determine if calling semaphore create from initialization was successful. */
|
||||
if (test_semaphore_from_init != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to create a semaphore from a timer. */
|
||||
status = tx_semaphore_create(&semaphore_2, "semaphore 2", 1);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to delete a semaphore from a timer. */
|
||||
status = tx_semaphore_delete(&semaphore_0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to get a semaphore with suspension from a timer. */
|
||||
status = tx_semaphore_get(&semaphore_0, 100);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
|
||||
timer_executed = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Attempt to create a semaphore from an ISR. */
|
||||
status = tx_semaphore_create(&semaphore_2, "semaphore 2", 1);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to delete a semaphore from an ISR. */
|
||||
status = tx_semaphore_delete(&semaphore_0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to get a semaphore with suspension from an ISR. */
|
||||
status = tx_semaphore_get(&semaphore_0, 100);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_WAIT_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
isr_executed = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_semaphore_basic_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
18, 18, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Basic Test........................................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a semaphore with an initial count of 1. */
|
||||
status = tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Basic Test........................................ ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a semaphore with an initial count of 0. */
|
||||
status = tx_semaphore_create(&semaphore_1, "semaphore 1", 1);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Basic Test........................................ ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Semaphore Basic Test........................................ ");
|
||||
|
||||
/* Perform semaphore memory test. */
|
||||
semaphore_memory.first = 0x11223344;
|
||||
semaphore_memory.second = 0x55667788;
|
||||
semaphore_memory.next_to_last = 0x99aabbcc;
|
||||
semaphore_memory.last = 0xddeeff00;
|
||||
|
||||
/* Create the semaphore. */
|
||||
status = tx_semaphore_create(&semaphore_memory.semaphore, "semaphore memory", 0);
|
||||
tx_semaphore_delete(&semaphore_memory.semaphore);
|
||||
|
||||
/* Check for status. */
|
||||
if ((status != TX_SUCCESS) ||
|
||||
(semaphore_memory.first != 0x11223344) ||
|
||||
(semaphore_memory.second != 0x55667788) ||
|
||||
(semaphore_memory.next_to_last != 0x99aabbcc) ||
|
||||
(semaphore_memory.last != 0xddeeff00))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Attempt to create a non-semaphore. */
|
||||
status = tx_semaphore_create(TX_NULL, "semaphore 0", 1);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a semaphore with a bad sized block. */
|
||||
status = _txe_semaphore_create(&semaphore_3, "semaphore 3", 1, (sizeof(TX_SEMAPHORE)+1));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create an already created semaphore. */
|
||||
status = tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to delete a non-semaphore. */
|
||||
status = tx_semaphore_delete(TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to delete a non-created semaphore. */
|
||||
semaphore_2.tx_semaphore_id = 0;
|
||||
status = tx_semaphore_delete(&semaphore_2);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get a non-semaphore. */
|
||||
status = tx_semaphore_get(TX_NULL, TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get a non-created semaphore. */
|
||||
semaphore_2.tx_semaphore_id = 0;
|
||||
status = tx_semaphore_get(&semaphore_2, TX_NO_WAIT);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to put a non-semaphore. */
|
||||
status = tx_semaphore_put(TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to put a non-created semaphore. */
|
||||
semaphore_2.tx_semaphore_id = 0;
|
||||
status = tx_semaphore_put(&semaphore_2);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to ceiling put a non-semaphore. */
|
||||
status = tx_semaphore_ceiling_put(TX_NULL, 0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to ceiling put a non-created semaphore. */
|
||||
semaphore_2.tx_semaphore_id = 0;
|
||||
status = tx_semaphore_ceiling_put(&semaphore_2, 0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to ceiling put with an invalid ceiling of 0. */
|
||||
status = tx_semaphore_ceiling_put(&semaphore_0, 0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_INVALID_CEILING)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Attempt to get from semaphore with an instance. Should be successful! */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get from semaphore without an instance. Should be unsuccessful. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_INSTANCE)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Put to semaphore that has an instance already. Should now be 2! */
|
||||
status = tx_semaphore_put(&semaphore_1);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (semaphore_1.tx_semaphore_count != 2))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Attempt to get from semaphore with an instance. Should be successful! */
|
||||
status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get from semaphore with an instance. Should be successful. */
|
||||
status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Create a timer for the test. */
|
||||
tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
|
||||
|
||||
/* Setup the ISR. */
|
||||
test_isr_dispatch = test_isr;
|
||||
|
||||
/* Sleep for a bit... */
|
||||
tx_thread_sleep(3);
|
||||
|
||||
/* Resume the thread 1 so we can take an interrupt on top of it. */
|
||||
tx_thread_resume(&thread_1);
|
||||
|
||||
/* Sleep for a bit... */
|
||||
tx_thread_sleep(3);
|
||||
|
||||
/* Clear the ISR. */
|
||||
test_isr_dispatch = TX_NULL;
|
||||
|
||||
/* Test for error. */
|
||||
if ((error) || (timer_executed != 1) || (isr_executed != 1))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Delete semaphores. */
|
||||
status = tx_semaphore_delete(&semaphore_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_semaphore_delete(&semaphore_1);
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
334
test/smp/regression/threadx_semaphore_ceiling_put_test.c
Normal file
334
test/smp/regression/threadx_semaphore_ceiling_put_test.c
Normal file
@ -0,0 +1,334 @@
|
||||
/* This test is designed to test the semaphore ceiling put. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
|
||||
static TX_SEMAPHORE semaphore_0;
|
||||
static TX_SEMAPHORE semaphore_1;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void put_notify(TX_SEMAPHORE *semaphore_ptr)
|
||||
{
|
||||
|
||||
/* Don't need to do anything in here... */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_semaphore_ceiling_put_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Ceiling Put Test.................................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Ceiling Put Test.................................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Ceiling Put Test.................................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a semaphore with an initial count of 0. */
|
||||
status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
|
||||
status += tx_semaphore_create(&semaphore_1, "semaphore 1", 0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Ceiling Put Test.................................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup the semaphore notify callback. */
|
||||
status = tx_semaphore_put_notify(&semaphore_0, put_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Ceiling Put Test.................................. ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Ceiling Put Test.................................. ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Semaphore Ceiling Put Test.................................. ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Perform semaphore puts in order to exercise the ceiling put logic. */
|
||||
status = tx_semaphore_ceiling_put(&semaphore_0, 2);
|
||||
status += tx_semaphore_ceiling_put(&semaphore_0, 2);
|
||||
status += tx_semaphore_ceiling_put(&semaphore_0, 2);
|
||||
status += tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
|
||||
status += tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_CEILING_EXCEEDED)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to make the other thread suspend on the semaphore. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Make sure the other thread has run. */
|
||||
if (thread_1_counter != 1)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Place an instance on the semaphore, this should resume the other thread
|
||||
but not preempt this thread. */
|
||||
status = tx_semaphore_ceiling_put(&semaphore_0, 2);
|
||||
|
||||
/* Check the status and the run counter of the other thread. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 1))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to allow the other thread to run. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Make sure the other thread has run. */
|
||||
if (thread_1_counter != 3)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point, we need to resume thread 2 and relinquish in order to get that thread suspended on the
|
||||
semaphore as well. */
|
||||
tx_thread_resume(&thread_2);
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Perform 2 semaphore put operations to resume both threads. */
|
||||
status = tx_semaphore_ceiling_put(&semaphore_0, 2);
|
||||
status += tx_semaphore_ceiling_put(&semaphore_0, 2);
|
||||
|
||||
/* Let both threads run again. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Check the status and the run counter of the other thread. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 3))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now turn off the semaphore notification. */
|
||||
status = tx_semaphore_put_notify(&semaphore_0, TX_NULL);
|
||||
|
||||
#ifdef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Clear the status since we know this feature is disabled and will return an error. */
|
||||
status = TX_SUCCESS;
|
||||
#endif
|
||||
|
||||
/* Put a semaphore on a semaphore that does not have suspension. */
|
||||
status += tx_semaphore_ceiling_put(&semaphore_1, 2);
|
||||
|
||||
/* Repeat the semaphore ceiling put without notification process! */
|
||||
|
||||
/* Place an instance on the semaphore, this should resume the other thread
|
||||
but not preempt this thread. */
|
||||
status += tx_semaphore_ceiling_put(&semaphore_0, 2);
|
||||
|
||||
/* Check the status and the run counter of the other thread. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 5))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #9a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to allow the other thread to run. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Make sure the other thread has run. */
|
||||
if (thread_1_counter != 7)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #10a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point, we need to resume thread 2 and relinquish in order to get that thread suspended on the
|
||||
semaphore as well. */
|
||||
tx_thread_resume(&thread_2);
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Perform 2 semaphore put operations to resume both threads. */
|
||||
status = tx_semaphore_ceiling_put(&semaphore_0, 2);
|
||||
status += tx_semaphore_ceiling_put(&semaphore_0, 2);
|
||||
|
||||
/* Let both threads run again. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Check the status and the run counter of the other thread. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 9) || (thread_2_counter != 5))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #11a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment thread run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Suspend on the semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment thread run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Suspend on the semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_2_counter++;
|
||||
}
|
||||
}
|
213
test/smp/regression/threadx_semaphore_delete_test.c
Normal file
213
test/smp/regression/threadx_semaphore_delete_test.c
Normal file
@ -0,0 +1,213 @@
|
||||
/* This test is designed to test the semaphore suspension and semaphore delete with
|
||||
suspended threads. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
|
||||
static TX_SEMAPHORE semaphore_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void put_notify(TX_SEMAPHORE *semaphore_ptr)
|
||||
{
|
||||
|
||||
/* Don't need to do anything in here... */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_semaphore_delete_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Delete Test....................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Delete Test....................................... ERROR #2!\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Delete Test....................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a semaphore with an initial count of 0. */
|
||||
status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Delete Test....................................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup the semaphore notify callback. */
|
||||
status = tx_semaphore_put_notify(&semaphore_0, put_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Delete Test....................................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Delete Test....................................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Semaphore Delete Test....................................... ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Relinquish to let other threads run. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Other threads should now be suspended on the semaphore. */
|
||||
|
||||
/* Delete the semaphore to test it out! */
|
||||
status = tx_semaphore_delete(&semaphore_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to allow other threads to run again before we return. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Now check the run counter of each thread. */
|
||||
if ((thread_1_counter != 1) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Suspend on the semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_DELETED)
|
||||
thread_1_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Suspend on the semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_DELETED)
|
||||
thread_2_counter++;
|
||||
}
|
418
test/smp/regression/threadx_semaphore_information_test.c
Normal file
418
test/smp/regression/threadx_semaphore_information_test.c
Normal file
@ -0,0 +1,418 @@
|
||||
/* This test is designed to test the semaphore information services. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_semaphore.h"
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static TX_SEMAPHORE semaphore_0;
|
||||
static TX_SEMAPHORE semaphore_1;
|
||||
static TX_SEMAPHORE semaphore_2;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
|
||||
UINT _tx_semaphore_performance_info_get(TX_SEMAPHORE *semaphore_ptr, ULONG *puts, ULONG *gets,
|
||||
ULONG *suspensions, ULONG *timeouts);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_semaphore_information_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Information Test.................................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a semaphore with an initial count of 1. */
|
||||
status = tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Information Test.................................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a semaphore with an initial count of 0. */
|
||||
status = tx_semaphore_create(&semaphore_1, "semaphore 1", 1);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Information Test.................................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *name;
|
||||
ULONG current_value;
|
||||
TX_THREAD *first_suspended;
|
||||
ULONG suspended_count;
|
||||
TX_SEMAPHORE *next_semaphore;
|
||||
ULONG puts;
|
||||
ULONG gets;
|
||||
ULONG suspensions;
|
||||
ULONG timeouts;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Semaphore Information Test.................................. ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Attempt to get semaphore information from a non-semaphore. */
|
||||
status = tx_semaphore_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get semaphore information from a non-created semaphore. */
|
||||
semaphore_2.tx_semaphore_id = 0;
|
||||
status = tx_semaphore_info_get(&semaphore_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Attempt to get from semaphore with an instance. Should be successful! */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get from semaphore without an instance. Should be unsuccessful. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_NO_INSTANCE)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Put to semaphore that has an instance already. Should now be 2! */
|
||||
status = tx_semaphore_put(&semaphore_1);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (semaphore_1.tx_semaphore_count != 2))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Attempt to get from semaphore with an instance. Should be successful! */
|
||||
status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get from semaphore with an instance. Should be successful. */
|
||||
status = tx_semaphore_get(&semaphore_1, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get semaphore information. */
|
||||
status = tx_semaphore_info_get(&semaphore_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
status += tx_semaphore_info_get(&semaphore_0, &name, ¤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);
|
||||
}
|
||||
}
|
271
test/smp/regression/threadx_semaphore_non_preemption_test.c
Normal file
271
test/smp/regression/threadx_semaphore_non_preemption_test.c
Normal file
@ -0,0 +1,271 @@
|
||||
/* This test is designed to test the semaphore suspension and another thread resuming the
|
||||
same priority thread by doing a semaphore put. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
|
||||
static TX_SEMAPHORE semaphore_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void put_notify(TX_SEMAPHORE *semaphore_ptr)
|
||||
{
|
||||
|
||||
/* Don't need to do anything in here... */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_semaphore_non_preemption_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Non Preemption Test............................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Non Preemption Test............................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Non Preemption Test............................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a semaphore with an initial count of 0. */
|
||||
status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Non Preemption Test............................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup the semaphore notify callback. */
|
||||
status = tx_semaphore_put_notify(&semaphore_0, put_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Non Preemption Test............................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Non Preemption Test............................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Semaphore Non Preemption Test............................... ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Perform a semaphore put and get, just to exercise the notify path of a non-resumption
|
||||
semaphore put. */
|
||||
status = tx_semaphore_put(&semaphore_0);
|
||||
status += tx_semaphore_get(&semaphore_0, TX_NO_WAIT);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to make the other thread suspend on the semaphore. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Make sure the other thread has run. */
|
||||
if (thread_1_counter != 1)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Place an instance on the semaphore, this should resume the other thread
|
||||
but not preempt this thread. */
|
||||
status = tx_semaphore_put(&semaphore_0);
|
||||
|
||||
/* Check the status and the run counter of the other thread. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 1))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to allow the other thread to run. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Make sure the other thread has run. */
|
||||
if (thread_1_counter != 3)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point, we need to resume thread 2 and relinquish in order to get that thread suspended on the
|
||||
semaphore as well. */
|
||||
tx_thread_resume(&thread_2);
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Perform 2 semaphore put operations to resume both threads. */
|
||||
status = tx_semaphore_put(&semaphore_0);
|
||||
status += tx_semaphore_put(&semaphore_0);
|
||||
|
||||
/* Let both threads run again. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Check the status and the run counter of the other thread. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 5) || (thread_2_counter != 3))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment thread run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Suspend on the semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment thread run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Suspend on the semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_2_counter++;
|
||||
}
|
||||
}
|
||||
|
179
test/smp/regression/threadx_semaphore_preemption_test.c
Normal file
179
test/smp/regression/threadx_semaphore_preemption_test.c
Normal file
@ -0,0 +1,179 @@
|
||||
/* This test is designed to test the semaphore suspension and another thread resuming the
|
||||
higher priority thread by doing a semaphore put. Higher-priority thread should preempt. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
|
||||
static TX_SEMAPHORE semaphore_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void put_notify(TX_SEMAPHORE *semaphore_ptr)
|
||||
{
|
||||
|
||||
/* Don't need to do anything in here... */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_semaphore_preemption_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Preemption Test................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Preemption Test................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a semaphore with an initial count of 0. */
|
||||
status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Preemption Test................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup the semaphore notify callback. */
|
||||
status = tx_semaphore_put_notify(&semaphore_0, put_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Preemption Test................................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Preemption Test................................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Semaphore Preemption Test................................... ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* The other thread should now be suspended on the semaphore. */
|
||||
if (thread_1_counter != 1)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Place an instance on the semaphore, this should cause the other thread
|
||||
to preempt. */
|
||||
status = tx_semaphore_put(&semaphore_0);
|
||||
|
||||
/* Check status and run counter of other thread. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 2))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Increment thread run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Suspend on the semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Did we get the right status? */
|
||||
if (status == TX_SUCCESS)
|
||||
thread_1_counter++;
|
||||
}
|
||||
|
525
test/smp/regression/threadx_semaphore_prioritize.c
Normal file
525
test/smp/regression/threadx_semaphore_prioritize.c
Normal file
@ -0,0 +1,525 @@
|
||||
/* This test is designed to test semaphore prioritize. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Define the external reference for the preempt disable flag. */
|
||||
|
||||
extern volatile UINT _tx_thread_preempt_disable;
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
static unsigned long thread_4_counter = 0;
|
||||
static TX_THREAD thread_4;
|
||||
|
||||
static unsigned long thread_5_counter = 0;
|
||||
static TX_THREAD thread_5;
|
||||
|
||||
static unsigned long thread_6_counter = 0;
|
||||
static TX_THREAD thread_6;
|
||||
|
||||
static TX_SEMAPHORE semaphore_0;
|
||||
static TX_SEMAPHORE semaphore_1;
|
||||
|
||||
static int test_status;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
static void thread_5_entry(ULONG thread_input);
|
||||
static void thread_6_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* Determine if the test case we are looking for is present. */
|
||||
if ((_tx_thread_preempt_disable) && (test_status == 1))
|
||||
{
|
||||
|
||||
/* Determine if thread 3 is at the front of the suspension list. */
|
||||
if (semaphore_0.tx_semaphore_suspension_list == &thread_3)
|
||||
{
|
||||
|
||||
/* Abort the wait of thread 3. */
|
||||
tx_thread_wait_abort(&thread_3);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Abort the wait of thread 5. */
|
||||
tx_thread_wait_abort(&thread_5);
|
||||
|
||||
/* End the ISR processing. */
|
||||
test_status = 2;
|
||||
test_isr_dispatch = TX_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void put_notify(TX_SEMAPHORE *semaphore_ptr)
|
||||
{
|
||||
|
||||
/* Don't need to do anything in here... */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_semaphore_prioritize_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Prioritize Test................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Prioritize Test................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Prioritize Test................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
3, 3, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Prioritize Test................................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
4, 4, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Prioritize Test................................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
5, 5, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Prioritize Test................................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 6,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
6, 6, 100, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Prioritize Test................................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the semaphore with no instances. */
|
||||
status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Prioritize Test................................... ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup the semaphore notify callback. */
|
||||
status = tx_semaphore_put_notify(&semaphore_0, put_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Prioritize Test................................... ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Prioritize Test................................... ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Semaphore Prioritize Test................................... ");
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Attempt to prioritize a non-semaphore. */
|
||||
status = tx_semaphore_prioritize(TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to prioritize a non-created semaphore. */
|
||||
semaphore_1.tx_semaphore_id = 0;
|
||||
status = tx_semaphore_prioritize(&semaphore_1);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Prioritize the semaphore suspension list - empty list case! */
|
||||
status = tx_semaphore_prioritize(&semaphore_0);
|
||||
|
||||
/* Check status and make sure thread 1 is terminated. */
|
||||
if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != TX_NULL))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Make sure thread 1 and 2 are suspended on the semaphore. */
|
||||
if ((thread_1.tx_thread_state != TX_SEMAPHORE_SUSP) || (thread_2.tx_thread_state != TX_SEMAPHORE_SUSP) ||
|
||||
(semaphore_0.tx_semaphore_suspension_list != &thread_1))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Prioritize the semaphore suspension list. */
|
||||
status = tx_semaphore_prioritize(&semaphore_0);
|
||||
|
||||
/* Check status and make sure thread 2 is not at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_2))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Prioritize the semaphore suspension list again - in this case, the list is already prioritized. */
|
||||
status = tx_semaphore_prioritize(&semaphore_0);
|
||||
|
||||
/* Check status and make sure thread 2 is not at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_2))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #15a\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* At this point we are going to get more than 2 threads suspended. */
|
||||
tx_thread_resume(&thread_1);
|
||||
tx_thread_resume(&thread_2);
|
||||
tx_thread_resume(&thread_3);
|
||||
tx_thread_resume(&thread_4);
|
||||
tx_thread_resume(&thread_5);
|
||||
tx_thread_resume(&thread_6);
|
||||
|
||||
/* Prioritize the semaphore suspension list. */
|
||||
status = tx_semaphore_prioritize(&semaphore_0);
|
||||
|
||||
/* Check status and make sure thread 3 is now at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_3))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now loop to test the interrupt of the prioritize loop logic. */
|
||||
test_status = 1;
|
||||
test_isr_dispatch = test_isr;
|
||||
do
|
||||
{
|
||||
|
||||
/* Prioritize the semaphore suspension list. */
|
||||
status = tx_semaphore_prioritize(&semaphore_0);
|
||||
|
||||
/* Check status and make sure thread 1 is terminated. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
} while (test_status == 1);
|
||||
|
||||
/* Check status and make sure thread 3 is now at the front of the suspension list. */
|
||||
if ((status != TX_SUCCESS) || (semaphore_0.tx_semaphore_suspension_list != &thread_4))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_3_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_4_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_6_entry(ULONG thread_input)
|
||||
{
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Loop forever! */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
/* Get semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_6_counter++;
|
||||
}
|
||||
}
|
||||
|
224
test/smp/regression/threadx_semaphore_thread_terminate_test.c
Normal file
224
test/smp/regression/threadx_semaphore_thread_terminate_test.c
Normal file
@ -0,0 +1,224 @@
|
||||
/* This test is designed to test thread terminate calls when threads are suspended on
|
||||
a semaphore. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
|
||||
static TX_SEMAPHORE semaphore_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void put_notify(TX_SEMAPHORE *semaphore_ptr)
|
||||
{
|
||||
|
||||
/* Don't need to do anything in here... */
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_semaphore_thread_terminate_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Thread Terminate Test............................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Thread Terminate Test............................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Thread Terminate Test............................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a semaphore with an initial count of 0. */
|
||||
status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Thread Terminate Test............................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup the semaphore notify callback. */
|
||||
status = tx_semaphore_put_notify(&semaphore_0, put_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Thread Terminate Test............................. ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Thread Terminate Test............................. ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Semaphore Thread Terminate Test............................. ");
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Relinquish to let other threads run. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Other threads should now be suspended on the semaphore. */
|
||||
if ((thread_1_counter != 1) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Terminate the other threads to make sure the semaphore gets
|
||||
cleaned up. */
|
||||
status = tx_thread_terminate(&thread_1);
|
||||
|
||||
/* Check status and run counters of other threads. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Terminate the other thread. */
|
||||
status = tx_thread_terminate(&thread_2);
|
||||
|
||||
/* Relinquish just to make sure. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Check status and run counters of other threads. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
/* Increment thread run counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Suspend on the semaphore. */
|
||||
tx_semaphore_get(&semaphore_0, 33);
|
||||
|
||||
/* Should never get here! */
|
||||
thread_1_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
/* Increment thread run counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Suspend on the semaphore. */
|
||||
tx_semaphore_get(&semaphore_0, 44);
|
||||
|
||||
/* Should never get here! */
|
||||
thread_2_counter++;
|
||||
}
|
165
test/smp/regression/threadx_semaphore_timeout_test.c
Normal file
165
test/smp/regression/threadx_semaphore_timeout_test.c
Normal file
@ -0,0 +1,165 @@
|
||||
/* This test is designed to test the semaphore suspension and timeout functionality. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
//static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static TX_SEMAPHORE semaphore_0;
|
||||
static TX_SEMAPHORE semaphore_1;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void put_notify(TX_SEMAPHORE *semaphore_ptr)
|
||||
{
|
||||
|
||||
/* Don't need to do anything in here... */
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_semaphore_timeout_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Suspension Timeout Test........................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a semaphore with an initial count of 0. */
|
||||
status = tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Suspension Timeout Test........................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup the semaphore notify callback. */
|
||||
status = tx_semaphore_put_notify(&semaphore_0, put_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Suspension Timeout Test........................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Semaphore Suspension Timeout Test........................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Semaphore Suspension Timeout Test........................... ");
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Attempt to setup semaphore notify callback on non-semaphore. */
|
||||
status = tx_semaphore_put_notify(TX_NULL, put_notify);
|
||||
|
||||
/* Check status */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to setup semaphore notify callback on non-created semaphore. */
|
||||
semaphore_1.tx_semaphore_id = 0;
|
||||
status = tx_semaphore_put_notify(&semaphore_1, put_notify);
|
||||
|
||||
/* Check status */
|
||||
if (status != TX_SEMAPHORE_ERROR)
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Sleep for 2 ticks for fresh timer. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Set clock to 0. */
|
||||
tx_time_set(0);
|
||||
|
||||
/* Suspend on the semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, 33);
|
||||
|
||||
/* Did we get the right status at the right time? */
|
||||
if ((status != TX_NO_INSTANCE) || (tx_time_get() != 33))
|
||||
{
|
||||
|
||||
/* Semaphore error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
348
test/smp/regression/threadx_smp_multiple_threads_one_core_test.c
Normal file
348
test/smp/regression/threadx_smp_multiple_threads_one_core_test.c
Normal file
@ -0,0 +1,348 @@
|
||||
/* Define the ThreadX SMP multiple threads excluded to one core test. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
static TX_THREAD thread_2;
|
||||
static TX_THREAD thread_3;
|
||||
static TX_THREAD thread_4;
|
||||
static TX_THREAD thread_5;
|
||||
static TX_THREAD thread_6;
|
||||
static TX_THREAD thread_7;
|
||||
|
||||
|
||||
static ULONG thread_0_counter;
|
||||
static ULONG thread_1_counter;
|
||||
static ULONG thread_2_counter;
|
||||
static ULONG thread_3_counter;
|
||||
static ULONG thread_4_counter;
|
||||
static ULONG thread_5_counter;
|
||||
static ULONG thread_6_counter;
|
||||
static ULONG thread_7_counter;
|
||||
|
||||
|
||||
static unsigned long error = 0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
static void thread_5_entry(ULONG thread_input);
|
||||
static void thread_6_entry(ULONG thread_input);
|
||||
static void thread_7_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_smp_multiple_threads_one_core_test(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Multiple Threads One Core Test.......................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_1, 0xD); /* Only core 1! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Multiple Threads One Core Test.......................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_2, 0xB); /* Only core 2! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Multiple Threads One Core Test.......................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_3, 0x7); /* Only core 3! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Multiple Threads One Core Test.......................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_4, 0xE); /* Only core 0! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Multiple Threads One Core Test.......................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_5, "thread 5", thread_5_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_5, 0xD); /* Only core 1! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Multiple Threads One Core Test.......................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_6, "thread 6", thread_6_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_6, 0xB); /* Only core 2! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Multiple Threads One Core Test.......................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_7, "thread 7", thread_7_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_7, 0x7); /* Only core 3! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Multiple Threads One Core Test.......................... ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 0. */
|
||||
status = tx_thread_resume(&thread_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Multiple Threads One Core Test.......................... ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running SMP Multiple Threads One Core Test.......................... ");
|
||||
|
||||
/* Resume all the threads. */
|
||||
status = tx_thread_resume(&thread_1);
|
||||
status += tx_thread_resume(&thread_2);
|
||||
status += tx_thread_resume(&thread_3);
|
||||
status += tx_thread_resume(&thread_4);
|
||||
status += tx_thread_resume(&thread_5);
|
||||
status += tx_thread_resume(&thread_6);
|
||||
status += tx_thread_resume(&thread_7);
|
||||
|
||||
/* Suspend this thread to let the others run. */
|
||||
tx_thread_sleep(5);
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (error) || (thread_1_counter != 1) || (tx_thread_smp_core_get() != 0) ||
|
||||
(thread_2_counter != 1) || (thread_3_counter != 1) || (thread_4_counter != 1) ||
|
||||
(thread_5_counter != 1) || (thread_6_counter != 1) || (thread_7_counter != 1))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* Ensure this thread is on the correct core. */
|
||||
if (tx_thread_smp_core_get() != 1)
|
||||
error++;
|
||||
|
||||
thread_1_counter++;
|
||||
tx_thread_suspend(&thread_1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Ensure this thread is on the correct core. */
|
||||
if (tx_thread_smp_core_get() != 2)
|
||||
error++;
|
||||
|
||||
thread_2_counter++;
|
||||
tx_thread_suspend(&thread_2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Ensure this thread is on the correct core. */
|
||||
if (tx_thread_smp_core_get() != 3)
|
||||
error++;
|
||||
|
||||
thread_3_counter++;
|
||||
tx_thread_suspend(&thread_3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Ensure this thread is on the correct core. */
|
||||
if (tx_thread_smp_core_get() != 0)
|
||||
error++;
|
||||
|
||||
thread_4_counter++;
|
||||
tx_thread_suspend(&thread_4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Ensure this thread is on the correct core. */
|
||||
if (tx_thread_smp_core_get() != 1)
|
||||
error++;
|
||||
|
||||
thread_5_counter++;
|
||||
tx_thread_suspend(&thread_5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_6_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Ensure this thread is on the correct core. */
|
||||
if (tx_thread_smp_core_get() != 2)
|
||||
error++;
|
||||
|
||||
thread_6_counter++;
|
||||
tx_thread_suspend(&thread_6);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_7_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Ensure this thread is on the correct core. */
|
||||
if (tx_thread_smp_core_get() != 3)
|
||||
error++;
|
||||
|
||||
thread_7_counter++;
|
||||
tx_thread_suspend(&thread_7);
|
||||
}
|
||||
}
|
350
test/smp/regression/threadx_smp_non_trivial_scheduling_test.c
Normal file
350
test/smp/regression/threadx_smp_non_trivial_scheduling_test.c
Normal file
@ -0,0 +1,350 @@
|
||||
/* Define the ThreadX SMP non-trivial scheduling test. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
static TX_THREAD thread_2;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
|
||||
static ULONG thread_0_counter;
|
||||
static ULONG thread_1_counter;
|
||||
static ULONG thread_2_counter;
|
||||
static ULONG thread_3_counter;
|
||||
|
||||
|
||||
extern TX_THREAD *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES];
|
||||
|
||||
static unsigned long error = 0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_smp_non_trivial_scheduling_test(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Only allow core 0 for now */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_1, 0x9); /* Exclude core 2 and 1 */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_2, 0xB); /* Exclude core 3, 1 and 0 */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
3, 3, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_3, 0xE); /* Exclude core 0 */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 0. */
|
||||
status = tx_thread_resume(&thread_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Non-Trivial Scheduling Test............................. ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UINT original_threshold;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running SMP Non-Trivial Scheduling Test............................. ");
|
||||
|
||||
/* Move enable core 0 and 1. */
|
||||
status = tx_thread_smp_core_exclude(&thread_0, 0xC); /* Allow core 0 and 1 */
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 1. */
|
||||
status = tx_thread_resume(&thread_1);
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 2. */
|
||||
status = tx_thread_resume(&thread_2);
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 3. */
|
||||
status = tx_thread_resume(&thread_3);
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Suspend thread 2 and cause a rebalance of the execution list. */
|
||||
status = tx_thread_suspend(&thread_2);
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_3) || (_tx_thread_execute_ptr[1] != &thread_0)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #10");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now suspend threads 3 and 1. */
|
||||
status = tx_thread_suspend(&thread_3);
|
||||
status += tx_thread_suspend(&thread_1);
|
||||
|
||||
/* Use preemption-threshold to test the rebalance routine. */
|
||||
status += tx_thread_preemption_change(&thread_3, 2, &original_threshold);
|
||||
|
||||
/* Move thread 0 back to core 0 and then allow core 1 again. */
|
||||
status += tx_thread_smp_core_exclude(&thread_0, 0xE);
|
||||
status += tx_thread_smp_core_exclude(&thread_0, 0xC);
|
||||
|
||||
/* Make sure threads 1 defaults to core 1. */
|
||||
status += tx_thread_smp_core_exclude(&thread_1, 0xD);
|
||||
status += tx_thread_smp_core_exclude(&thread_1, 0x9);
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #11");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 1. */
|
||||
status = tx_thread_resume(&thread_1);
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 2. */
|
||||
status = tx_thread_resume(&thread_2);
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 3. */
|
||||
status = tx_thread_resume(&thread_3);
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_2) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Suspend thread 2 and cause a rebalance of the execution list. */
|
||||
status = tx_thread_suspend(&thread_2);
|
||||
|
||||
/* With preemption-threshold disabled, thread_3 can not run since preemption-threshold is set to 0 and there is already a
|
||||
zero priority thread running. */
|
||||
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_3) || (_tx_thread_execute_ptr[1] != &thread_0)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
#else
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_1)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #15");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now suspend threads 3 and 1. */
|
||||
status = tx_thread_suspend(&thread_3);
|
||||
status += tx_thread_suspend(&thread_1);
|
||||
|
||||
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != TX_NULL) || (_tx_thread_execute_ptr[1] != &thread_0)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
#else
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #16");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
thread_1_counter++;
|
||||
tx_thread_identify();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
thread_2_counter++;
|
||||
tx_thread_identify();
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
thread_3_counter++;
|
||||
tx_thread_identify();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,145 @@
|
||||
/* Define the ThreadX SMP one thread dynamic thread exclusion test. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
|
||||
static ULONG thread_0_counter;
|
||||
|
||||
|
||||
static unsigned long error = 0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_smp_one_thread_dynamic_exclusion_test(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_0, 0x0); /* No exclusions! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP One Thread Dynamic Exclusion Test....................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Resume thread 0. */
|
||||
status = tx_thread_resume(&thread_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP One Thread Dynamic Exclusion Test....................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running SMP One Thread Dynamic Exclusion Test....................... ");
|
||||
|
||||
/* Move to core 1. */
|
||||
status = tx_thread_smp_core_exclude(&thread_0, 0xD); /* Only core 1! */
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (tx_thread_smp_core_get() != 1))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Move to core 2. */
|
||||
status = tx_thread_smp_core_exclude(&thread_0, 0xB); /* Only core 2! */
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (tx_thread_smp_core_get() != 2))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Move to core 3. */
|
||||
status = tx_thread_smp_core_exclude(&thread_0, 0x7); /* Only core 3! */
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (tx_thread_smp_core_get() != 3))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Move back to core 0. */
|
||||
status = tx_thread_smp_core_exclude(&thread_0, 0xE); /* Only core 0! */
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (tx_thread_smp_core_get() != 0))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
534
test/smp/regression/threadx_smp_preemption_threshold_test.c
Normal file
534
test/smp/regression/threadx_smp_preemption_threshold_test.c
Normal file
@ -0,0 +1,534 @@
|
||||
/* Define the ThreadX SMP preemption-threshold test. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
extern TX_THREAD *_tx_thread_execute_ptr[TX_THREAD_SMP_MAX_CORES];
|
||||
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
static TX_THREAD thread_5;
|
||||
static TX_THREAD thread_16;
|
||||
static TX_THREAD thread_16_pt5;
|
||||
static TX_THREAD thread_18;
|
||||
static TX_THREAD thread_23_pt17;
|
||||
static TX_THREAD thread_25;
|
||||
static TX_THREAD thread_27_pt24;
|
||||
static TX_THREAD thread_31;
|
||||
|
||||
static ULONG thread_run_counter[10];
|
||||
|
||||
|
||||
static unsigned long error = 0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_entry(ULONG thread_input);
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void delay(UINT i)
|
||||
{
|
||||
|
||||
/* Wait until the thread runs! */
|
||||
while (thread_run_counter[i] == 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_smp_preemption_threshold_test(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
UINT i;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Preemption-Threshold Test............................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_1, 0); /* Any core! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Preemption-Threshold Test............................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_5, "thread 5", thread_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
5, 5, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_5, 0); /* Any core! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Preemption-Threshold Test............................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_16, "thread 16", thread_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_16, 0); /* Any core! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Preemption-Threshold Test............................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_16_pt5, "thread 16 PT5", thread_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 5, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_16_pt5, 0); /* Any core! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Preemption-Threshold Test............................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_18, "thread 18", thread_entry, 5,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
18, 18, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_18, 0); /* Any core! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Preemption-Threshold Test............................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_23_pt17, "thread 23 PT17", thread_entry, 6,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
23, 17, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_23_pt17, 0); /* Any core! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Preemption-Threshold Test............................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_25, "thread 25", thread_entry, 7,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
25, 25, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_25, 0); /* Any core! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Preemption-Threshold Test............................... ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_27_pt24, "thread 27 PT24", thread_entry, 8,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
27, 24, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_27_pt24, 0); /* Any core! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Preemption-Threshold Test............................... ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_31, "thread 31", thread_entry, 9,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31, 0); /* Any core! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Preemption-Threshold Test............................... ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Clear the thread run count array. */
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
thread_run_counter[i] = 0;
|
||||
}
|
||||
|
||||
/* Resume thread 0. */
|
||||
status = tx_thread_resume(&thread_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Preemption-Threshold Test............................... ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running SMP Preemption-Threshold Test............................... ");
|
||||
|
||||
/* This test is only useful when preemption-threshold is enabled. */
|
||||
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
|
||||
/* Resume thread. */
|
||||
status = tx_thread_resume(&thread_31);
|
||||
delay(9);
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_31)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread. */
|
||||
status = tx_thread_resume(&thread_27_pt24);
|
||||
delay(8);
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_27_pt24)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread. */
|
||||
status = tx_thread_resume(&thread_23_pt17);
|
||||
delay(6);
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_23_pt17)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread. */
|
||||
status = tx_thread_resume(&thread_16_pt5);
|
||||
delay(4);
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread. */
|
||||
status = tx_thread_resume(&thread_16);
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread. */
|
||||
status = tx_thread_resume(&thread_25);
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread. */
|
||||
status = tx_thread_resume(&thread_18);
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread. */
|
||||
status = tx_thread_resume(&thread_5);
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread. */
|
||||
status = tx_thread_resume(&thread_1);
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_16_pt5)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Suspend Thread 16 pt5. */
|
||||
status = tx_thread_suspend(&thread_16_pt5);
|
||||
|
||||
delay(2);
|
||||
delay(3);
|
||||
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_16))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Suspend Thread 16. */
|
||||
status = tx_thread_suspend(&thread_16);
|
||||
|
||||
delay(6);
|
||||
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_23_pt17))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Suspend Thread 23 pt 17. */
|
||||
status = tx_thread_suspend(&thread_23_pt17);
|
||||
|
||||
delay(5);
|
||||
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_18))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Suspend Thread 18. */
|
||||
status = tx_thread_suspend(&thread_18);
|
||||
|
||||
delay(8);
|
||||
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_27_pt24))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Suspend Thread 27 pt 24. */
|
||||
status = tx_thread_suspend(&thread_27_pt24);
|
||||
|
||||
delay(7);
|
||||
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_25))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Suspend Thread 25. */
|
||||
status = tx_thread_suspend(&thread_25);
|
||||
|
||||
delay(9);
|
||||
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_31))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #26\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 16 pt 5. */
|
||||
status = tx_thread_resume(&thread_16_pt5);
|
||||
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_31))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #27\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Suspend thread 16 pt 5. */
|
||||
status = tx_thread_suspend(&thread_16_pt5);
|
||||
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != &thread_31))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #28\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Suspend thread 31. */
|
||||
status = tx_thread_suspend(&thread_31);
|
||||
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
|
||||
|| (_tx_thread_execute_ptr[2] != &thread_1) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #29\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Suspend thread 1. */
|
||||
status = tx_thread_suspend(&thread_1);
|
||||
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != &thread_5)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #30\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Suspend thread 5. */
|
||||
status = tx_thread_suspend(&thread_5);
|
||||
|
||||
/* Check for the correct results. */
|
||||
if ((status != TX_SUCCESS) || (_tx_thread_execute_ptr[0] != &thread_0) || (_tx_thread_execute_ptr[1] != TX_NULL)
|
||||
|| (_tx_thread_execute_ptr[2] != TX_NULL) || (_tx_thread_execute_ptr[3] != TX_NULL))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #31\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static void thread_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
/* Increment the run counter. */
|
||||
thread_run_counter[thread_input]++;
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_identify();
|
||||
|
||||
/* Indicate the thread is running... */
|
||||
thread_run_counter[thread_input]++;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2329
test/smp/regression/threadx_smp_random_resume_suspend_test.c
Normal file
2329
test/smp/regression/threadx_smp_random_resume_suspend_test.c
Normal file
File diff suppressed because it is too large
Load Diff
204
test/smp/regression/threadx_smp_rebalance_exclusion_test.c
Normal file
204
test/smp/regression/threadx_smp_rebalance_exclusion_test.c
Normal file
@ -0,0 +1,204 @@
|
||||
/* Define the ThreadX SMP rebalance exclusion test. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
static TX_THREAD thread_2;
|
||||
static TX_THREAD thread_31k;
|
||||
|
||||
|
||||
static ULONG thread_0_counter;
|
||||
static ULONG thread_1_counter;
|
||||
static ULONG thread_2_counter;
|
||||
static ULONG thread_31k_counter;
|
||||
|
||||
|
||||
static unsigned long error = 0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_31k_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_smp_rebalance_exclustion_test(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_0, 0x0); /* No exclusions! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Rebalance Exclusion Test................................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_1, 0x0); /* No exclusions! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Rebalance Exclusion Test................................ ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_2, 0x0); /* No exclusions! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Rebalance Exclusion Test................................ ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_31k, "thread 31k", thread_31k_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 15, 16, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31k, 0xE); /* Core 0 only! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Rebalance Exclusion Test................................ ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 0. */
|
||||
status = tx_thread_resume(&thread_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Rebalance Exclusion Test................................ ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running SMP Rebalance Exclusion Test................................ ");
|
||||
|
||||
/* Resume all the threads. */
|
||||
status = tx_thread_resume(&thread_1);
|
||||
status += tx_thread_resume(&thread_2);
|
||||
status += tx_thread_resume(&thread_31k);
|
||||
|
||||
/* Suspend this thread to let the others run. */
|
||||
tx_thread_sleep(5);
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (error) || (thread_1_counter != 1) ||
|
||||
(thread_2_counter != 1) || (thread_31k_counter != 1))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
thread_1_counter++;
|
||||
tx_thread_suspend(&thread_1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
thread_2_counter++;
|
||||
tx_thread_suspend(&thread_2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31k_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Ensure this thread is on the correct core. */
|
||||
if (tx_thread_smp_core_get() != 0)
|
||||
error++;
|
||||
|
||||
thread_31k_counter++;
|
||||
tx_thread_suspend(&thread_31k);
|
||||
}
|
||||
}
|
365
test/smp/regression/threadx_smp_relinquish_test.c
Normal file
365
test/smp/regression/threadx_smp_relinquish_test.c
Normal file
@ -0,0 +1,365 @@
|
||||
/* Define the ThreadX SMP relinquish test. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_31a;
|
||||
static TX_THREAD thread_31b;
|
||||
static TX_THREAD thread_31c;
|
||||
static TX_THREAD thread_31d;
|
||||
static TX_THREAD thread_31e;
|
||||
static TX_THREAD thread_31f;
|
||||
static TX_THREAD thread_31g;
|
||||
static TX_THREAD thread_31h;
|
||||
|
||||
|
||||
static ULONG thread_31a_counter;
|
||||
static ULONG thread_31b_counter;
|
||||
static ULONG thread_31c_counter;
|
||||
static ULONG thread_31d_counter;
|
||||
static ULONG thread_31e_counter;
|
||||
static ULONG thread_31f_counter;
|
||||
static ULONG thread_31g_counter;
|
||||
static ULONG thread_31h_counter;
|
||||
|
||||
|
||||
static unsigned long error = 0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_31a_entry(ULONG thread_input);
|
||||
static void thread_31b_entry(ULONG thread_input);
|
||||
static void thread_31c_entry(ULONG thread_input);
|
||||
static void thread_31d_entry(ULONG thread_input);
|
||||
static void thread_31e_entry(ULONG thread_input);
|
||||
static void thread_31f_entry(ULONG thread_input);
|
||||
static void thread_31g_entry(ULONG thread_input);
|
||||
static void thread_31h_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_smp_relinquish_test(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
UINT i;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Relinquish Test......................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_31a, "thread 31a", thread_31a_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31a, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Relinquish Test......................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_31b, "thread 31b", thread_31b_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31b, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Relinquish Test......................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
status = tx_thread_create(&thread_31c, "thread 31c", thread_31c_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31c, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Relinquish Test......................................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
status = tx_thread_create(&thread_31d, "thread 31d", thread_31d_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31d, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Relinquish Test......................................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_31e, "thread 31e", thread_31e_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31e, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Relinquish Test......................................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_31f, "thread 31f", thread_31f_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31f, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Relinquish Test......................................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
status = tx_thread_create(&thread_31g, "thread 31g", thread_31g_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31g, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Relinquish Test......................................... ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_31h, "thread 31h", thread_31h_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31h, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Relinquish Test......................................... ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Clear all the counters. */
|
||||
thread_31a_counter = 0;
|
||||
thread_31b_counter = 0;
|
||||
thread_31c_counter = 0;
|
||||
thread_31d_counter = 0;
|
||||
thread_31e_counter = 0;
|
||||
thread_31f_counter = 0;
|
||||
thread_31g_counter = 0;
|
||||
thread_31h_counter = 0;
|
||||
|
||||
/* Resume thread 0. */
|
||||
status = tx_thread_resume(&thread_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Relinquish Test......................................... ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running SMP Relinquish Test......................................... ");
|
||||
|
||||
/* Resume all the same priority threads. */
|
||||
status = tx_thread_resume(&thread_31a);
|
||||
status += tx_thread_resume(&thread_31b);
|
||||
status += tx_thread_resume(&thread_31c);
|
||||
status += tx_thread_resume(&thread_31d);
|
||||
status += tx_thread_resume(&thread_31e);
|
||||
status += tx_thread_resume(&thread_31f);
|
||||
status += tx_thread_resume(&thread_31g);
|
||||
status += tx_thread_resume(&thread_31h);
|
||||
|
||||
/* Now sleep for 10 ticks to let see if all the threads execute. */
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Now check and make sure all the threads ran. */
|
||||
if ((status != TX_SUCCESS) || (thread_31a_counter == 0) || (thread_31b_counter == 0) || (thread_31c_counter == 0) || (thread_31d_counter == 0) ||
|
||||
(thread_31e_counter == 0) || (thread_31f_counter == 0) || (thread_31g_counter == 0) || (thread_31h_counter == 0))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #31\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static void thread_31a_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_relinquish();
|
||||
|
||||
thread_31a_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31b_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_relinquish();
|
||||
|
||||
thread_31b_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31c_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_relinquish();
|
||||
|
||||
thread_31c_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31d_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_relinquish();
|
||||
|
||||
thread_31d_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31e_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_relinquish();
|
||||
|
||||
thread_31e_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31f_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_relinquish();
|
||||
|
||||
thread_31f_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31g_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_relinquish();
|
||||
|
||||
thread_31g_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31h_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_relinquish();
|
||||
|
||||
thread_31h_counter++;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
361
test/smp/regression/threadx_smp_time_slice_test.c
Normal file
361
test/smp/regression/threadx_smp_time_slice_test.c
Normal file
@ -0,0 +1,361 @@
|
||||
/* Define the ThreadX SMP time-slice test. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_31a;
|
||||
static TX_THREAD thread_31b;
|
||||
static TX_THREAD thread_31c;
|
||||
static TX_THREAD thread_31d;
|
||||
static TX_THREAD thread_31e;
|
||||
static TX_THREAD thread_31f;
|
||||
static TX_THREAD thread_31g;
|
||||
static TX_THREAD thread_31h;
|
||||
|
||||
|
||||
static ULONG thread_31a_counter;
|
||||
static ULONG thread_31b_counter;
|
||||
static ULONG thread_31c_counter;
|
||||
static ULONG thread_31d_counter;
|
||||
static ULONG thread_31e_counter;
|
||||
static ULONG thread_31f_counter;
|
||||
static ULONG thread_31g_counter;
|
||||
static ULONG thread_31h_counter;
|
||||
|
||||
|
||||
static unsigned long error = 0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_31a_entry(ULONG thread_input);
|
||||
static void thread_31b_entry(ULONG thread_input);
|
||||
static void thread_31c_entry(ULONG thread_input);
|
||||
static void thread_31d_entry(ULONG thread_input);
|
||||
static void thread_31e_entry(ULONG thread_input);
|
||||
static void thread_31f_entry(ULONG thread_input);
|
||||
static void thread_31g_entry(ULONG thread_input);
|
||||
static void thread_31h_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_smp_time_slice_test(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
UINT i;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_0, 0xE); /* Core 0 only! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Time-Slice Test......................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_31a, "thread 31a", thread_31a_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, 1, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31a, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Time-Slice Test......................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_31b, "thread 31b", thread_31b_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, 1, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31b, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Time-Slice Test......................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
status = tx_thread_create(&thread_31c, "thread 31c", thread_31c_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, 1, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31c, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Time-Slice Test......................................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
status = tx_thread_create(&thread_31d, "thread 31d", thread_31d_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, 1, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31d, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Time-Slice Test......................................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_31e, "thread 31e", thread_31e_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, 1, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31e, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Time-Slice Test......................................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_31f, "thread 31f", thread_31f_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, 1, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31f, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Time-Slice Test......................................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
status = tx_thread_create(&thread_31g, "thread 31g", thread_31g_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 31, 1, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31g, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Time-Slice Test......................................... ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Enable preemption-threshold for this thread to hit branch in tx_thread_time_slice
|
||||
where the expired time-slice thread is replaced by a thread with preemption-threshold
|
||||
enabled. */
|
||||
status = tx_thread_create(&thread_31h, "thread 31h", thread_31h_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
31, 30, 1, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_31h, 0); /* Any core. */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Time-Slice Test......................................... ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Clear all the counters. */
|
||||
thread_31a_counter = 0;
|
||||
thread_31b_counter = 0;
|
||||
thread_31c_counter = 0;
|
||||
thread_31d_counter = 0;
|
||||
thread_31e_counter = 0;
|
||||
thread_31f_counter = 0;
|
||||
thread_31g_counter = 0;
|
||||
thread_31h_counter = 0;
|
||||
|
||||
/* Resume thread 0. */
|
||||
status = tx_thread_resume(&thread_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Time-Slice Test......................................... ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running SMP Time-Slice Test......................................... ");
|
||||
|
||||
/* Resume all the same priority threads. */
|
||||
status = tx_thread_resume(&thread_31a);
|
||||
status += tx_thread_resume(&thread_31b);
|
||||
status += tx_thread_resume(&thread_31c);
|
||||
status += tx_thread_resume(&thread_31d);
|
||||
status += tx_thread_resume(&thread_31e);
|
||||
status += tx_thread_resume(&thread_31f);
|
||||
status += tx_thread_resume(&thread_31g);
|
||||
status += tx_thread_resume(&thread_31h);
|
||||
|
||||
/* Now sleep for 20 ticks to let see if all the threads execute. */
|
||||
tx_thread_sleep(20);
|
||||
|
||||
/* Now check and make sure all the threads ran. */
|
||||
if ((status != TX_SUCCESS) || (thread_31a_counter == 0) || (thread_31b_counter == 0) || (thread_31c_counter == 0) || (thread_31d_counter == 0) ||
|
||||
(thread_31e_counter == 0) || (thread_31f_counter == 0) || (thread_31g_counter == 0) || (thread_31h_counter == 0))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #31\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31a_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
tx_thread_identify();
|
||||
thread_31a_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31b_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_identify();
|
||||
thread_31b_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31c_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_identify();
|
||||
thread_31c_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31d_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_identify();
|
||||
thread_31d_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31e_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_identify();
|
||||
thread_31e_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31f_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_identify();
|
||||
thread_31f_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31g_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_identify();
|
||||
thread_31g_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_31h_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
tx_thread_identify();
|
||||
thread_31h_counter++;
|
||||
}
|
||||
}
|
||||
|
268
test/smp/regression/threadx_smp_two_threads_one_core_test.c
Normal file
268
test/smp/regression/threadx_smp_two_threads_one_core_test.c
Normal file
@ -0,0 +1,268 @@
|
||||
/* Define the ThreadX SMP two threads excluded to one core test. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
|
||||
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
static TX_THREAD thread_2;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
|
||||
static ULONG thread_0_counter;
|
||||
static ULONG thread_1_counter;
|
||||
static ULONG thread_2_counter;
|
||||
|
||||
|
||||
static unsigned long error = 0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_smp_two_threads_one_core_test(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
ULONG exclusion_map;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
0, 0, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_0, 0x0); /* No exclusions! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Two Threads One Core Test............................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_1, 0xD); /* Only core 1! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Two Threads One Core Test............................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
2, 2, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_smp_core_exclude(&thread_2, 0xD); /* Only core 1! */
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Two Threads One Core Test............................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 0. */
|
||||
status = tx_thread_resume(&thread_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running SMP Two Threads One Core Test............................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to call the core-exclusion API with a NULL pointer. */
|
||||
status = tx_thread_smp_core_exclude(TX_NULL, 1);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("Running SMP Two Threads One Core Test............................... ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to call the core-exclusion API with a bad thread pointer. */
|
||||
thread_3.tx_thread_id = 0;
|
||||
status = tx_thread_smp_core_exclude(&thread_3, 1);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("Running SMP Two Threads One Core Test............................... ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Test the core exclusion get API. */
|
||||
status = tx_thread_smp_core_exclude_get(TX_NULL, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("Running SMP Two Threads One Core Test............................... ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Test the core exclusion get API with a bad thread pointer. */
|
||||
status = tx_thread_smp_core_exclude_get(&thread_3, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("Running SMP Two Threads One Core Test............................... ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Test the core exclusion get API with a good thread pointer, but a bad return pointer. */
|
||||
status = tx_thread_smp_core_exclude_get(&thread_2, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
printf("Running SMP Two Threads One Core Test............................... ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now test the proper usage for the core exclusiong get API. */
|
||||
status = tx_thread_smp_core_exclude_get(&thread_2, &exclusion_map);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (exclusion_map != 0xD))
|
||||
{
|
||||
|
||||
printf("Running SMP Two Threads One Core Test............................... ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running SMP Two Threads One Core Test............................... ");
|
||||
|
||||
/* Resume all the threads. */
|
||||
status = tx_thread_resume(&thread_1);
|
||||
status += tx_thread_resume(&thread_2);
|
||||
|
||||
/* Suspend this thread to let the others run. */
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Determine if the test was successful or there was an error. */
|
||||
if ((status != TX_SUCCESS) || (error) || (thread_1_counter != 1) ||
|
||||
(thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Execution error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* Ensure this thread is on the correct core. */
|
||||
if (tx_thread_smp_core_get() != 1)
|
||||
error++;
|
||||
|
||||
thread_1_counter++;
|
||||
tx_thread_suspend(&thread_1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Ensure this thread is on the correct core. */
|
||||
if (tx_thread_smp_core_get() != 1)
|
||||
error++;
|
||||
|
||||
thread_2_counter++;
|
||||
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Increment the preempt disable flag. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Now call the exclude routine to exclude core 1 - move the thread. */
|
||||
if (tx_thread_smp_core_exclude(&thread_2, 0x2))
|
||||
error++;
|
||||
|
||||
/* Decrement the preempt disable flag. */
|
||||
_tx_thread_preempt_disable--;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Suspend thread. */
|
||||
tx_thread_suspend(&thread_2);
|
||||
}
|
||||
}
|
863
test/smp/regression/threadx_thread_basic_execution_test.c
Normal file
863
test/smp/regression/threadx_thread_basic_execution_test.c
Normal file
@ -0,0 +1,863 @@
|
||||
/* This test is designed to see if one thread can be created and executed.
|
||||
It thread_0_entry is hit, then the thread was successfully scheduled.
|
||||
On success, thread_0_counter gets incremented. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_block_pool.h"
|
||||
#include "tx_byte_pool.h"
|
||||
#include "tx_event_flags.h"
|
||||
#include "tx_mutex.h"
|
||||
#include "tx_queue.h"
|
||||
#include "tx_semaphore.h"
|
||||
#include "tx_thread.h"
|
||||
|
||||
|
||||
typedef struct THREAD_MEMORY_TEST_STRUCT
|
||||
{
|
||||
ULONG first;
|
||||
ULONG second;
|
||||
TX_THREAD thread_block;
|
||||
ULONG first_middle;
|
||||
ULONG second_middle;
|
||||
ULONG stack[2048/sizeof(ULONG)];
|
||||
ULONG next_to_last;
|
||||
ULONG last;
|
||||
|
||||
} THREAD_MEMORY_TEST;
|
||||
|
||||
static THREAD_MEMORY_TEST thread_memory;
|
||||
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
static TX_THREAD thread_2;
|
||||
static TX_THREAD thread_3;
|
||||
static TX_THREAD test_thread;
|
||||
|
||||
static TX_TIMER timer_0;
|
||||
|
||||
|
||||
static UCHAR not_used_stack[TEST_STACK_SIZE_PRINTF];
|
||||
|
||||
static unsigned long error = 0;
|
||||
static unsigned long timer_executed = 0;
|
||||
static unsigned long isr_executed = 0;
|
||||
|
||||
|
||||
/* Define task prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG task_input);
|
||||
|
||||
UINT _txe_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr,
|
||||
VOID (*entry_function)(ULONG), ULONG entry_input,
|
||||
VOID *stack_start, ULONG stack_size,
|
||||
UINT priority, UINT preempt_threshold,
|
||||
ULONG time_slice, UINT auto_start, UINT thread_control_block_size);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the timer for this test. */
|
||||
|
||||
static void timer_entry(ULONG i)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
/* Attempt to create a thread from a timer. */
|
||||
pointer = (CHAR *) 0x3000;
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt a thread reset from a timer. */
|
||||
status = tx_thread_reset(&thread_0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
timer_executed = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
CHAR *pointer;
|
||||
UINT status;
|
||||
UINT old_value;
|
||||
ULONG old_time_slice;
|
||||
|
||||
|
||||
/* Call tx_thread_relinquish from ISR to make sure the error checking discards the call. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Attempt to create a thread from a timer. */
|
||||
pointer = (CHAR *) not_used_stack;
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to delete a thread from an ISR. */
|
||||
status = tx_thread_delete(&thread_0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to change preemption from an ISR. */
|
||||
status = tx_thread_preemption_change(&thread_0, 1, &old_value);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt to change priority from an ISR. */
|
||||
status = tx_thread_priority_change(&thread_0, 1, &old_value);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt a thread reset from an ISR. */
|
||||
status = tx_thread_reset(&thread_0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt a thread terminate from an ISR. */
|
||||
status = tx_thread_terminate(&thread_0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
/* Attempt a thread time slice change from an ISR. */
|
||||
status = tx_thread_time_slice_change(&thread_0, 1, &old_time_slice);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
|
||||
isr_executed = 1;
|
||||
#endif
|
||||
|
||||
/* Test thread sleep call from ISR. */
|
||||
status = tx_thread_sleep(11);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_CALLER_ERROR)
|
||||
{
|
||||
|
||||
/* Error! */
|
||||
error++;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void test_thread_entry(ULONG thread_input)
|
||||
{
|
||||
/* Do nothing here! */
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_thread_basic_execution_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
INT status;
|
||||
CHAR *pointer;
|
||||
TX_THREAD fake_thread;
|
||||
|
||||
|
||||
/* Setup a pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Adjust it forward just to make sure there is some space for the test below. */
|
||||
pointer = pointer + 200;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Basic Execution Test................................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Now setup a fake thread to generate the other NULL pointer test in the cleanup routines. */
|
||||
fake_thread.tx_thread_suspend_control_block = TX_NULL;
|
||||
_tx_semaphore_cleanup(&fake_thread, 0);
|
||||
_tx_queue_cleanup(&fake_thread, 0);
|
||||
_tx_mutex_cleanup(&fake_thread, 0);
|
||||
_tx_event_flags_cleanup(&fake_thread, 0);
|
||||
_tx_byte_pool_cleanup(&fake_thread, 0);
|
||||
_tx_block_pool_cleanup(&fake_thread, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
UINT old_value;
|
||||
ULONG old_time_slice;
|
||||
#endif
|
||||
|
||||
VOID (*temp_mutex_release)(TX_THREAD *thread_ptr);
|
||||
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Inform user of success getting to this test. */
|
||||
printf("Running Thread Basic Execution Test................................. ");
|
||||
|
||||
/* Setup test thread to make sure _tx_thread_wait_abort can handle a NULL cleanup. */
|
||||
test_thread.tx_thread_state = TX_IO_DRIVER;
|
||||
test_thread.tx_thread_suspend_cleanup = TX_NULL;
|
||||
test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
|
||||
test_thread.tx_thread_suspending = TX_TRUE;
|
||||
test_thread.tx_thread_delayed_suspend = TX_TRUE;
|
||||
if(_tx_thread_wait_abort(&test_thread) != TX_WAIT_ABORT_ERROR)
|
||||
{
|
||||
printf("ERROR #XX\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Setup test thread to make sure _tx_thread_timeout can handle a NULL cleanup. */
|
||||
test_thread.tx_thread_state = TX_IO_DRIVER;
|
||||
test_thread.tx_thread_suspend_cleanup = TX_NULL;
|
||||
test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
|
||||
test_thread.tx_thread_suspending = TX_TRUE;
|
||||
test_thread.tx_thread_delayed_suspend = TX_TRUE;
|
||||
_tx_thread_timeout((ULONG) &test_thread);
|
||||
|
||||
/* Setup test thread to make sure _tx_thread_terminate can handle a NULL mutex release function pointer. */
|
||||
temp_mutex_release = _tx_thread_mutex_release;
|
||||
_tx_thread_mutex_release = TX_NULL;
|
||||
test_thread.tx_thread_state = TX_TERMINATED;
|
||||
test_thread.tx_thread_suspend_cleanup = TX_NULL;
|
||||
test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
|
||||
test_thread.tx_thread_suspending = TX_TRUE;
|
||||
test_thread.tx_thread_timer.tx_timer_internal_list_head = TX_NULL;
|
||||
test_thread.tx_thread_delayed_suspend = TX_TRUE;
|
||||
status = _tx_thread_terminate(&test_thread);
|
||||
_tx_thread_mutex_release = temp_mutex_release; /* Recover Mutex release pointer. */
|
||||
|
||||
/* Perform thread memory test. */
|
||||
thread_memory.first = 0x11223344;
|
||||
thread_memory.second = 0x55667788;
|
||||
thread_memory.first_middle = 0x21314151;
|
||||
thread_memory.second_middle= 0x61718191;
|
||||
thread_memory.next_to_last = 0x99aabbcc;
|
||||
thread_memory.last = 0xddeeff00;
|
||||
|
||||
/* Create the thread. */
|
||||
status += tx_thread_create(&thread_memory.thread_block, "thread memory", thread_0_entry, 1,
|
||||
&thread_memory.stack[0], (2048*sizeof(ULONG))/sizeof(ULONG),
|
||||
16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
tx_thread_delete(&thread_memory.thread_block);
|
||||
|
||||
/* Check for status. */
|
||||
if ((status != TX_SUCCESS) ||
|
||||
(thread_memory.first != 0x11223344) ||
|
||||
(thread_memory.second != 0x55667788) ||
|
||||
(thread_memory.first_middle != 0x21314151) ||
|
||||
(thread_memory.second_middle != 0x61718191) ||
|
||||
(thread_memory.next_to_last != 0x99aabbcc) ||
|
||||
(thread_memory.last != 0xddeeff00))
|
||||
{
|
||||
|
||||
/* Memory overwrite error. */
|
||||
printf("ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef TX_DISABLE_ERROR_CHECKING
|
||||
|
||||
/* Attempt to create a thread with a null pointer. */
|
||||
pointer = (CHAR *) not_used_stack;
|
||||
status = tx_thread_create(TX_NULL, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a thread with a bad control block size. */
|
||||
pointer = (CHAR *) not_used_stack;
|
||||
status = _txe_thread_create(&thread_3, "thread 3", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START, (sizeof(TX_THREAD)+1));
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a thread with a NULL entry function. */
|
||||
pointer = (CHAR *) not_used_stack;
|
||||
status = tx_thread_create(&thread_3, "thread 3", TX_NULL, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a thread that has already been created. */
|
||||
pointer = (CHAR *) not_used_stack;
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a thread with an overlapping stack. */
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
|
||||
thread_0.tx_thread_stack_ptr, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a thread with another variation of an overlapping stack. */
|
||||
pointer = thread_0.tx_thread_stack_start;
|
||||
pointer = pointer - 20;
|
||||
status = tx_thread_create(&thread_1, "thread 1", TX_NULL, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a thread an extra small stack. */
|
||||
pointer = (CHAR *) not_used_stack;
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
|
||||
pointer, 1,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SIZE_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a thread with an invalid thread priority. */
|
||||
pointer = (CHAR *) not_used_stack;
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
5000, 5000, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_PRIORITY_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a thread with an invalid preemption-threshold. */
|
||||
pointer = (CHAR *) not_used_stack;
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 17, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THRESH_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to create a thread with an invalid auto start. */
|
||||
pointer = (CHAR *) not_used_stack;
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, 3456);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_START_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to delete a non-thread. */
|
||||
status = tx_thread_delete(TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to delete a non-created thread. */
|
||||
thread_2.tx_thread_id = 0;
|
||||
status = tx_thread_delete(&thread_2);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to register a entry/exit callback on a non-thread. */
|
||||
status = tx_thread_entry_exit_notify(TX_NULL, TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to register a entry/exit callback on a non-created thread. */
|
||||
thread_2.tx_thread_id = 0;
|
||||
status = tx_thread_entry_exit_notify(&thread_2, TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get info on a non-thread. */
|
||||
status = tx_thread_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to get info on a non-created thread. */
|
||||
thread_2.tx_thread_id = 0;
|
||||
status = tx_thread_info_get(&thread_2, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to change preemption of a non-thread. */
|
||||
status = tx_thread_preemption_change(TX_NULL, 1, TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to change preemption of a non-created thread. */
|
||||
thread_2.tx_thread_id = 0;
|
||||
status = tx_thread_preemption_change(&thread_2, 1, TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to change preemption with a NULL return value. */
|
||||
status = tx_thread_preemption_change(&thread_0, 1, TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to change preemption with a bad threshold value. */
|
||||
status = tx_thread_preemption_change(&thread_0, 17, &old_value);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THRESH_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Attempt to change priority of a non-thread. */
|
||||
status = tx_thread_priority_change(TX_NULL, 1, TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to change priority of a non-created thread. */
|
||||
thread_2.tx_thread_id = 0;
|
||||
status = tx_thread_priority_change(&thread_2, 1, TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to change priority with a NULL return value. */
|
||||
status = tx_thread_priority_change(&thread_0, 1, TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to change priority with a bad priority value. */
|
||||
status = tx_thread_priority_change(&thread_0, 2046, &old_value);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_PRIORITY_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #26\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread reset for a non-thread. */
|
||||
status = tx_thread_reset(TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #27\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread reset from same thread. */
|
||||
status = tx_thread_reset(&thread_0);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_NOT_DONE)
|
||||
{
|
||||
|
||||
printf("ERROR #28\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread reset for a non-created thread. */
|
||||
thread_2.tx_thread_id = 0;
|
||||
status = tx_thread_reset(&thread_2);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #29\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread resume with a NULL pointer. */
|
||||
status = tx_thread_resume(TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #30\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread resume on a non-created thread. */
|
||||
thread_2.tx_thread_id = 0;
|
||||
status = tx_thread_resume(&thread_2);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #31\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread suspend with a NULL pointer. */
|
||||
status = tx_thread_suspend(TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #32\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread suspend on a non-created thread. */
|
||||
thread_2.tx_thread_id = 0;
|
||||
status = tx_thread_suspend(&thread_2);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #33\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread termiante with a NULL pointer. */
|
||||
status = tx_thread_terminate(TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #34\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread terminate on a non-created thread. */
|
||||
thread_2.tx_thread_id = 0;
|
||||
status = tx_thread_terminate(&thread_2);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #35\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread time-slice chagne with a NULL pointer. */
|
||||
status = tx_thread_time_slice_change(TX_NULL, 1, &old_time_slice);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #36\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread time-slice change on a non-created thread. */
|
||||
thread_2.tx_thread_id = 0;
|
||||
status = tx_thread_time_slice_change(&thread_2, 1, &old_time_slice);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #37\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread time-slice change with a null return pointer. */
|
||||
status = tx_thread_time_slice_change(&thread_0, 1, TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #38\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread wait abort with a NULL pointer. */
|
||||
status = tx_thread_wait_abort(TX_NULL);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #39\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt a thread wait abort on a non-created thread. */
|
||||
thread_2.tx_thread_id = 0;
|
||||
status = tx_thread_wait_abort(&thread_2);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_THREAD_ERROR)
|
||||
{
|
||||
|
||||
printf("ERROR #40\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a timer for the test. */
|
||||
tx_timer_create(&timer_0, "timer 0", timer_entry, 0, 1, 1, TX_AUTO_ACTIVATE);
|
||||
|
||||
/* Setup the ISR. */
|
||||
test_isr_dispatch = test_isr;
|
||||
|
||||
/* Sleep for a bit... */
|
||||
tx_thread_sleep(3);
|
||||
|
||||
/* Clear the ISR. */
|
||||
test_isr_dispatch = TX_NULL;
|
||||
|
||||
/* Test for error. */
|
||||
if ((error) || (timer_executed != 1) || (isr_executed != 1))
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #41\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Check status. */
|
||||
if (error)
|
||||
{
|
||||
|
||||
/* Block memory error. */
|
||||
printf("ERROR #42\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
}
|
117
test/smp/regression/threadx_thread_basic_time_slice_test.c
Normal file
117
test/smp/regression/threadx_thread_basic_time_slice_test.c
Normal file
@ -0,0 +1,117 @@
|
||||
/* This test is designed to see if a thread can be created with a time-slice.
|
||||
No time-slice occurs, only the processing to check for time-slicing. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_thread_basic_time_slice_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UCHAR *memory;
|
||||
|
||||
|
||||
memory = (UCHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
memory, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 1, TX_AUTO_START);
|
||||
memory = memory + TEST_STACK_SIZE_PRINTF;
|
||||
status += tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
memory, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 1, TX_DONT_START);
|
||||
status += tx_thread_smp_core_exclude(&thread_1, 0xF);
|
||||
status += tx_thread_resume(&thread_1);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Basic Time-Slice Test................................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG target_time;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Thread Basic Time-Slice Test................................ ");
|
||||
|
||||
/* Calculate the target running time. */
|
||||
target_time = tx_time_get() + 20;
|
||||
|
||||
/* Enter into a forever loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Determine if we are done. */
|
||||
if (tx_time_get() >= target_time)
|
||||
{
|
||||
|
||||
/* Determine if thread 1 executed. */
|
||||
if (thread_1_counter != 0)
|
||||
{
|
||||
|
||||
/* Error, thread 1 has all cores excluded so it should never run. */
|
||||
printf("ERROR #2\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful Time-slice test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
/* Loop forever. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
}
|
258
test/smp/regression/threadx_thread_completed_test.c
Normal file
258
test/smp/regression/threadx_thread_completed_test.c
Normal file
@ -0,0 +1,258 @@
|
||||
/* This test is designed to see if one thread can be created, executed, and
|
||||
return to the thread shell function. The thread shell function places
|
||||
the thread in a finished state. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static unsigned long thread_0_enter = 0;
|
||||
static unsigned long thread_0_exit = 0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
static TX_THREAD thread_2;
|
||||
static TX_THREAD *saved_ptr;
|
||||
static ULONG saved_count;
|
||||
|
||||
/* Define task prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
static void entry_exit_notify(TX_THREAD *thread_ptr, UINT type)
|
||||
{
|
||||
|
||||
/* Check for the appropriate thread. */
|
||||
if (thread_ptr != &thread_0)
|
||||
return;
|
||||
|
||||
/* Check for type. */
|
||||
if (type == TX_THREAD_ENTRY)
|
||||
thread_0_enter++;
|
||||
else if (type == TX_THREAD_EXIT)
|
||||
thread_0_exit++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_thread_completed_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Setup the notify call to test that logic. */
|
||||
status += tx_thread_entry_exit_notify(&thread_0, entry_exit_notify);
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Completed Test....................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
printf("Running Thread Completed Test....................................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 17, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Completed Test....................................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
18, 18, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Completed Test....................................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Move the created pointer to thread 1 to test the delete path fully. */
|
||||
saved_ptr = _tx_thread_created_ptr;
|
||||
_tx_thread_created_ptr = &thread_0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test thread. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Fall through to the return in order to place the thread in a finished
|
||||
state. */
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Thread Completed Test....................................... ");
|
||||
|
||||
/* Increment thread 1 counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Attempt to delete thread 2, which is in the wrong stat for deleting. */
|
||||
status = tx_thread_delete(&thread_2);
|
||||
|
||||
/* Check for the proper status. */
|
||||
if (status != TX_DELETE_ERROR)
|
||||
{
|
||||
|
||||
/* Thread delete error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to suspend thread 0, which is in a completed state. */
|
||||
status = tx_thread_suspend(&thread_0);
|
||||
|
||||
/* Check for the correct status. */
|
||||
if (status != TX_SUSPEND_ERROR)
|
||||
{
|
||||
|
||||
/* Thread suspend error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Attempt to delete thread 0. */
|
||||
status = tx_thread_delete(&thread_0);
|
||||
|
||||
/* Check for the proper status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Thread delete error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Sleep to let thread 2 run. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Save the created count. */
|
||||
saved_count = _tx_thread_created_count;
|
||||
|
||||
/* Now setup things so we can fake a delete of one thread. */
|
||||
_tx_thread_created_ptr = &thread_2;
|
||||
thread_2.tx_thread_created_next = &thread_2;
|
||||
thread_2.tx_thread_created_previous = &thread_2;
|
||||
_tx_thread_created_count = 1;
|
||||
|
||||
/* Attempt to delete thread 2. */
|
||||
status = tx_thread_delete(&thread_2);
|
||||
|
||||
/* Check for the proper status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Thread delete error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* if still okay, restore the saved thread pointer. */
|
||||
if (saved_ptr -> tx_thread_id == TX_THREAD_ID)
|
||||
{
|
||||
/* Restore. */
|
||||
_tx_thread_created_ptr = saved_ptr;
|
||||
|
||||
/* Setup the link pointers again. */
|
||||
saved_ptr -> tx_thread_created_previous = &thread_1;
|
||||
thread_1.tx_thread_created_next = saved_ptr;
|
||||
|
||||
/* Setup the created count. */
|
||||
_tx_thread_created_count = saved_count - 1;
|
||||
}
|
||||
|
||||
/* Determine if the first Thread has run and if it's current state is
|
||||
finished. */
|
||||
if ((thread_0.tx_thread_state == TX_COMPLETED) && (thread_0_counter == 1) &&
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
(thread_0_enter == 1) && (thread_0_exit == 1))
|
||||
#else
|
||||
(thread_0_enter == 0) && (thread_0_exit == 0))
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Successful thread finish test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Thread Finish error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
/* Fall through to the return in order to place the thread in a finished
|
||||
state. */
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
/* This test is designed to test for preemption-threshold use during thread creation during initialization. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
//static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_thread_create_preemption_threshold_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
17, 0, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Create Preemption-Threshold from Init Test........... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 0, 100, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Create Preemption-Threshold from Init Test........... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 0, 100, TX_DONT_START);
|
||||
status += tx_thread_resume(&thread_0);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Create Preemption-Threshold from Init Test........... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Thread Create Preemption-Threshold from Init Test........... ");
|
||||
|
||||
/* If either of the other threads have run, an error is present. */
|
||||
if ((thread_1_counter) || (thread_2_counter))
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Sleep for two ticks (one is insufficient to guarantee the other
|
||||
tasks will run, if this executes too close to the tick interrupt. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
|
||||
/* Now, both threads should have run. */
|
||||
if ((thread_1_counter != 1) || (thread_2_counter != 1))
|
||||
{
|
||||
|
||||
/* Test error! */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(2);
|
||||
}
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_1_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
|
390
test/smp/regression/threadx_thread_delayed_suspension_test.c
Normal file
390
test/smp/regression/threadx_thread_delayed_suspension_test.c
Normal file
@ -0,0 +1,390 @@
|
||||
/* This test checks out the delayed suspension clear from tx_thread_resume. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h"
|
||||
|
||||
|
||||
#define DEMO_STACK_SIZE TEST_STACK_SIZE_PRINTF
|
||||
|
||||
|
||||
/* Define the ThreadX object control blocks... */
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
static TX_THREAD thread_1;
|
||||
static TX_SEMAPHORE semaphore_0;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
#if defined(TX_WIN32_MEMORY_SIZE) || defined(TX_LINUX_MEMORY_SIZE)
|
||||
/* Use larger array size when running on Win32 test platform because of greater speed. */
|
||||
#define ARRAY_SIZE 100
|
||||
#else
|
||||
#define ARRAY_SIZE 10
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
|
||||
static UINT delayed_suspend_set;
|
||||
|
||||
static ULONG thread_2_counter;
|
||||
static ULONG thread_2_counter_capture;
|
||||
|
||||
static ULONG min_loop_count;
|
||||
static ULONG max_loop_count;
|
||||
static ULONG loop_count;
|
||||
static volatile ULONG count;
|
||||
static volatile ULONG destination = 0;
|
||||
static ULONG start_time;
|
||||
static ULONG lower_bound;
|
||||
static ULONG upper_bound;
|
||||
static ULONG current_itterations;
|
||||
#ifdef DEBUG_1
|
||||
static ULONG last_loop_count;
|
||||
#endif
|
||||
static TX_THREAD thread_2;
|
||||
static TX_SEMAPHORE semaphore_1;
|
||||
|
||||
static ULONG array_delay[ARRAY_SIZE];
|
||||
|
||||
static ULONG delay_function(void)
|
||||
{
|
||||
|
||||
ULONG accumulator;
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE; i++)
|
||||
array_delay[i] = i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE-4; i++)
|
||||
{
|
||||
array_delay[i] = (array_delay[i+1] * array_delay[i+2]) * (array_delay[i+3] * array_delay[i+4]);
|
||||
}
|
||||
|
||||
accumulator = 0;
|
||||
for (i = 0; i < ARRAY_SIZE; i++)
|
||||
accumulator = accumulator + array_delay[i];
|
||||
|
||||
return(accumulator);
|
||||
}
|
||||
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
/* Determine if we are in calibration mode. */
|
||||
if (loop_count != 0xFFFFFFFF)
|
||||
{
|
||||
if (loop_count < min_loop_count)
|
||||
min_loop_count = loop_count;
|
||||
if (loop_count > max_loop_count)
|
||||
max_loop_count = loop_count;
|
||||
|
||||
lower_bound = loop_count - 1;
|
||||
upper_bound = loop_count + 1;
|
||||
if (lower_bound < min_loop_count)
|
||||
lower_bound = min_loop_count;
|
||||
if (upper_bound > max_loop_count)
|
||||
lower_bound = max_loop_count;
|
||||
|
||||
if ((current_itterations < lower_bound) || (current_itterations > upper_bound))
|
||||
current_itterations = lower_bound;
|
||||
|
||||
#ifdef DEBUG_1
|
||||
/* Last loop count. */
|
||||
last_loop_count = loop_count;
|
||||
#endif
|
||||
|
||||
/* Reset the loop count to all ones! */
|
||||
loop_count = 0xFFFFFFFF;
|
||||
}
|
||||
count++;
|
||||
for (i = 0; i < (count%32); i++)
|
||||
destination++;
|
||||
|
||||
/* Check to see if the interrupt occurred in the middle of the suspension. */
|
||||
if ((thread_2.tx_thread_suspending) && (delayed_suspend_set == 0))
|
||||
{
|
||||
|
||||
/* Yes, we have taken the interrupt in the middle of a thread suspension. */
|
||||
|
||||
/* Indicate we have got the condition. */
|
||||
delayed_suspend_set = 1;
|
||||
|
||||
/* Capture the current thread 2 counter. */
|
||||
thread_2_counter_capture = thread_2_counter;
|
||||
|
||||
/* Now attempt to set the delayed suspension. */
|
||||
tx_thread_suspend(&thread_2);
|
||||
|
||||
/* Check for the delayed suspension flag being set. */
|
||||
if (thread_2.tx_thread_delayed_suspend != 1)
|
||||
{
|
||||
|
||||
/* Error! Setup the counters to indicate an error. */
|
||||
thread_2_counter = 0xEEEEEEEE;
|
||||
thread_2_counter_capture = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/* Now, abort the suspension for thread 2... the thread should switch to a pure suspended state. */
|
||||
tx_thread_wait_abort(&thread_2);
|
||||
|
||||
/* Check for the proper state. */
|
||||
if (thread_2.tx_thread_state != TX_SUSPENDED)
|
||||
{
|
||||
|
||||
/* Error! Setup the counters to indicate an error. */
|
||||
thread_2_counter = 0xEEEEEEEE;
|
||||
thread_2_counter_capture = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_thread_delayed_suspension_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
CHAR *pointer;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
/* Create the main thread. */
|
||||
tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
pointer = pointer + DEMO_STACK_SIZE;
|
||||
|
||||
/* Create threads 1 and 2. */
|
||||
tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
pointer = pointer + DEMO_STACK_SIZE;
|
||||
|
||||
/* Create the semaphore. */
|
||||
tx_semaphore_create(&semaphore_0, "semaphore 0", 0);
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + DEMO_STACK_SIZE;
|
||||
|
||||
tx_semaphore_create(&semaphore_1, "semaphore 1", 0);
|
||||
|
||||
thread_2_counter = 0;
|
||||
thread_2_counter_capture = 0;
|
||||
min_loop_count = 0xFFFFFFFF;
|
||||
max_loop_count = 0;
|
||||
loop_count = 0xFFFFFFFF;
|
||||
#ifdef DEBUG_1
|
||||
last_loop_count = 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Thread Delayed Suspension Clearing Test..................... ");
|
||||
|
||||
/* Relinquish to the other thread. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* At this point thread 1 has suspended on the semaphore. */
|
||||
|
||||
/* Suspend the already suspended thread. */
|
||||
tx_thread_suspend(&thread_1);
|
||||
|
||||
/* Set the semaphore, which should make it go into a suspend state. */
|
||||
tx_semaphore_put(&semaphore_0);
|
||||
|
||||
/* Resume the other thread so it runs again. */
|
||||
tx_thread_resume(&thread_1);
|
||||
|
||||
/* Relinquish so it can run again. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Suspend the already suspended thread. */
|
||||
tx_thread_suspend(&thread_1);
|
||||
|
||||
/* Now, clear the delayed suspension. */
|
||||
status = tx_thread_resume(&thread_1);
|
||||
|
||||
if (status != TX_SUSPEND_LIFTED)
|
||||
{
|
||||
|
||||
/* Delayed suspension error. */
|
||||
printf("ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Setup the test ISR. */
|
||||
test_isr_dispatch = test_isr;
|
||||
|
||||
/* Resume the test thread. */
|
||||
tx_thread_resume(&thread_2);
|
||||
|
||||
/* Wait until we see the delayed suspension set flag. */
|
||||
while(delayed_suspend_set == 0)
|
||||
{
|
||||
|
||||
/* Abort the suspension for thread 2. */
|
||||
tx_thread_wait_abort(&thread_2);
|
||||
|
||||
/* Just relinquish. */
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
|
||||
/* Relinquish one more time to make sure thread 2 could run if it is ready. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* At this point, check for an error. */
|
||||
if (thread_2_counter != thread_2_counter_capture)
|
||||
{
|
||||
|
||||
/* Delayed suspension error... thread kept running! */
|
||||
printf("ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* This thread simply gets the semaphore... */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Get semaphore. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check completion status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG i;
|
||||
|
||||
/* Callibrate the loop count from thread sleep. */
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
|
||||
/* Sleep to get a fresh time. */
|
||||
tx_thread_sleep(1);
|
||||
|
||||
start_time = _tx_timer_system_clock;
|
||||
do
|
||||
{
|
||||
|
||||
/* Call delay function. */
|
||||
delay_function();
|
||||
loop_count++;
|
||||
} while (start_time == _tx_timer_system_clock);
|
||||
|
||||
/* Wait to reset the loop count. */
|
||||
tx_thread_sleep(1);
|
||||
}
|
||||
|
||||
/* Setup the lower and upper bounds. */
|
||||
lower_bound = min_loop_count;
|
||||
if (lower_bound > 5)
|
||||
lower_bound = lower_bound - 5;
|
||||
upper_bound = max_loop_count + 5;
|
||||
|
||||
current_itterations = lower_bound;
|
||||
|
||||
/* This thread simply suspends over and over... */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Sleep to get a fresh starting time. */
|
||||
tx_thread_sleep(1);
|
||||
|
||||
loop_count = 0;
|
||||
start_time = _tx_timer_system_clock;
|
||||
do
|
||||
{
|
||||
/* Call delay function. */
|
||||
delay_function();
|
||||
loop_count++;
|
||||
} while (loop_count < current_itterations);
|
||||
|
||||
/* Suspend this thread. */
|
||||
tx_semaphore_get(&semaphore_1, TX_WAIT_FOREVER);
|
||||
|
||||
/* Adjust the current itterations. */
|
||||
current_itterations++;
|
||||
if (current_itterations > upper_bound)
|
||||
{
|
||||
if (lower_bound > min_loop_count)
|
||||
lower_bound--;
|
||||
if (upper_bound < max_loop_count)
|
||||
upper_bound++;
|
||||
current_itterations = lower_bound;
|
||||
}
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
474
test/smp/regression/threadx_thread_information_test.c
Normal file
474
test/smp/regression/threadx_thread_information_test.c
Normal file
@ -0,0 +1,474 @@
|
||||
/* This test is for the thread information services. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
/* Define task prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG task_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_thread_information_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
INT status;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
first_unused_memory, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Information Test..................................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *name;
|
||||
UINT state;
|
||||
ULONG run_count;
|
||||
UINT priority;
|
||||
UINT preemption_threshold;
|
||||
ULONG time_slice;
|
||||
TX_THREAD *next_thread;
|
||||
TX_THREAD *suspended_thread;
|
||||
ULONG resumptions;
|
||||
ULONG suspensions;
|
||||
ULONG solicited_preemptions;
|
||||
ULONG interrupt_preemptions;
|
||||
ULONG priority_inversions;
|
||||
ULONG time_slices;
|
||||
ULONG relinquishes;
|
||||
ULONG timeouts;
|
||||
ULONG wait_aborts;
|
||||
TX_THREAD *last_preempted_by;
|
||||
ULONG non_idle_returns;
|
||||
ULONG idle_returns;
|
||||
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Inform user of success getting to this test. */
|
||||
printf("Running Thread Information Test..................................... ");
|
||||
|
||||
/* Get information about this thread. */
|
||||
status = tx_thread_info_get(&thread_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
status += tx_thread_info_get(&thread_0, &name, &state, &run_count, &priority, &preemption_threshold, &time_slice, &next_thread, &suspended_thread);
|
||||
|
||||
/* Check for error status. */
|
||||
if ((status != TX_SUCCESS) || (state != TX_READY) || (run_count != thread_0.tx_thread_run_count) || (priority != 16) || (preemption_threshold != 16) ||
|
||||
(time_slice != 0) || (next_thread != thread_0.tx_thread_created_next) || (suspended_thread != thread_0.tx_thread_suspended_next))
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef TX_THREAD_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Get the performance information about a NULL thread pointer. */
|
||||
status = _tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_PTR_ERROR)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the performance information about this thread. */
|
||||
status = tx_thread_performance_info_get(&thread_0, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
status += tx_thread_performance_info_get(&thread_0, &resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
|
||||
|
||||
/* Check for error. */
|
||||
if ((status != TX_SUCCESS) || (resumptions != thread_0.tx_thread_performance_resume_count) || (suspensions != thread_0.tx_thread_performance_suspend_count) ||
|
||||
(solicited_preemptions != thread_0.tx_thread_performance_solicited_preemption_count) || (interrupt_preemptions != thread_0.tx_thread_performance_interrupt_preemption_count) ||
|
||||
(priority_inversions != thread_0.tx_thread_performance_priority_inversion_count) || (time_slices != thread_0.tx_thread_performance_time_slice_count) ||
|
||||
(relinquishes != thread_0.tx_thread_performance_relinquish_count) || (timeouts != thread_0.tx_thread_performance_timeout_count) || (wait_aborts != thread_0.tx_thread_performance_wait_abort_count) ||
|
||||
(last_preempted_by != thread_0.tx_thread_performance_last_preempting_thread))
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the system performance information. */
|
||||
status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
status += tx_thread_performance_system_info_get(&resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
|
||||
|
||||
/* Check for error. */
|
||||
if ((status != TX_SUCCESS) || (resumptions != _tx_thread_performance_resume_count) || (suspensions != _tx_thread_performance_suspend_count) ||
|
||||
(solicited_preemptions != _tx_thread_performance_solicited_preemption_count) || (interrupt_preemptions != _tx_thread_performance_interrupt_preemption_count) ||
|
||||
(priority_inversions != _tx_thread_performance_priority_inversion_count) || (time_slices != _tx_thread_performance_time_slice_count) ||
|
||||
(relinquishes != _tx_thread_performance_relinquish_count) || (timeouts != _tx_thread_performance_timeout_count) || (wait_aborts != _tx_thread_performance_wait_abort_count) ||
|
||||
(non_idle_returns != _tx_thread_performance_non_idle_return_count) || (idle_returns != _tx_thread_performance_idle_return_count))
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Success! */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
#else
|
||||
|
||||
/* Get the performance information about this thread. */
|
||||
status = tx_thread_performance_info_get(&thread_0, &resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the performance information about this thread. */
|
||||
status = tx_thread_performance_info_get(TX_NULL, &resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the performance information about this thread. */
|
||||
status = tx_thread_performance_info_get(TX_NULL, TX_NULL, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the performance information about this thread. */
|
||||
status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the performance information about this thread. */
|
||||
status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &interrupt_preemptions, &priority_inversions, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the performance information about this thread. */
|
||||
status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &priority_inversions, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the performance information about this thread. */
|
||||
status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the performance information about this thread. */
|
||||
status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
|
||||
&relinquishes, &timeouts, &wait_aborts, &last_preempted_by);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the performance information about this thread. */
|
||||
status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
|
||||
TX_NULL, &timeouts, &wait_aborts, &last_preempted_by);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the performance information about this thread. */
|
||||
status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
|
||||
TX_NULL, TX_NULL, &wait_aborts, &last_preempted_by);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the performance information about this thread. */
|
||||
status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
|
||||
TX_NULL, TX_NULL, TX_NULL, &last_preempted_by);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the performance information about this thread. */
|
||||
status = tx_thread_performance_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
|
||||
TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the system performance information. */
|
||||
status = tx_thread_performance_system_info_get(&resumptions, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the system performance information. */
|
||||
status = tx_thread_performance_system_info_get(TX_NULL, &suspensions, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the system performance information. */
|
||||
status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, &solicited_preemptions, &interrupt_preemptions, &priority_inversions, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the system performance information. */
|
||||
status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, &interrupt_preemptions, &priority_inversions, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the system performance information. */
|
||||
status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, &priority_inversions, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the system performance information. */
|
||||
status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, &time_slices,
|
||||
&relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the system performance information. */
|
||||
status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
|
||||
&relinquishes, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the system performance information. */
|
||||
status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
|
||||
TX_NULL, &timeouts, &wait_aborts, &non_idle_returns, &idle_returns);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the system performance information. */
|
||||
status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
|
||||
TX_NULL, TX_NULL, &wait_aborts, &non_idle_returns, &idle_returns);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #26\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the system performance information. */
|
||||
status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
|
||||
TX_NULL, TX_NULL, TX_NULL, &non_idle_returns, &idle_returns);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #27\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the system performance information. */
|
||||
status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
|
||||
TX_NULL, TX_NULL, TX_NULL, TX_NULL, &idle_returns);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #28\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the system performance information. */
|
||||
status = tx_thread_performance_system_info_get(TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL,
|
||||
TX_NULL, TX_NULL, TX_NULL, TX_NULL, TX_NULL);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_FEATURE_NOT_ENABLED)
|
||||
{
|
||||
|
||||
/* Thread error. */
|
||||
printf("ERROR #29\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Success! */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
@ -0,0 +1,982 @@
|
||||
/* This test is designed to test multi-level preemption threshold. The protection placed
|
||||
by a thread must be preserved after higher-priority thread preemption that is above the threshold. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
|
||||
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static TX_THREAD thread_2;
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_2a_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
static unsigned long thread_1_counter = 0;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
|
||||
static unsigned long thread_2a_counter = 0;
|
||||
static TX_THREAD thread_2a;
|
||||
|
||||
static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
static unsigned long thread_4_counter = 0;
|
||||
static TX_THREAD thread_4;
|
||||
|
||||
#endif
|
||||
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
|
||||
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
|
||||
/* Define new preemption-threshold threads for complete bit map checking. */
|
||||
|
||||
static TX_THREAD thread_1_0;
|
||||
static TX_THREAD thread_2_1;
|
||||
static TX_THREAD thread_3_2;
|
||||
static TX_THREAD thread_4_3;
|
||||
static TX_THREAD thread_6_5;
|
||||
static TX_THREAD thread_8_7;
|
||||
static TX_THREAD thread_10_9;
|
||||
static TX_THREAD thread_12_11;
|
||||
static TX_THREAD thread_14_13;
|
||||
static TX_THREAD thread_16_15;
|
||||
static TX_THREAD thread_18_17;
|
||||
static TX_THREAD thread_20_19;
|
||||
static TX_THREAD thread_22_21;
|
||||
static TX_THREAD thread_24_23;
|
||||
static TX_THREAD thread_26_25;
|
||||
static TX_THREAD thread_28_27;
|
||||
static TX_THREAD thread_30_29;
|
||||
|
||||
|
||||
/* Define timer for preemption of priority 1 test. */
|
||||
|
||||
static TX_TIMER timer_0;
|
||||
|
||||
|
||||
/* Define counters. */
|
||||
|
||||
static unsigned long timer_0_counter = 0;
|
||||
static unsigned long thread_1_0_counter = 0;
|
||||
static unsigned long thread_2_1_counter = 0;
|
||||
static unsigned long thread_3_2_counter = 0;
|
||||
static unsigned long thread_4_3_counter = 0;
|
||||
static unsigned long thread_6_5_counter = 0;
|
||||
static unsigned long thread_8_7_counter = 0;
|
||||
static unsigned long thread_10_9_counter = 0;
|
||||
static unsigned long thread_12_11_counter = 0;
|
||||
static unsigned long thread_14_13_counter = 0;
|
||||
static unsigned long thread_16_15_counter = 0;
|
||||
static unsigned long thread_18_17_counter = 0;
|
||||
static unsigned long thread_20_19_counter = 0;
|
||||
static unsigned long thread_22_21_counter = 0;
|
||||
static unsigned long thread_24_23_counter = 0;
|
||||
static unsigned long thread_26_25_counter = 0;
|
||||
static unsigned long thread_28_27_counter = 0;
|
||||
static unsigned long thread_30_29_counter = 0;
|
||||
|
||||
|
||||
/* Define new preemption-threshold test thread entry points. */
|
||||
|
||||
static void thread_1_0_entry(ULONG thread_input);
|
||||
static void thread_2_1_entry(ULONG thread_input);
|
||||
static void thread_3_2_entry(ULONG thread_input);
|
||||
static void thread_4_3_entry(ULONG thread_input);
|
||||
static void thread_6_5_entry(ULONG thread_input);
|
||||
static void thread_8_7_entry(ULONG thread_input);
|
||||
static void thread_10_9_entry(ULONG thread_input);
|
||||
static void thread_12_11_entry(ULONG thread_input);
|
||||
static void thread_14_13_entry(ULONG thread_input);
|
||||
static void thread_16_15_entry(ULONG thread_input);
|
||||
static void thread_18_17_entry(ULONG thread_input);
|
||||
static void thread_20_19_entry(ULONG thread_input);
|
||||
static void thread_22_21_entry(ULONG thread_input);
|
||||
static void thread_24_23_entry(ULONG thread_input);
|
||||
static void thread_26_25_entry(ULONG thread_input);
|
||||
static void thread_28_27_entry(ULONG thread_input);
|
||||
static void thread_30_29_entry(ULONG thread_input);
|
||||
|
||||
/* Define timer 1 entry. */
|
||||
|
||||
static void timer_0_entry(ULONG id);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_thread_multi_level_preemption_threshold_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
(TX_MAX_PRIORITIES-1), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
(TX_MAX_PRIORITIES/2), (TX_MAX_PRIORITIES/2), TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 10, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2a, "thread 2a", thread_2a_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
11, 11, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
9, 9, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create new cascading preemption-threshold test threads. */
|
||||
|
||||
status = tx_thread_create(&thread_30_29, "thread 30-29", thread_30_29_entry, 30,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
30, 29, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_28_27, "thread 28-27", thread_28_27_entry, 28,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
28, 27, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_26_25, "thread 26-25", thread_26_25_entry, 26,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
26, 25, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_24_23, "thread 24-23", thread_24_23_entry, 24,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
24, 23, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_22_21, "thread 22-21", thread_22_21_entry, 22,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
22, 21, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_20_19, "thread 20-19", thread_20_19_entry, 20,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
20,19, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_18_17, "thread 18-17", thread_18_17_entry, 18,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
18, 17, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_16_15, "thread 16-15", thread_16_15_entry, 16,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 15, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_14_13, "thread 14-13", thread_14_13_entry, 14,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
14, 13, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #15\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_12_11, "thread 12-11", thread_12_11_entry, 12,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
12, 11, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #16\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_10_9, "thread 10-9", thread_10_9_entry, 10,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
10, 9, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #17\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_8_7, "thread 8-7", thread_8_7_entry, 8,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
8, 7, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #18\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_6_5, "thread 6-5", thread_6_5_entry, 6,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
6, 5, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #19\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_4_3, "thread 4-3", thread_4_3_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
4, 3, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #20\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3_2, "thread 3-2", thread_3_2_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
3, 2, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #21\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2_1, "thread 2-1", thread_2_1_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
2, 1, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #22\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1_0, "thread 1-0", thread_1_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #23\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_timer_create(&timer_0, "timer 0", timer_0_entry, 0, 1, 0, TX_NO_ACTIVATE);
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ERROR #24\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
UINT status;
|
||||
UINT old_preempt;
|
||||
#endif
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Thread Multi-Level Preemption Threshold Test................ ");
|
||||
|
||||
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD /* skip this test and pretend it passed */
|
||||
|
||||
/* Wakeup Thread 1. It has a higher-priority but should be blocked by
|
||||
preemption threshold. */
|
||||
status = tx_thread_resume(&thread_1);
|
||||
|
||||
/* Check status and make sure the other run counters are proper. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter) || (thread_2_counter) ||
|
||||
(thread_3_counter) || (thread_4_counter))
|
||||
{
|
||||
|
||||
/* Thread Preempt Threshold error. */
|
||||
printf("ERROR #25\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Resume thread 2 which will preempt this thread. */
|
||||
status = tx_thread_resume(&thread_2);
|
||||
|
||||
/* Check for good status and proper run counters. All other threads except for
|
||||
thread 1 should have executed. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter) || (thread_2_counter != 1) ||
|
||||
(thread_3_counter != 1) || (thread_4_counter != 1))
|
||||
{
|
||||
|
||||
/* Thread Preempt Threshold error. */
|
||||
printf("ERROR #26\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set preemption threshold low enough to allow thread 1 to execute. */
|
||||
status = tx_thread_preemption_change(&thread_0, ((TX_MAX_PRIORITIES/2)+1), &old_preempt);
|
||||
|
||||
/* Check for good status and proper run counters. All other threads except for
|
||||
thread 1 should have executed. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 1) || (thread_2_counter != 1) ||
|
||||
(thread_3_counter != 1) || (thread_4_counter != 1) ||
|
||||
(_tx_thread_preempt_disable))
|
||||
{
|
||||
|
||||
/* Thread Preempt Threshold error. */
|
||||
printf("ERROR #27\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Set preemption threshold to keep new test threads from running. */
|
||||
status = tx_thread_preemption_change(&thread_0, 17, &old_preempt);
|
||||
|
||||
/* Now wakup the lowest priority preemption-threshold thread. */
|
||||
status += tx_thread_resume(&thread_30_29);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Thread Preempt Threshold error. */
|
||||
printf("ERROR #28\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now, self suspend. */
|
||||
status = tx_thread_suspend(&thread_0);
|
||||
|
||||
/* Check to make sure all the preemption-threshold threads ran. */
|
||||
if ((thread_1_0_counter != 1) ||
|
||||
(thread_2_1_counter != 1) ||
|
||||
(thread_3_2_counter != 1) ||
|
||||
(thread_4_3_counter != 1) ||
|
||||
(thread_6_5_counter != 1) ||
|
||||
(thread_8_7_counter != 1) ||
|
||||
(thread_10_9_counter != 1) ||
|
||||
(thread_12_11_counter != 1) ||
|
||||
(thread_14_13_counter != 1) ||
|
||||
(thread_16_15_counter != 1) ||
|
||||
(thread_18_17_counter != 1) ||
|
||||
(thread_20_19_counter != 1) ||
|
||||
(thread_22_21_counter != 1) ||
|
||||
(thread_24_23_counter != 1) ||
|
||||
(thread_26_25_counter != 1) ||
|
||||
(thread_28_27_counter != 1) ||
|
||||
(thread_30_29_counter != 1))
|
||||
{
|
||||
|
||||
/* Thread Preempt Threshold error. */
|
||||
printf("ERROR #29\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Successful Thread Suspend non-current thread test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
thread_1_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Resume thread 3 which will not preempt because of thread 2's preemption
|
||||
threshold. */
|
||||
status = tx_thread_resume(&thread_3);
|
||||
|
||||
/* Resume thread 2a which will not preempt this thread because it is at
|
||||
the same priority. */
|
||||
status += tx_thread_resume(&thread_2a);
|
||||
|
||||
/* Check status and run counters. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_3_counter) ||
|
||||
(thread_4_counter))
|
||||
return;
|
||||
|
||||
/* Resume thread 4 which will preempt. We should get back here before thread
|
||||
three runs because of preemption threshold. */
|
||||
status = tx_thread_resume(&thread_4);
|
||||
|
||||
/* Check status and run counters. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_3_counter) ||
|
||||
(thread_4_counter != 1))
|
||||
return;
|
||||
|
||||
/* Relinquish to the other thread at this priority level. This should
|
||||
clear the preemption threshold condition and allow thread 3 to run. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Check status and run counters. */
|
||||
if ((status != TX_SUCCESS) || (thread_1_counter != 0) || (thread_2a_counter != 1) ||
|
||||
(thread_3_counter != 1) || (thread_4_counter != 1))
|
||||
return;
|
||||
|
||||
/* If all is okay, increment thread 2's counter. */
|
||||
thread_2_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_2a_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
if (thread_3_counter == 1)
|
||||
thread_2a_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
thread_3_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
thread_4_counter++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void timer_0_entry(ULONG id)
|
||||
{
|
||||
|
||||
/* Pretend like a preemption occurred on a thread priority of 1 with preemption-threshold set to 0. */
|
||||
_tx_thread_preempted_maps[0] = _tx_thread_preempted_maps[0] | 2;
|
||||
|
||||
/* Set the thread's preemption threshold as well. */
|
||||
thread_1_0.tx_thread_preempt_threshold = 0;
|
||||
|
||||
/* Increment timer 0 counter. */
|
||||
timer_0_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Activate the timer to force a priority 0 thread to interrupt. */
|
||||
status = tx_timer_activate(&timer_0);
|
||||
|
||||
/* Loop to wait until timer 0 runs. */
|
||||
while (timer_0_counter == 0)
|
||||
{
|
||||
}
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_1_0_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_2_1_counter++;
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_1_0);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_3_2_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_4_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_2_1);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_4_3_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_6_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_4_3);
|
||||
|
||||
/* In this particular case, we have two different preemptions to make
|
||||
sure we exercise all the code. */
|
||||
|
||||
/* Now resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_3_2);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_6_5_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_8_7_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_6_5);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_8_7_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_10_9_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_8_7);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_10_9_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_12_11_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_10_9);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_12_11_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_14_13_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_12_11);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_14_13_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_16_15_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_14_13);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_16_15_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_18_17_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_16_15);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_18_17_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_20_19_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_18_17);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_20_19_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_22_21_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_20_19);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_22_21_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_24_23_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_22_21);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_24_23_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_26_25_entry(ULONG thread_input)\
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_24_23);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_26_25_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_28_27_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_26_25);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_28_27_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
static void thread_30_29_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Resume next highest priority thread. */
|
||||
status = tx_thread_resume(&thread_28_27);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status == TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Increment this thread's counter. */
|
||||
thread_30_29_counter++;
|
||||
}
|
||||
|
||||
/* Resume thread_0. */
|
||||
tx_thread_resume(&thread_0);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
222
test/smp/regression/threadx_thread_multiple_non_current_test.c
Normal file
222
test/smp/regression/threadx_thread_multiple_non_current_test.c
Normal file
@ -0,0 +1,222 @@
|
||||
/* This test is designed to see if multiple non-current threads can be suspended.
|
||||
The order the suspension and resumption occurs makes sure everything is working
|
||||
right. Thread execution should remain predictable even after suspension and
|
||||
resumption of threads within a priority group. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
|
||||
static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
static unsigned long thread_4_counter = 0;
|
||||
static TX_THREAD thread_4;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
static void thread_4_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_thread_multiple_non_current_suspension_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Non-Current Suspend Test............................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Non-Current Suspend Test............................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Non-Current Suspend Test............................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 3,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Non-Current Suspend Test............................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_4, "thread 4", thread_4_entry, 4,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, TX_NO_TIME_SLICE, TX_DONT_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Non-Current Suspend Test............................. ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Thread Non-Current Suspend Test............................. ");
|
||||
|
||||
/* Wakeup all other threads at same priority. */
|
||||
status = tx_thread_resume(&thread_1);
|
||||
status += tx_thread_resume(&thread_2);
|
||||
|
||||
/* Check for good status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Thread Suspend error. */
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Wakeup thread with preempt. */
|
||||
status = tx_thread_resume(&thread_3);
|
||||
|
||||
/* Check for good status and proper counters. */
|
||||
if ((status != TX_SUCCESS) || (thread_3_counter != 1) || (thread_1_counter) ||
|
||||
(thread_2_counter) || (thread_4_counter))
|
||||
{
|
||||
|
||||
/* Thread Suspend error. */
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Suspend thread 1. */
|
||||
status = tx_thread_suspend(&thread_1);
|
||||
|
||||
/* Resume thread 4. */
|
||||
status += tx_thread_resume(&thread_4);
|
||||
|
||||
/* Check for good status and proper counters. */
|
||||
if ((status != TX_SUCCESS) || (thread_3_counter != 1) || (thread_1_counter) ||
|
||||
(thread_2_counter) || (thread_4_counter))
|
||||
{
|
||||
|
||||
/* Thread Suspend error. */
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to thread 2 and 4 before we get back. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Check for good status and proper counters. */
|
||||
if ((status != TX_SUCCESS) || (thread_3_counter != 1) || (thread_1_counter) ||
|
||||
(thread_2_counter != 1) || (thread_4_counter != 1))
|
||||
{
|
||||
|
||||
/* Thread Suspend error. */
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Successful Thread Suspend non-current thread test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
thread_1_counter++;
|
||||
}
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
if (thread_4_counter == 0)
|
||||
thread_2_counter++;
|
||||
}
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
thread_3_counter++;
|
||||
}
|
||||
|
||||
static void thread_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
if (thread_2_counter == 1)
|
||||
thread_4_counter++;
|
||||
}
|
||||
|
184
test/smp/regression/threadx_thread_multiple_sleep_test.c
Normal file
184
test/smp/regression/threadx_thread_multiple_sleep_test.c
Normal file
@ -0,0 +1,184 @@
|
||||
/* This test is designed to test multiple threads sleeping for 33 ticks. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
|
||||
static unsigned long thread_0_counter = 0;
|
||||
static TX_THREAD thread_0;
|
||||
static unsigned long thread_1_counter = 0;
|
||||
static TX_THREAD thread_1;
|
||||
static unsigned long thread_2_counter = 0;
|
||||
static TX_THREAD thread_2;
|
||||
//static unsigned long thread_3_counter = 0;
|
||||
static TX_THREAD thread_3;
|
||||
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input);
|
||||
static void thread_1_entry(ULONG thread_input);
|
||||
static void thread_2_entry(ULONG thread_input);
|
||||
static void thread_3_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void threadx_thread_multiple_sleep_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *pointer;
|
||||
|
||||
/* Put first available memory address into a character pointer. */
|
||||
pointer = (CHAR *) first_unused_memory;
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
status = tx_thread_create(&thread_0, "thread 0", thread_0_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 3, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 3, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_2, "thread 2", thread_2_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
16, 16, 3, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = tx_thread_create(&thread_3, "thread 3", thread_3_entry, 1,
|
||||
pointer, TEST_STACK_SIZE_PRINTF,
|
||||
15, 15, 3, TX_AUTO_START);
|
||||
pointer = pointer + TEST_STACK_SIZE_PRINTF;
|
||||
|
||||
/* Check for status. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running Thread Multiple Thread Sleep for 33 Test.................... ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
static void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
|
||||
/* Enter into a forever loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Sleep for a couple ticks. */
|
||||
tx_thread_sleep(33);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
|
||||
/* Enter into a forever loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment thread 1 counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Sleep for a couple ticks. */
|
||||
tx_thread_sleep(33);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
|
||||
/* Enter into a forever loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment thread 0 counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Sleep for a couple ticks. */
|
||||
tx_thread_sleep(33);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void thread_3_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Thread Multiple Thread Sleep for 33 Test.................... ");
|
||||
|
||||
/* Clear the tick count. */
|
||||
tx_time_set(0);
|
||||
|
||||
/* Sleep for 100 ticks (+1 in case tick before threads 0,1,2 have run). */
|
||||
tx_thread_sleep(101);
|
||||
|
||||
/* Determine if the sleep was accurate. */
|
||||
if ((thread_0_counter == 4) && (thread_1_counter == 4) &&
|
||||
(thread_2_counter == 4))
|
||||
{
|
||||
|
||||
/* Successful Multiple Sleep test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Thread Multiple Sleep error. */
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user