更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
los_task.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "los_task_pri.h"
33#include "los_base_pri.h"
34#include "los_event_pri.h"
35#include "los_exc.h"
36#include "los_hw_pri.h"
37#include "los_init.h"
38#include "los_memstat_pri.h"
39#include "los_mp.h"
40#include "los_mux_pri.h"
41#include "los_sched_pri.h"
42#include "los_sem_pri.h"
43#include "los_spinlock.h"
45#include "los_percpu_pri.h"
46#include "los_process_pri.h"
47#include "los_vm_map.h"
48#include "los_vm_syscall.h"
49#include "los_signal.h"
50#include "los_hook.h"
51
52#ifdef LOSCFG_KERNEL_CPUP
53#include "los_cpup_pri.h"
54#endif
55#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE
56#include "los_swtmr_pri.h"
57#endif
58#ifdef LOSCFG_KERNEL_LITEIPC
59#include "hm_liteipc.h"
60#endif
61#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK
62#include "los_oom.h"
63#endif
64
65/**
66 * @file los_task.c
67 * @brief
68 * @verbatim
69 基本概念
70 从系统角度看,任务是竞争系统资源的最小运行单元。任务可以使用或等待CPU、
71 使用内存空间等系统资源,并独立于其它任务运行。
72 任务模块可以给用户提供多个任务,实现任务间的切换,帮助用户管理业务程序流程。具有如下特性:
73 支持多任务。
74 一个任务表示一个线程。
75 抢占式调度机制,高优先级的任务可打断低优先级任务,低优先级任务必须在高优先级任务阻塞或结束后才能得到调度。
76 相同优先级任务支持时间片轮转调度方式。
77 共有32个优先级[0-31],最高优先级为0,最低优先级为31。
78
79 任务状态通常分为以下四种:
80 就绪(Ready):该任务在就绪队列中,只等待CPU。
81 运行(Running):该任务正在执行。
82 阻塞(Blocked):该任务不在就绪队列中。包含任务被挂起(suspend状态)、任务被延时(delay状态)、
83 任务正在等待信号量、读写队列或者等待事件等。
84 退出态(Dead):该任务运行结束,等待系统回收资源。
85
86 任务状态迁移说明
87 就绪态→运行态
88 任务创建后进入就绪态,发生任务切换时,就绪队列中最高优先级的任务被执行,
89 从而进入运行态,但此刻该任务依旧在就绪队列中。
90 运行态→阻塞态
91 正在运行的任务发生阻塞(挂起、延时、读信号量等)时,该任务会从就绪队列中删除,
92 任务状态由运行态变成阻塞态,然后发生任务切换,运行就绪队列中最高优先级任务。
93 阻塞态→就绪态(阻塞态→运行态)
94 阻塞的任务被恢复后(任务恢复、延时时间超时、读信号量超时或读到信号量等),此时被
95 恢复的任务会被加入就绪队列,从而由阻塞态变成就绪态;此时如果被恢复任务的优先级高于
96 正在运行任务的优先级,则会发生任务切换,该任务由就绪态变成运行态。
97 就绪态→阻塞态
98 任务也有可能在就绪态时被阻塞(挂起),此时任务状态由就绪态变为阻塞态,该任务
99 从就绪队列中删除,不会参与任务调度,直到该任务被恢复。
100 运行态→就绪态
101 有更高优先级任务创建或者恢复后,会发生任务调度,此刻就绪队列中最高优先级任务
102 变为运行态,那么原先运行的任务由运行态变为就绪态,依然在就绪队列中。
103 运行态→退出态
104 运行中的任务运行结束,任务状态由运行态变为退出态。退出态包含任务运行结束的正常退出状态
105 以及Invalid状态。例如,任务运行结束但是没有自删除,对外呈现的就是Invalid状态,即退出态。
106 阻塞态→退出态
107 阻塞的任务调用删除接口,任务状态由阻塞态变为退出态。
108
109 主要术语
110 任务ID
111 任务ID,在任务创建时通过参数返回给用户,是任务的重要标识。系统中的ID号是唯一的。用户可以
112 通过任务ID对指定任务进行任务挂起、任务恢复、查询任务名等操作。
113
114 任务优先级
115 优先级表示任务执行的优先顺序。任务的优先级决定了在发生任务切换时即将要执行的任务,
116 就绪队列中最高优先级的任务将得到执行。
117
118 任务入口函数
119 新任务得到调度后将执行的函数。该函数由用户实现,在任务创建时,通过任务创建结构体设置。
120
121 任务栈
122 每个任务都拥有一个独立的栈空间,我们称为任务栈。栈空间里保存的信息包含局部变量、寄存器、函数参数、函数返回地址等。
123
124 任务上下文
125 任务在运行过程中使用的一些资源,如寄存器等,称为任务上下文。当这个任务挂起时,其他任务继续执行,
126 可能会修改寄存器等资源中的值。如果任务切换时没有保存任务上下文,可能会导致任务恢复后出现未知错误。
127 因此,Huawei LiteOS在任务切换时会将切出任务的任务上下文信息,保存在自身的任务栈中,以便任务恢复后,
128 从栈空间中恢复挂起时的上下文信息,从而继续执行挂起时被打断的代码。
129 任务控制块TCB
130 每个任务都含有一个任务控制块(TCB)。TCB包含了任务上下文栈指针(stack pointer)、任务状态、
131 任务优先级、任务ID、任务名、任务栈大小等信息。TCB可以反映出每个任务运行情况。
132 任务切换
133 任务切换包含获取就绪队列中最高优先级任务、切出任务上下文保存、切入任务上下文恢复等动作。
134
135 运作机制
136 用户创建任务时,系统会初始化任务栈,预置上下文。此外,系统还会将“任务入口函数”
137 地址放在相应位置。这样在任务第一次启动进入运行态时,将会执行“任务入口函数”。
138 * @endverbatim
139 * @param pathname
140 * @return int
141 */
142
143#if (LOSCFG_BASE_CORE_TSK_LIMIT <= 0)
144#error "task maxnum cannot be zero"
145#endif /* LOSCFG_BASE_CORE_TSK_LIMIT <= 0 */
146
147LITE_OS_SEC_BSS LosTaskCB *g_taskCBArray;//任务池 128个
148LITE_OS_SEC_BSS LOS_DL_LIST g_losFreeTask;//空闲任务链表
149LITE_OS_SEC_BSS LOS_DL_LIST g_taskRecycleList;//回收任务链表
150LITE_OS_SEC_BSS UINT32 g_taskMaxNum;//任务最大个数
151LITE_OS_SEC_BSS UINT32 g_taskScheduled; /* one bit for each cores *///任务调度器,每个CPU都有对应位
152LITE_OS_SEC_BSS EVENT_CB_S g_resourceEvent;//资源的事件
153/* spinlock for task module, only available on SMP mode */
154LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_taskSpin);
155
156STATIC VOID OsConsoleIDSetHook(UINT32 param1,
157 UINT32 param2) __attribute__((weakref("OsSetConsoleID")));
158
159/* temp task blocks for booting procedure */
160LITE_OS_SEC_BSS STATIC LosTaskCB g_mainTask[LOSCFG_KERNEL_CORE_NUM];//启动引导过程中使用的临时任务
161
163{
164 return (LosTaskCB *)(g_mainTask + ArchCurrCpuid());
165}
166
168{
169 UINT32 i;
170 CHAR *name = "osMain";//任务名称
171 SchedParam schedParam = { 0 };
172
173 schedParam.policy = LOS_SCHED_RR;
174 schedParam.basePrio = OS_PROCESS_PRIORITY_HIGHEST;
175 schedParam.priority = OS_TASK_PRIORITY_LOWEST;
176 //为每个CPU core 设置mainTask
177 for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) {
178 g_mainTask[i].taskStatus = OS_TASK_STATUS_UNUSED;
179 g_mainTask[i].taskID = LOSCFG_BASE_CORE_TSK_LIMIT;//128
180 g_mainTask[i].processID = OS_KERNEL_PROCESS_GROUP;
181#ifdef LOSCFG_KERNEL_SMP_LOCKDEP
183 g_mainTask[i].lockDep.waitLock = NULL;
184#endif
185 (VOID)strncpy_s(g_mainTask[i].taskName, OS_TCB_NAME_LEN, name, OS_TCB_NAME_LEN - 1);
186 LOS_ListInit(&g_mainTask[i].lockList);//初始化任务锁链表,上面挂的是任务已申请到的互斥锁
187 (VOID)OsSchedParamInit(&g_mainTask[i], schedParam.policy, &schedParam, NULL);
188 }
189}
190///空闲任务,每个CPU都有自己的空闲任务
191LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID)
192{
193 while (1) {//只有一个死循环
194 WFI;//WFI指令:arm core 立即进入low-power standby state,进入休眠模式,等待中断。
195 }
196}
197
199{
201}
202
203/*!
204 * @brief OsTaskJoinPostUnsafe
205 * 查找task 通过 OS_TCB_FROM_PENDLIST 来完成,相当于由LOS_DL_LIST找到LosTaskCB,
206 * 将那些和参数任务绑在一起的task唤醒.
207 * @param taskCB
208 * @return
209 *
210 * @see
211 */
212LITE_OS_SEC_TEXT_INIT VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB)
213{
214 if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {//join任务处理
215 if (!LOS_ListEmpty(&taskCB->joinList)) {//注意到了这里 joinList中的节点身上都有阻塞标签
216 LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(taskCB->joinList)));//通过贴有JOIN标签链表的第一个节点找到Task
217 OsTaskWakeClearPendMask(resumedTask);//清除任务的挂起标记
218 resumedTask->ops->wake(resumedTask);
219 }
220 }
221 taskCB->taskStatus |= OS_TASK_STATUS_EXIT;//贴上任务退出标签
222}
223/// 挂起任务,任务进入等待链表,Join代表是支持通过一个任务去唤醒其他的任务
224LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB)
225{
226 if (taskCB->taskStatus & OS_TASK_STATUS_INIT) {
227 return LOS_EINVAL;
228 }
229
230 if (taskCB->taskStatus & OS_TASK_STATUS_EXIT) {
231 return LOS_OK;
232 }
233
234 if ((taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) && LOS_ListEmpty(&taskCB->joinList)) {
235 OsTaskWaitSetPendMask(OS_TASK_WAIT_JOIN, taskCB->taskID, LOS_WAIT_FOREVER);//设置任务的等待标记
236 LosTaskCB *runTask = OsCurrTaskGet();
237 return runTask->ops->wait(runTask, &taskCB->joinList, LOS_WAIT_FOREVER);
238 }
239
240 return LOS_EINVAL;
241}
242///任务设置分离模式 Deatch和JOIN是一对有你没我的状态
243LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB)
244{
245 if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {//join状态时
246 if (LOS_ListEmpty(&(taskCB->joinList))) {//joinlist中没有数据了
247 LOS_ListDelete(&(taskCB->joinList));//所谓删除就是自己指向自己
248 taskCB->taskStatus &= ~OS_TASK_FLAG_PTHREAD_JOIN;//去掉JOIN标签
249 return LOS_OK;
250 }
251 /* This error code has a special purpose and is not allowed to appear again on the interface */
252 return LOS_ESRCH;
253 }
254
255 return LOS_EINVAL;
256}
257
258//初始化任务模块
259LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(VOID)
260{
261 UINT32 index;
262 UINT32 size;
263 UINT32 ret;
264
265 g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT;//任务池中最多默认128个,可谓铁打的任务池流水的线程
266 size = (g_taskMaxNum + 1) * sizeof(LosTaskCB);//计算需分配内存总大小
267 /*
268 * This memory is resident memory and is used to save the system resources
269 * of task control block and will not be freed.
270 */
271 g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size);//任务池常驻内存,不被释放
272 if (g_taskCBArray == NULL) {
273 ret = LOS_ERRNO_TSK_NO_MEMORY;
274 goto EXIT;
275 }
276 (VOID)memset_s(g_taskCBArray, size, 0, size);
277
278 LOS_ListInit(&g_losFreeTask);//初始化空闲任务链表
279 LOS_ListInit(&g_taskRecycleList);//初始化回收任务链表
280 for (index = 0; index < g_taskMaxNum; index++) {//任务挨个初始化
281 g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED;//默认未使用,干净.
282 g_taskCBArray[index].taskID = index;//任务ID [0 ~ g_taskMaxNum - 1]
283 LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList);//通过pendList节点插入空闲任务列表
284 }//注意:这里挂的是pendList节点,所以取TCB也要通过 OS_TCB_FROM_PENDLIST 取.
285
286 ret = OsSchedInit();//调度器初始化
287
288EXIT:
289 if (ret != LOS_OK) {
290 PRINT_ERR("OsTaskInit error\n");
291 }
292 return ret;
293}
294///获取IdletaskId,每个CPU核都对Task进行了内部管理,做到真正的并行处理
296{
297 return OsSchedRunqueueIdleGet();
298}
299///创建一个空闲任务
300LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID)
301{
302 UINT32 ret;
303 TSK_INIT_PARAM_S taskInitParam;
304 UINT32 idleTaskID;
305
306 (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//任务初始参数清0
307 taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask;//入口函数
308 taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE;//任务栈大小 2K
309 taskInitParam.pcName = "Idle";//任务名称 叫pcName有点怪怪的,不能换个撒
310 taskInitParam.policy = LOS_SCHED_IDLE;
311 taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST;//默认最低优先级 31
312 taskInitParam.processID = OsGetIdleProcessID();//任务的进程ID绑定为空闲进程
313#ifdef LOSCFG_KERNEL_SMP
314 taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());//每个idle任务只在单独的cpu上运行
315#endif
316 ret = LOS_TaskCreateOnly(&idleTaskID, &taskInitParam);
317 if (ret != LOS_OK) {
318 return ret;
319 }
320 LosTaskCB *idleTask = OS_TCB_FROM_TID(idleTaskID);
321 idleTask->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK; //标记为系统任务,idle任务是给CPU休息用的,当然是个系统任务
322 OsSchedRunqueueIdleInit(idleTaskID);
323
324 return LOS_TaskResume(idleTaskID);
325}
326
327/*
328 * Description : get id of current running task. | 获取当前CPU正在执行的任务ID
329 * Return : task id
330 */
331LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
332{
333 LosTaskCB *runTask = OsCurrTaskGet();
334
335 if (runTask == NULL) {
336 return LOS_ERRNO_TSK_ID_INVALID;
337 }
338 return runTask->taskID;
339}
340/// 创建指定任务同步信号量
341STATIC INLINE UINT32 OsTaskSyncCreate(LosTaskCB *taskCB)
342{
343#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
344 UINT32 ret = LOS_SemCreate(0, &taskCB->syncSignal);
345 if (ret != LOS_OK) {
346 return LOS_ERRNO_TSK_MP_SYNC_RESOURCE;
347 }
348#else
349 (VOID)taskCB;
350#endif
351 return LOS_OK;
352}
353/// 销毁指定任务同步信号量
354STATIC INLINE VOID OsTaskSyncDestroy(UINT32 syncSignal)
355{
356#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
357 (VOID)LOS_SemDelete(syncSignal);
358#else
359 (VOID)syncSignal;
360#endif
361}
362
363#ifdef LOSCFG_KERNEL_SMP
364/*!
365 * @brief OsTaskSyncWait
366 * 任务同步等待,通过信号量保持同步
367 * @param taskCB
368 * @return
369 *
370 * @see
371 */
372STATIC INLINE UINT32 OsTaskSyncWait(const LosTaskCB *taskCB)
373{
374#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
375 UINT32 ret = LOS_OK;
376
377 LOS_ASSERT(LOS_SpinHeld(&g_taskSpin));
379 /*
380 * gc soft timer works every OS_MP_GC_PERIOD period, to prevent this timer
381 * triggered right at the timeout has reached, we set the timeout as double
382 * of the gc peroid.
383 */
384 if (LOS_SemPend(taskCB->syncSignal, OS_MP_GC_PERIOD * 2) != LOS_OK) {
385 ret = LOS_ERRNO_TSK_MP_SYNC_FAILED;
386 }
387
389
390 return ret;
391#else
392 (VOID)taskCB;
393 return LOS_OK;
394#endif
395}
396#endif
397/// 同步唤醒
398STATIC INLINE VOID OsTaskSyncWake(const LosTaskCB *taskCB)
399{
400#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
401 (VOID)OsSemPostUnsafe(taskCB->syncSignal, NULL);
402#else
403 (VOID)taskCB;
404#endif
405}
406
407STATIC INLINE VOID OsInsertTCBToFreeList(LosTaskCB *taskCB)
408{
409 UINT32 taskID = taskCB->taskID;
410 (VOID)memset_s(taskCB, sizeof(LosTaskCB), 0, sizeof(LosTaskCB));
411 taskCB->taskID = taskID;
412 taskCB->taskStatus = OS_TASK_STATUS_UNUSED;
413 taskCB->processID = OS_INVALID_VALUE;
415}
416
417STATIC VOID OsTaskKernelResourcesToFree(UINT32 syncSignal, UINTPTR topOfStack)
418{
419 OsTaskSyncDestroy(syncSignal);
420
421 (VOID)LOS_MemFree((VOID *)m_aucSysMem1, (VOID *)topOfStack);
422}
423
425{
426 UINT32 syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT;
427 UINT32 intSave;
428 UINTPTR topOfStack;
429
430#ifdef LOSCFG_KERNEL_VM
431 if ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) && (taskCB->userMapBase != 0)) {
432 SCHEDULER_LOCK(intSave);
433 UINT32 mapBase = (UINTPTR)taskCB->userMapBase;
434 UINT32 mapSize = taskCB->userMapSize;
435 taskCB->userMapBase = 0;
436 taskCB->userArea = 0;
437 SCHEDULER_UNLOCK(intSave);
438
439 LosProcessCB *processCB = OS_PCB_FROM_PID(taskCB->processID);
440 LOS_ASSERT(!(OsProcessVmSpaceGet(processCB) == NULL));
441 UINT32 ret = OsUnMMap(OsProcessVmSpaceGet(processCB), (UINTPTR)mapBase, mapSize);
442 if ((ret != LOS_OK) && (mapBase != 0) && !OsProcessIsInit(processCB)) {
443 PRINT_ERR("process(%u) unmmap user task(%u) stack failed! mapbase: 0x%x size :0x%x, error: %d\n",
444 taskCB->processID, taskCB->taskID, mapBase, mapSize, ret);
445 }
446
447#ifdef LOSCFG_KERNEL_LITEIPC
449#endif
450 }
451#endif
452
453 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
454 topOfStack = taskCB->topOfStack;
455 taskCB->topOfStack = 0;
456#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
457 syncSignal = taskCB->syncSignal;
458 taskCB->syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT;
459#endif
460 OsTaskKernelResourcesToFree(syncSignal, topOfStack);
461
462 SCHEDULER_LOCK(intSave);
463#ifdef LOSCFG_KERNEL_VM
464 OsClearSigInfoTmpList(&(taskCB->sig));
465#endif
466 OsInsertTCBToFreeList(taskCB);
467 SCHEDULER_UNLOCK(intSave);
468 }
469 return;
470}
471
472LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree()
473{
474 UINT32 intSave;
475
476 SCHEDULER_LOCK(intSave);
478 LosTaskCB *taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecycleList));
479 LOS_ListDelete(&taskCB->pendList);
480 SCHEDULER_UNLOCK(intSave);
481
482 OsTaskResourcesToFree(taskCB);
483
484 SCHEDULER_LOCK(intSave);
485 }
486 SCHEDULER_UNLOCK(intSave);
487}
488
489/*
490 * Description : All task entry
491 * Input : taskID --- The ID of the task to be run
492 *///所有任务的入口函数,OsTaskEntry是在new task OsTaskStackInit 时指定的
493LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID)
494{
495 LOS_ASSERT(!OS_TID_CHECK_INVALID(taskID));
496
497 /*
498 * task scheduler needs to be protected throughout the whole process
499 * from interrupt and other cores. release task spinlock and enable
500 * interrupt in sequence at the task entry.
501 */
502 LOS_SpinUnlock(&g_taskSpin);//释放任务自旋锁
503 (VOID)LOS_IntUnLock();//恢复中断
504
505 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
506 taskCB->joinRetval = taskCB->taskEntry(taskCB->args[0], taskCB->args[1],//调用任务的入口函数
507 taskCB->args[2], taskCB->args[3]); /* 2 & 3: just for args array index */
508 if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) {
509 taskCB->joinRetval = 0;//结合数为0
510 }
511
512 OsRunningTaskToExit(taskCB, 0);
513}
514///任务创建参数检查
515LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCreateParamCheck(const UINT32 *taskID,
516 TSK_INIT_PARAM_S *initParam, VOID **pool)
517{
518 UINT32 poolSize = OS_SYS_MEM_SIZE;
519 *pool = (VOID *)m_aucSysMem1;//默认使用 系统动态内存池地址的起始地址
520
521 if (taskID == NULL) {
522 return LOS_ERRNO_TSK_ID_INVALID;
523 }
524
525 if (initParam == NULL) {
526 return LOS_ERRNO_TSK_PTR_NULL;
527 }
528
529 LosProcessCB *process = OS_PCB_FROM_PID(initParam->processID);
530 if (!OsProcessIsUserMode(process)) {
531 if (initParam->pcName == NULL) {
532 return LOS_ERRNO_TSK_NAME_EMPTY;
533 }
534 }
535
536 if (initParam->pfnTaskEntry == NULL) {//入口函数不能为空
537 return LOS_ERRNO_TSK_ENTRY_NULL;
538 }
539
540 if (initParam->usTaskPrio > OS_TASK_PRIORITY_LOWEST) {//优先级必须大于31
541 return LOS_ERRNO_TSK_PRIOR_ERROR;
542 }
543
544 if (initParam->uwStackSize > poolSize) {//希望申请的栈大小不能大于总池子
545 return LOS_ERRNO_TSK_STKSZ_TOO_LARGE;
546 }
547
548 if (initParam->uwStackSize == 0) {//任何任务都必须由内核态栈,所以uwStackSize不能为0
549 initParam->uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
550 }
551 initParam->uwStackSize = (UINT32)ALIGN(initParam->uwStackSize, LOSCFG_STACK_POINT_ALIGN_SIZE);
552
553 if (initParam->uwStackSize < LOS_TASK_MIN_STACK_SIZE) {//运行栈空间不能低于最低值
554 return LOS_ERRNO_TSK_STKSZ_TOO_SMALL;
555 }
556
557 return LOS_OK;
558}
559///任务栈(内核态)内存分配,由内核态进程空间提供,即 KProcess 的进程空间
560LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskStackAlloc(VOID **topStack, UINT32 stackSize, VOID *pool)
561{
562 *topStack = (VOID *)LOS_MemAllocAlign(pool, stackSize, LOSCFG_STACK_POINT_ALIGN_SIZE);
563}
564
565///任务基本信息的初始化
566STATIC VOID TaskCBBaseInit(LosTaskCB *taskCB, const VOID *stackPtr, const VOID *topStack,
567 const TSK_INIT_PARAM_S *initParam)
568{
569 taskCB->stackPointer = (VOID *)stackPtr;//内核态SP位置
570 taskCB->args[0] = initParam->auwArgs[0]; /* 0~3: just for args array index */
571 taskCB->args[1] = initParam->auwArgs[1];
572 taskCB->args[2] = initParam->auwArgs[2];
573 taskCB->args[3] = initParam->auwArgs[3];
574 taskCB->topOfStack = (UINTPTR)topStack; //内核态栈顶
575 taskCB->stackSize = initParam->uwStackSize;//
576 taskCB->taskEntry = initParam->pfnTaskEntry;
577 taskCB->signal = SIGNAL_NONE;
578
579#ifdef LOSCFG_KERNEL_SMP
580 taskCB->currCpu = OS_TASK_INVALID_CPUID;
581 taskCB->cpuAffiMask = (initParam->usCpuAffiMask) ?
582 initParam->usCpuAffiMask : LOSCFG_KERNEL_CPU_MASK;
583#endif
584 taskCB->taskStatus = OS_TASK_STATUS_INIT;
585 if (initParam->uwResved & LOS_TASK_ATTR_JOINABLE) {
586 taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN;
587 LOS_ListInit(&taskCB->joinList);
588 }
589
590 LOS_ListInit(&taskCB->lockList);//初始化互斥锁链表
591 SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME);
592}
593///任务初始化
594STATIC UINT32 OsTaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam,
595 const VOID *stackPtr, const VOID *topStack)
596{
597 UINT32 ret;
598 UINT32 numCount;
599 SchedParam schedParam = { 0 };
600 UINT16 policy = (initParam->policy == LOS_SCHED_NORMAL) ? LOS_SCHED_RR : initParam->policy;
601
602 TaskCBBaseInit(taskCB, stackPtr, topStack, initParam);//初始化任务的基本信息,
603 //taskCB->stackPointer指向内核态栈 sp位置,该位置存着 任务初始上下文
604
605 schedParam.policy = policy;
606 numCount = OsProcessAddNewTask(initParam->processID, taskCB, &schedParam);
607#ifdef LOSCFG_KERNEL_VM
608 taskCB->futex.index = OS_INVALID_VALUE;
609 if (taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) {
610 taskCB->userArea = initParam->userParam.userArea;
611 taskCB->userMapBase = initParam->userParam.userMapBase;
612 taskCB->userMapSize = initParam->userParam.userMapSize;
613 OsUserTaskStackInit(taskCB->stackPointer, (UINTPTR)taskCB->taskEntry, initParam->userParam.userSP);//初始化用户态任务栈
614 //这里要注意,任务的上下文是始终保存在内核栈空间,而用户态时运行在用户态栈空间.(context->SP = userSP 指向了用户态栈空间)
615 }
616#endif
617
618 ret = OsSchedParamInit(taskCB, policy, &schedParam, initParam);
619 if (ret != LOS_OK) {
620 return ret;
621 }
622
623 if (initParam->pcName != NULL) {
624 ret = (UINT32)OsSetTaskName(taskCB, initParam->pcName, FALSE);
625 if (ret == LOS_OK) {
626 return LOS_OK;
627 }
628 }
629
630 if (snprintf_s(taskCB->taskName, OS_TCB_NAME_LEN, OS_TCB_NAME_LEN - 1, "thread%u", numCount) < 0) {
631 return LOS_NOK;
632 }
633 return LOS_OK;
634}
635///获取一个空闲TCB
636LITE_OS_SEC_TEXT LosTaskCB *OsGetFreeTaskCB(VOID)
637{
638 UINT32 intSave;
639
640 SCHEDULER_LOCK(intSave);
641 if (LOS_ListEmpty(&g_losFreeTask)) {//全局空闲task为空
642 SCHEDULER_UNLOCK(intSave);
643 PRINT_ERR("No idle TCB in the system!\n");
644 return NULL;
645 }
646
647 LosTaskCB *taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_losFreeTask));
648 LOS_ListDelete(LOS_DL_LIST_FIRST(&g_losFreeTask));//从g_losFreeTask链表中摘除自己
649 SCHEDULER_UNLOCK(intSave);
650
651 return taskCB;
652}
653
654/*!
655 * @brief LOS_TaskCreateOnly
656 * 创建任务,并使该任务进入suspend状态,不对该任务进行调度。如果需要调度,可以调用LOS_TaskResume使该任务进入ready状态
657 * @param initParam
658 * @param taskID
659 * @return
660 *
661 * @see
662 */
663LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
664{
665 UINT32 intSave, errRet;
666 VOID *topStack = NULL;
667 VOID *pool = NULL;
668
669 errRet = OsTaskCreateParamCheck(taskID, initParam, &pool);//参数检查,获取内存池 *pool = (VOID *)m_aucSysMem1;
670 if (errRet != LOS_OK) {
671 return errRet;
672 }
673
674 LosTaskCB *taskCB = OsGetFreeTaskCB();//从g_losFreeTask中获取,还记得吗任务池中最多默认128个
675 if (taskCB == NULL) {
676 errRet = LOS_ERRNO_TSK_TCB_UNAVAILABLE;
677 goto LOS_ERREND;
678 }
679
680 errRet = OsTaskSyncCreate(taskCB);//SMP cpu多核间负载均衡相关
681 if (errRet != LOS_OK) {
682 goto LOS_ERREND_REWIND_TCB;
683 }
684 //OsTaskStackAlloc 只在LOS_TaskCreateOnly中被调用,此处是分配任务在内核态栈空间
685 OsTaskStackAlloc(&topStack, initParam->uwStackSize, pool);//为任务分配内核栈空间,注意此内存来自系统内核空间
686 if (topStack == NULL) {
687 errRet = LOS_ERRNO_TSK_NO_MEMORY;
688 goto LOS_ERREND_REWIND_SYNC;
689 }
690
691 VOID *stackPtr = OsTaskStackInit(taskCB->taskID, initParam->uwStackSize, topStack, TRUE);//初始化内核态任务栈,返回栈SP位置
692 errRet = OsTaskCBInit(taskCB, initParam, stackPtr, topStack);//初始化TCB,包括绑定进程等操作
693 if (errRet != LOS_OK) {
694 goto LOS_ERREND_TCB_INIT;
695 }
696 if (OsConsoleIDSetHook != NULL) {//每个任务都可以有属于自己的控制台
697 OsConsoleIDSetHook(taskCB->taskID, OsCurrTaskGet()->taskID);//设置控制台ID
698 }
699
700 *taskID = taskCB->taskID;
701 OsHookCall(LOS_HOOK_TYPE_TASK_CREATE, taskCB);
702 return LOS_OK;
703
704LOS_ERREND_TCB_INIT:
705 (VOID)LOS_MemFree(pool, topStack);
706LOS_ERREND_REWIND_SYNC:
707#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
709#endif
710LOS_ERREND_REWIND_TCB:
711 SCHEDULER_LOCK(intSave);
712 OsInsertTCBToFreeList(taskCB);//归还freetask
713 SCHEDULER_UNLOCK(intSave);
714LOS_ERREND:
715 return errRet;
716}
717///创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务
718LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
719{
720 UINT32 ret;
721 UINT32 intSave;
722
723 if (initParam == NULL) {
724 return LOS_ERRNO_TSK_PTR_NULL;
725 }
726
727 if (OS_INT_ACTIVE) {
728 return LOS_ERRNO_TSK_YIELD_IN_INT;
729 }
730
731 if (OsProcessIsUserMode(OsCurrProcessGet())) { //当前进程为用户进程
732 initParam->processID = OsGetKernelInitProcessID();//@note_thinking 为什么进程ID变成了内核态根进程
733 } else {
734 initParam->processID = OsCurrProcessGet()->processID;
735 }
736
737 ret = LOS_TaskCreateOnly(taskID, initParam);
738 if (ret != LOS_OK) {
739 return ret;
740 }
741
742 LosTaskCB *taskCB = OS_TCB_FROM_TID(*taskID);
743
744 SCHEDULER_LOCK(intSave);
745 taskCB->ops->enqueue(OsSchedRunqueue(), taskCB);
746 SCHEDULER_UNLOCK(intSave);
747
748 /* in case created task not running on this core,
749 schedule or not depends on other schedulers status. */
750 LOS_MpSchedule(OS_MP_CPU_ALL);
751 if (OS_SCHEDULER_ACTIVE) {
752 LOS_Schedule();
753 }
754
755 return LOS_OK;
756}
757///恢复挂起的任务,使该任务进入ready状态
758LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID)
759{
760 UINT32 intSave;
761 UINT32 errRet;
762 BOOL needSched = FALSE;
763
764 if (OS_TID_CHECK_INVALID(taskID)) {
765 return LOS_ERRNO_TSK_ID_INVALID;
766 }
767
768 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
769 SCHEDULER_LOCK(intSave);
770
771 /* clear pending signal */
772 taskCB->signal &= ~SIGNAL_SUSPEND;//清楚挂起信号
773
774 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
775 errRet = LOS_ERRNO_TSK_NOT_CREATED;
776 OS_GOTO_ERREND();
777 } else if (!(taskCB->taskStatus & OS_TASK_STATUS_SUSPENDED)) {
778 errRet = LOS_ERRNO_TSK_NOT_SUSPENDED;
779 OS_GOTO_ERREND();
780 }
781
782 errRet = taskCB->ops->resume(taskCB, &needSched);
783 SCHEDULER_UNLOCK(intSave);
784
785 LOS_MpSchedule(OS_MP_CPU_ALL);
786 if (OS_SCHEDULER_ACTIVE && needSched) {
787 LOS_Schedule();
788 }
789
790 return errRet;
791
792LOS_ERREND:
793 SCHEDULER_UNLOCK(intSave);
794 return errRet;
795}
796
797/*
798 * Check if needs to do the suspend operation on the running task. //检查是否需要对正在运行的任务执行挂起操作。
799 * Return TRUE, if needs to do the suspension. //如果需要暂停,返回TRUE。
800 * Rerturn FALSE, if meets following circumstances: //如果满足以下情况,则返回FALSE:
801 * 1. Do the suspension across cores, if SMP is enabled //1.如果启用了SMP,则跨CPU核执行挂起操作
802 * 2. Do the suspension when preemption is disabled //2.当禁用抢占时则挂起
803 * 3. Do the suspension in hard-irq //3.在硬中断时则挂起
804 * then LOS_TaskSuspend will directly return with 'ret' value. //那么LOS_taskssuspend将直接返回ret值。
805 */
806LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UINT32 *ret)
807{
808 /* init default out return value */
809 *ret = LOS_OK;
810
811#ifdef LOSCFG_KERNEL_SMP
812 /* ASYNCHRONIZED. No need to do task lock checking */
813 if (taskCB->currCpu != ArchCurrCpuid()) {//跨CPU核的情况
814 taskCB->signal = SIGNAL_SUSPEND;
815 LOS_MpSchedule(taskCB->currCpu);//task所属CPU执行调度
816 return FALSE;
817 }
818#endif
819
820 if (!OsPreemptableInSched()) {//不能抢占时
821 /* Suspending the current core's running task */
822 *ret = LOS_ERRNO_TSK_SUSPEND_LOCKED;
823 return FALSE;
824 }
825
826 if (OS_INT_ACTIVE) {//正在硬中断中
827 /* suspend running task in interrupt */
828 taskCB->signal = SIGNAL_SUSPEND;
829 return FALSE;
830 }
831
832 return TRUE;
833}
834///任务暂停,参数可以不是当前任务,也就是说 A任务可以让B任务处于阻塞状态,挂起指定的任务,然后切换任务
835LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB)
836{
837 UINT32 errRet;
838 UINT16 tempStatus = taskCB->taskStatus;
839 if (tempStatus & OS_TASK_STATUS_UNUSED) {
840 return LOS_ERRNO_TSK_NOT_CREATED;
841 }
842
843 if (tempStatus & OS_TASK_STATUS_SUSPENDED) {
844 return LOS_ERRNO_TSK_ALREADY_SUSPENDED;
845 }
846
847 if ((tempStatus & OS_TASK_STATUS_RUNNING) && //如果参数任务正在运行,注意多Cpu core情况下,贴着正在运行标签的任务并不一定是当前CPU的执行任务,
848 !OsTaskSuspendCheckOnRun(taskCB, &errRet)) {//很有可能是别的CPU core在跑的任务
849 return errRet;
850 }
851
852 return taskCB->ops->suspend(taskCB);
853}
854///外部接口,对OsTaskSuspend的封装
855LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID)
856{
857 UINT32 intSave;
858 UINT32 errRet;
859
860 if (OS_TID_CHECK_INVALID(taskID)) {
861 return LOS_ERRNO_TSK_ID_INVALID;
862 }
863
864 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
865 if (taskCB->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
866 return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK;
867 }
868
869 SCHEDULER_LOCK(intSave);
870 errRet = OsTaskSuspend(taskCB);
871 SCHEDULER_UNLOCK(intSave);
872 return errRet;
873}
874///设置任务为不使用状态
875STATIC INLINE VOID OsTaskStatusUnusedSet(LosTaskCB *taskCB)
876{
877 taskCB->taskStatus |= OS_TASK_STATUS_UNUSED;
878 taskCB->eventMask = 0;
879
880 OS_MEM_CLEAR(taskCB->taskID);
881}
882
884{
885 LosMux *mux = NULL;
886 UINT32 ret;
887
888 while (!LOS_ListEmpty(&taskCB->lockList)) {
889 mux = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&taskCB->lockList), LosMux, holdList);
890 ret = OsMuxUnlockUnsafe(taskCB, mux, NULL);
891 if (ret != LOS_OK) {
893 PRINT_ERR("mux ulock failed! : %u\n", ret);
894 }
895 }
896
897#ifdef LOSCFG_KERNEL_VM
898 if (taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) {
899 OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL);
900 }
901#endif
902
903 OsTaskJoinPostUnsafe(taskCB);
904
905 OsTaskSyncWake(taskCB);
906}
907
908LITE_OS_SEC_TEXT VOID OsRunningTaskToExit(LosTaskCB *runTask, UINT32 status)
909{
910 UINT32 intSave;
911
912 if (OsProcessThreadGroupIDGet(runTask) == runTask->taskID) {
914 }
915
916 OsHookCall(LOS_HOOK_TYPE_TASK_DELETE, runTask);
917
918 SCHEDULER_LOCK(intSave);
919 if (OsProcessThreadNumberGet(runTask) == 1) { /* 1: The last task of the process exits */
920 SCHEDULER_UNLOCK(intSave);
921
922 OsTaskResourcesToFree(runTask);
923 OsProcessResourcesToFree(OS_PCB_FROM_PID(runTask->processID));
924
925 SCHEDULER_LOCK(intSave);
926
927 OsProcessNaturalExit(OS_PCB_FROM_PID(runTask->processID), status);
928 OsTaskReleaseHoldLock(runTask);
929 OsTaskStatusUnusedSet(runTask);
930 } else if (runTask->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {
931 OsTaskReleaseHoldLock(runTask);
932 } else {
933 SCHEDULER_UNLOCK(intSave);
934
935 OsTaskResourcesToFree(runTask);
936
937 SCHEDULER_LOCK(intSave);
938 OsInactiveTaskDelete(runTask);
939 OsEventWriteUnsafe(&g_resourceEvent, OS_RESOURCE_EVENT_FREE, FALSE, NULL);
940 }
941
943 SCHEDULER_UNLOCK(intSave);
944 return;
945}
946
947LITE_OS_SEC_TEXT VOID OsInactiveTaskDelete(LosTaskCB *taskCB)
948{
949 UINT16 taskStatus = taskCB->taskStatus;
950
951 OsTaskReleaseHoldLock(taskCB);
952
953 taskCB->ops->exit(taskCB);
954 if (taskStatus & OS_TASK_STATUS_PENDING) {
955 LosMux *mux = (LosMux *)taskCB->taskMux;
956 if (LOS_MuxIsValid(mux) == TRUE) {
957 OsMuxBitmapRestore(mux, NULL, taskCB);
958 }
959 }
960
961 OsTaskStatusUnusedSet(taskCB);
962
964
965 OsHookCall(LOS_HOOK_TYPE_TASK_DELETE, taskCB);
966}
967
968LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID)
969{
970 UINT32 intSave;
971 UINT32 ret = LOS_OK;
972
973 if (OS_TID_CHECK_INVALID(taskID)) {
974 return LOS_ERRNO_TSK_ID_INVALID;
975 }
976
977 if (OS_INT_ACTIVE) {
978 return LOS_ERRNO_TSK_YIELD_IN_INT;
979 }
980
981 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
982 if (taskCB == OsCurrTaskGet()) {
983 if (!OsPreemptable()) {
984 return LOS_ERRNO_TSK_DELETE_LOCKED;
985 }
986 OsRunningTaskToExit(taskCB, OS_PRO_EXIT_OK);
987 return LOS_NOK;
988 }
989
990 SCHEDULER_LOCK(intSave);
991 if (taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_FLAG_SYSTEM_TASK | OS_TASK_FLAG_NO_DELETE)) {
992 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
993 ret = LOS_ERRNO_TSK_NOT_CREATED;
994 } else {
995 ret = LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK;
996 }
997 OS_GOTO_ERREND();
998 }
999
1000#ifdef LOSCFG_KERNEL_SMP
1001 if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {
1002 taskCB->signal = SIGNAL_KILL;
1003 LOS_MpSchedule(taskCB->currCpu);
1004 ret = OsTaskSyncWait(taskCB);
1005 OS_GOTO_ERREND();
1006 }
1007#endif
1008
1009 OsInactiveTaskDelete(taskCB);
1010 OsEventWriteUnsafe(&g_resourceEvent, OS_RESOURCE_EVENT_FREE, FALSE, NULL);
1011
1012LOS_ERREND:
1013 SCHEDULER_UNLOCK(intSave);
1014 if (ret == LOS_OK) {
1015 LOS_Schedule();
1016 }
1017 return ret;
1018}
1019///任务延时等待,释放CPU,等待时间到期后该任务会重新进入ready状态
1020LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)
1021{
1022 UINT32 intSave;
1023
1024 if (OS_INT_ACTIVE) {
1025 PRINT_ERR("In interrupt not allow delay task!\n");
1026 return LOS_ERRNO_TSK_DELAY_IN_INT;
1027 }
1028
1029 LosTaskCB *runTask = OsCurrTaskGet();
1030 if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
1031 OsBackTrace();
1032 return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK;
1033 }
1034
1035 if (!OsPreemptable()) {
1036 return LOS_ERRNO_TSK_DELAY_IN_LOCK;
1037 }
1038 OsHookCall(LOS_HOOK_TYPE_TASK_DELAY, tick);
1039 if (tick == 0) {
1040 return LOS_TaskYield();
1041 }
1042
1043 SCHEDULER_LOCK(intSave);
1044 UINT32 ret = runTask->ops->delay(runTask, OS_SCHED_TICK_TO_CYCLE(tick));
1045 OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, runTask);
1046 SCHEDULER_UNLOCK(intSave);
1047 return ret;
1048}
1049///获取任务的优先级
1050LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID)
1051{
1052 UINT32 intSave;
1053 SchedParam param = { 0 };
1054
1055 if (OS_TID_CHECK_INVALID(taskID)) {
1056 return (UINT16)OS_INVALID;
1057 }
1058
1059 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1060 SCHEDULER_LOCK(intSave);
1061 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//就这么一句话也要来个自旋锁,内核代码自旋锁真是无处不在啊
1062 SCHEDULER_UNLOCK(intSave);
1063 return (UINT16)OS_INVALID;
1064 }
1065
1066 taskCB->ops->schedParamGet(taskCB, &param);
1067 SCHEDULER_UNLOCK(intSave);
1068 return param.priority;
1069}
1070///设置指定任务的优先级
1071LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio)
1072{
1073 UINT32 intSave;
1074 SchedParam param = { 0 };
1075
1076 if (taskPrio > OS_TASK_PRIORITY_LOWEST) {
1077 return LOS_ERRNO_TSK_PRIOR_ERROR;
1078 }
1079
1080 if (OS_TID_CHECK_INVALID(taskID)) {
1081 return LOS_ERRNO_TSK_ID_INVALID;
1082 }
1083
1084 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1085 if (taskCB->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
1086 return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK;
1087 }
1088
1089 SCHEDULER_LOCK(intSave);
1090 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
1091 SCHEDULER_UNLOCK(intSave);
1092 return LOS_ERRNO_TSK_NOT_CREATED;
1093 }
1094
1095 taskCB->ops->schedParamGet(taskCB, &param);
1096
1097 param.priority = taskPrio;
1098
1099 BOOL needSched = taskCB->ops->schedParamModify(taskCB, &param);
1100 SCHEDULER_UNLOCK(intSave);
1101
1102 LOS_MpSchedule(OS_MP_CPU_ALL);
1103 if (needSched && OS_SCHEDULER_ACTIVE) {
1104 LOS_Schedule();
1105 }
1106 return LOS_OK;
1107}
1108///设置当前任务的优先级
1109LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio)
1110{
1111 return LOS_TaskPriSet(OsCurrTaskGet()->taskID, taskPrio);
1112}
1113
1114//当前任务释放CPU,并将其移到具有相同优先级的就绪任务队列的末尾. 读懂这个函数 你就彻底搞懂了 yield
1115LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID)
1116{
1117 UINT32 intSave;
1118
1119 if (OS_INT_ACTIVE) {
1120 return LOS_ERRNO_TSK_YIELD_IN_INT;
1121 }
1122
1123 if (!OsPreemptable()) {
1124 return LOS_ERRNO_TSK_YIELD_IN_LOCK;
1125 }
1126
1127 LosTaskCB *runTask = OsCurrTaskGet();
1128 if (OS_TID_CHECK_INVALID(runTask->taskID)) {
1129 return LOS_ERRNO_TSK_ID_INVALID;
1130 }
1131
1132 SCHEDULER_LOCK(intSave);
1133 /* reset timeslice of yielded task */
1134 runTask->ops->yield(runTask);
1135 SCHEDULER_UNLOCK(intSave);
1136 return LOS_OK;
1137}
1138
1139LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID)
1140{
1141 UINT32 intSave;
1142
1143 intSave = LOS_IntLock();
1144 OsSchedLock();
1145 LOS_IntRestore(intSave);
1146}
1147
1148LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID)
1149{
1150 UINT32 intSave;
1151
1152 intSave = LOS_IntLock();
1153 BOOL needSched = OsSchedUnlockResch();
1154 LOS_IntRestore(intSave);
1155
1156 if (needSched) {
1157 LOS_Schedule();
1158 }
1159}
1160//获取任务信息,给shell使用的
1161LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo)
1162{
1163 UINT32 intSave;
1164 SchedParam param = { 0 };
1165
1166 if (taskInfo == NULL) {
1167 return LOS_ERRNO_TSK_PTR_NULL;
1168 }
1169
1170 if (OS_TID_CHECK_INVALID(taskID)) {
1171 return LOS_ERRNO_TSK_ID_INVALID;
1172 }
1173
1174 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1175 SCHEDULER_LOCK(intSave);
1176 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
1177 SCHEDULER_UNLOCK(intSave);
1178 return LOS_ERRNO_TSK_NOT_CREATED;
1179 }
1180
1181 if (!(taskCB->taskStatus & OS_TASK_STATUS_RUNNING) || OS_INT_ACTIVE) {
1182 taskInfo->uwSP = (UINTPTR)taskCB->stackPointer;
1183 } else {
1184 taskInfo->uwSP = ArchSPGet();
1185 }
1186
1187 taskCB->ops->schedParamGet(taskCB, &param);
1188 taskInfo->usTaskStatus = taskCB->taskStatus;
1189 taskInfo->usTaskPrio = param.priority;
1190 taskInfo->uwStackSize = taskCB->stackSize; //内核态栈大小
1191 taskInfo->uwTopOfStack = taskCB->topOfStack;//内核态栈顶位置
1192 taskInfo->uwEventMask = taskCB->eventMask;
1193 taskInfo->taskEvent = taskCB->taskEvent;
1194 taskInfo->pTaskMux = taskCB->taskMux;
1195 taskInfo->uwTaskID = taskID;
1196
1197 if (strncpy_s(taskInfo->acName, LOS_TASK_NAMELEN, taskCB->taskName, LOS_TASK_NAMELEN - 1) != EOK) {
1198 PRINT_ERR("Task name copy failed!\n");
1199 }
1200 taskInfo->acName[LOS_TASK_NAMELEN - 1] = '\0';
1201
1202 taskInfo->uwBottomOfStack = TRUNCATE(((UINTPTR)taskCB->topOfStack + taskCB->stackSize),//这里可以看出栈底地址是高于栈顶
1203 OS_TASK_STACK_ADDR_ALIGN);
1204 taskInfo->uwCurrUsed = (UINT32)(taskInfo->uwBottomOfStack - taskInfo->uwSP);//当前任务栈已使用了多少
1205
1206 taskInfo->bOvf = OsStackWaterLineGet((const UINTPTR *)taskInfo->uwBottomOfStack,//获取栈的使用情况
1207 (const UINTPTR *)taskInfo->uwTopOfStack, &taskInfo->uwPeakUsed);
1208 SCHEDULER_UNLOCK(intSave);
1209 return LOS_OK;
1210}
1211///CPU亲和性(affinity)将任务绑在指定CPU上,用于多核CPU情况,(该函数仅在SMP模式下支持)
1212LITE_OS_SEC_TEXT BOOL OsTaskCpuAffiSetUnsafe(UINT32 taskID, UINT16 newCpuAffiMask, UINT16 *oldCpuAffiMask)
1213{
1214#ifdef LOSCFG_KERNEL_SMP
1215 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1216
1217 taskCB->cpuAffiMask = newCpuAffiMask;
1218 *oldCpuAffiMask = CPUID_TO_AFFI_MASK(taskCB->currCpu);
1219 if (!((*oldCpuAffiMask) & newCpuAffiMask)) {
1220 taskCB->signal = SIGNAL_AFFI;
1221 return TRUE;
1222 }
1223#else
1224 (VOID)taskID;
1225 (VOID)newCpuAffiMask;
1226 (VOID)oldCpuAffiMask;
1227#endif /* LOSCFG_KERNEL_SMP */
1228 return FALSE;
1229}
1230
1231LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMask)
1232{
1233 BOOL needSched = FALSE;
1234 UINT32 intSave;
1235 UINT16 currCpuMask;
1236
1237 if (OS_TID_CHECK_INVALID(taskID)) {//检测taskid是否有效,task由task池分配,鸿蒙默认128个任务 ID范围[0:127]
1238 return LOS_ERRNO_TSK_ID_INVALID;
1239 }
1240
1241 if (!(cpuAffiMask & LOSCFG_KERNEL_CPU_MASK)) {//检测cpu亲和力
1242 return LOS_ERRNO_TSK_CPU_AFFINITY_MASK_ERR;
1243 }
1244
1245 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1246 SCHEDULER_LOCK(intSave);
1247 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//贴有未使用标签的处理
1248 SCHEDULER_UNLOCK(intSave);
1249 return LOS_ERRNO_TSK_NOT_CREATED;
1250 }
1251 needSched = OsTaskCpuAffiSetUnsafe(taskID, cpuAffiMask, &currCpuMask);
1252
1253 SCHEDULER_UNLOCK(intSave);
1254
1255 if (needSched && OS_SCHEDULER_ACTIVE) {
1256 LOS_MpSchedule(currCpuMask);//发送信号调度信号给目标CPU
1257 LOS_Schedule();//申请调度
1258 }
1259
1260 return LOS_OK;
1261}
1262///查询任务被绑在哪个CPU上
1263LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID)
1264{
1265#ifdef LOSCFG_KERNEL_SMP
1266#define INVALID_CPU_AFFI_MASK 0
1267 UINT16 cpuAffiMask;
1268 UINT32 intSave;
1269
1270 if (OS_TID_CHECK_INVALID(taskID)) {
1271 return INVALID_CPU_AFFI_MASK;
1272 }
1273
1274 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1275 SCHEDULER_LOCK(intSave);
1276 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { //任务必须在使用
1277 SCHEDULER_UNLOCK(intSave);
1278 return INVALID_CPU_AFFI_MASK;
1279 }
1280
1281 cpuAffiMask = taskCB->cpuAffiMask; //获取亲和力掩码
1282 SCHEDULER_UNLOCK(intSave);
1283
1284 return cpuAffiMask;
1285#else
1286 (VOID)taskID;
1287 return 1;//单核情况直接返回1 ,0号cpu对应0x01
1288#endif
1289}
1290
1291/*
1292 * Description : Process pending signals tagged by others cores
1293 */
1294 /*!
1295 由其他CPU核触发阻塞进程的信号
1296 函数由汇编代码调用 ..\arch\arm\arm\src\los_dispatch.S
1297*/
1298LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID)
1299{
1300 UINT32 ret;
1301 //私有且不可中断,无需保护。这个任务在其他CPU核看到它时总是在运行,所以它在执行代码的同时也可以继续接收信号
1302 /*
1303 * private and uninterruptable, no protection needed.
1304 * while this task is always running when others cores see it,
1305 * so it keeps receiving signals while follow code executing.
1306 */
1307 LosTaskCB *runTask = OsCurrTaskGet();
1308 if (runTask->signal == SIGNAL_NONE) {
1309 return;
1310 }
1311
1312 if (runTask->signal & SIGNAL_KILL) {//意思是其他cpu发起了要干掉你的信号
1313 /*
1314 * clear the signal, and do the task deletion. if the signaled task has been
1315 * scheduled out, then this deletion will wait until next run.
1316 *///如果发出信号的任务已出调度就绪队列,则此删除将等待下次运行
1317 runTask->signal = SIGNAL_NONE;//清除信号,
1318 ret = LOS_TaskDelete(runTask->taskID);
1319 if (ret != LOS_OK) {
1320 PRINT_ERR("Task proc signal delete task(%u) failed err:0x%x\n", runTask->taskID, ret);
1321 }
1322 } else if (runTask->signal & SIGNAL_SUSPEND) {//意思是其他cpu发起了要挂起你的信号
1323 runTask->signal &= ~SIGNAL_SUSPEND;//任务贴上被其他CPU挂起的标签
1324
1325 /* suspend killed task may fail, ignore the result */
1326 (VOID)LOS_TaskSuspend(runTask->taskID);
1327#ifdef LOSCFG_KERNEL_SMP
1328 } else if (runTask->signal & SIGNAL_AFFI) {//意思是下次调度其他cpu要媾和你
1329 runTask->signal &= ~SIGNAL_AFFI;//任务贴上被其他CPU媾和的标签
1330
1331 /* pri-queue has updated, notify the target cpu */
1332 LOS_MpSchedule((UINT32)runTask->cpuAffiMask);//发生调度,此任务将移交给媾和CPU运行.
1333#endif
1334 }
1335}
1336
1337LITE_OS_SEC_TEXT INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL setPName)
1338{
1339 UINT32 intSave;
1340 errno_t err;
1341 const CHAR *namePtr = NULL;
1342 CHAR nameBuff[OS_TCB_NAME_LEN] = { 0 };
1343
1344 if ((taskCB == NULL) || (name == NULL)) {
1345 return EINVAL;
1346 }
1347
1348 if (LOS_IsUserAddress((VADDR_T)(UINTPTR)name)) {
1349 err = LOS_StrncpyFromUser(nameBuff, (const CHAR *)name, OS_TCB_NAME_LEN);
1350 if (err < 0) {
1351 return -err;
1352 }
1353 namePtr = nameBuff;
1354 } else {
1355 namePtr = name;
1356 }
1357
1358 SCHEDULER_LOCK(intSave);
1359
1360 err = strncpy_s(taskCB->taskName, OS_TCB_NAME_LEN, (VOID *)namePtr, OS_TCB_NAME_LEN - 1);
1361 if (err != EOK) {
1362 err = EINVAL;
1363 goto EXIT;
1364 }
1365
1366 err = LOS_OK;
1367 /* if thread is main thread, then set processName as taskName */
1368 if ((taskCB->taskID == OsProcessThreadGroupIDGet(taskCB)) && (setPName == TRUE)) {
1369 err = (INT32)OsSetProcessName(OS_PCB_FROM_PID(taskCB->processID), (const CHAR *)taskCB->taskName);
1370 if (err != LOS_OK) {
1371 err = EINVAL;
1372 }
1373 }
1374
1375EXIT:
1376 SCHEDULER_UNLOCK(intSave);
1377 return err;
1378}
1379
1381{
1382 return OsUserProcessOperatePermissionsCheck(taskCB, OsCurrProcessGet()->processID);
1383}
1384
1386{
1387 if (taskCB == NULL) {
1388 return LOS_EINVAL;
1389 }
1390
1391 if (processID == OS_INVALID_VALUE) {
1392 return LOS_EINVAL;
1393 }
1394
1395 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
1396 return LOS_EINVAL;
1397 }
1398
1399 if (processID != taskCB->processID) {
1400 return LOS_EPERM;
1401 }
1402
1403 return LOS_OK;
1404}
1405///创建任务之前,检查用户态任务栈的参数,是否地址在用户空间
1406LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID, TSK_INIT_PARAM_S *param)
1407{
1408 UserTaskParam *userParam = NULL;
1409
1410 if (param == NULL) {
1411 return OS_INVALID_VALUE;
1412 }
1413
1414 userParam = &param->userParam;
1415 if ((processID == OS_INVALID_VALUE) && !LOS_IsUserAddress(userParam->userArea)) {//堆地址必须在用户空间
1416 return OS_INVALID_VALUE;
1417 }
1418
1419 if (!LOS_IsUserAddress((UINTPTR)param->pfnTaskEntry)) {//入口函数必须在用户空间
1420 return OS_INVALID_VALUE;
1421 }
1422 //堆栈必须在用户空间
1423 if (userParam->userMapBase && !LOS_IsUserAddressRange(userParam->userMapBase, userParam->userMapSize)) {
1424 return OS_INVALID_VALUE;
1425 }
1426 //检查堆,栈范围
1427 if (!LOS_IsUserAddress(userParam->userSP)) {
1428 return OS_INVALID_VALUE;
1429 }
1430
1431 return LOS_OK;
1432}
1433///创建一个用户态任务
1434LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam)
1435{
1436 UINT32 taskID;
1437 UINT32 ret;
1438 UINT32 intSave;
1439
1440 ret = OsCreateUserTaskParamCheck(processID, initParam);//检查参数,堆栈,入口地址必须在用户空间
1441 if (ret != LOS_OK) {
1442 return ret;
1443 }
1444 //这里可看出一个任务有两个栈,内核态栈(内核指定栈大小)和用户态栈(用户指定栈大小)
1445 initParam->uwStackSize = OS_USER_TASK_SYSCALL_STACK_SIZE;
1446 initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST;//设置最低优先级 31级
1447 initParam->policy = LOS_SCHED_RR;//调度方式为抢占式,注意鸿蒙不仅仅只支持抢占式调度方式
1448 if (processID == OS_INVALID_VALUE) {//外面没指定进程ID的处理
1449 SCHEDULER_LOCK(intSave);
1450 LosProcessCB *processCB = OsCurrProcessGet();
1451 initParam->processID = processCB->processID;//进程ID赋值
1452 initParam->consoleID = processCB->consoleID;//任务控制台ID归属
1453 SCHEDULER_UNLOCK(intSave);
1454 } else {//进程已经创建
1455 initParam->processID = processID;//进程ID赋值
1456 initParam->consoleID = 0;//默认0号控制台
1457 }
1458
1459 ret = LOS_TaskCreateOnly(&taskID, initParam);//只创建task实体,不申请调度
1460 if (ret != LOS_OK) {
1461 return OS_INVALID_VALUE;
1462 }
1463
1464 return taskID;
1465}
1466///获取任务的调度方式
1467LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID)
1468{
1469 UINT32 intSave;
1470 INT32 policy;
1471 SchedParam param = { 0 };
1472
1473 if (OS_TID_CHECK_INVALID(taskID)) {
1474 return -LOS_EINVAL;
1475 }
1476
1477 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1478 SCHEDULER_LOCK(intSave);
1479 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//状态不能是没有在使用
1480 policy = -LOS_EINVAL;
1481 OS_GOTO_ERREND();
1482 }
1483
1484 taskCB->ops->schedParamGet(taskCB, &param);
1485 policy = (INT32)param.policy;
1486
1487LOS_ERREND:
1488 SCHEDULER_UNLOCK(intSave);
1489 return policy;
1490}
1491
1492//设置任务的调度信息
1493LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 priority)
1494{
1495 SchedParam param = { 0 };
1496 UINT32 intSave;
1497
1498 if (OS_TID_CHECK_INVALID(taskID)) {
1499 return LOS_ESRCH;
1500 }
1501
1502 if (priority > OS_TASK_PRIORITY_LOWEST) {
1503 return LOS_EINVAL;
1504 }
1505
1506 if ((policy != LOS_SCHED_FIFO) && (policy != LOS_SCHED_RR)) {
1507 return LOS_EINVAL;
1508 }
1509
1510 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1511 if (taskCB->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
1512 return LOS_EPERM;
1513 }
1514
1515 SCHEDULER_LOCK(intSave);
1516 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
1517 SCHEDULER_UNLOCK(intSave);
1518 return LOS_EINVAL;
1519 }
1520
1521 taskCB->ops->schedParamGet(taskCB, &param);
1522 param.policy = policy;
1523 param.priority = priority;
1524 BOOL needSched = taskCB->ops->schedParamModify(taskCB, &param);
1525 SCHEDULER_UNLOCK(intSave);
1526
1527 LOS_MpSchedule(OS_MP_CPU_ALL);
1528 if (needSched && OS_SCHEDULER_ACTIVE) {
1529 LOS_Schedule();
1530 }
1531
1532 return LOS_OK;
1533}
1534
1536{
1537 if (OS_TID_CHECK_INVALID(taskID)) {
1538 return LOS_EINVAL;
1539 }
1540
1541 if (OS_INT_ACTIVE) {
1542 return LOS_EINTR;
1543 }
1544
1545 if (!OsPreemptable()) {
1546 return LOS_EINVAL;
1547 }
1548
1549 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1550 if (taskCB->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
1551 return LOS_EPERM;
1552 }
1553
1554 if (taskCB == OsCurrTaskGet()) {
1555 return LOS_EDEADLK;
1556 }
1557
1558 return LOS_OK;
1559}
1560
1562{
1563 UINT32 intSave;
1564 LosTaskCB *runTask = OsCurrTaskGet();
1565 UINT32 errRet;
1566
1567 errRet = OsTaskJoinCheck(taskID);
1568 if (errRet != LOS_OK) {
1569 return errRet;
1570 }
1571
1572 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1573 SCHEDULER_LOCK(intSave);
1574 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
1575 SCHEDULER_UNLOCK(intSave);
1576 return LOS_EINVAL;
1577 }
1578
1579 if (runTask->processID != taskCB->processID) {
1580 SCHEDULER_UNLOCK(intSave);
1581 return LOS_EPERM;
1582 }
1583
1584 errRet = OsTaskJoinPendUnsafe(taskCB);
1585 SCHEDULER_UNLOCK(intSave);
1586
1587 if (errRet == LOS_OK) {
1588 LOS_Schedule();
1589
1590 if (retval != NULL) {
1591 *retval = (UINTPTR)taskCB->joinRetval;
1592 }
1593
1594 (VOID)LOS_TaskDelete(taskID);
1595 return LOS_OK;
1596 }
1597
1598 return errRet;
1599}
1600
1602{
1603 UINT32 intSave;
1604 LosTaskCB *runTask = OsCurrTaskGet();
1605 UINT32 errRet;
1606
1607 if (OS_TID_CHECK_INVALID(taskID)) {
1608 return LOS_EINVAL;
1609 }
1610
1611 if (OS_INT_ACTIVE) {
1612 return LOS_EINTR;
1613 }
1614
1615 LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
1616 SCHEDULER_LOCK(intSave);
1617 if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
1618 SCHEDULER_UNLOCK(intSave);
1619 return LOS_EINVAL;
1620 }
1621
1622 if (runTask->processID != taskCB->processID) {
1623 SCHEDULER_UNLOCK(intSave);
1624 return LOS_EPERM;
1625 }
1626
1627 if (taskCB->taskStatus & OS_TASK_STATUS_EXIT) {
1628 SCHEDULER_UNLOCK(intSave);
1629 return LOS_TaskJoin(taskID, NULL);
1630 }
1631
1632 errRet = OsTaskSetDetachUnsafe(taskCB);
1633 SCHEDULER_UNLOCK(intSave);
1634 return errRet;
1635}
1636
1637LITE_OS_SEC_TEXT UINT32 LOS_GetSystemTaskMaximum(VOID)
1638{
1639 return g_taskMaxNum;
1640}
1641
1642LITE_OS_SEC_TEXT VOID OsWriteResourceEvent(UINT32 events)
1643{
1644 (VOID)LOS_EventWrite(&g_resourceEvent, events);
1645}
1646
1647LITE_OS_SEC_TEXT VOID OsWriteResourceEventUnsafe(UINT32 events)
1648{
1649 (VOID)OsEventWriteUnsafe(&g_resourceEvent, events, FALSE, NULL);
1650}
1651///资源回收任务
1652STATIC VOID OsResourceRecoveryTask(VOID)
1653{
1654 UINT32 ret;
1655
1656 while (1) {//死循环,回收资源不存在退出情况,只要系统在运行资源就需要回收
1657 ret = LOS_EventRead(&g_resourceEvent, OS_RESOURCE_EVENT_MASK,
1658 LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);//读取资源事件
1659 if (ret & (OS_RESOURCE_EVENT_FREE | OS_RESOURCE_EVENT_OOM)) {//收到资源释放或内存异常情况
1661 OsProcessCBRecycleToFree();//回收进程到空闲进程池
1662 }
1663
1664#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK //内存溢出监测任务开关
1665 if (ret & OS_RESOURCE_EVENT_OOM) {//触发了这个事件
1666 (VOID)OomCheckProcess();//检查进程的内存溢出情况
1667 }
1668#endif
1669 }
1670}
1671///创建一个回收资源的任务
1672LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID)
1673{
1674 UINT32 ret;
1675 UINT32 taskID;
1676 TSK_INIT_PARAM_S taskInitParam;
1677
1678 ret = LOS_EventInit((PEVENT_CB_S)&g_resourceEvent);//初始化资源事件
1679 if (ret != LOS_OK) {
1680 return LOS_NOK;
1681 }
1682
1683 (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
1684 taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsResourceRecoveryTask;//入口函数
1685 taskInitParam.uwStackSize = OS_TASK_RESOURCE_STATIC_SIZE;
1686 taskInitParam.pcName = "ResourcesTask";
1687 taskInitParam.usTaskPrio = OS_TASK_RESOURCE_FREE_PRIORITY;// 5 ,优先级很高
1688 ret = LOS_TaskCreate(&taskID, &taskInitParam);
1689 if (ret == LOS_OK) {
1690 OS_TCB_FROM_TID(taskID)->taskStatus |= OS_TASK_FLAG_NO_DELETE;
1691 }
1692 return ret;
1693}
1694
1695LOS_MODULE_INIT(OsResourceFreeTaskCreate, LOS_INIT_LEVEL_KMOD_TASK);//资源回收任务初始化
macro EXC_SP_SET stackSize
Definition: asm.h:50
LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout)
读取指定事件类型,超时时间为相对时间:单位为Tick
Definition: los_event.c:313
LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events)
写指定的事件类型
Definition: los_event.c:318
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
初始化一个事件控制块
Definition: los_event.c:95
VOID OsBackTrace(VOID)
Kernel backtrace function.
Definition: los_exc.c:1025
STATIC INLINE UINT32 LOS_IntUnLock(VOID)
Enable all interrupts. | 打开当前处理器所有中断响应
Definition: los_hwi.h:311
STATIC INLINE VOID LOS_IntRestore(UINT32 intSave)
Restore interrupts. | 恢复到使用LOS_IntLock关闭所有中断之前的状态
Definition: los_hwi.h:337
STATIC INLINE UINT32 LOS_IntLock(VOID)
Disable all interrupts. | 关闭当前处理器所有中断响应
Definition: los_hwi.h:286
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
Definition: los_list.h:104
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a node to the tail of a doubly linked list.
Definition: los_list.h:244
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
Definition: los_list.h:292
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListAdd(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a new node to a doubly linked list.
Definition: los_list.h:217
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
Definition: los_list.h:321
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
Definition: los_memory.c:1123
UINT8 * m_aucSysMem1
系统动态内存池地址的起始地址 @note_thinking 能否不要用 0,1来命名核心变量 ???
Definition: los_memory.c:108
VOID * LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary)
从指定内存池中申请size长度的内存且地址按boundary字节对齐的内存
Definition: los_memory.c:1150
UINT32 LOS_MemFree(VOID *pool, VOID *ptr)
释放从指定动态内存中申请的内存
Definition: los_memory.c:1369
UINT8 * m_aucSysMem0
异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。
Definition: los_memory.c:107
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle)
对外接口 创建信号量
Definition: los_sem.c:177
LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
对外接口 申请指定的信号量,并设置超时时间
Definition: los_sem.c:226
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle)
对外接口 删除指定的信号量,参数就是 semID
Definition: los_sem.c:187
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMask)
Set the affinity mask of the task scheduling cpu.
Definition: los_task.c:1231
UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, UINT32 *peakUsed)
Get stack waterline.
Definition: los_stackinfo.c:70
LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID)
Unlock the task scheduling.
Definition: los_task.c:1148
LITE_OS_SEC_BSS UINT32 g_taskMaxNum
任务最大数量 默认128个
Definition: los_task.c:150
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID)
Delete a task.
Definition: los_task.c:968
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio)
设置当前任务的优先级
Definition: los_task.c:1109
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID)
恢复挂起的任务,使该任务进入ready状态
Definition: los_task.c:758
UINT32 LOS_TaskDetach(UINT32 taskID)
Change the joinable attribute of the task to detach.
Definition: los_task.c:1601
LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
Obtain current running task ID.
Definition: los_task.c:331
LITE_OS_SEC_TEXT UINT32 LOS_GetSystemTaskMaximum(VOID)
Gets the maximum number of threads supported by the system.
Definition: los_task.c:1637
LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID)
获取任务的优先级
Definition: los_task.c:1050
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID)
Change the scheduling sequence of tasks with the same priority.
Definition: los_task.c:1115
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio)
设置指定任务的优先级
Definition: los_task.c:1071
LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID)
获取任务的调度方式
Definition: los_task.c:1467
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
LOS_TaskCreateOnly 创建任务,并使该任务进入suspend状态,不对该任务进行调度。如果需要调度,可以调用LOS_TaskResume使该任务进入ready状态
Definition: los_task.c:663
LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 priority)
Set the scheduling policy and priority for the task.
Definition: los_task.c:1493
struct tagTskInitParam TSK_INIT_PARAM_S
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID)
外部接口,对OsTaskSuspend的封装
Definition: los_task.c:855
LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID)
Lock the task scheduling.
Definition: los_task.c:1139
LITE_OS_SEC_BSS LosTaskCB * g_taskCBArray
外部变量 任务池 默认128个
Definition: los_task.c:147
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务
Definition: los_task.c:718
VOID LOS_Schedule(VOID)
Trigger active task scheduling.
Definition: los_sched.c:469
LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)
任务延时等待,释放CPU,等待时间到期后该任务会重新进入ready状态
Definition: los_task.c:1020
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo)
Obtain a task information structure.
Definition: los_task.c:1161
VOID *(* TSK_ENTRY_FUNC)(UINTPTR param1, UINTPTR param2, UINTPTR param3, UINTPTR param4)
Define the type of a task entrance function.
Definition: los_task.h:480
UINT32 LOS_TaskJoin(UINT32 taskID, UINTPTR *retval)
Wait for the specified task to finish and reclaim its resources.
Definition: los_task.c:1561
LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID)
查询任务被绑在哪个CPU上
Definition: los_task.c:1263
LITE_OS_SEC_TEXT VOID LiteIpcRemoveServiceHandle(UINT32 taskID)
删除指定的Service
Definition: hm_liteipc.c:661
__attribute__((aligned(MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS)))
Definition: los_arch_mmu.c:98
VOID OsEventWriteUnsafe(PEVENT_CB_S eventCB, UINT32 events, BOOL once, UINT8 *exitFlag)
以不安全的方式写事件
Definition: los_event.c:247
VOID OsFutexNodeDeleteFromFutexHash(FutexNode *node, BOOL isDeleteHead, FutexNode **headNode, BOOL *queueFlags)
从哈希桶上删除快锁
Definition: los_futex.c:302
STATIC INLINE UINT32 ArchSPGet(VOID)
Definition: los_hw_cpu.h:284
STATIC INLINE UINT32 ArchCurrCpuid(VOID)
Definition: los_hw_cpu.h:168
VOID * OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag)
内核态任务运行栈初始化
Definition: los_hw.c:73
VOID OsUserTaskStackInit(TaskContext *context, UINTPTR taskEntry, UINTPTR stack)
用户态运行栈初始化,此时上下文还在内核区
Definition: los_hw.c:123
VOID LOS_MpSchedule(UINT32 target)
Definition: los_mp.c:76
LITE_OS_SEC_TEXT BOOL LOS_MuxIsValid(const LosMux *mutex)
互斥锁是否有效
Definition: los_mux.c:239
VOID OsMuxBitmapRestore(const LosMux *mutex, const LOS_DL_LIST *list, const LosTaskCB *runTask)
恢复互斥锁位图
Definition: los_mux.c:328
UINT32 OsMuxUnlockUnsafe(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched)
Definition: los_mux.c:527
LITE_OS_SEC_TEXT_MINOR BOOL OomCheckProcess(VOID)
Definition: oom.c:124
LITE_OS_SEC_TEXT UINT32 OsGetIdleProcessID(VOID)
获取内核态空闲进程
Definition: los_process.c:2254
VOID OsDeleteTaskFromProcess(LosTaskCB *taskCB)
Definition: los_process.c:107
LITE_OS_SEC_TEXT UINT32 OsGetKernelInitProcessID(VOID)
获取内核态根进程
Definition: los_process.c:2249
VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status)
Definition: los_process.c:550
UINT32 OsProcessAddNewTask(UINT32 pid, LosTaskCB *taskCB, SchedParam *param)
Definition: los_process.c:116
LITE_OS_SEC_TEXT VOID OsProcessThreadGroupDestroy(VOID)
Definition: los_process.c:2200
LITE_OS_SEC_TEXT VOID OsProcessCBRecycleToFree(VOID)
Definition: los_process.c:625
UINT32 OsSetProcessName(LosProcessCB *processCB, const CHAR *name)
Definition: los_process.c:704
LITE_OS_SEC_TEXT VOID OsProcessResourcesToFree(LosProcessCB *processCB)
Definition: los_process.c:431
STATIC INLINE LosVmSpace * OsProcessVmSpaceGet(const LosProcessCB *processCB)
STATIC INLINE UINT32 OsProcessThreadGroupIDGet(const LosTaskCB *taskCB)
STATIC INLINE UINT32 OsProcessThreadNumberGet(const LosTaskCB *taskCB)
STATIC INLINE BOOL OsProcessIsInit(const LosProcessCB *processCB)
STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB)
STATIC INLINE LosProcessCB * OsCurrProcessGet(VOID)
STATIC INLINE BOOL OsSchedUnlockResch(VOID)
struct TagTaskCB LosTaskCB
Definition: los_sched_pri.h:72
STATIC INLINE LosTaskCB * OsCurrTaskGet(VOID)
VOID OsSchedRunqueueIdleInit(UINT32 idleTaskID)
Definition: los_sched.c:207
STATIC INLINE BOOL OsPreemptableInSched(VOID)
STATIC INLINE BOOL OsPreemptable(VOID)
UINT32 OsSchedInit(VOID)
Definition: los_sched.c:213
STATIC INLINE SchedRunqueue * OsSchedRunqueue(VOID)
STATIC INLINE UINT32 OsSchedRunqueueIdleGet(VOID)
UINT32 OsSchedParamInit(LosTaskCB *taskCB, UINT16 policy, const SchedParam *parentParam, const TSK_INIT_PARAM_S *param)
Definition: los_sched.c:250
STATIC INLINE VOID OsSchedLock(VOID)
VOID OsSchedResched(VOID)
Definition: los_sched.c:449
UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched)
以不安全的方式释放指定的信号量,所谓不安全指的是不用自旋锁
Definition: los_sem.c:287
VOID OsClearSigInfoTmpList(sig_cb *sigcb)
Definition: los_signal.c:123
BOOL LOS_SpinHeld(const SPIN_LOCK_S *lock)
Definition: los_spinlock.c:45
VOID LOS_SpinLock(SPIN_LOCK_S *lock)
Definition: los_spinlock.c:50
VOID LOS_SpinUnlock(SPIN_LOCK_S *lock)
Definition: los_spinlock.c:84
LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID, TSK_INIT_PARAM_S *param)
创建任务之前,检查用户态任务栈的参数,是否地址在用户空间
Definition: los_task.c:1406
LITE_OS_SEC_BSS LOS_DL_LIST g_losFreeTask
Definition: los_task.c:148
STATIC VOID OsConsoleIDSetHook(UINT32 param1, UINT32 param2) __attribute__((weakref("OsSetConsoleID")))
STATIC INLINE VOID OsInsertTCBToFreeList(LosTaskCB *taskCB)
Definition: los_task.c:407
STATIC INLINE VOID OsTaskStatusUnusedSet(LosTaskCB *taskCB)
设置任务为不使用状态
Definition: los_task.c:875
STATIC INLINE VOID OsTaskSyncWake(const LosTaskCB *taskCB)
同步唤醒
Definition: los_task.c:398
LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree()
Definition: los_task.c:472
LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID)
创建一个回收资源的任务
Definition: los_task.c:1672
LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UINT32 *ret)
Definition: los_task.c:806
STATIC VOID OsTaskReleaseHoldLock(LosTaskCB *taskCB)
Definition: los_task.c:883
STATIC VOID OsResourceRecoveryTask(VOID)
资源回收任务
Definition: los_task.c:1652
STATIC VOID OsTaskKernelResourcesToFree(UINT32 syncSignal, UINTPTR topOfStack)
Definition: los_task.c:417
LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCreateParamCheck(const UINT32 *taskID, TSK_INIT_PARAM_S *initParam, VOID **pool)
任务创建参数检查
Definition: los_task.c:515
LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID)
创建一个空闲任务
Definition: los_task.c:300
LosTaskCB * OsGetMainTask()
Definition: los_task.c:162
LITE_OS_SEC_BSS LOS_DL_LIST g_taskRecycleList
Definition: los_task.c:149
STATIC INLINE VOID OsTaskSyncDestroy(UINT32 syncSignal)
销毁指定任务同步信号量
Definition: los_task.c:354
LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(VOID)
Definition: los_task.c:259
INT32 OsUserProcessOperatePermissionsCheck(const LosTaskCB *taskCB, UINT32 processID)
Definition: los_task.c:1385
LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB)
任务暂停,参数可以不是当前任务,也就是说 A任务可以让B任务处于阻塞状态,挂起指定的任务,然后切换任务
Definition: los_task.c:835
LITE_OS_SEC_TEXT BOOL OsTaskCpuAffiSetUnsafe(UINT32 taskID, UINT16 newCpuAffiMask, UINT16 *oldCpuAffiMask)
CPU亲和性(affinity)将任务绑在指定CPU上,用于多核CPU情况,(该函数仅在SMP模式下支持)
Definition: los_task.c:1212
LITE_OS_SEC_BSS STATIC LosTaskCB g_mainTask[LOSCFG_KERNEL_CORE_NUM]
Definition: los_task.c:160
UINT32 OsGetIdleTaskId(VOID)
获取IdletaskId,每个CPU核都对Task进行了内部管理,做到真正的并行处理
Definition: los_task.c:295
STATIC INLINE UINT32 OsTaskSyncCreate(LosTaskCB *taskCB)
创建指定任务同步信号量
Definition: los_task.c:341
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_taskSpin)
LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB)
挂起任务,任务进入等待链表,Join代表是支持通过一个任务去唤醒其他的任务
Definition: los_task.c:224
LITE_OS_SEC_TEXT INT32 OsSetTaskName(LosTaskCB *taskCB, const CHAR *name, BOOL setPName)
Definition: los_task.c:1337
LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID)
Definition: los_task.c:493
STATIC UINT32 OsTaskJoinCheck(UINT32 taskID)
Definition: los_task.c:1535
LOS_MODULE_INIT(OsResourceFreeTaskCreate, LOS_INIT_LEVEL_KMOD_TASK)
STATIC UINT32 OsTaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam, const VOID *stackPtr, const VOID *topStack)
任务初始化
Definition: los_task.c:594
LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID)
Definition: los_task.c:1298
LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID)
空闲任务,每个CPU都有自己的空闲任务
Definition: los_task.c:191
LITE_OS_SEC_TEXT VOID OsWriteResourceEventUnsafe(UINT32 events)
Definition: los_task.c:1647
LITE_OS_SEC_TEXT VOID OsWriteResourceEvent(UINT32 events)
Definition: los_task.c:1642
LITE_OS_SEC_BSS UINT32 g_taskScheduled
Definition: los_task.c:151
STATIC INLINE UINT32 OsTaskSyncWait(const LosTaskCB *taskCB)
OsTaskSyncWait 任务同步等待,通过信号量保持同步
Definition: los_task.c:372
LITE_OS_SEC_TEXT LosTaskCB * OsGetFreeTaskCB(VOID)
获取一个空闲TCB
Definition: los_task.c:636
STATIC VOID TaskCBBaseInit(LosTaskCB *taskCB, const VOID *stackPtr, const VOID *topStack, const TSK_INIT_PARAM_S *initParam)
任务基本信息的初始化
Definition: los_task.c:566
VOID OsTaskInsertToRecycleList(LosTaskCB *taskCB)
Definition: los_task.c:198
LITE_OS_SEC_TEXT VOID OsInactiveTaskDelete(LosTaskCB *taskCB)
Definition: los_task.c:947
LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskStackAlloc(VOID **topStack, UINT32 stackSize, VOID *pool)
任务栈(内核态)内存分配,由内核态进程空间提供,即 KProcess 的进程空间
Definition: los_task.c:560
INT32 OsUserTaskOperatePermissionsCheck(const LosTaskCB *taskCB)
Definition: los_task.c:1380
LITE_OS_SEC_TEXT_INIT VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB)
OsTaskJoinPostUnsafe 查找task 通过 OS_TCB_FROM_PENDLIST 来完成,相当于由LOS_DL_LIST找到LosTaskCB,...
Definition: los_task.c:212
STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB)
Definition: los_task.c:424
LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB)
任务设置分离模式 Deatch和JOIN是一对有你没我的状态
Definition: los_task.c:243
LITE_OS_SEC_TEXT VOID OsRunningTaskToExit(LosTaskCB *runTask, UINT32 status)
Definition: los_task.c:908
LITE_OS_SEC_BSS EVENT_CB_S g_resourceEvent
Definition: los_task.c:152
LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam)
创建一个用户态任务
Definition: los_task.c:1434
VOID OsSetMainTask()
Definition: los_task.c:167
STATIC INLINE VOID OsTaskWaitSetPendMask(UINT16 mask, UINTPTR lockID, UINT32 timeout)
设置事件阻塞掩码,即设置任务的等待事件.
Definition: los_task_pri.h:289
STATIC INLINE VOID OsTaskWakeClearPendMask(LosTaskCB *resumeTask)
清除事件阻塞掩码,即任务不再等待任何事件.
Definition: los_task_pri.h:298
SPIN_LOCK_S g_taskSpin
unsigned short UINT16
Definition: los_typedef.h:56
signed int INT32
Definition: los_typedef.h:60
unsigned long VADDR_T
Definition: los_typedef.h:208
unsigned long UINTPTR
Definition: los_typedef.h:68
unsigned int UINT32
Definition: los_typedef.h:57
char CHAR
Definition: los_typedef.h:63
size_t BOOL
Definition: los_typedef.h:88
STATIC INLINE BOOL LOS_IsUserAddressRange(VADDR_T vaddr, size_t len)
虚拟地址[vaddr,vaddr + len]是否在用户空间
Definition: los_vm_map.h:281
STATIC INLINE BOOL LOS_IsUserAddress(VADDR_T vaddr)
虚拟地址是否在用户空间
Definition: los_vm_map.h:275
STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size)
INT32 LOS_StrncpyFromUser(CHAR *dst, const CHAR *src, INT32 count)
UINT32 index
Definition: los_futex_pri.h:79
INT32 lockDepth
Definition: los_lockdep.h:63
VOID * waitLock
Definition: los_lockdep.h:62
Definition: los_mux.h:73
LOS_DL_LIST holdList
Definition: los_mux.h:76
UINT32 processID
UINT16 consoleID
VOID(* exit)(LosTaskCB *taskCB)
任务退出
UINT32(* resume)(LosTaskCB *taskCB, BOOL *needSched)
恢复任务
VOID(* enqueue)(SchedRunqueue *rq, LosTaskCB *taskCB)
入队列
UINT32(* delay)(LosTaskCB *taskCB, UINT64 waitTime)
延时执行
UINT32(* wait)(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 timeout)
任务等待
VOID(* wake)(LosTaskCB *taskCB)
任务唤醒
VOID(* yield)(LosTaskCB *taskCB)
让出控制权
UINT32(* suspend)(LosTaskCB *taskCB)
挂起任务
BOOL(* schedParamModify)(LosTaskCB *taskCB, const SchedParam *param)
修改调度参数
UINT32(* schedParamGet)(const LosTaskCB *taskCB, SchedParam *param)
获取调度参数
UINT16 basePrio
UINT16 policy
UINT16 priority
LockDep lockDep
死锁依赖检测
FutexNode futex
指明任务在等待哪把快锁,一次只等一锁,锁和任务的关系是(1:N)关系
UINT32 syncSignal
TSK_ENTRY_FUNC taskEntry
VOID * joinRetval
UINTPTR args[4]
LOS_DL_LIST joinList
UINT16 cpuAffiMask
LOS_DL_LIST pendList
UINT32 taskID
SortLinkList sortList
UINT32 stackSize
UINT32 signal
sig_cb sig
信号控制块,用于异步通信,类似于 linux singal模块
UINTPTR userMapBase
用户空间的栈顶位置,内存来自用户空间,和topOfStack有本质的区别.
CHAR taskName[OS_TCB_NAME_LEN]
UINTPTR topOfStack
UINT32 eventMask
VOID * stackPointer
VOID * taskEvent
LOS_DL_LIST lockList
UINT16 currCpu
UINT32 userMapSize
VOID * taskMux
UINT32 processID
const SchedOps * ops
UINTPTR userArea
用户空间的堆区开始位置
UINT16 taskStatus
UINT32 userMapSize
用户空间的栈大小,栈底 = userMapBase + userMapSize
Definition: los_task.h:494
UINTPTR userArea
用户空间的堆区开始位置
Definition: los_task.h:491
UINTPTR userMapBase
用户空间的栈顶位置.
Definition: los_task.h:493
UINTPTR userSP
用户空间当前栈指针位置
Definition: los_task.h:492
UINT16 usTaskPrio
Definition: los_task.h:536
UINT16 usTaskStatus
Definition: los_task.h:535
UINT32 uwStackSize
Definition: los_task.h:541
UINTPTR uwBottomOfStack
Definition: los_task.h:543
VOID * pTaskMux
Definition: los_task.h:538
UINT32 uwPeakUsed
Definition: los_task.h:546
UINT32 uwTaskID
Definition: los_task.h:534
UINTPTR uwSP
Definition: los_task.h:544
UINT32 uwCurrUsed
Definition: los_task.h:545
BOOL bOvf
Definition: los_task.h:547
CHAR acName[LOS_TASK_NAMELEN]
Definition: los_task.h:533
UINTPTR uwTopOfStack
Definition: los_task.h:542
UINT32 uwEventMask
Definition: los_task.h:540
VOID * taskEvent
Definition: los_task.h:539
UINT16 policy
Definition: los_task.h:506
UINT16 usTaskPrio
Definition: los_task.h:505
UINTPTR auwArgs[4]
Definition: los_task.h:507
UINT16 usCpuAffiMask
Definition: los_task.h:511
UINT32 uwStackSize
Definition: los_task.h:508
CHAR * pcName
Definition: los_task.h:509
UINT32 processID
进程ID
Definition: los_task.h:516
TSK_ENTRY_FUNC pfnTaskEntry
Definition: los_task.h:504
UserTaskParam userParam
任务用户态运行时任何参数
Definition: los_task.h:517
UINT32 uwResved
Definition: los_task.h:513
UINT16 consoleID
Definition: los_task.h:515
if(tv==NULL)
Definition: time.c:430