1.4. thrd — Threads

A thread is the basic execution entity in the OS. A pre-emptive or cooperative scheduler controls the execution of threads.

1.4.1. Scheduler

The single core scheduler is configured as cooperative or preemptive at compile time. The cooperative scheduler is implemented for all boards, but the preemptive scheduler is only implemented for a few boards.

There are two threads that are always present; the main thread and the idle thread. The main thread is the root thread in the system, created in the main() function by calling sys_start(). The idle thread is running when no other thread is ready to run. It simply waits for an interrupt to occur and then reschedules to run other ready threads.

The diagram below is an example of how three threads; shell, main and idle are scheduled over time.

../../_images/thread-scheduling.jpg

As it is a single core scheduler only one thread is runnng at a time. In the beginning the system is idle and the idle thread is running. After a while the main and shell threads have some work to do, and since they have higher priority than the idle thread they are scheduled. At the end the idle thread is running again.

1.4.2. Debug file system commands

Four debug file system commands are available, all located in the directory kernel/thrd/.

Command Description
list Print a list of all threads.
set_log_mask <thread name> <mask> Set the log mask of thread <thread name> to mask.
monitor/set_period_ms <ms> Set the monitor thread sampling period to <ms>
milliseconds.
monitor/set_print <state> Enable(1)/disable(0) monitor statistics to be
printed periodically.

Example output from the shell:

$ kenel/thrd/list
            NAME        STATE  PRIO   CPU   SCHEDULED  LOGMASK
            main      current     0    0%           1     0x0f
                        ready   127    0%           0     0x0f
                        ready   -80    0%           0     0x0f
OK

Source code: src/kernel/thrd.h, src/kernel/thrd.c

Test code: tst/kernel/thrd/main.c

Test coverage: src/kernel/thrd.c


Defines

THRD_STACK(name, size)
THRD_CONTEXT_STORE_ISR

Push all callee-save registers not part of the context struct. The preemptive scheduler requires this macro before the thrd_yield_isr() function is called from interrupt context.

THRD_CONTEXT_LOAD_ISR

Pop all callee-save registers not part of the context struct. The preemptive scheduler requires this macro after the thrd_yield_isr() function is called from interrupt context.

THRD_RESCHEDULE_ISR

Reschuedule from isr. Used by preemptive systems to interrupt low priority threads in favour of high priority threads.

Functions

int thrd_module_init(void)

Initialize the thread module. This function must be called before calling any other function in this module.

The module will only be initialized once even if this function is called multiple times.

Return
zero(0) or negative error code

struct thrd_t *thrd_spawn(void *(*main)(void *), void *arg_p, int prio, void *stack_p, size_t stack_size, )

Spawn a thread with given main (entry) function and argument. The thread is initialized and added to the ready queue in the scheduler for execution when prioritized.

Return
Thread id, or NULL on error.
Parameters
  • main: Thread main (entry) function. This function normally contains an infinate loop waiting for events to occur.
  • arg_p: Main function argument. Passed as arg_p to the main function.
  • prio: Thread scheduling priority. [-127..127], where -127 is the highest priority and 127 is the lowest.
  • stack_p: Stack pointer. The pointer to a stack created with the macro THRD_STACK().
  • stack_size: The stack size in number of bytes.

int thrd_suspend(const struct time_t *timeout_p)

Suspend current thread and wait to be resumed or a timeout occurs (if given).

Return
zero(0), -ETIMEDOUT on timeout or other negative error code.
Parameters
  • timeout_p: Time to wait to be resumed before a timeout occurs and the function returns.

int thrd_resume(struct thrd_t *thrd_p, int err)

Resume given thread. If resumed thread is not yet suspended it will not be suspended on next suspend call to thrd_suspend() or thrd_suspend_isr().

Return
zero(0) or negative error code.
Parameters
  • thrd_p: Thread id to resume.
  • err: Error code to be returned by thrd_suspend() or thrd_suspend_isr().

int thrd_yield(void)

Put the currently executing thread on the ready list and reschedule.

This function is often called periodically from low priority work heavy threads to give higher priority threads the chance to execute.

Return
zero(0) or negative error code.

int thrd_join(struct thrd_t *thrd_p)

Wait for given thread to terminate.

Return
zero(0) or negative error code.
Parameters
  • thrd_p: Thread to wait for.

int thrd_sleep(float seconds)

Pauses the current thread for given number of seconds.

Return
zero(0) or negative error code.
Parameters
  • seconds: Seconds to sleep.

int thrd_sleep_ms(int milliseconds)

Pauses the current thread for given number of milliseconds.

Return
zero(0) or negative error code.
Parameters
  • milliseconds: Milliseconds to sleep.

int thrd_sleep_us(long microseconds)

Pauses the current thread for given number of microseconds.

Return
zero(0) or negative error code.
Parameters
  • microseconds: Microseconds to sleep.

struct thrd_t *thrd_self(void)

Get current thread’s id.

Return
Thread id.

int thrd_set_name(const char *name_p)

Set the name of the current thread.

Return
zero(0) or negative error code.
Parameters
  • name_p: New thread name.

const char *thrd_get_name(void)

Get the name of the current thread.

Return
Current thread name.

struct thrd_t *thrd_get_by_name(const char *name_p)

Get the pointer to given thread.

Return
Thraed pointer or NULL if the thread was not found.

int thrd_set_log_mask(struct thrd_t *thrd_p, int mask)

Set the log mask of given thread.

Return
Old log mask.
Parameters
  • thrd_p: Thread to set the log mask of.
  • mask: Log mask. See the log module for available levels.

int thrd_get_log_mask(void)

Get the log mask of the current thread.

Return
Log mask of current thread.

int thrd_set_prio(struct thrd_t *thrd_p, int prio)

Set the priority of given thread.

Return
zero(0) or negative error code.
Parameters
  • thrd_p: Thread to set the priority for.
  • prio: Priority.

int thrd_get_prio(void)

Get the priority of the current thread.

Return
Priority of current thread.

int thrd_init_global_env(struct thrd_environment_variable_t *variables_p, int length)

Initialize the global environment variables storage. These variables are shared among all threads.

Return
zero(0) or negative error code.
Parameters
  • variables_p: Variables array.
  • length: Length of the variables array.

int thrd_set_global_env(const char *name_p, const char *value_p)

Set the value of given environment variable. The pointers to given name and value are stored in the current global environment array.

Return
zero(0) or negative error code.
Parameters
  • name_p: Name of the environment variable to set.
  • value_p: Value of the environment variable. Set to NULL to remove the variable.

const char *thrd_get_global_env(const char *name_p)

Get the value of given environment variable in the global environment array.

Return
Value of given environment variable or NULL if it is not found.
Parameters
  • name_p: Name of the environment variable to get.

int thrd_init_env(struct thrd_environment_variable_t *variables_p, int length)

Initialize the current threads’ environment variables storage.

Return
zero(0) or negative error code.
Parameters
  • variables_p: Variables are to be used by this therad.
  • length: Length of the variables array.

int thrd_set_env(const char *name_p, const char *value_p)

Set the value of given environment variable. The pointers to given name and value are stored in the current threads’ environment array.

Return
zero(0) or negative error code.
Parameters
  • name_p: Name of the environment variable to set.
  • value_p: Value of the environment variable. Set to NULL to remove the variable.

const char *thrd_get_env(const char *name_p)

Get the value of given environment variable. If given variable is not found in the current threads’ environment array, the global environment array is searched.

Return
Value of given environment variable or NULL if it is not found.
Parameters
  • name_p: Name of the environment variable to get.

int thrd_suspend_isr(const struct time_t *timeout_p)

Suspend current thread with the system lock taken (see sys_lock()) and wait to be resumed or a timeout occurs (if given).

Return
zero(0), -ETIMEDOUT on timeout or other negative error code.
Parameters
  • timeout_p: Time to wait to be resumed before a timeout occurs and the function returns.

int thrd_resume_isr(struct thrd_t *thrd_p, int err)

Resume given thread from isr or with the system lock taken (see sys_lock()). If resumed thread is not yet suspended it will not be suspended on next suspend call to thrd_suspend() or thrd_suspend_isr().

Return
zero(0) or negative error code.
Parameters
  • thrd_p: Thread id to resume.
  • err: Error code to be returned by thrd_suspend() or thrd_suspend_isr().

int thrd_yield_isr(void)

Yield current thread from isr (preemptive scheduler only) or with the system lock taken.

Return
zero(0) or negative error code.

void *thrd_stack_alloc(size_t size)

Allocate a thread stack of given size.

Return
The pointer to allocated thread stack, or NULL on error.

int thrd_stack_free(void *stack_p)

Free given thread stack.

Return
zero(0) or negative error code.

const void *thrd_get_bottom_of_stack(struct thrd_t *thrd_p)

Get the pointer to given threads’ bottom of stack.

Return
The pointer to given threds’ bottom of stack, or NULL on error.

const void *thrd_get_top_of_stack(struct thrd_t *thrd_p)

Get the pointer to given threads’ top of stack.

Return
The pointer to given threds’ top of stack, or NULL on error.

int thrd_prio_list_init(struct thrd_prio_list_t *self_p)

Initialize given prio list.

void thrd_prio_list_push_isr(struct thrd_prio_list_t *self_p, struct thrd_prio_list_elem_t *elem_p)

Push given element on given priority list. The priority list is a linked list with the highest priority thread first. The pushed element is added after any already pushed elements with the same thread priority.

Return
void.
Parameters
  • self_p: Priority list to push on.
  • elem_p: Element to push.

struct thrd_prio_list_elem_t *thrd_prio_list_pop_isr(struct thrd_prio_list_t *self_p)

Pop the highest priority element from given priority list.

Return
Poped element or NULL if the list was empty.
Parameters
  • self_p: Priority list to pop from.

int thrd_prio_list_remove_isr(struct thrd_prio_list_t *self_p, struct thrd_prio_list_elem_t *elem_p)

Remove given element from given priority list.

Return
zero(0) or negative error code.
Parameters
  • self_p: Priority list to remove given element from.
  • elem_p: Element to remove.

struct thrd_environment_variable_t
#include <thrd.h>

A thread environment variable.

Public Members

const char *name_p
const char *value_p
struct thrd_environment_t

Public Members

struct thrd_environment_variable_t *variables_p
size_t number_of_variables
size_t max_number_of_variables
struct thrd_t

Public Members

struct thrd_prio_list_elem_t elem
struct thrd_t::@86 thrd_t::scheduler
struct thrd_port_t port
int8_t prio
int8_t state
int err
uint8_t log_mask
struct timer_t *timer_p
const char *name_p
struct thrd_t *next_p
struct thrd_t::@87 thrd_t::statistics
size_t stack_size