| /* |
| * Copyright (c) 2018-2021, Arm Limited. All rights reserved. |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| * |
| */ |
| |
| #ifndef __M_THREAD_H__ /* Add an extra M as thread.h is common. */ |
| #define __M_THREAD_H__ |
| |
| #include <stdint.h> |
| #include <stddef.h> |
| |
| /* State codes */ |
| #define THRD_STATE_CREATING 0 |
| #define THRD_STATE_RUNNABLE 1 |
| #define THRD_STATE_BLOCK 2 |
| #define THRD_STATE_DETACH 3 |
| #define THRD_STATE_INVALID 4 |
| |
| /* Priorities. Lower value has higher priority */ |
| #define THRD_PRIOR_HIGHEST 0x0 |
| #define THRD_PRIOR_HIGH 0xF |
| #define THRD_PRIOR_MEDIUM 0x1F |
| #define THRD_PRIOR_LOW 0x7F |
| #define THRD_PRIOR_LOWEST 0xFF |
| |
| /* Error codes */ |
| #define THRD_SUCCESS 0 |
| #define THRD_ERR_GENERIC 1 |
| |
| /* Thread entry function type */ |
| typedef void *(*thrd_fn_t)(void *); |
| |
| /* Thread context */ |
| struct thread_t { |
| uint8_t priority; /* Priority */ |
| uint8_t state; /* State */ |
| uint16_t flags; /* specific flags */ |
| void *p_context_ctrl; /* Context control (sp, splimit, lr) */ |
| struct thread_t *next; /* Next thread in list */ |
| }; |
| |
| /* |
| * Definition for the current thread and its access helper preprocessor. |
| * The definition needs to be declared in one of the sources. |
| */ |
| extern struct thread_t *p_curr_thrd; |
| #define CURRENT_THREAD p_curr_thrd |
| |
| /* |
| * Initialize the thread_t struct with the given inputs. |
| * |
| * Parameters: |
| * p_thrd - Pointer of caller provided thread_t struct to be init |
| * p_ctx_ctrl - Initial Context control (sp, splimit, lr) |
| * priority - Initial priority |
| */ |
| #define THRD_INIT(p_thrd, p_ctx_ctrl, prio) do { \ |
| (p_thrd)->priority = (uint8_t)(prio); \ |
| (p_thrd)->state = THRD_STATE_CREATING; \ |
| (p_thrd)->flags = 0; \ |
| (p_thrd)->p_context_ctrl = p_ctx_ctrl; \ |
| } while (0) |
| |
| /* |
| * Set thread priority. |
| * |
| * Parameters : |
| * p_thrd - Pointer of thread_t struct |
| * priority - Priority value (0~255) |
| * |
| * Note : |
| * The new priority may not take effect immediately. |
| */ |
| #define THRD_SET_PRIORITY(p_thrd, priority) \ |
| p_thrd->priority = (uint8_t)(priority) |
| |
| /* |
| * Update current thread's bound context pointer. |
| * |
| * Parameters : |
| * x - Context pointer to be bound with the current thread. |
| */ |
| #define THRD_UPDATE_CUR_CTXCTRL(x) \ |
| CURRENT_THREAD->p_context_ctrl = (void *)(x) |
| |
| /* |
| * Set thread state, and updates the runnable head. |
| * |
| * Parameters : |
| * p_thrd - Pointer of thread_t struct |
| * new_state - New state of thread |
| */ |
| void thrd_set_state(struct thread_t *p_thrd, uint32_t new_state); |
| |
| /* |
| * Prepare thread context with given info and insert it into schedulable list. |
| * |
| * Parameters : |
| * p_thrd - Pointer of thread_t struct |
| * fn - Thread entry function |
| * param - The single parameter for thread entry function |
| * sp_limit - Stack limit addr |
| * sp - Current stack pointer |
| * |
| * Note : |
| * - thrd_fn_t does not have parameters but param is still set into R0 for some |
| * special usages, for example the NS agent. |
| * - The thread is not "started" immediately. |
| */ |
| void thrd_start(struct thread_t *p_thrd, |
| thrd_fn_t fn, void *param, |
| uintptr_t sp_limit, uintptr_t sp); |
| |
| /* |
| * Get the next thread to run in list. |
| * |
| * Return : |
| * Pointer of next thread to run. |
| */ |
| struct thread_t *thrd_next(void); |
| |
| /* |
| * Start scheduling. |
| * |
| * ppth [out] - The first runnable thread |
| * |
| * Return : |
| * The EXC_RETURN payload of the first runnable thread for caller usage. |
| */ |
| uint32_t thrd_start_scheduler(struct thread_t **ppth); |
| |
| |
| /* Sync object */ |
| |
| /* A magic for corruption detecting */ |
| #ifndef NDEBUG |
| #define THRD_SYNC_MAGIC 0x736f626a /* 'sobj' */ |
| #endif |
| |
| struct sync_obj_t { |
| #ifndef NDEBUG |
| uint32_t magic; /* The magic for corruption detecting */ |
| #endif |
| struct thread_t *owner; /* The owner thread of the sync object */ |
| }; |
| |
| #ifndef NDEBUG |
| #define THRD_SYNC_INIT(p_sync_obj) do { \ |
| (p_sync_obj)->magic = THRD_SYNC_MAGIC; \ |
| (p_sync_obj)->owner = NULL; \ |
| } while (0) |
| #else |
| #define THRD_SYNC_INIT(p_sync_obj) (p_sync_obj)->owner = NULL |
| #endif |
| |
| /* |
| * Block the thread to wait on an sync object. The thread becomes the onwer of |
| * sync object. |
| * |
| * Parameters: |
| * p_sync_obj - The pointer of sync object allocated by the caller |
| * pth - The thread_t which waits on p_sync_obj. |
| * |
| */ |
| void thrd_wait_on(struct sync_obj_t *p_sync_obj, struct thread_t *pth); |
| |
| /* |
| * Wake up the sync object owner thread and set the return value of the function |
| * that caused the "waiting". |
| * |
| * Parameters : |
| * p_sync_obj - The sync object that the thread is waiting on |
| * ret_val - Value to be returned to owner |
| */ |
| void thrd_wake_up(struct sync_obj_t *p_sync_obj, uint32_t ret_val); |
| |
| #endif /* __M_THREAD_H__ */ |