thread.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2014 Freie Universität Berlin
3  * SPDX-License-Identifier: LGPL-2.1-only
4  */
5 
6 #pragma once
7 
118 #include <stdbool.h>
119 
120 #include "cib.h"
121 #include "clist.h"
122 #include "compiler_hints.h"
123 #include "msg.h"
124 #include "sched.h"
125 #include "thread_config.h"
126 
127 #ifdef MODULE_CORE_THREAD_FLAGS
128 #include "thread_flags.h"
129 #endif
130 
131 #include "thread_arch.h" /* IWYU pragma: export */
132 
133 #ifdef __cplusplus
134 extern "C" {
135 #endif
136 
143 #ifdef THREAD_API_INLINED
144 #define THREAD_MAYBE_INLINE static inline __attribute__((always_inline))
145 #else
146 #define THREAD_MAYBE_INLINE
147 #endif /* THREAD_API_INLINED */
148 
149 #if defined(DEVELHELP) && !defined(CONFIG_THREAD_NAMES)
156 #define CONFIG_THREAD_NAMES
157 #endif
158 
162 typedef void *(*thread_task_func_t)(void *arg);
163 
167 struct _thread {
168  char *sp;
170  uint8_t priority;
174 #if defined(MODULE_CORE_THREAD_FLAGS) || defined(DOXYGEN)
176 #endif
177 
180 #if defined(MODULE_CORE_MSG) || defined(MODULE_CORE_THREAD_FLAGS) \
181  || defined(MODULE_CORE_MBOX) || defined(DOXYGEN)
182  void *wait_data;
184 #endif
185 #if defined(MODULE_CORE_MSG) || defined(DOXYGEN)
193 #endif
194 #if defined(DEVELHELP) || IS_ACTIVE(SCHED_TEST_STACK) \
195  || defined(MODULE_MPU_STACK_GUARD) || defined(DOXYGEN)
196  char *stack_start;
197 #endif
198 #if defined(CONFIG_THREAD_NAMES) || defined(DOXYGEN)
199  const char *name;
200 #endif
201 #if defined(DEVELHELP) || defined(DOXYGEN)
203 #endif
204 /* enable TLS only when Picolibc is compiled with TLS enabled */
205 #ifdef PICOLIBC_TLS
206  void *tls;
207 #endif
208 };
209 
217 #define THREAD_CREATE_SLEEPING (1)
218 
222 #define THREAD_AUTO_FREE (2)
223 
230 #define THREAD_CREATE_WOUT_YIELD (4)
231 
237 #define THREAD_CREATE_NO_STACKTEST (8)
238 
246 #define THREAD_CREATE_STACKTEST (0)
277  int stacksize,
278  uint8_t priority,
279  int flags,
280  thread_task_func_t task_func,
281  void *arg,
282  const char *name);
283 
292 {
293  return (thread_t *)sched_threads[pid];
294 }
295 
303 static inline thread_t *thread_get(kernel_pid_t pid)
304 {
305  if (pid_is_valid(pid)) {
306  return thread_get_unchecked(pid);
307  }
308  return NULL;
309 }
310 
320 
324 void thread_sleep(void);
325 
337 #if defined(MODULE_CORE_THREAD) || DOXYGEN
338 void thread_yield(void);
339 #else
340 static inline void thread_yield(void)
341 {
342  /* NO-OP */
343 }
344 #endif
345 
359 
369 void thread_zombify(void);
370 
380 
390 
396 static inline kernel_pid_t thread_getpid(void)
397 {
398  extern volatile kernel_pid_t sched_active_pid;
399 
400  return sched_active_pid;
401 }
402 
410 static inline thread_t *thread_get_active(void)
411 {
412  extern volatile thread_t *sched_active_thread;
413 
414  return (thread_t *)sched_active_thread;
415 }
416 
427 char *thread_stack_init(thread_task_func_t task_func, void *arg,
428  void *stack_start, int stack_size);
429 
444 
455 #if defined(MODULE_CORE_THREAD) || DOXYGEN
456 const char *thread_getname(kernel_pid_t pid);
457 #else
458 static inline const char *thread_getname(kernel_pid_t pid)
459 {
460  (void)pid;
461  return "(none)";
462 }
463 #endif
464 
480 uintptr_t measure_stack_free_internal(const char *stack, size_t size);
481 
486 
491 
496 
501 
506 
520 static inline bool thread_has_msg_queue(const thread_t *thread)
521 {
522  assume(thread != NULL);
523 #if defined(MODULE_CORE_MSG) || defined(DOXYGEN)
524  return (thread->msg_array != NULL);
525 #else
526  (void)thread;
527  return 0;
528 #endif
529 }
530 
537 static inline thread_status_t thread_get_status(const thread_t *thread)
538 {
539  return thread->status;
540 }
541 
548 static inline uint8_t thread_get_priority(const thread_t *thread)
549 {
550  return thread->priority;
551 }
552 
559 static inline bool thread_is_active(const thread_t *thread)
560 {
561  return thread->status >= STATUS_ON_RUNQUEUE;
562 }
563 
571 
578 static inline void *thread_get_stackstart(const thread_t *thread)
579 {
580 #if defined(DEVELHELP) || IS_ACTIVE(SCHED_TEST_STACK) \
581  || defined(MODULE_MPU_STACK_GUARD)
582  return thread->stack_start;
583 #else
584  (void)thread;
585  return NULL;
586 #endif
587 }
588 
597 static inline void *thread_get_sp(const thread_t *thread)
598 {
599  return thread->sp;
600 }
601 
608 static inline size_t thread_get_stacksize(const thread_t *thread)
609 {
610 #if defined(DEVELHELP)
611  return thread->stack_size;
612 #else
613  (void)thread;
614  return 0;
615 #endif
616 }
617 
626 static inline kernel_pid_t thread_getpid_of(const thread_t *thread)
627 {
628  return thread->pid;
629 }
630 
637 static inline const char *thread_get_name(const thread_t *thread)
638 {
639 #if defined(CONFIG_THREAD_NAMES)
640  return thread->name;
641 #else
642  (void)thread;
643  return NULL;
644 #endif
645 }
646 
657 static inline uintptr_t thread_measure_stack_free(const thread_t *thread)
658 {
659  /* explicitly casting void pointers is bad code style, but needed for C++
660  * compatibility */
661  return measure_stack_free_internal((const char *)thread_get_stackstart(thread),
662  thread_get_stacksize(thread));
663 }
664 
665 #ifdef __cplusplus
666 }
667 #endif
668 
Circular integer buffer interface.
Circular linked list.
Common macros and compiler attributes/pragmas configuration.
#define assume(cond)
Behaves like an assert(), but tells the compiler that cond can never be false.
static int pid_is_valid(kernel_pid_t pid)
Determine if the given pid is valid.
Definition: sched.h:144
int16_t kernel_pid_t
Unique process identifier.
Definition: sched.h:135
volatile thread_t * sched_threads[KERNEL_PID_LAST+1]
Thread table.
thread_status_t
Definition: sched.h:159
#define STATUS_ON_RUNQUEUE
to check if on run queue: st >= STATUS_ON_RUNQUEUE
Definition: sched.h:181
uint16_t thread_flags_t
Type definition of thread_flags_t.
Definition: thread_flags.h:118
void thread_stack_print(void)
Print the current stack to stdout.
uintptr_t measure_stack_free_internal(const char *stack, size_t size)
Measures the stack usage of a stack.
thread_status_t thread_getstatus(kernel_pid_t pid)
Returns the status of a process.
static uint8_t thread_get_priority(const thread_t *thread)
Get a thread's priority.
Definition: thread.h:548
static thread_t * thread_get(kernel_pid_t pid)
Retrieve a thread control block by PID.
Definition: thread.h:303
static size_t thread_get_stacksize(const thread_t *thread)
Get size of a thread's stack.
Definition: thread.h:608
char * thread_stack_init(thread_task_func_t task_func, void *arg, void *stack_start, int stack_size)
Gets called upon thread creation to set CPU registers.
const char * thread_state_to_string(thread_status_t state)
Convert a thread state code to a human readable string.
static thread_t * thread_get_unchecked(kernel_pid_t pid)
Retrieve a thread control block by PID.
Definition: thread.h:291
static thread_t * thread_get_active(void)
Returns a pointer to the Thread Control Block of the currently running thread.
Definition: thread.h:410
void thread_add_to_list(list_node_t *list, thread_t *thread)
Add thread to list, sorted by priority (internal)
static uintptr_t thread_measure_stack_free(const thread_t *thread)
Measures the stack usage of a stack.
Definition: thread.h:657
static const char * thread_get_name(const thread_t *thread)
Get name of thread.
Definition: thread.h:637
void thread_zombify(void)
Puts the current thread into zombie state.
void * thread_isr_stack_pointer(void)
Get the current ISR stack pointer.
kernel_pid_t thread_create(char *stack, int stacksize, uint8_t priority, int flags, thread_task_func_t task_func, void *arg, const char *name)
Creates a new thread.
void * thread_isr_stack_start(void)
Get the start of the ISR stack.
THREAD_MAYBE_INLINE void thread_yield_higher(void)
Lets current thread yield in favor of a higher prioritized thread.
int thread_kill_zombie(kernel_pid_t pid)
Terminates zombie thread.
void thread_sleep(void)
Puts the current thread into sleep mode.
const char * thread_getname(kernel_pid_t pid)
Returns the name of a process.
void thread_yield(void)
Lets current thread yield.
int thread_wakeup(kernel_pid_t pid)
Wakes up a sleeping thread.
static void * thread_get_sp(const thread_t *thread)
Get stored Stack Pointer of thread.
Definition: thread.h:597
void *(* thread_task_func_t)(void *arg)
Prototype for a thread entry function.
Definition: thread.h:162
static kernel_pid_t thread_getpid(void)
Returns the process ID of the currently running thread.
Definition: thread.h:396
static bool thread_is_active(const thread_t *thread)
Returns if a thread is active (currently running or waiting to be scheduled)
Definition: thread.h:559
int thread_isr_stack_usage(void)
Get the number of bytes used on the ISR stack.
static thread_status_t thread_get_status(const thread_t *thread)
Get a thread's status.
Definition: thread.h:537
static void * thread_get_stackstart(const thread_t *thread)
Get start address (lowest) of a thread's stack.
Definition: thread.h:578
void thread_print_stack(void)
Prints human readable, ps-like thread information for debugging purposes.
#define THREAD_MAYBE_INLINE
Macro definition to inline some of the platform specific implementations.
Definition: thread.h:146
static bool thread_has_msg_queue(const thread_t *thread)
Checks if a thread has an initialized message queue.
Definition: thread.h:520
static kernel_pid_t thread_getpid_of(const thread_t *thread)
Get PID of thread.
Definition: thread.h:626
Scheduler API definition.
thread_t holds thread's context data.
Definition: thread.h:167
char * sp
thread's stack pointer
Definition: thread.h:168
char * stack_start
thread's stack start address
Definition: thread.h:196
cib_t msg_queue
index of this [thread's message queue] (thread_t::msg_array), if any
Definition: thread.h:189
thread_flags_t flags
currently set flags
Definition: thread.h:175
list_node_t msg_waiters
threads waiting for their message to be delivered to this thread (i.e.
Definition: thread.h:186
thread_status_t status
thread's status
Definition: thread.h:169
msg_t * msg_array
memory holding messages sent to this thread's message queue
Definition: thread.h:191
uint8_t priority
thread's priority
Definition: thread.h:170
int stack_size
thread's stack size
Definition: thread.h:202
const char * name
thread's name
Definition: thread.h:199
clist_node_t rq_entry
run queue entry
Definition: thread.h:178
void * wait_data
used by msg, mbox and thread flags
Definition: thread.h:182
kernel_pid_t pid
thread's process id
Definition: thread.h:172
circular integer buffer structure
Definition: cib.h:41
List node structure.
Definition: list.h:36
Describes a message object which can be sent between threads.
Definition: msg.h:192
Definitions for parsing and composition of DNS messages.
Thread configuration defines.
Thread Flags API.