1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# Portions of this file were generated with AI assistance.
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
cmake_policy(SET CMP0057 NEW)
project(thread_transition_test LANGUAGES C)
set(REPO_ROOT ${CMAKE_CURRENT_LIST_DIR}/../../../..)
set(SOURCE_DIR ${REPO_ROOT}/test/tx/thread_transition)
# TX_NOT_INTERRUPTABLE and TX_DISABLE_ERROR_CHECKING are not among the five build
# configurations this tree compiles, and the tree builds the whole ThreadX library
# once per configuration, so neither can be reached from inside the regression
# suite. Both matter to the completion and termination transitions:
#
# - TX_NOT_INTERRUPTABLE selects a different transition, in which the exit
# notification callback runs with interrupts disabled and the interruptable
# suspension path -- which is what sets and clears the transition marker in the
# configurations the tree does build -- is not used at all. The marker is set
# and cleared there by stores that exist only in that configuration, and a
# marker left set would make a normally completed thread permanently
# undeletable.
#
# - TX_DISABLE_ERROR_CHECKING removes the _txe_ wrappers, so the public names bind
# straight to the core services. The refusal lives in the core services for that
# reason, and the way to show it is to call the public names in a build with no
# wrappers.
#
# So the four sources that change are compiled directly into a test executable, once
# per combination, with recorders standing behind the scheduler services they call.
# That is the same technique the module manager tests in this tree use, for the same
# reason: the code under test cannot be reached through the library the suite links.
#
# These executables are deliberately left out of the coverage instrumentation. The
# same source compiled under different feature macros has a different line set, and
# merging those into the union the coverage report takes would confuse the figure
# rather than add to it. The coverage figure belongs to the five configurations the
# tree builds, and every line this change adds outside a TX_NOT_INTERRUPTABLE guard
# is in them.
set(transition_kernel_sources
${REPO_ROOT}/common/src/tx_thread_shell_entry.c
${REPO_ROOT}/common/src/tx_thread_terminate.c
${REPO_ROOT}/common/src/tx_thread_delete.c
${REPO_ROOT}/common/src/tx_thread_reset.c
${REPO_ROOT}/common/src/txe_thread_delete.c
${REPO_ROOT}/common/src/txe_thread_reset.c
${REPO_ROOT}/common/src/txe_thread_terminate.c
${REPO_ROOT}/common/src/tx_thread_initialize.c)
set(transition_sources
${SOURCE_DIR}/threadx_thread_transition_configuration_test.c
${transition_kernel_sources})
# The shim goes on the kernel sources only, not on the test. It defines
# TX_SOURCE_CODE, which is what tells tx_api.h to leave the public service names
# unmapped so that internal sources can use the core names; the test needs the
# opposite, because calling the public names and letting tx_api.h decide what they
# bind to is exactly what the TX_DISABLE_ERROR_CHECKING configuration is here to
# demonstrate.
if(MSVC)
set(transition_kernel_compile_options
"/FI${SOURCE_DIR}/threadx_thread_transition_host_test_port.h")
set(transition_undefine_options /UTX_ENABLE_EVENT_TRACE
/UTX_ENABLE_EVENT_LOG)
else()
set(transition_kernel_compile_options
"-include;${SOURCE_DIR}/threadx_thread_transition_host_test_port.h")
set(transition_undefine_options -UTX_ENABLE_EVENT_TRACE
-UTX_ENABLE_EVENT_LOG)
endif()
set_source_files_properties(
${transition_kernel_sources}
DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
PROPERTIES COMPILE_OPTIONS "${transition_kernel_compile_options}")
# Each entry is a test-name suffix, a colon, and the feature macros that define the
# configuration, separated by "|". A semicolon cannot be used as that separator: it
# is CMake's own list separator, so the foreach below would iterate the macros
# instead of the configurations.
set(transition_configurations
"ni:TX_NOT_INTERRUPTABLE"
"ni_no_error_checking:TX_NOT_INTERRUPTABLE|TX_DISABLE_ERROR_CHECKING"
"ni_no_notify:TX_NOT_INTERRUPTABLE|TX_DISABLE_NOTIFY_CALLBACKS"
"no_error_checking:TX_DISABLE_ERROR_CHECKING")
foreach(configuration ${transition_configurations})
string(REPLACE ":" ";" configuration_parts ${configuration})
list(GET configuration_parts 0 configuration_name)
list(GET configuration_parts 1 configuration_macro_text)
string(REPLACE "|" ";" configuration_macros ${configuration_macro_text})
set(test_name threadx_thread_transition_${configuration_name}_test)
# Keep the internal target name short. CMake includes it in every object path,
# and the descriptive test name can otherwise reach the legacy MSVC MAX_PATH
# boundary in a normally nested Windows worktree.
set(test_target tx_tt_${configuration_name})
add_executable(${test_target} ${transition_sources})
target_include_directories(
${test_target}
PRIVATE ${SOURCE_DIR}
${REPO_ROOT}/common/inc
${REPO_ROOT}/ports/${THREADX_ARCH}/${THREADX_TOOLCHAIN}/inc)
target_compile_definitions(${test_target} PRIVATE ${configuration_macros})
# This directory is configured once per build configuration of the tree, so
# these executables inherit whichever feature macros that configuration sets --
# which is useful, since it means the two configurations above are also seen in
# combination with stack checking and with the other four. The one that cannot
# be inherited is event tracing: the trace macros in these sources reference the
# trace component's buffer and registry, and this harness links four kernel
# sources rather than the library, so the references would not resolve. The
# trace insertions in these same sources are covered by the tree's own
# trace_build configuration, where the whole library is linked, so nothing is
# lost by turning tracing off here. Event logging is turned off for the same
# reason; no configuration of the tree enables it.
#
# The undefine options have to reach the test source as well as the kernel sources,
# because TX_ENABLE_EVENT_TRACE is visible to tx_api.h and the two must agree on
# what the headers declare. Target compile options land after the directory's
# definition flags on the command line, which is what makes them effective.
target_compile_options(${test_target} PRIVATE ${transition_undefine_options})
add_test(${CMAKE_BUILD_TYPE}::${test_name} ${test_target})
endforeach()
|