k_thread_create(): allow K_FOREVER delay
It's now possible to instantiate a thread object, but delay its execution indefinitely. This was already supported with K_THREAD_DEFINE. A new API, k_thread_start(), now exists to start threads that are in this state. The intended use-case is to initialize a thread with K_USER, then grant it various access permissions, and only then start it. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
8e51f36bbf
commit
7d627c5971
4 changed files with 46 additions and 5 deletions
|
@ -496,7 +496,8 @@ typedef struct _k_thread_stack_element *k_thread_stack_t;
|
|||
* @param p3 3rd entry point parameter.
|
||||
* @param prio Thread priority.
|
||||
* @param options Thread options.
|
||||
* @param delay Scheduling delay (in milliseconds), or K_NO_WAIT (for no delay).
|
||||
* @param delay Scheduling delay (in milliseconds), or K_NO_WAIT (for no delay),
|
||||
* or K_FOREVER (to not run until k_thread_start() is called)
|
||||
*
|
||||
* @return ID of new thread.
|
||||
*/
|
||||
|
@ -626,6 +627,18 @@ extern int k_thread_cancel(k_tid_t thread);
|
|||
*/
|
||||
extern void k_thread_abort(k_tid_t thread);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Start an inactive thread
|
||||
*
|
||||
* If a thread was created with K_FOREVER in the delay parameter, it will
|
||||
* not be added to the scheduling queue until this function is called
|
||||
* on it.
|
||||
*
|
||||
* @param thread thread to start
|
||||
*/
|
||||
extern void k_thread_start(k_tid_t thread);
|
||||
|
||||
/**
|
||||
* @cond INTERNAL_HIDDEN
|
||||
*/
|
||||
|
|
|
@ -209,10 +209,15 @@ FUNC_NORETURN void _thread_entry(void (*entry)(void *, void *, void *),
|
|||
}
|
||||
|
||||
#ifdef CONFIG_MULTITHREADING
|
||||
static void start_thread(struct k_thread *thread)
|
||||
void k_thread_start(struct k_thread *thread)
|
||||
{
|
||||
int key = irq_lock(); /* protect kernel queues */
|
||||
|
||||
if (_has_thread_started(thread)) {
|
||||
irq_unlock(key);
|
||||
return;
|
||||
}
|
||||
|
||||
_mark_thread_as_started(thread);
|
||||
|
||||
if (_is_thread_ready(thread)) {
|
||||
|
@ -232,7 +237,7 @@ static void schedule_new_thread(struct k_thread *thread, s32_t delay)
|
|||
{
|
||||
#ifdef CONFIG_SYS_CLOCK_EXISTS
|
||||
if (delay == 0) {
|
||||
start_thread(thread);
|
||||
k_thread_start(thread);
|
||||
} else {
|
||||
s32_t ticks = _TICK_ALIGN + _ms_to_ticks(delay);
|
||||
int key = irq_lock();
|
||||
|
@ -242,7 +247,7 @@ static void schedule_new_thread(struct k_thread *thread, s32_t delay)
|
|||
}
|
||||
#else
|
||||
ARG_UNUSED(delay);
|
||||
start_thread(thread);
|
||||
k_thread_start(thread);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
@ -260,7 +265,9 @@ k_tid_t k_thread_create(struct k_thread *new_thread,
|
|||
prio, options);
|
||||
_k_object_init(new_thread);
|
||||
|
||||
schedule_new_thread(new_thread, delay);
|
||||
if (delay != K_FOREVER) {
|
||||
schedule_new_thread(new_thread, delay);
|
||||
}
|
||||
return new_thread;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
extern void test_threads_spawn_params(void);
|
||||
extern void test_threads_spawn_priority(void);
|
||||
extern void test_threads_spawn_delay(void);
|
||||
extern void test_threads_spawn_forever(void);
|
||||
extern void test_threads_suspend_resume_cooperative(void);
|
||||
extern void test_threads_suspend_resume_preemptible(void);
|
||||
extern void test_threads_cancel_undelayed(void);
|
||||
|
@ -31,6 +32,7 @@ void test_main(void)
|
|||
ztest_unit_test(test_threads_spawn_params),
|
||||
ztest_unit_test(test_threads_spawn_priority),
|
||||
ztest_unit_test(test_threads_spawn_delay),
|
||||
ztest_unit_test(test_threads_spawn_forever),
|
||||
ztest_unit_test(test_threads_suspend_resume_cooperative),
|
||||
ztest_unit_test(test_threads_suspend_resume_preemptible),
|
||||
ztest_unit_test(test_threads_cancel_undelayed),
|
||||
|
|
|
@ -80,3 +80,22 @@ void test_threads_spawn_delay(void)
|
|||
zassert_true(tp2 == 100, NULL);
|
||||
k_thread_abort(tid);
|
||||
}
|
||||
|
||||
void test_threads_spawn_forever(void)
|
||||
{
|
||||
/* spawn thread with highest priority. It will run immediately once
|
||||
* started.
|
||||
*/
|
||||
tp2 = 10;
|
||||
k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
|
||||
thread_entry_delay, NULL, NULL, NULL,
|
||||
K_HIGHEST_THREAD_PRIO, 0, K_FOREVER);
|
||||
k_yield();
|
||||
/* checkpoint: check spawn thread not execute */
|
||||
zassert_true(tp2 == 10, NULL);
|
||||
/* checkpoint: check spawn thread executed */
|
||||
k_thread_start(tid);
|
||||
k_yield();
|
||||
zassert_true(tp2 == 100, NULL);
|
||||
k_thread_abort(tid);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue