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:
Anas Nashif 2018-03-03 02:31:05 -06:00
commit 57554055d2
8 changed files with 113 additions and 24 deletions

View file

@ -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>
/**

View file

@ -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"

View file

@ -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
/**

View file

@ -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 */

View file

@ -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);

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;
}