1 /*
2  * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
3  * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon
4  * company) or an affiliate of Cypress Semiconductor Corporation. All rights
5  * reserved.
6  *
7  * SPDX-License-Identifier: BSD-3-Clause
8  *
9  */
10 
11 #ifndef __M_THREAD_H__ /* Add an extra M as thread.h is common. */
12 #define __M_THREAD_H__
13 
14 #include <stddef.h>
15 #include <stdint.h>
16 
17 /* State codes */
18 #define THRD_STATE_CREATING       0
19 #define THRD_STATE_RUNNABLE       1
20 #define THRD_STATE_BLOCK          2
21 #define THRD_STATE_DETACH         3
22 #define THRD_STATE_INVALID        4
23 #define THRD_STATE_RET_VAL_AVAIL  5
24 
25 /* Priorities. Lower value has higher priority */
26 #define THRD_PRIOR_HIGHEST        0x0
27 #define THRD_PRIOR_HIGH           0xF
28 #define THRD_PRIOR_MEDIUM         0x1F
29 #define THRD_PRIOR_LOW            0x7F
30 #define THRD_PRIOR_LOWEST         0xFF
31 
32 /* Error codes */
33 #define THRD_SUCCESS              0
34 #define THRD_ERR_GENERIC          1
35 
36 /* Thread entry function type */
37 typedef void (*thrd_fn_t)(void *);
38 
39 /* An address causes exceptions (invalid address and security bit). */
40 #define THRD_GENERAL_EXIT  ((thrd_fn_t)(0xFFFFFFFE))
41 
42 /* Thread context */
43 struct thread_t {
44     uint8_t         priority;           /* Priority                          */
45     uint8_t         state;              /* State                             */
46     uint16_t        flags;              /* Flags and align, DO NOT REMOVE!   */
47     void            *p_context_ctrl;    /* Context control (sp, splimit, lr) */
48     struct thread_t *next;              /* Next thread in list               */
49 };
50 
51 /* Query thread state function type */
52 typedef uint32_t (*thrd_query_state_t)(struct thread_t *p_thrd,
53                                        uint32_t *p_retval);
54 /*
55  * Definition for the current thread and its access helper preprocessor.
56  * The definition needs to be declared in one of the sources.
57  */
58 extern struct thread_t *p_curr_thrd;
59 #define CURRENT_THREAD p_curr_thrd
60 
61 /*
62  * Initialize the thread_t struct with the given inputs.
63  *
64  * Parameters:
65  *  p_thrd         -    Pointer of caller provided thread_t struct to be init
66  *  p_ctx_ctrl     -    Initial Context control (sp, splimit, lr)
67  *  priority       -    Initial priority
68  */
69 #define THRD_INIT(p_thrd, p_ctx_ctrl, prio) do {                         \
70                         (p_thrd)->priority       = (uint8_t)(prio);      \
71                         (p_thrd)->state          = THRD_STATE_CREATING;  \
72                         (p_thrd)->flags          = 0;                    \
73                         (p_thrd)->p_context_ctrl = p_ctx_ctrl;           \
74                     } while (0)
75 
76 /*
77  * Set thread priority.
78  *
79  * Parameters :
80  *  p_thrd         -     Pointer of thread_t struct
81  *  priority       -     Priority value (0~255)
82  *
83  * Note :
84  *  The new priority may not take effect immediately.
85  */
86 #define THRD_SET_PRIORITY(p_thrd, priority) \
87                                         p_thrd->priority = (uint8_t)(priority)
88 
89 /*
90  * Update current thread's bound context pointer.
91  *
92  * Parameters :
93  *  x              -     Context pointer to be bound with the current thread.
94  */
95 #define THRD_UPDATE_CUR_CTXCTRL(x)          \
96                                 CURRENT_THREAD->p_context_ctrl = (void *)(x)
97 
98 /*
99  * Check if a schedule is under expectation by measuring on a given thread.
100  *
101  * Return :
102  *  `true` if schedule is under expectation. `false` if not.
103  */
104 #define THRD_EXPECTING_SCHEDULE() (!(thrd_next() == CURRENT_THREAD))
105 
106 /*
107  * Init the global query state callback function pointer.
108  *
109  * Parameters :
110  *  fn             -     Query state function pointer.
111  */
112 void thrd_set_query_callback(thrd_query_state_t fn);
113 
114 /*
115  * Set thread state, and updates the runnable head.
116  *
117  * Parameters :
118  *  p_thrd         -     Pointer of thread_t struct
119  *  new_state      -     New state of thread
120  */
121 void thrd_set_state(struct thread_t *p_thrd, uint32_t new_state);
122 
123 /*
124  * Prepare thread context with given info and insert it into schedulable list.
125  *
126  * Parameters :
127  *  p_thrd         -     Pointer of thread_t struct
128  *  fn             -     Thread entry function
129  *  exit_fn        -     The function to go when 'fn' exited
130  *  param          -     Parameter passed to fn
131  *
132  * Note :
133  *  - The thread is not "started" immediately.
134  */
135 void thrd_start(struct thread_t *p_thrd, thrd_fn_t fn, thrd_fn_t exit_fn, void *param);
136 
137 /*
138  * Get the next thread to run in list.
139  *
140  * Return :
141  *  Pointer of next thread to run.
142  */
143 struct thread_t *thrd_next(void);
144 
145 /*
146  * Start scheduling.
147  *
148  * ppth [out]       -     The first runnable thread
149  *
150  * Return :
151  *  The EXC_RETURN payload of the first runnable thread for caller usage.
152  */
153 uint32_t thrd_start_scheduler(struct thread_t **ppth);
154 
155 #endif /* __M_THREAD_H__ */
156