Skip to content

Commit 389d744

Browse files
committed
tests: kernel/smp: rework signals in stress test
The k_poll signal and event code is reworked a bit such that signal is raised and event is processed only when appropriate. We want to avoid changing the internal of event and signal objects at the same time we try to raise the signal (which changes the internal states too). In addition, print out some information on how many signals raised and received to indicate we are actually switching all related threads. Fixes #98136 Signed-off-by: Daniel Leung <daniel.leung@intel.com>
1 parent f2428c6 commit 389d744

File tree

1 file changed

+64
-5
lines changed

1 file changed

+64
-5
lines changed

tests/kernel/smp/src/main.c

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,12 @@ ZTEST(smp, test_inc_concurrency)
11111111
"total count %d is wrong(M)", global_cnt);
11121112
}
11131113

1114+
/** Keep track of how many signals raised. */
1115+
static unsigned int t_signal_raised;
1116+
1117+
/** Keep track of how many signals received per thread. */
1118+
static unsigned int t_signals_rcvd[MAX_NUM_THREADS];
1119+
11141120
/**
11151121
* @brief Torture test for context switching code
11161122
*
@@ -1125,27 +1131,66 @@ static void process_events(void *arg0, void *arg1, void *arg2)
11251131
ARG_UNUSED(arg2);
11261132

11271133
uintptr_t id = (uintptr_t) arg0;
1134+
unsigned int signaled;
1135+
int result;
11281136

11291137
while (1) {
1130-
k_poll(&tevent[id], 1, K_FOREVER);
1138+
/* Retry if no event(s) are ready.
1139+
* For example, -EINTR where polling is interrupted.
1140+
*/
1141+
if (k_poll(&tevent[id], 1, K_FOREVER) != 0) {
1142+
continue;
1143+
}
1144+
1145+
/* Grab the raised signal. */
1146+
k_poll_signal_check(tevent[id].signal, &signaled, &result);
11311147

1132-
if (tevent[id].signal->result != 0x55) {
1148+
/* Check if signal is actually raised, which should be
1149+
* the case since k_poll() above returns 0. Though since
1150+
* we are testing switching and not the correctly of
1151+
* k_poll(), we simply re-try k_poll() if signal has not
1152+
* actually been raised.
1153+
*/
1154+
if (signaled == 0U) {
1155+
continue;
1156+
}
1157+
1158+
/* Check correct result. */
1159+
if (result != 0x55) {
11331160
ztest_test_fail();
11341161
}
11351162

1136-
tevent[id].signal->signaled = 0;
1137-
tevent[id].state = K_POLL_STATE_NOT_READY;
1163+
t_signals_rcvd[id]++;
11381164

1139-
k_poll_signal_reset(&tsignal[id]);
1165+
/* Reset both event and signal. */
1166+
tevent[id].state = K_POLL_STATE_NOT_READY;
1167+
tevent[id].signal->result = 0;
1168+
k_poll_signal_reset(tevent[id].signal);
11401169
}
11411170
}
11421171

11431172
static void signal_raise(void *arg0, void *arg1, void *arg2)
11441173
{
11451174
unsigned int num_threads = arch_num_cpus();
1175+
unsigned int signaled;
1176+
int result;
1177+
1178+
t_signal_raised = 0U;
11461179

11471180
while (1) {
11481181
for (uintptr_t i = 0; i < num_threads; i++) {
1182+
/* Only raise signal when it is okay to do so.
1183+
* We don't want to raise a signal while the signal
1184+
* and the associated event are still in the process
1185+
* of being reset (see above).
1186+
*/
1187+
k_poll_signal_check(tevent[i].signal, &signaled, &result);
1188+
1189+
if (signaled != 0U) {
1190+
continue;
1191+
}
1192+
1193+
t_signal_raised++;
11491194
k_poll_signal_raise(&tsignal[i], 0x55);
11501195
}
11511196
}
@@ -1169,6 +1214,8 @@ ZTEST(smp, test_smp_switch_torture)
11691214
}
11701215

11711216
for (uintptr_t i = 0; i < num_threads; i++) {
1217+
t_signals_rcvd[i] = 0;
1218+
11721219
k_poll_signal_init(&tsignal[i]);
11731220
k_poll_event_init(&tevent[i], K_POLL_TYPE_SIGNAL,
11741221
K_POLL_MODE_NOTIFY_ONLY, &tsignal[i]);
@@ -1190,6 +1237,18 @@ ZTEST(smp, test_smp_switch_torture)
11901237
k_thread_abort(&tthread[i]);
11911238
k_thread_join(&tthread[i], K_FOREVER);
11921239
}
1240+
1241+
TC_PRINT("Total signals raised %u\n", t_signal_raised);
1242+
1243+
for (unsigned int i = 0; i < num_threads; i++) {
1244+
TC_PRINT("Thread #%d received %u signals\n", i, t_signals_rcvd[i]);
1245+
}
1246+
1247+
/* Check if we at least have done some switching. */
1248+
for (unsigned int i = 0; i < num_threads; i++) {
1249+
zassert_not_equal(0, t_signals_rcvd[i],
1250+
"Thread #%d has not received any signals", i);
1251+
}
11931252
}
11941253

11951254
/**

0 commit comments

Comments
 (0)