• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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