Skip to content

Commit

Permalink
tests: kernel/msgq_api: join threads after each test
Browse files Browse the repository at this point in the history
On SMP systems, threads going through k_thread_abort() may still
be running while the test moves on to the next one. This creates
some interferences and may result in the next test failing. So
after each test, we need to do k_thread_join() on those threads
to make sure they are no longer active.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
  • Loading branch information
dcpleung authored and kartben committed Jan 22, 2025
1 parent 7ae2b50 commit 32f5ef5
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 35 deletions.
28 changes: 26 additions & 2 deletions tests/kernel/msgq/msgq_api/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ extern struct k_msgq kmsgq;
extern struct k_msgq msgq;
extern struct k_sem end_sema;
extern struct k_thread tdata;
extern k_tid_t tids[2];
K_THREAD_STACK_DECLARE(tstack, STACK_SIZE);

void *msgq_api_setup(void)
Expand All @@ -36,6 +37,29 @@ void *msgq_api_setup(void)
k_thread_heap_assign(k_current_get(), &test_pool);
return NULL;
}
ZTEST_SUITE(msgq_api, NULL, msgq_api_setup, NULL, NULL, NULL);

static void test_end_threads_join(void)
{
for (int i = 0; i < ARRAY_SIZE(tids); i++) {
if (tids[i] != NULL) {
k_thread_join(tids[i], K_FOREVER);
tids[i] = NULL;
}
}
}

static void msgq_api_test_after(void *data)
{
test_end_threads_join();
}

static void msgq_api_test_1cpu_after(void *data)
{
test_end_threads_join();

ztest_simple_1cpu_after(data);
}

ZTEST_SUITE(msgq_api, NULL, msgq_api_setup, NULL, msgq_api_test_after, NULL);
ZTEST_SUITE(msgq_api_1cpu, NULL, msgq_api_setup,
ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);
ztest_simple_1cpu_before, msgq_api_test_1cpu_after, NULL);
57 changes: 29 additions & 28 deletions tests/kernel/msgq/msgq_api/src/test_msgq_contexts.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct k_msgq msgq1;
K_THREAD_STACK_DEFINE(tstack, STACK_SIZE);
K_THREAD_STACK_DEFINE(tstack1, STACK_SIZE);
K_THREAD_STACK_DEFINE(tstack2, STACK_SIZE);
ZTEST_BMEM k_tid_t tids[2];
struct k_thread tdata;
struct k_thread tdata1;
struct k_thread tdata2;
Expand Down Expand Up @@ -94,12 +95,12 @@ static void msgq_thread(struct k_msgq *pmsgq)
{
/**TESTPOINT: thread-thread data passing via message queue*/
put_msgq(pmsgq);
k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
thread_entry, pmsgq, NULL, NULL,
K_PRIO_PREEMPT(0),
K_USER | K_INHERIT_PERMS, K_NO_WAIT);
tids[0] = k_thread_create(&tdata, tstack, STACK_SIZE,
thread_entry, pmsgq, NULL, NULL,
K_PRIO_PREEMPT(0),
K_USER | K_INHERIT_PERMS, K_NO_WAIT);
k_sem_take(&end_sema, K_FOREVER);
k_thread_abort(tid);
k_thread_abort(tids[0]);

/**TESTPOINT: msgq purge*/
purge_msgq(pmsgq);
Expand Down Expand Up @@ -131,17 +132,17 @@ static void msgq_thread_overflow(struct k_msgq *pmsgq)
zassert_equal(ret, 0);

/**TESTPOINT: thread-thread data passing via message queue*/
k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
thread_entry_overflow, pmsgq, NULL, NULL,
K_PRIO_PREEMPT(0),
K_USER | K_INHERIT_PERMS, K_NO_WAIT);
tids[0] = k_thread_create(&tdata, tstack, STACK_SIZE,
thread_entry_overflow, pmsgq, NULL, NULL,
K_PRIO_PREEMPT(0),
K_USER | K_INHERIT_PERMS, K_NO_WAIT);

ret = k_msgq_put(pmsgq, (void *)&data[1], K_FOREVER);

zassert_equal(ret, 0);

k_sem_take(&end_sema, K_FOREVER);
k_thread_abort(tid);
k_thread_abort(tids[0]);

/**TESTPOINT: msgq purge*/
k_msgq_purge(pmsgq);
Expand Down Expand Up @@ -182,17 +183,17 @@ static void msgq_thread_data_passing(struct k_msgq *pmsgq)
while (k_msgq_put(pmsgq, &data[0], K_NO_WAIT) != 0) {
}

k_tid_t tid = k_thread_create(&tdata2, tstack2, STACK_SIZE,
pend_thread_entry, pmsgq, NULL,
NULL, K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
tids[0] = k_thread_create(&tdata2, tstack2, STACK_SIZE,
pend_thread_entry, pmsgq, NULL,
NULL, K_PRIO_PREEMPT(0), 0, K_NO_WAIT);

k_tid_t tid1 = k_thread_create(&tdata1, tstack1, STACK_SIZE,
thread_entry_get_data, pmsgq, NULL,
NULL, K_PRIO_PREEMPT(1), 0, K_NO_WAIT);
tids[1] = k_thread_create(&tdata1, tstack1, STACK_SIZE,
thread_entry_get_data, pmsgq, NULL,
NULL, K_PRIO_PREEMPT(1), 0, K_NO_WAIT);

k_sem_take(&end_sema, K_FOREVER);
k_thread_abort(tid);
k_thread_abort(tid1);
k_thread_abort(tids[0]);
k_thread_abort(tids[1]);

/**TESTPOINT: msgq purge*/
k_msgq_purge(pmsgq);
Expand Down Expand Up @@ -399,13 +400,13 @@ ZTEST(msgq_api_1cpu, test_msgq_empty)
ret = k_sem_init(&end_sema, 0, 1);
zassert_equal(ret, 0);

k_tid_t tid = k_thread_create(&tdata2, tstack2, STACK_SIZE,
get_empty_entry, &msgq1, NULL,
NULL, pri, 0, K_NO_WAIT);
tids[0] = k_thread_create(&tdata2, tstack2, STACK_SIZE,
get_empty_entry, &msgq1, NULL,
NULL, pri, 0, K_NO_WAIT);

k_sem_take(&end_sema, K_FOREVER);
/* that getting thread is being blocked now */
zassert_equal(tid->base.thread_state, _THREAD_PENDING);
zassert_equal(tids[0]->base.thread_state, _THREAD_PENDING);
/* since there is a thread is waiting for message, this queue
* can't be cleanup
*/
Expand All @@ -416,7 +417,7 @@ ZTEST(msgq_api_1cpu, test_msgq_empty)
ret = k_msgq_put(&msgq1, &data[0], K_NO_WAIT);
zassert_equal(ret, 0);

k_thread_abort(tid);
k_thread_abort(tids[0]);
}

/**
Expand All @@ -442,13 +443,13 @@ ZTEST(msgq_api_1cpu, test_msgq_full)
ret = k_msgq_put(&msgq1, &data[0], K_NO_WAIT);
zassert_equal(ret, 0);

k_tid_t tid = k_thread_create(&tdata2, tstack2, STACK_SIZE,
put_full_entry, &msgq1, NULL,
NULL, pri, 0, K_NO_WAIT);
tids[0] = k_thread_create(&tdata2, tstack2, STACK_SIZE,
put_full_entry, &msgq1, NULL,
NULL, pri, 0, K_NO_WAIT);
k_sem_take(&end_sema, K_FOREVER);
/* that putting thread is being blocked now */
zassert_equal(tid->base.thread_state, _THREAD_PENDING);
k_thread_abort(tid);
zassert_equal(tids[0]->base.thread_state, _THREAD_PENDING);
k_thread_abort(tids[0]);
}

/**
Expand Down
11 changes: 6 additions & 5 deletions tests/kernel/msgq/msgq_api/src/test_msgq_purge.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

K_THREAD_STACK_DECLARE(tstack, STACK_SIZE);
extern struct k_thread tdata;
extern k_tid_t tids[2];
extern struct k_msgq msgq;
static ZTEST_BMEM char __aligned(4) tbuffer[MSG_SIZE * MSGQ_LEN];
static ZTEST_DMEM uint32_t data[MSGQ_LEN] = { MSG0, MSG1 };
Expand All @@ -29,10 +30,10 @@ static void purge_when_put(struct k_msgq *q)
zassert_equal(ret, 0);
}
/*create another thread waiting to put msg*/
k_thread_create(&tdata, tstack, STACK_SIZE,
tThread_entry, q, NULL, NULL,
K_PRIO_PREEMPT(0), K_USER | K_INHERIT_PERMS,
K_NO_WAIT);
tids[0] = k_thread_create(&tdata, tstack, STACK_SIZE,
tThread_entry, q, NULL, NULL,
K_PRIO_PREEMPT(0), K_USER | K_INHERIT_PERMS,
K_NO_WAIT);
k_msleep(TIMEOUT_MS >> 1);
/**TESTPOINT: msgq purge while another thread waiting to put msg*/
k_msgq_purge(q);
Expand All @@ -43,7 +44,7 @@ static void purge_when_put(struct k_msgq *q)
zassert_equal(ret, 0);
}

k_thread_abort(&tdata);
k_thread_abort(tids[0]);
}

/**
Expand Down

0 comments on commit 32f5ef5

Please sign in to comment.