Thread creation, lifecycle and per-thread state.
More...
Thread creation, lifecycle and per-thread state.
Threads are scheduled by fixed priority, highest first; threads of equal priority round-robin on every tick and on pbl_thread_yield(). The thread struct and its stack are owned by the caller and must outlive the thread. Returning from the entry function ends the thread, after which the struct may be reused for a new one.
static void prv_worker(void *arg) {
for (;;) {
do_work(arg);
}
}
void worker_start(void) {
.entry = prv_worker,
.prio = 2,
.privileged = true,
.stack = s_worker_stack,
.stack_size = sizeof(s_worker_stack),
};
}
const char * name
Name, truncated to PBL_THREAD_NAME_LEN - 1 characters.
Definition thread.h:75
Thread creation attributes.
Definition thread.h:73
Thread object.
Definition thread.h:97
int pbl_thread_create(struct pbl_thread *t, const struct pbl_thread_attr *attr)
Create and start a thread.
void pbl_thread_sleep(pbl_timeout_t timeout)
Block the calling thread for a while.
#define PBL_THREAD_STACK_DEFINE(name, size)
Define a thread stack with the alignment the MPU port needs for a guard region.
Definition thread.h:124
#define PBL_MSEC(ms)
Timeout in milliseconds, rounded down to whole ticks.
Definition types.h:62
◆ pbl_thread_attr
Thread creation attributes.
◆ pbl_thread
Thread object.
Caller-owned; set up by pbl_thread_create(). Read fields through the accessor functions.
| Data Fields |
|
struct pbl_thread_backend |
backend |
Backend state; first, the arch code relies on its offset. |
|
uint32_t |
id |
Unique per creation, never 0. |
|
char |
name[PBL_THREAD_NAME_LEN] |
NUL-terminated name. |
|
pbl_prio_t |
prio |
Effective priority, including any boost inherited through a mutex. |
|
bool |
privileged |
Runs in privileged mode. |
|
void * |
stack |
Lowest address of the stack. |
|
size_t |
stack_size |
Stack size in bytes. |
|
void * |
tls[CONFIG_KERNEL_THREAD_TLS_SLOTS] |
Thread-local pointer slots, see pbl_thread_tls_get(). |
◆ PBL_THREAD_MAX_MEM_REGIONS
| #define PBL_THREAD_MAX_MEM_REGIONS 4 |
Number of MPU regions switched in with each thread.
◆ PBL_THREAD_NAME_LEN
| #define PBL_THREAD_NAME_LEN 16 |
Size of a thread name, including the terminating NUL.
◆ PBL_THREAD_STACK_DEFINE
| #define PBL_THREAD_STACK_DEFINE |
( |
|
name, |
|
|
|
size |
|
) |
| static uint8_t name[size] PBL_ALIGNED(CONFIG_KERNEL_STACK_ALIGN) |
Define a thread stack with the alignment the MPU port needs for a guard region.
Expands to a static array; CONFIG_KERNEL_STACK_ALIGN gives the alignment.
- Parameters
-
| name | Name of the stack array. |
| size | Stack size in bytes. |
◆ pbl_thread_entry_t
| typedef void(* pbl_thread_entry_t) (void *arg) |
Thread entry function.
- Parameters
-
◆ pbl_thread_state
Thread state.
| Enumerator |
|---|
| PBL_THREAD_READY | Runnable, waiting for the CPU.
|
| PBL_THREAD_RUNNING | Currently executing.
|
| PBL_THREAD_BLOCKED | Waiting on an object or sleeping.
|
| PBL_THREAD_SUSPENDED | Stopped by pbl_thread_suspend() until pbl_thread_resume().
|
| PBL_THREAD_DEAD | Ended or aborted; the struct may be reused.
|
◆ pbl_kernel_privilege_raise_allowed()
| bool pbl_kernel_privilege_raise_allowed |
( |
uint32_t |
caller_pc | ) |
|
Decide whether code may raise privilege through the kernel's supervisor call.
Implemented by the application. Called from the SVC handler on every privilege-raise request.
- Parameters
-
| caller_pc | Address of the instruction after the SVC. |
- Returns
- true to grant privileged mode to the caller.
◆ pbl_kernel_syscall_entered()
| void pbl_kernel_syscall_entered |
( |
uintptr_t |
orig_sp, |
|
|
uintptr_t * |
lr_slot |
|
) |
| |
Notify the application that privilege is being raised for a syscall.
Implemented by the application. Called from the SVC handler just before the thread is made privileged.
- Parameters
-
| orig_sp | Caller's stack pointer before the SVC. |
| [in,out] | lr_slot | Stacked return address of the syscall; may be rewritten to redirect the return, e.g. through code that drops privilege again. |
◆ pbl_kernel_syscall_stack()
| uint32_t * pbl_kernel_syscall_stack |
( |
uintptr_t * |
base_out | ) |
|
Provide a dedicated privileged stack for the current thread's syscalls.
Implemented by the application; the kernel's weak default returns NULL. Called from the SVC handler once a privilege raise is allowed: the exception frame and the caller's stacked arguments are copied onto the returned stack, so the syscall body runs there.
- Parameters
-
| [out] | base_out | Lowest address of the stack, used as the stack limit where supported. |
- Returns
- Top of the stack, or NULL to run syscalls on the caller's stack.
◆ pbl_thread_abort()
End a thread.
Mutexes it holds are not released.
- Parameters
-
| t | Thread to end, or NULL for the calling thread, in which case this does not return. |
◆ pbl_thread_create()
Create and start a thread.
The stack is filled with a pattern for high-water tracking. The new thread runs as soon as it is the highest priority runnable thread, possibly before this call returns. Returning from the entry function ends the thread. Asserts if t still holds a live thread.
- Parameters
-
| [out] | t | Thread object, caller-owned. |
| attr | Creation attributes; only read during the call. |
- Returns
- 0.
◆ pbl_thread_current()
Get the calling thread.
Callable from unprivileged code.
- Returns
- The running thread, or the interrupted thread when called from an ISR.
◆ pbl_thread_id()
| static uint32_t pbl_thread_id |
( |
const struct pbl_thread * |
t | ) |
|
|
inlinestatic |
Get the creation ID of a thread.
Distinguishes successive threads created in the same struct.
- Parameters
-
- Returns
- ID, unique per creation and never 0.
References pbl_thread::id.
◆ pbl_thread_idle()
Get the kernel's idle thread.
- Returns
- The idle thread, which runs at PBL_PRIO_IDLE when nothing else is runnable.
◆ pbl_thread_name()
| static const char * pbl_thread_name |
( |
const struct pbl_thread * |
t | ) |
|
|
inlinestatic |
Get the name of a thread.
- Parameters
-
- Returns
- NUL-terminated name, owned by
t.
References pbl_thread::name.
◆ pbl_thread_prio_get()
Get the base priority of a thread.
- Parameters
-
- Returns
- Priority set at creation or by pbl_thread_prio_set(), without inherited boosts.
◆ pbl_thread_prio_set()
Change the base priority of a thread.
A priority boost inherited through a mutex is kept until the mutex is released.
- Parameters
-
◆ pbl_thread_regions_set()
Replace the MPU regions of a thread.
Used for the idle thread, whose regions cannot be passed at creation.
- Parameters
-
◆ pbl_thread_resume()
Make a suspended thread runnable again.
Has no effect if t is not suspended.
- Parameters
-
◆ pbl_thread_sleep()
Block the calling thread for a while.
- Parameters
-
◆ pbl_thread_stack_overflow()
| void pbl_thread_stack_overflow |
( |
struct pbl_thread * |
t, |
|
|
const char * |
name |
|
) |
| |
Handle a thread that overran its stack.
Implemented by the application.
- Parameters
-
| t | Thread that overflowed. |
| name | Its name. |
◆ pbl_thread_state()
Get the state of a thread.
- Parameters
-
- Returns
- Current state.
◆ pbl_thread_suspend()
Stop scheduling a thread until pbl_thread_resume().
A thread suspended while blocked sees the blocking call fail with -EINTR once resumed. Has no effect on a suspended or dead thread.
- Parameters
-
| t | Thread to suspend, or NULL for the calling thread. |
◆ pbl_thread_tls_get()
| static void * pbl_thread_tls_get |
( |
const struct pbl_thread * |
t, |
|
|
unsigned int |
slot |
|
) |
| |
|
inlinestatic |
Read a thread-local pointer slot.
- Parameters
-
| t | Thread. |
| slot | Slot index, below CONFIG_KERNEL_THREAD_TLS_SLOTS. |
- Returns
- Stored pointer, NULL if never set.
References pbl_thread::tls.
◆ pbl_thread_tls_set()
| static void pbl_thread_tls_set |
( |
struct pbl_thread * |
t, |
|
|
unsigned int |
slot, |
|
|
void * |
v |
|
) |
| |
|
inlinestatic |
Write a thread-local pointer slot.
- Parameters
-
| t | Thread. |
| slot | Slot index, below CONFIG_KERNEL_THREAD_TLS_SLOTS. |
| v | Pointer to store. |
References pbl_thread::tls.
◆ pbl_thread_yield()
| void pbl_thread_yield |
( |
void |
| ) |
|
Let other ready threads of the same priority run.