kernel: add a new API for setting thread names
Added k_thread_name_set() and enable thread name setting when declaring static threads. This is enabled only when THREAD_MONITOR is used. System threads get a name by default. Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
3a117c220a
commit
57554055d2
8 changed files with 113 additions and 24 deletions
|
@ -539,6 +539,11 @@ struct k_thread {
|
|||
struct k_thread *next_thread;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_THREAD_NAME)
|
||||
/* Thread name */
|
||||
const char *name;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_THREAD_CUSTOM_DATA
|
||||
/** crude thread-local storage */
|
||||
void *custom_data;
|
||||
|
@ -914,11 +919,12 @@ struct _static_thread_data {
|
|||
u32_t init_options;
|
||||
s32_t init_delay;
|
||||
void (*init_abort)(void);
|
||||
const char *init_name;
|
||||
};
|
||||
|
||||
#define _THREAD_INITIALIZER(thread, stack, stack_size, \
|
||||
entry, p1, p2, p3, \
|
||||
prio, options, delay, abort) \
|
||||
prio, options, delay, abort, tname) \
|
||||
{ \
|
||||
.init_thread = (thread), \
|
||||
.init_stack = (stack), \
|
||||
|
@ -931,6 +937,7 @@ struct _static_thread_data {
|
|||
.init_options = (options), \
|
||||
.init_delay = (delay), \
|
||||
.init_abort = (abort), \
|
||||
.init_name = STRINGIFY(tname), \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -977,7 +984,7 @@ struct _static_thread_data {
|
|||
_THREAD_INITIALIZER(&_k_thread_obj_##name, \
|
||||
_k_thread_stack_##name, stack_size, \
|
||||
entry, p1, p2, p3, prio, options, delay, \
|
||||
NULL); \
|
||||
NULL, name); \
|
||||
const k_tid_t name = (k_tid_t)&_k_thread_obj_##name
|
||||
|
||||
/**
|
||||
|
@ -1223,10 +1230,28 @@ __syscall void k_thread_custom_data_set(void *value);
|
|||
*/
|
||||
__syscall void *k_thread_custom_data_get(void);
|
||||
|
||||
/**
|
||||
* @brief Set current thread name
|
||||
*
|
||||
* Set the name of the thread to be used when THREAD_MONITOR is enabled for
|
||||
* tracing and debugging.
|
||||
*
|
||||
*/
|
||||
__syscall void k_thread_name_set(k_tid_t thread_id, const char *value);
|
||||
|
||||
/**
|
||||
* @brief Get thread name
|
||||
*
|
||||
* Get the name of a thread
|
||||
*
|
||||
* @param thread_id Thread ID
|
||||
*
|
||||
*/
|
||||
__syscall const char *k_thread_name_get(k_tid_t thread_id);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <sys_clock.h>
|
||||
|
||||
/**
|
||||
|
|
|
@ -339,6 +339,11 @@ config THREAD_MONITOR
|
|||
This option instructs the kernel to maintain a list of all threads
|
||||
(excluding those that have not yet started or have already
|
||||
terminated).
|
||||
|
||||
config THREAD_NAME
|
||||
bool "Thread name [EXPERIMENTAL]"
|
||||
help
|
||||
This option allows to set a name for a thread.
|
||||
endmenu
|
||||
|
||||
menu "Work Queue Options"
|
||||
|
|
|
@ -49,7 +49,7 @@ extern void _setup_new_thread(struct k_thread *new_thread,
|
|||
k_thread_stack_t *stack, size_t stack_size,
|
||||
k_thread_entry_t entry,
|
||||
void *p1, void *p2, void *p3,
|
||||
int prio, u32_t options);
|
||||
int prio, u32_t options, const char *name);
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
/**
|
||||
|
|
|
@ -236,6 +236,10 @@ static ALWAYS_INLINE void _new_thread_init(struct k_thread *thread,
|
|||
thread->custom_data = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_THREAD_NAME
|
||||
thread->name = NULL;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_USERSPACE)
|
||||
thread->mem_domain_info.mem_domain = NULL;
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include <tracing.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define IDLE_THREAD_NAME "idle"
|
||||
|
||||
/* boot banner items */
|
||||
#if defined(CONFIG_BOOT_DELAY) && CONFIG_BOOT_DELAY > 0
|
||||
#define BOOT_DELAY_BANNER " (delayed boot " \
|
||||
|
@ -251,7 +253,7 @@ static void init_idle_thread(struct k_thread *thr, k_thread_stack_t *stack)
|
|||
|
||||
_setup_new_thread(thr, stack,
|
||||
IDLE_STACK_SIZE, idle, NULL, NULL, NULL,
|
||||
K_LOWEST_THREAD_PRIO, K_ESSENTIAL);
|
||||
K_LOWEST_THREAD_PRIO, K_ESSENTIAL, IDLE_THREAD_NAME);
|
||||
_mark_thread_as_started(thr);
|
||||
}
|
||||
#endif
|
||||
|
@ -314,8 +316,7 @@ static void prepare_multithreading(struct k_thread *dummy_thread)
|
|||
_setup_new_thread(_main_thread, _main_stack,
|
||||
MAIN_STACK_SIZE, bg_thread_main,
|
||||
NULL, NULL, NULL,
|
||||
CONFIG_MAIN_THREAD_PRIORITY, K_ESSENTIAL);
|
||||
|
||||
CONFIG_MAIN_THREAD_PRIORITY, K_ESSENTIAL, "main");
|
||||
sys_trace_thread_create(_main_thread);
|
||||
|
||||
_mark_thread_as_started(_main_thread);
|
||||
|
|
|
@ -130,22 +130,11 @@ void _impl_k_thread_custom_data_set(void *value)
|
|||
_current->custom_data = value;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
Z_SYSCALL_HANDLER(k_thread_custom_data_set, data)
|
||||
{
|
||||
_impl_k_thread_custom_data_set((void *)data);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void *_impl_k_thread_custom_data_get(void)
|
||||
{
|
||||
return _current->custom_data;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
Z_SYSCALL_HANDLER0_SIMPLE(k_thread_custom_data_get);
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
#endif /* CONFIG_THREAD_CUSTOM_DATA */
|
||||
|
||||
#if defined(CONFIG_THREAD_MONITOR)
|
||||
|
@ -173,7 +162,63 @@ void _thread_monitor_exit(struct k_thread *thread)
|
|||
|
||||
irq_unlock(key);
|
||||
}
|
||||
#endif /* CONFIG_THREAD_MONITOR */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_THREAD_NAME
|
||||
void _impl_k_thread_name_set(struct k_thread *thread, const char *value)
|
||||
{
|
||||
if (thread == NULL) {
|
||||
_current->name = value;
|
||||
} else {
|
||||
thread->name = value;
|
||||
}
|
||||
}
|
||||
|
||||
const char *_impl_k_thread_name_get(struct k_thread *thread)
|
||||
{
|
||||
return (const char *)thread->name;
|
||||
}
|
||||
|
||||
#else
|
||||
void _impl_k_thread_name_set(k_tid_t thread_id, const char *value)
|
||||
{
|
||||
ARG_UNUSED(thread_id);
|
||||
ARG_UNUSED(value);
|
||||
}
|
||||
|
||||
const char *_impl_k_thread_name_get(k_tid_t thread_id)
|
||||
{
|
||||
ARG_UNUSED(thread_id);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CONFIG_THREAD_NAME */
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
|
||||
#if defined(CONFIG_THREAD_NAME)
|
||||
Z_SYSCALL_HANDLER(k_thread_name_set, thread, data)
|
||||
{
|
||||
char *name_copy = NULL;
|
||||
|
||||
name_copy = z_user_string_alloc_copy((char *)data, 64);
|
||||
_impl_k_thread_name_set((struct k_thread *)thread, name_copy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Z_SYSCALL_HANDLER1_SIMPLE(k_thread_name_get, K_OBJ_THREAD, k_tid_t);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_THREAD_CUSTOM_DATA
|
||||
Z_SYSCALL_HANDLER(k_thread_custom_data_set, data)
|
||||
{
|
||||
_impl_k_thread_custom_data_set((void *)data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Z_SYSCALL_HANDLER0_SIMPLE(k_thread_custom_data_get);
|
||||
#endif /* CONFIG_THREAD_CUSTOM_DATA */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STACK_SENTINEL
|
||||
/* Check that the stack sentinel is still present
|
||||
|
@ -291,7 +336,7 @@ void _setup_new_thread(struct k_thread *new_thread,
|
|||
k_thread_stack_t *stack, size_t stack_size,
|
||||
k_thread_entry_t entry,
|
||||
void *p1, void *p2, void *p3,
|
||||
int prio, u32_t options)
|
||||
int prio, u32_t options, const char *name)
|
||||
{
|
||||
stack_size = adjust_stack_size(stack_size);
|
||||
|
||||
|
@ -329,6 +374,9 @@ void _setup_new_thread(struct k_thread *new_thread,
|
|||
_kernel.threads = new_thread;
|
||||
irq_unlock(key);
|
||||
#endif
|
||||
#ifdef CONFIG_THREAD_NAME
|
||||
new_thread->name = name;
|
||||
#endif
|
||||
#ifdef CONFIG_USERSPACE
|
||||
_k_object_init(new_thread);
|
||||
_k_object_init(stack);
|
||||
|
@ -372,7 +420,7 @@ k_tid_t _impl_k_thread_create(struct k_thread *new_thread,
|
|||
__ASSERT(!_is_in_isr(), "Threads may not be created in ISRs");
|
||||
|
||||
_setup_new_thread(new_thread, stack, stack_size, entry, p1, p2, p3,
|
||||
prio, options);
|
||||
prio, options, NULL);
|
||||
|
||||
if (delay != K_FOREVER) {
|
||||
schedule_new_thread(new_thread, delay);
|
||||
|
@ -455,7 +503,7 @@ Z_SYSCALL_HANDLER(k_thread_create,
|
|||
_setup_new_thread((struct k_thread *)new_thread, stack, stack_size,
|
||||
(k_thread_entry_t)entry, (void *)p1,
|
||||
(void *)margs->arg6, (void *)margs->arg7, prio,
|
||||
options);
|
||||
options, NULL);
|
||||
|
||||
if (delay != K_FOREVER) {
|
||||
schedule_new_thread(new_thread, delay);
|
||||
|
@ -607,7 +655,8 @@ void _init_static_threads(void)
|
|||
thread_data->init_p2,
|
||||
thread_data->init_p3,
|
||||
thread_data->init_prio,
|
||||
thread_data->init_options);
|
||||
thread_data->init_options,
|
||||
thread_data->init_name);
|
||||
|
||||
thread_data->init_thread->init_data = thread_data;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define WORKQUEUE_THREAD_NAME "workqueue"
|
||||
|
||||
static void work_q_main(void *work_q_ptr, void *p2, void *p3)
|
||||
{
|
||||
struct k_work_q *work_q = work_q_ptr;
|
||||
|
@ -53,6 +55,8 @@ void k_work_q_start(struct k_work_q *work_q, k_thread_stack_t *stack,
|
|||
k_queue_init(&work_q->queue);
|
||||
(void)k_thread_create(&work_q->thread, stack, stack_size, work_q_main,
|
||||
work_q, 0, 0, prio, 0, 0);
|
||||
|
||||
k_thread_name_set(&work_q->thread, WORKQUEUE_THREAD_NAME);
|
||||
_k_object_init(work_q);
|
||||
}
|
||||
|
||||
|
|
|
@ -1256,11 +1256,12 @@ int shell_init(const struct shell *shell, const void *transport_config,
|
|||
}
|
||||
}
|
||||
|
||||
(void)k_thread_create(shell->thread,
|
||||
k_tid_t tid = k_thread_create(shell->thread,
|
||||
shell->stack, CONFIG_SHELL_STACK_SIZE,
|
||||
shell_thread, (void *)shell, NULL, NULL,
|
||||
CONFIG_SHELL_THREAD_PRIO, 0, K_NO_WAIT);
|
||||
|
||||
k_thread_name_set(tid, "shell");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue