Skip to content

Commit d053ba5

Browse files
Andrew Boieandrewboie
authored andcommitted
tests: dynamic_thread: cover thread_idx_free()
Address a coverage gap in kernel/userspace. Unfortunately, in the process of fixing this, a bug was discovered, see zephyrproject-rtos#17023. This test is user mode specific, filter the testcase on whether userspace is available instead of ifdefing the code. Signed-off-by: Andrew Boie <[email protected]>
1 parent 777336e commit d053ba5

File tree

3 files changed

+49
-18
lines changed

3 files changed

+49
-18
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
CONFIG_ZTEST=y
22
CONFIG_TEST_USERSPACE=y
3-
CONFIG_HEAP_MEM_POOL_SIZE=2048
3+
CONFIG_HEAP_MEM_POOL_SIZE=4096

tests/kernel/threads/dynamic_thread/src/main.c

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
#define STACKSIZE (256 + CONFIG_TEST_EXTRA_STACKSIZE)
1212

13-
#if defined(CONFIG_USERSPACE) && defined(CONFIG_DYNAMIC_OBJECTS)
14-
1513
static K_THREAD_STACK_DEFINE(dyn_thread_stack, STACKSIZE);
1614
static K_SEM_DEFINE(start_sem, 0, 1);
1715
static K_SEM_DEFINE(end_sem, 0, 1);
@@ -106,25 +104,56 @@ static void test_dyn_thread_perms(void)
106104
TC_PRINT("===== must have access denied on k_sem %p\n", &end_sem);
107105
}
108106

109-
#else /* (CONFIG_USERSPACE && CONFIG_DYNAMIC_OBJECTS) */
107+
static struct k_thread *dynamic_threads[CONFIG_MAX_THREAD_BYTES * 8];
110108

111-
static void prep(void)
109+
static void test_thread_index_management(void)
112110
{
113-
}
111+
int i, ctr = 0;
114112

115-
static void create_dynamic_thread(void)
116-
{
117-
TC_PRINT("Test skipped. Userspace and dynamic objects required.\n");
118-
ztest_test_skip();
119-
}
113+
/* Create thread objects until we run out of ids */
114+
while (true) {
115+
struct k_thread *t = k_object_alloc(K_OBJ_THREAD);
120116

121-
static void test_dyn_thread_perms(void)
122-
{
123-
TC_PRINT("Test skipped. Userspace and dynamic objects required.\n");
124-
ztest_test_skip();
125-
}
117+
if (t == NULL) {
118+
break;
119+
}
126120

127-
#endif /* !(CONFIG_USERSPACE && CONFIG_DYNAMIC_OBJECTS) */
121+
dynamic_threads[ctr] = t;
122+
ctr++;
123+
}
124+
125+
zassert_true(ctr != 0, "unable to create any thread objects");
126+
127+
TC_PRINT("created %d thread objects\n", ctr);
128+
129+
/* Show that the above NULL return value wasn't because we ran out of
130+
* heap space/
131+
*/
132+
void *blob = k_malloc(256);
133+
zassert_true(blob != NULL, "out of heap memory");
134+
135+
/* Free one of the threads... */
136+
k_object_free(dynamic_threads[0]);
137+
138+
/* And show that we can now create another one, the freed thread's
139+
* index should have been garbage collected.
140+
*/
141+
dynamic_threads[0] = k_object_alloc(K_OBJ_THREAD);
142+
zassert_true(dynamic_threads[0] != NULL,
143+
"couldn't create thread object\n");
144+
145+
/* TODO: Implement a test that shows that thread IDs are properly
146+
* recycled when a thread object is garbage collected due to references
147+
* dropping to zero. For example, we ought to be able to exit here
148+
* without calling k_object_free() on any of the threads we created
149+
* here; their references would drop to zero and they would be
150+
* automatically freed. However, it is known that the thread IDs are
151+
* not properly recycled when this happens, see #17023.
152+
*/
153+
for (i = 0; i < ctr; i++) {
154+
k_object_free(dynamic_threads[i]);
155+
}
156+
}
128157

129158
/**
130159
* @ingroup kernel_thread_tests
@@ -160,7 +189,8 @@ void test_main(void)
160189
ztest_test_suite(thread_dynamic,
161190
ztest_unit_test(test_kernel_create_dyn_user_thread),
162191
ztest_user_unit_test(test_user_create_dyn_user_thread),
163-
ztest_unit_test(test_dyn_thread_perms)
192+
ztest_unit_test(test_dyn_thread_perms),
193+
ztest_unit_test(test_thread_index_management)
164194
);
165195
ztest_run_test_suite(thread_dynamic);
166196
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
tests:
22
kernel.threads.dynamic:
33
tags: kernel threads userspace ignore_faults
4+
filter: CONFIG_ARCH_HAS_USERSPACE

0 commit comments

Comments
 (0)