unified: Rework K_THREAD_DEFINE()
K_THREAD_DEFINE() can no longer specify a thread group. However, it now accepts a 'delay' parameter just as k_thread_spawn() does. To create a statically defined thread that may belong to one or more thread groups the new internal _MDEF_THREAD_DEFINE() macro is used. It is only used for legacy purposes. Threads can not both have a delayed start AND belong to a thread group. Jira: ZEP-916 Change-Id: Ia6e59ddcb4fc68f1f60f9c6b0f4f227f161ad1bb Signed-off-by: Peter Mitsis <peter.mitsis@windriver.com>
This commit is contained in:
parent
41a4caadfc
commit
b2fd5be4dc
4 changed files with 104 additions and 29 deletions
|
@ -166,13 +166,16 @@ struct _static_thread_data {
|
||||||
struct k_thread *thread;
|
struct k_thread *thread;
|
||||||
};
|
};
|
||||||
unsigned int init_stack_size;
|
unsigned int init_stack_size;
|
||||||
|
int32_t init_delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define K_THREAD_INITIALIZER(stack, stack_size, \
|
/*
|
||||||
|
* Common macro used by both K_THREAD_INITIALIZER()
|
||||||
|
* and _MDEF_THREAD_INITIALIZER().
|
||||||
|
*/
|
||||||
|
#define _THREAD_INITIALIZER(stack, stack_size, \
|
||||||
entry, p1, p2, p3, \
|
entry, p1, p2, p3, \
|
||||||
abort, prio, groups) \
|
abort, prio) \
|
||||||
{ \
|
|
||||||
.init_groups = (groups), \
|
|
||||||
.init_prio = (prio), \
|
.init_prio = (prio), \
|
||||||
.init_entry = (void (*)(void *, void *, void *))entry, \
|
.init_entry = (void (*)(void *, void *, void *))entry, \
|
||||||
.init_p1 = (void *)p1, \
|
.init_p1 = (void *)p1, \
|
||||||
|
@ -180,24 +183,72 @@ struct _static_thread_data {
|
||||||
.init_p3 = (void *)p3, \
|
.init_p3 = (void *)p3, \
|
||||||
.init_abort = abort, \
|
.init_abort = abort, \
|
||||||
.init_stack = (stack), \
|
.init_stack = (stack), \
|
||||||
.init_stack_size = (stack_size), \
|
.init_stack_size = (stack_size),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Thread initializer macro
|
||||||
|
*
|
||||||
|
* This macro is to only be used with statically defined threads that were not
|
||||||
|
* defined in the MDEF file. As such the associated threads can not belong to
|
||||||
|
* any thread group.
|
||||||
|
*/
|
||||||
|
#define K_THREAD_INITIALIZER(stack, stack_size, \
|
||||||
|
entry, p1, p2, p3, \
|
||||||
|
abort, prio, delay) \
|
||||||
|
{ \
|
||||||
|
_THREAD_INITIALIZER(stack, stack_size, \
|
||||||
|
entry, p1, p2, p3, \
|
||||||
|
abort, prio) \
|
||||||
|
.init_groups = 0, \
|
||||||
|
.init_delay = (delay), \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Define thread initializer object and initialize it
|
* @brief Thread initializer macro
|
||||||
* NOTE: For thread group functions thread initializers must be organized
|
*
|
||||||
* in array and thus should not have gaps between them.
|
* This macro is to only be used with statically defined threads that were
|
||||||
* On x86 by default compiler aligns them by 32 byte boundary. To prevent
|
* defined with legacy APIs (including the MDEF file). As such the associated
|
||||||
* this 32-bit alignment in specified here.
|
* threads may belong to one or more thread groups.
|
||||||
* _static_thread_data structure sise needs to be kept 32-bit aligned as well
|
*/
|
||||||
|
#define _MDEF_THREAD_INITIALIZER(stack, stack_size, \
|
||||||
|
entry, p1, p2, p3, \
|
||||||
|
abort, prio, groups) \
|
||||||
|
{ \
|
||||||
|
_THREAD_INITIALIZER(stack, stack_size, \
|
||||||
|
entry, p1, p2, p3, \
|
||||||
|
abort, prio) \
|
||||||
|
.init_groups = (groups), \
|
||||||
|
.init_delay = K_FOREVER, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Define thread initializer and initialize it.
|
||||||
|
*
|
||||||
|
* @internal It has been observed that the x86 compiler by default aligns
|
||||||
|
* these _static_thread_data structures to 32-byte boundaries, thereby
|
||||||
|
* wasting space. To work around this, force a 4-byte alignment.
|
||||||
*/
|
*/
|
||||||
#define K_THREAD_DEFINE(name, stack_size, \
|
#define K_THREAD_DEFINE(name, stack_size, \
|
||||||
|
entry, p1, p2, p3, \
|
||||||
|
abort, prio, delay) \
|
||||||
|
char __noinit __stack _k_thread_obj_##name[stack_size]; \
|
||||||
|
struct _static_thread_data _k_thread_data_##name __aligned(4) \
|
||||||
|
__in_section(_k_task_list, private, task) = \
|
||||||
|
K_THREAD_INITIALIZER(_k_thread_obj_##name, stack_size, \
|
||||||
|
entry, p1, p2, p3, abort, prio, delay)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Define thread initializer for MDEF defined thread and initialize it.
|
||||||
|
*
|
||||||
|
* @ref K_THREAD_DEFINE
|
||||||
|
*/
|
||||||
|
#define _MDEF_THREAD_DEFINE(name, stack_size, \
|
||||||
entry, p1, p2, p3, \
|
entry, p1, p2, p3, \
|
||||||
abort, prio, groups) \
|
abort, prio, groups) \
|
||||||
char __noinit __stack _k_thread_obj_##name[stack_size]; \
|
char __noinit __stack _k_thread_obj_##name[stack_size]; \
|
||||||
struct _static_thread_data _k_thread_data_##name __aligned(4) \
|
struct _static_thread_data _k_thread_data_##name __aligned(4) \
|
||||||
__in_section(_k_task_list, private, task) = \
|
__in_section(_k_task_list, private, task) = \
|
||||||
K_THREAD_INITIALIZER(_k_thread_obj_##name, stack_size, \
|
_MDEF_THREAD_INITIALIZER(_k_thread_obj_##name, stack_size, \
|
||||||
entry, p1, p2, p3, abort, prio, groups)
|
entry, p1, p2, p3, abort, prio, groups)
|
||||||
|
|
||||||
extern int k_thread_priority_get(k_tid_t thread);
|
extern int k_thread_priority_get(k_tid_t thread);
|
||||||
|
|
|
@ -84,7 +84,7 @@ typedef int nano_context_type_t;
|
||||||
char __noinit __stack _k_thread_obj_##name[stack_size]; \
|
char __noinit __stack _k_thread_obj_##name[stack_size]; \
|
||||||
struct _static_thread_data _k_thread_data_##name __aligned(4) \
|
struct _static_thread_data _k_thread_data_##name __aligned(4) \
|
||||||
__in_section(_k_task_list, private, task) = \
|
__in_section(_k_task_list, private, task) = \
|
||||||
K_THREAD_INITIALIZER(_k_thread_obj_##name, stack_size, \
|
_MDEF_THREAD_INITIALIZER(_k_thread_obj_##name, stack_size, \
|
||||||
entry, NULL, NULL, NULL, \
|
entry, NULL, NULL, NULL, \
|
||||||
NULL, prio, (uint32_t)(groups)); \
|
NULL, prio, (uint32_t)(groups)); \
|
||||||
k_tid_t const name = (k_tid_t)_k_thread_obj_##name
|
k_tid_t const name = (k_tid_t)_k_thread_obj_##name
|
||||||
|
|
|
@ -424,6 +424,8 @@ void _k_thread_single_abort(struct k_thread *thread)
|
||||||
|
|
||||||
void _init_static_threads(void)
|
void _init_static_threads(void)
|
||||||
{
|
{
|
||||||
|
unsigned int key;
|
||||||
|
|
||||||
_FOREACH_STATIC_THREAD(thread_data) {
|
_FOREACH_STATIC_THREAD(thread_data) {
|
||||||
_new_thread(
|
_new_thread(
|
||||||
thread_data->init_stack,
|
thread_data->init_stack,
|
||||||
|
@ -438,7 +440,29 @@ void _init_static_threads(void)
|
||||||
|
|
||||||
thread_data->thread->init_data = thread_data;
|
thread_data->thread->init_data = thread_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
k_sched_lock();
|
||||||
|
/* Start all (legacy) threads that are part of the EXE group */
|
||||||
_k_thread_group_op(K_THREAD_GROUP_EXE, _k_thread_single_start);
|
_k_thread_group_op(K_THREAD_GROUP_EXE, _k_thread_single_start);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Non-legacy static threads may be started immediately or after a
|
||||||
|
* previously specified delay. Even though the scheduler is locked,
|
||||||
|
* ticks can still be delivered and processed. Lock interrupts so
|
||||||
|
* that the countdown until execution begins from the same tick.
|
||||||
|
*
|
||||||
|
* Note that static threads defined using the legacy API have a
|
||||||
|
* delay of K_FOREVER.
|
||||||
|
*/
|
||||||
|
key = irq_lock();
|
||||||
|
_FOREACH_STATIC_THREAD(thread_data) {
|
||||||
|
if (thread_data->init_delay != K_FOREVER) {
|
||||||
|
schedule_new_thread(thread_data->thread,
|
||||||
|
thread_data->init_delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
irq_unlock(key);
|
||||||
|
k_sched_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t _k_thread_group_mask_get(struct k_thread *thread)
|
uint32_t _k_thread_group_mask_get(struct k_thread *thread)
|
||||||
|
|
|
@ -448,7 +448,7 @@ def kernel_main_c_tasks_unified():
|
||||||
kernel_main_c_out("EXTERN_C void %s(void);\n" % abort)
|
kernel_main_c_out("EXTERN_C void %s(void);\n" % abort)
|
||||||
|
|
||||||
kernel_main_c_out(
|
kernel_main_c_out(
|
||||||
"K_THREAD_DEFINE(%s, %u, %s, %s, %s, %s, %s, %d, 0x%x);\n" %
|
"_MDEF_THREAD_DEFINE(%s, %u, %s, %s, %s, %s, %s, %d, 0x%x);\n" %
|
||||||
(name, int(stack_size), entry,
|
(name, int(stack_size), entry,
|
||||||
params[0], params[1], params[2],
|
params[0], params[1], params[2],
|
||||||
abort, int(prio), int(groups)))
|
abort, int(prio), int(groups)))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue