thread.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Freie Universität Berlin
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License v2.1. See the file LICENSE in the top level
6  * directory for more details.
7  */
8 
9 #pragma once
10 
121 #include <stdbool.h>
122 
123 #include "cib.h"
124 #include "clist.h"
125 #include "compiler_hints.h"
126 #include "msg.h"
127 #include "sched.h"
128 #include "thread_config.h"
129 
130 #ifdef MODULE_CORE_THREAD_FLAGS
131 #include "thread_flags.h"
132 #endif
133 
134 #include "thread_arch.h" /* IWYU pragma: export */
135 
136 #ifdef __cplusplus
137 extern "C" {
138 #endif
139 
146 #ifdef THREAD_API_INLINED
147 #define THREAD_MAYBE_INLINE static inline __attribute__((always_inline))
148 #else
149 #define THREAD_MAYBE_INLINE
150 #endif /* THREAD_API_INLINED */
151 
152 #if defined(DEVELHELP) && !defined(CONFIG_THREAD_NAMES)
159 #define CONFIG_THREAD_NAMES
160 #endif
161 
165 typedef void *(*thread_task_func_t)(void *arg);
166 
170 struct _thread {
171  char *sp;
173  uint8_t priority;
177 #if defined(MODULE_CORE_THREAD_FLAGS) || defined(DOXYGEN)
179 #endif
195  void *exit_val;
196 
199 #if defined(MODULE_CORE_MSG) || defined(MODULE_CORE_THREAD_FLAGS) \
200  || defined(MODULE_CORE_MBOX) || defined(DOXYGEN)
201  void *wait_data;
203 #endif
204 #if defined(MODULE_CORE_MSG) || defined(DOXYGEN)
212 #endif
213 #if defined(DEVELHELP) || IS_ACTIVE(SCHED_TEST_STACK) \
214  || defined(MODULE_MPU_STACK_GUARD) || defined(DOXYGEN)
215  char *stack_start;
216 #endif
217 #if defined(CONFIG_THREAD_NAMES) || defined(DOXYGEN)
218  const char *name;
219 #endif
220 #if defined(DEVELHELP) || defined(DOXYGEN)
222 #endif
223 /* enable TLS only when Picolibc is compiled with TLS enabled */
224 #ifdef PICOLIBC_TLS
225  void *tls;
226 #endif
227 };
228 
236 #define THREAD_CREATE_SLEEPING (1)
237 
241 #define THREAD_AUTO_FREE (2)
242 
249 #define THREAD_CREATE_WOUT_YIELD (4)
250 
256 #define THREAD_CREATE_NO_STACKTEST (8)
257 
264 #define THREAD_CREATE_JOINABLE (16)
265 
273 #define THREAD_CREATE_STACKTEST (0)
304  int stacksize,
305  uint8_t priority,
306  int flags,
307  thread_task_func_t task_func,
308  void *arg,
309  const char *name);
310 
325 int thread_join(kernel_pid_t pid, void **exit_value);
326 
335 {
336  return (thread_t *)sched_threads[pid];
337 }
338 
346 static inline thread_t *thread_get(kernel_pid_t pid)
347 {
348  if (pid_is_valid(pid)) {
349  return thread_get_unchecked(pid);
350  }
351  return NULL;
352 }
353 
363 
367 void thread_sleep(void);
368 
380 #if defined(MODULE_CORE_THREAD) || DOXYGEN
381 void thread_yield(void);
382 #else
383 static inline void thread_yield(void)
384 {
385  /* NO-OP */
386 }
387 #endif
388 
402 
412 void thread_zombify(void);
413 
423 
433 
439 static inline kernel_pid_t thread_getpid(void)
440 {
441  extern volatile kernel_pid_t sched_active_pid;
442 
443  return sched_active_pid;
444 }
445 
453 static inline thread_t *thread_get_active(void)
454 {
455  extern volatile thread_t *sched_active_thread;
456 
457  return (thread_t *)sched_active_thread;
458 }
459 
470 char *thread_stack_init(thread_task_func_t task_func, void *arg,
471  void *stack_start, int stack_size);
472 
487 
498 #if defined(MODULE_CORE_THREAD) || DOXYGEN
499 const char *thread_getname(kernel_pid_t pid);
500 #else
501 static inline const char *thread_getname(kernel_pid_t pid)
502 {
503  (void)pid;
504  return "(none)";
505 }
506 #endif
507 
523 uintptr_t measure_stack_free_internal(const char *stack, size_t size);
524 
529 
534 
539 
544 
549 
563 static inline bool thread_has_msg_queue(const thread_t *thread)
564 {
565  assume(thread != NULL);
566 #if defined(MODULE_CORE_MSG) || defined(DOXYGEN)
567  return (thread->msg_array != NULL);
568 #else
569  (void)thread;
570  return 0;
571 #endif
572 }
573 
580 static inline thread_status_t thread_get_status(const thread_t *thread)
581 {
582  return thread->status;
583 }
584 
591 static inline uint8_t thread_get_priority(const thread_t *thread)
592 {
593  return thread->priority;
594 }
595 
602 static inline bool thread_is_active(const thread_t *thread)
603 {
604  return thread->status >= STATUS_ON_RUNQUEUE;
605 }
606 
614 
621 static inline void *thread_get_stackstart(const thread_t *thread)
622 {
623 #if defined(DEVELHELP) || IS_ACTIVE(SCHED_TEST_STACK) \
624  || defined(MODULE_MPU_STACK_GUARD)
625  return thread->stack_start;
626 #else
627  (void)thread;
628  return NULL;
629 #endif
630 }
631 
640 static inline void *thread_get_sp(const thread_t *thread)
641 {
642  return thread->sp;
643 }
644 
651 static inline size_t thread_get_stacksize(const thread_t *thread)
652 {
653 #if defined(DEVELHELP)
654  return thread->stack_size;
655 #else
656  (void)thread;
657  return 0;
658 #endif
659 }
660 
669 static inline kernel_pid_t thread_getpid_of(const thread_t *thread)
670 {
671  return thread->pid;
672 }
673 
680 static inline const char *thread_get_name(const thread_t *thread)
681 {
682 #if defined(CONFIG_THREAD_NAMES)
683  return thread->name;
684 #else
685  (void)thread;
686  return NULL;
687 #endif
688 }
689 
700 static inline uintptr_t thread_measure_stack_free(const thread_t *thread)
701 {
702  /* explicitly casting void pointers is bad code style, but needed for C++
703  * compatibility */
704  return measure_stack_free_internal((const char *)thread_get_stackstart(thread),
705  thread_get_stacksize(thread));
706 }
707 
708 #ifdef __cplusplus
709 }
710 #endif
711 
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:147
int16_t kernel_pid_t
Unique process identifier.
Definition: sched.h:138
volatile thread_t * sched_threads[KERNEL_PID_LAST+1]
Thread table.
thread_status_t
Definition: sched.h:162
#define STATUS_ON_RUNQUEUE
to check if on run queue: st >= STATUS_ON_RUNQUEUE
Definition: sched.h:184
uint16_t thread_flags_t
Type definition of thread_flags_t.
Definition: thread_flags.h:121
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:591
static thread_t * thread_get(kernel_pid_t pid)
Retrieve a thread control block by PID.
Definition: thread.h:346
static size_t thread_get_stacksize(const thread_t *thread)
Get size of a thread's stack.
Definition: thread.h:651
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:334
static thread_t * thread_get_active(void)
Returns a pointer to the Thread Control Block of the currently running thread.
Definition: thread.h:453
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:700
static const char * thread_get_name(const thread_t *thread)
Get name of thread.
Definition: thread.h:680
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:640
void *(* thread_task_func_t)(void *arg)
Prototype for a thread entry function.
Definition: thread.h:165
static kernel_pid_t thread_getpid(void)
Returns the process ID of the currently running thread.
Definition: thread.h:439
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:602
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:580
static void * thread_get_stackstart(const thread_t *thread)
Get start address (lowest) of a thread's stack.
Definition: thread.h:621
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:149
static bool thread_has_msg_queue(const thread_t *thread)
Checks if a thread has an initialized message queue.
Definition: thread.h:563
static kernel_pid_t thread_getpid_of(const thread_t *thread)
Get PID of thread.
Definition: thread.h:669
int thread_join(kernel_pid_t pid, void **exit_value)
Wait for a thread to finish.
Scheduler API definition.
thread_t holds thread's context data.
Definition: thread.h:170
char * sp
thread's stack pointer
Definition: thread.h:171
char * stack_start
thread's stack start address
Definition: thread.h:215
cib_t msg_queue
index of this [thread's message queue] (thread_t::msg_array), if any
Definition: thread.h:208
thread_flags_t flags
currently set flags
Definition: thread.h:178
list_node_t msg_waiters
threads waiting for their message to be delivered to this thread (i.e.
Definition: thread.h:205
thread_status_t status
thread's status
Definition: thread.h:172
msg_t * msg_array
memory holding messages sent to this thread's message queue
Definition: thread.h:210
uint8_t priority
thread's priority
Definition: thread.h:173
int stack_size
thread's stack size
Definition: thread.h:221
const char * name
thread's name
Definition: thread.h:218
void * exit_val
Thread exit value or join mutex.
Definition: thread.h:195
clist_node_t rq_entry
run queue entry
Definition: thread.h:197
void * wait_data
used by msg, mbox and thread flags
Definition: thread.h:201
kernel_pid_t pid
thread's process id
Definition: thread.h:175
circular integer buffer structure
Definition: cib.h:44
List node structure.
Definition: list.h:39
Describes a message object which can be sent between threads.
Definition: msg.h:195
Definitions for parsing and composition of DNS messages.
Thread configuration defines.
Thread Flags API.