1 /*
2 * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 * http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2009-12-22
13 * Description: 任务模块的内部头文件
14 */
15 #ifndef PRT_TASK_EXTERNAL_H
16 #define PRT_TASK_EXTERNAL_H
17
18 #include "prt_task.h"
19 #include "prt_lib_external.h"
20 #include "prt_list_external.h"
21 #include "prt_sys_external.h"
22 #include "prt_err_external.h"
23 #include "prt_tick_external.h"
24 #include "prt_cpu_external.h"
25 #include "prt_mem_external.h"
26
27 #if defined(OS_OPTION_POSIX)
28 #include "pthread.h"
29 #define PTHREAD_KEYS_MAX 32
30 #endif
31
32 struct TagOsRunQue {
33 U32 taskReadyListBitMap;
34 /* 优先级bit位表 */
35 U32 tskChildBitMap[OS_GET_WORD_NUM_BY_PRIONUM(OS_TSK_NUM_OF_PRIORITIES)];
36 struct TagListObject readyList[OS_TSK_NUM_OF_PRIORITIES];
37 };
38
39 struct TagOsTskSortedDelayList {
40 /* 延时任务链表 */
41 struct TagListObject tskList;
42 };
43
44 /*
45 * 任务线程及进程控制块的结构体统一定义。
46 */
47 struct TagTskCb {
48 /* 当前任务的SP */
49 void *stackPointer;
50 /* 任务状态,后续内部全改成U32 */
51 U32 taskStatus;
52 /* 任务的运行优先级 */
53 TskPrior priority;
54 /* 任务栈配置标记 */
55 U16 stackCfgFlg;
56 /* 任务栈大小 */
57 U32 stackSize;
58 TskHandle taskPid;
59
60 /* 任务栈顶 */
61 uintptr_t topOfStack;
62
63 /* 任务入口函数 */
64 TskEntryFunc taskEntry;
65 /* 任务Pend的信号量指针 */
66 void *taskSem;
67
68 /* 任务的参数 */
69 uintptr_t args[4];
70 #if (defined(OS_OPTION_TASK_INFO))
71 /* 存放任务名 */
72 char name[OS_TSK_NAME_LEN];
73 #endif
74 /* 信号量链表指针 */
75 struct TagListObject pendList;
76 /* 任务延时链表指针 */
77 struct TagListObject timerList;
78 /* 持有互斥信号量链表 */
79 struct TagListObject semBList;
80
81 #if defined(OS_OPTION_EVENT)
82 /* 任务事件 */
83 U32 event;
84 /* 任务事件掩码 */
85 U32 eventMask;
86 #endif
87
88 /* 任务记录的最后一个错误码 */
89 U32 lastErr;
90 /* 任务恢复的时间点(单位Tick) */
91 U64 expirationTick;
92 #if defined(OS_OPTION_POSIX)
93 /* 当前任务状态 */
94 U8 state;
95 /* pthread cancel */
96 U8 cancelState;
97 U8 cancelType;
98 U8 cancelPending;
99 struct _pthread_cleanup_context *cancelBuf;
100 /* exit status */
101 void *retval;
102 /* count for thread join */
103 U16 joinCount;
104 /* semaphore for thread join */
105 SemHandle joinableSem;
106 /* pthread key */
107 void *tsd[PTHREAD_KEYS_MAX];
108 U32 tsdUsed;
109 #endif
110 };
111
112 /*
113 * 任务信息表节点数据结构
114 */
115 struct TagTskMonNode {
116 /* 撑死/饿死的时间点(tick) */
117 U64 expiredTick;
118 /* 撑死/饿死标记 */
119 U32 flag;
120 /* 撑死/饿死检测标记 */
121 U32 ckFlag;
122 /* 检测类型 */
123 U32 ckStyles;
124 /* 保留(对齐) */
125 U32 reserved;
126 };
127
128 typedef void (*TskCoresleep)(void);
129 typedef void (*TaskNameGetFunc)(U32 taskId, char **taskName);
130 typedef U32 (*TaskNameAddFunc)(U32 taskId, const char *name);
131
132 extern U16 g_uniTaskLock;
133 extern TskHandle g_idleTaskId;
134 extern struct TagOsRunQue g_runQueue;
135 extern struct TagTskCb *g_runningTask;
136 extern struct TagTskCb *g_highestTask;
137 extern struct TagOsTskSortedDelayList g_tskSortedDelay;
138
139 extern U32 g_tskMaxNum;
140 extern U32 g_tskBaseId;
141 extern struct TagTskCb *g_tskCbArray;
142 extern struct TskModInfo g_tskModInfo;
143 extern struct TagTskMonNode *g_tskMonList;
144
145 extern TskEntryFunc g_tskIdleEntry;
146 extern TaskNameAddFunc g_taskNameAdd;
147 extern TaskNameGetFunc g_taskNameGet;
148
149 extern volatile TskCoresleep g_taskCoreSleep;
150
151 #define OS_TSK_PARA_0 0
152 #define OS_TSK_PARA_1 1
153 #define OS_TSK_PARA_2 2
154 #define OS_TSK_PARA_3 3
155
156 /* 定义任务的缺省优先级 */
157 #define OS_TSK_DEFAULT_PRIORITY 20
158 #define OS_TSK_PRIO_BIT_MAP_POW 5
159 #define OS_TSK_STACK_TOP_MAGIC 0xAAAAAAAA
160
161 #define OS_TSK_PRIO_RDY_BIT 0x80000000U
162
163 #define OS_TASK_LOCK_DATA g_uniTaskLock
164 #define IDLE_TASK_ID g_idleTaskId
165 #define RUNNING_TASK g_runningTask
166 #define TSK_GET_INDEX(taskId) ((taskId) - g_tskBaseId)
167
168 /* 内核进程的进程及线程调度控制块使用同一类型 */
169 #define OS_MAX_TCB_NUM (g_tskMaxNum + 1 + 1) // 1个IDLE,1个无效任务
170
171 #define OS_TSK_DELAY_LOCKED_DETACH(task) ListDelete(&(task)->timerList)
172 #define CHECK_TSK_PID_OVERFLOW(taskId) (TSK_GET_INDEX(taskId) >= (g_tskMaxNum + 1))
173
174 /* 定义任务的缺省任务栈大小 */
175 #define OS_PST_ZOMBIE_TASK (&g_tskCbArray[OS_MAX_TCB_NUM - 1])
176 #define TSK_IS_UNUSED(tsk) ((tsk)->taskStatus == OS_TSK_UNUSED)
177 #define TSK_STATUS_TST(tsk, statBit) (((tsk)->taskStatus & (statBit)) != 0)
178 #define TSK_STATUS_CLEAR(tsk, statBit) ((tsk)->taskStatus &= ~(statBit))
179 #define TSK_STATUS_SET(tsk, statBit) ((tsk)->taskStatus |= (statBit))
180 #define OS_TSK_LOCK() (OS_TASK_LOCK_DATA++)
181 #define GET_TCB_PEND(ptr) LIST_COMPONENT(ptr, struct TagTskCb, pendList)
182 #define GET_TCB_HANDLE(taskPid) (((struct TagTskCb *)g_tskCbArray) + TSK_GET_INDEX(taskPid))
183 // 保留一个idle task。最大任务handle为FE,FF表示硬中断线程。
184 #define MAX_TASK_NUM ((1U << OS_TSK_TCB_INDEX_BITS) - 2) // 254
185 #define OS_TSK_BLOCK (OS_TSK_DELAY | OS_TSK_PEND | OS_TSK_SUSPEND | OS_TSK_QUEUE_PEND | \
186 OS_TSK_EVENT_PEND)
187
188 #define OS_TSK_SUSPEND_READY_BLOCK (OS_TSK_SUSPEND)
189 // 设置任务优先级就绪链表主BitMap中Bit位,每32个优先级对应一个BIT位,即Bit0(优先级0~31),Bit1(优先级32~63),依次类推。
190 #define OS_SET_RDY_TSK_BIT_MAP(priority) \
191 (OS_TSK_PRIO_RDY_BIT >> ((priority) >> OS_TSK_PRIO_BIT_MAP_POW))
192 // 清除任务优先级就绪链表主BitMap中Bit位,每32个优先级对应一个BIT位,即Bit0(优先级0~31),Bit1(优先级32~63),依次类推。
193 #define OS_CLR_RDY_TSK_BIT_MAP(priority) \
194 (~(OS_TSK_PRIO_RDY_BIT >> ((priority) >> OS_TSK_PRIO_BIT_MAP_POW)))
195
196 // 设置任务优先级就绪链表子BitMap中Bit位,每个优先级对应一个BIT位。
197 #define OS_SET_CHILD_BIT_MAP(priority) \
198 (OS_TSK_PRIO_RDY_BIT >> ((priority) % OS_WORD_BIT_NUM))
199 // 清除任务优先级就绪链表子BitMap中Bit位,每个优先级对应一个BIT位。
200 #define OS_CLR_CHILD_BIT_MAP(priority) \
201 (~(OS_TSK_PRIO_RDY_BIT >> ((priority) % OS_WORD_BIT_NUM)))
202
203 extern void OsTaskScan(void);
204 extern void OsTskSchedule(void);
205 extern void OsTskEntry(TskHandle taskId);
206 extern void OsTaskExit(struct TagTskCb *tsk);
207 extern void OsTskReadyAdd(struct TagTskCb *task);
208 extern void OsTskReadyDel(struct TagTskCb *taskCb);
209 extern void OsTskSwitchHookCaller(U32 prevPid, U32 nextPid);
210 extern void OsTskTimerAdd(struct TagTskCb *taskCb, uintptr_t timeout);
211
212 extern U32 OsTskMaxNumGet(void);
213 extern U32 OsTaskDelete(TskHandle taskPid);
214 extern U32 OsTaskCreateOnly(TskHandle *taskPid, struct TskInitParam *initParam);
215
216 extern void OsTskScheduleFast(void);
217 extern void OsTskScheduleFastPs(uintptr_t intSave);
218
219 /*
220 * 模块内内联函数定义
221 */
OsTskHighestSet(void)222 OS_SEC_ALW_INLINE INLINE void OsTskHighestSet(void)
223 {
224 U32 rdyListIdx;
225 struct TagListObject *readyList = NULL;
226 U32 childBitMapIdx;
227
228 /* find the highest priority */
229 /* get valid Child BitMap according to the ReadyListBitMap */
230 childBitMapIdx = OsGetLmb1(g_runQueue.taskReadyListBitMap);
231
232 /* get the ready list task priority idx in the Child BitMap */
233 rdyListIdx = OsGetLmb1(g_runQueue.tskChildBitMap[childBitMapIdx]);
234
235 /* get task ready list according to the task priority */
236 readyList = &(g_runQueue.readyList[OS_GET_32BIT_ARRAY_BASE(childBitMapIdx) + rdyListIdx]);
237
238 g_highestTask = GET_TCB_PEND(OS_LIST_FIRST(readyList));
239 }
240
OsTskReadyAddBgd(struct TagTskCb * task)241 OS_SEC_ALW_INLINE INLINE void OsTskReadyAddBgd(struct TagTskCb *task)
242 {
243 OsTskReadyAdd(task);
244 }
245
246 #endif /* PRT_TASK_EXTERNAL_H */
247