Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 57 additions & 1 deletion zephyr/test/userspace/ksem.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,62 @@ ZTEST(sof_boot, user_space)
{
test_user_thread();
test_user_thread_with_sem();
}

#include <zephyr/sys/sem.h>
#include <zephyr/app_memory/mem_domain.h>
Comment on lines +62 to +63
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The include directives should be placed at the top of the file with the other includes, not in the middle of the file after a ZTEST function. This violates standard C coding conventions and can make the code harder to maintain.

Copilot uses AI. Check for mistakes.

struct sem_mem {
struct sys_sem sem1;
struct sys_sem sem2;
uint8_t reserved[4096 - 2 * sizeof(struct sys_sem)];
};

static struct sem_mem simple_sem __attribute__((aligned(4096)));
static struct k_mem_domain dp_mdom;

static void sys_sem_function(void *p1, void *p2, void *p3)
{
__ASSERT(k_is_user_context(), "isn't user");
/* This is the goal, but it hangs with this disabled too */
sys_sem_give(&simple_sem.sem1);
int ret = sys_sem_take(&simple_sem.sem2, K_MSEC(20));

LOG_INF("SOF thread %s (%s) sem %p: %d",
k_is_user_context() ? "UserSpace!" : "privileged mode.",
CONFIG_BOARD_TARGET, &simple_sem, ret);
}

static void test_user_thread_sys_sem(void)
{
struct k_mem_partition mpart = {
.start = (uintptr_t)&simple_sem,
.size = 4096,
.attr = K_MEM_PARTITION_P_RW_U_RW/* | XTENSA_MMU_CACHED_WB*/,
};

ztest_test_pass();
k_mem_domain_init(&dp_mdom, 0, NULL);
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The memory domain is initialized but never cleaned up after the test completes. The memory domain should be destroyed with k_mem_domain_remove_thread or appropriate cleanup to avoid resource leaks, especially in a test suite where multiple tests may run.

Copilot uses AI. Check for mistakes.
sys_sem_init(&simple_sem.sem1, 0, 1);
sys_sem_init(&simple_sem.sem2, 0, 1);

k_thread_create(&user_thread, user_stack, USER_STACKSIZE,
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The global variable 'user_thread' is being reused from the earlier tests in this file. This can cause issues if multiple tests run in sequence, as the thread structure may contain state from previous test runs. Consider using a separate thread structure for this test, such as 'sys_sem_thread', to avoid potential conflicts.

Copilot uses AI. Check for mistakes.
sys_sem_function, NULL, NULL, NULL,
-1, K_USER, K_FOREVER);
k_mem_domain_add_partition(&dp_mdom, &mpart);
k_mem_domain_add_thread(&dp_mdom, &user_thread);

k_thread_start(&user_thread);
Comment on lines +98 to +104
Copy link

Copilot AI Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a potential race condition here. The user thread is started with K_FOREVER delay, then immediately started on line 104. The thread could execute sys_sem_give on line 78 before the kernel thread reaches sys_sem_take on line 107, causing the semaphore signal to be lost. This is likely why the test hangs. Consider adding synchronization to ensure the kernel thread is waiting on sem1 before the user thread is started, similar to how test_user_thread_with_sem uses K_MSEC(10) delay.

Copilot uses AI. Check for mistakes.

/* This is what doesn't work: enabling this line crashes the DSP */
zassert_ok(sys_sem_take(&simple_sem.sem1, K_MSEC(20)));

sys_sem_give(&simple_sem.sem2);

k_thread_join(&user_thread, K_FOREVER);
k_mem_domain_remove_partition(&dp_mdom, &mpart);
}

ZTEST(sof_boot, test_sys_sem)
{
test_user_thread_sys_sem();
}
Loading