• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2023 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_sched_pri.h"
33 #include "los_hw_pri.h"
34 #include "los_task_pri.h"
35 #include "los_swtmr_pri.h"
36 #include "los_process_pri.h"
37 #include "los_arch_mmu.h"
38 #include "los_hook.h"
39 #ifdef LOSCFG_KERNEL_CPUP
40 #include "los_cpup_pri.h"
41 #endif
42 #include "los_hw_tick_pri.h"
43 #include "los_tick_pri.h"
44 #ifdef LOSCFG_BASE_CORE_TSK_MONITOR
45 #include "los_stackinfo_pri.h"
46 #endif
47 #include "los_mp.h"
48 
49 SchedRunqueue g_schedRunqueue[LOSCFG_KERNEL_CORE_NUM];
50 
SchedNextExpireTimeSet(UINT32 responseID,UINT64 taskEndTime,UINT32 oldResponseID)51 STATIC INLINE VOID SchedNextExpireTimeSet(UINT32 responseID, UINT64 taskEndTime, UINT32 oldResponseID)
52 {
53     SchedRunqueue *rq = OsSchedRunqueue();
54     BOOL isTimeSlice = FALSE;
55     UINT64 currTime = OsGetCurrSchedTimeCycle();
56     UINT64 nextExpireTime = OsGetSortLinkNextExpireTime(&rq->timeoutQueue, currTime, OS_TICK_RESPONSE_PRECISION);
57 
58     rq->schedFlag &= ~INT_PEND_TICK;
59     if (rq->responseID == oldResponseID) {
60         /* This time has expired, and the next time the theory has expired is infinite */
61         rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME;
62     }
63 
64     /* The current thread's time slice has been consumed, but the current system lock task cannot
65      * trigger the schedule to release the CPU
66      */
67     if ((nextExpireTime > taskEndTime) && ((nextExpireTime - taskEndTime) > OS_SCHED_MINI_PERIOD)) {
68         nextExpireTime = taskEndTime;
69         isTimeSlice = TRUE;
70     }
71 
72     if ((rq->responseTime <= nextExpireTime) ||
73         ((rq->responseTime - nextExpireTime) < OS_TICK_RESPONSE_PRECISION)) {
74         return;
75     }
76 
77     if (isTimeSlice) {
78         /* The expiration time of the current system is the thread's slice expiration time */
79         rq->responseID = responseID;
80     } else {
81         rq->responseID = OS_INVALID_VALUE;
82     }
83 
84     UINT64 nextResponseTime = nextExpireTime - currTime;
85     rq->responseTime = currTime + HalClockTickTimerReload(nextResponseTime);
86 }
87 
OsSchedExpireTimeUpdate(VOID)88 VOID OsSchedExpireTimeUpdate(VOID)
89 {
90     UINT32 intSave;
91     if (!OS_SCHEDULER_ACTIVE || OS_INT_ACTIVE) {
92         OsSchedRunqueuePendingSet();
93         return;
94     }
95 
96     LosTaskCB *runTask = OsCurrTaskGet();
97     SCHEDULER_LOCK(intSave);
98     UINT64 deadline = runTask->ops->deadlineGet(runTask);
99     SCHEDULER_UNLOCK(intSave);
100     SchedNextExpireTimeSet(runTask->taskID, deadline, runTask->taskID);
101 }
102 
SchedTimeoutTaskWake(SchedRunqueue * rq,UINT64 currTime,LosTaskCB * taskCB,BOOL * needSched)103 STATIC INLINE VOID SchedTimeoutTaskWake(SchedRunqueue *rq, UINT64 currTime, LosTaskCB *taskCB, BOOL *needSched)
104 {
105     LOS_SpinLock(&g_taskSpin);
106     if (OsSchedPolicyIsEDF(taskCB)) {
107         SchedEDF *sched = (SchedEDF *)&taskCB->sp;
108         if (sched->finishTime <= currTime) {
109             if (taskCB->timeSlice >= 0) {
110                 PrintExcInfo("EDF task: %u name: %s is timeout, timeout for %llu us.\n",
111                              taskCB->taskID, taskCB->taskName, OS_SYS_CYCLE_TO_US(currTime - sched->finishTime));
112             }
113             taskCB->timeSlice = 0;
114         }
115         if (sched->flags == EDF_WAIT_FOREVER) {
116             taskCB->taskStatus &= ~OS_TASK_STATUS_PEND_TIME;
117             sched->flags = EDF_UNUSED;
118         }
119     }
120 
121     UINT16 tempStatus = taskCB->taskStatus;
122     if (tempStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY)) {
123         taskCB->taskStatus &= ~(OS_TASK_STATUS_PENDING | OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY);
124         if (tempStatus & OS_TASK_STATUS_PEND_TIME) {
125             taskCB->taskStatus |= OS_TASK_STATUS_TIMEOUT;
126             LOS_ListDelete(&taskCB->pendList);
127             taskCB->taskMux = NULL;
128             OsTaskWakeClearPendMask(taskCB);
129         }
130 
131         if (!(tempStatus & OS_TASK_STATUS_SUSPENDED)) {
132 #ifdef LOSCFG_SCHED_HPF_DEBUG
133             taskCB->schedStat.pendTime += currTime - taskCB->startTime;
134             taskCB->schedStat.pendCount++;
135 #endif
136             taskCB->ops->enqueue(rq, taskCB);
137             *needSched = TRUE;
138         }
139     }
140 
141     LOS_SpinUnlock(&g_taskSpin);
142 }
143 
SchedTimeoutQueueScan(SchedRunqueue * rq)144 STATIC INLINE BOOL SchedTimeoutQueueScan(SchedRunqueue *rq)
145 {
146     BOOL needSched = FALSE;
147     SortLinkAttribute *timeoutQueue = &rq->timeoutQueue;
148     LOS_DL_LIST *listObject = &timeoutQueue->sortLink;
149     /*
150      * When task is pended with timeout, the task block is on the timeout sortlink
151      * (per cpu) and ipc(mutex,sem and etc.)'s block at the same time, it can be waken
152      * up by either timeout or corresponding ipc it's waiting.
153      *
154      * Now synchronize sortlink procedure is used, therefore the whole task scan needs
155      * to be protected, preventing another core from doing sortlink deletion at same time.
156      */
157     LOS_SpinLock(&timeoutQueue->spinLock);
158 
159     if (LOS_ListEmpty(listObject)) {
160         LOS_SpinUnlock(&timeoutQueue->spinLock);
161         return needSched;
162     }
163 
164     SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
165     UINT64 currTime = OsGetCurrSchedTimeCycle();
166     while (sortList->responseTime <= currTime) {
167         LosTaskCB *taskCB = LOS_DL_LIST_ENTRY(sortList, LosTaskCB, sortList);
168         OsDeleteNodeSortLink(timeoutQueue, &taskCB->sortList);
169         LOS_SpinUnlock(&timeoutQueue->spinLock);
170 
171         SchedTimeoutTaskWake(rq, currTime, taskCB, &needSched);
172 
173         LOS_SpinLock(&timeoutQueue->spinLock);
174         if (LOS_ListEmpty(listObject)) {
175             break;
176         }
177 
178         sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
179     }
180 
181     LOS_SpinUnlock(&timeoutQueue->spinLock);
182 
183     return needSched;
184 }
185 
OsSchedTick(VOID)186 VOID OsSchedTick(VOID)
187 {
188     SchedRunqueue *rq = OsSchedRunqueue();
189 
190     if (rq->responseID == OS_INVALID_VALUE) {
191         if (SchedTimeoutQueueScan(rq)) {
192             LOS_MpSchedule(OS_MP_CPU_ALL);
193             rq->schedFlag |= INT_PEND_RESCH;
194         }
195     }
196     rq->schedFlag |= INT_PEND_TICK;
197     rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME;
198 }
199 
OsSchedResponseTimeReset(UINT64 responseTime)200 VOID OsSchedResponseTimeReset(UINT64 responseTime)
201 {
202     OsSchedRunqueue()->responseTime = responseTime;
203 }
204 
OsSchedRunqueueInit(VOID)205 VOID OsSchedRunqueueInit(VOID)
206 {
207     if (ArchCurrCpuid() != 0) {
208         return;
209     }
210 
211     for (UINT16 index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) {
212         SchedRunqueue *rq = OsSchedRunqueueByID(index);
213         OsSortLinkInit(&rq->timeoutQueue);
214         rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME;
215     }
216 }
217 
OsSchedRunqueueIdleInit(LosTaskCB * idleTask)218 VOID OsSchedRunqueueIdleInit(LosTaskCB *idleTask)
219 {
220     SchedRunqueue *rq = OsSchedRunqueue();
221     rq->idleTask = idleTask;
222 }
223 
OsSchedInit(VOID)224 UINT32 OsSchedInit(VOID)
225 {
226     for (UINT16 cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) {
227         SchedRunqueue *rq = OsSchedRunqueueByID(cpuid);
228         EDFSchedPolicyInit(rq);
229         HPFSchedPolicyInit(rq);
230     }
231 
232 #ifdef LOSCFG_SCHED_TICK_DEBUG
233     UINT32 ret = OsSchedDebugInit();
234     if (ret != LOS_OK) {
235         return ret;
236     }
237 #endif
238     return LOS_OK;
239 }
240 
241 /*
242  * If the return value greater than 0,  task1 has a lower priority than task2.
243  * If the return value less than 0, task1 has a higher priority than task2.
244  * If the return value is 0, task1 and task2 have the same priority.
245  */
OsSchedParamCompare(const LosTaskCB * task1,const LosTaskCB * task2)246 INT32 OsSchedParamCompare(const LosTaskCB *task1, const LosTaskCB *task2)
247 {
248     SchedHPF *rp1 = (SchedHPF *)&task1->sp;
249     SchedHPF *rp2 = (SchedHPF *)&task2->sp;
250 
251     if (rp1->policy == rp2->policy) {
252         return task1->ops->schedParamCompare(&task1->sp, &task2->sp);
253     }
254 
255     if (rp1->policy == LOS_SCHED_IDLE) {
256         return 1;
257     } else if (rp2->policy == LOS_SCHED_IDLE) {
258         return -1;
259     }
260     return 0;
261 }
262 
OsSchedParamInit(LosTaskCB * taskCB,UINT16 policy,const SchedParam * parentParam,const LosSchedParam * param)263 UINT32 OsSchedParamInit(LosTaskCB *taskCB, UINT16 policy, const SchedParam *parentParam, const LosSchedParam *param)
264 {
265     switch (policy) {
266         case LOS_SCHED_FIFO:
267         case LOS_SCHED_RR:
268             HPFTaskSchedParamInit(taskCB, policy, parentParam, param);
269             break;
270         case LOS_SCHED_DEADLINE:
271             return EDFTaskSchedParamInit(taskCB, policy, parentParam, param);
272         case LOS_SCHED_IDLE:
273             IdleTaskSchedParamInit(taskCB);
274             break;
275         default:
276             return LOS_NOK;
277     }
278 
279     return LOS_OK;
280 }
281 
OsSchedProcessDefaultSchedParamGet(UINT16 policy,SchedParam * param)282 VOID OsSchedProcessDefaultSchedParamGet(UINT16 policy, SchedParam *param)
283 {
284     switch (policy) {
285         case LOS_SCHED_FIFO:
286         case LOS_SCHED_RR:
287             HPFProcessDefaultSchedParamGet(param);
288             break;
289         case LOS_SCHED_DEADLINE:
290             EDFProcessDefaultSchedParamGet(param);
291             break;
292         case LOS_SCHED_IDLE:
293         default:
294             PRINT_ERR("Invalid process-level scheduling policy, %u\n", policy);
295             break;
296     }
297     return;
298 }
299 
TopTaskGet(SchedRunqueue * rq)300 STATIC LosTaskCB *TopTaskGet(SchedRunqueue *rq)
301 {
302     LosTaskCB *newTask = EDFRunqueueTopTaskGet(rq->edfRunqueue);
303     if (newTask != NULL) {
304         goto FIND;
305     }
306 
307     newTask = HPFRunqueueTopTaskGet(rq->hpfRunqueue);
308     if (newTask != NULL) {
309         goto FIND;
310     }
311 
312     newTask = rq->idleTask;
313 
314 FIND:
315     newTask->ops->start(rq, newTask);
316     return newTask;
317 }
318 
OsSchedStart(VOID)319 VOID OsSchedStart(VOID)
320 {
321     UINT32 cpuid = ArchCurrCpuid();
322     UINT32 intSave;
323 
324     PRINTK("cpu %d entering scheduler\n", cpuid);
325 
326     SCHEDULER_LOCK(intSave);
327 
328     OsTickStart();
329 
330     SchedRunqueue *rq = OsSchedRunqueue();
331     LosTaskCB *newTask = TopTaskGet(rq);
332     newTask->taskStatus |= OS_TASK_STATUS_RUNNING;
333 
334 #ifdef LOSCFG_KERNEL_SMP
335     /*
336      * attention: current cpu needs to be set, in case first task deletion
337      * may fail because this flag mismatch with the real current cpu.
338      */
339     newTask->currCpu = cpuid;
340 #endif
341 
342     OsCurrTaskSet((VOID *)newTask);
343 
344     newTask->startTime = OsGetCurrSchedTimeCycle();
345 
346     OsSwtmrResponseTimeReset(newTask->startTime);
347 
348     /* System start schedule */
349     OS_SCHEDULER_SET(cpuid);
350 
351     rq->responseID = OS_INVALID;
352     UINT64 deadline = newTask->ops->deadlineGet(newTask);
353     SchedNextExpireTimeSet(newTask->taskID, deadline, OS_INVALID);
354     OsTaskContextLoad(newTask);
355 }
356 
357 #ifdef LOSCFG_KERNEL_SMP
OsSchedToUserReleaseLock(VOID)358 VOID OsSchedToUserReleaseLock(VOID)
359 {
360     /* The scheduling lock needs to be released before returning to user mode */
361     LOCKDEP_CHECK_OUT(&g_taskSpin);
362     ArchSpinUnlock(&g_taskSpin.rawLock);
363 
364     OsSchedUnlock();
365 }
366 #endif
367 
368 #ifdef LOSCFG_BASE_CORE_TSK_MONITOR
TaskStackCheck(LosTaskCB * runTask,LosTaskCB * newTask)369 STATIC VOID TaskStackCheck(LosTaskCB *runTask, LosTaskCB *newTask)
370 {
371     if (!OS_STACK_MAGIC_CHECK(runTask->topOfStack)) {
372         LOS_Panic("CURRENT task ID: %s:%d stack overflow!\n", runTask->taskName, runTask->taskID);
373     }
374 
375     if (((UINTPTR)(newTask->stackPointer) <= newTask->topOfStack) ||
376         ((UINTPTR)(newTask->stackPointer) > (newTask->topOfStack + newTask->stackSize))) {
377         LOS_Panic("HIGHEST task ID: %s:%u SP error! StackPointer: %p TopOfStack: %p\n",
378                   newTask->taskName, newTask->taskID, newTask->stackPointer, newTask->topOfStack);
379     }
380 }
381 #endif
382 
SchedSwitchCheck(LosTaskCB * runTask,LosTaskCB * newTask)383 STATIC INLINE VOID SchedSwitchCheck(LosTaskCB *runTask, LosTaskCB *newTask)
384 {
385 #ifdef LOSCFG_BASE_CORE_TSK_MONITOR
386     TaskStackCheck(runTask, newTask);
387 #endif /* LOSCFG_BASE_CORE_TSK_MONITOR */
388     OsHookCall(LOS_HOOK_TYPE_TASK_SWITCHEDIN, newTask, runTask);
389 }
390 
SchedTaskSwitch(SchedRunqueue * rq,LosTaskCB * runTask,LosTaskCB * newTask)391 STATIC VOID SchedTaskSwitch(SchedRunqueue *rq, LosTaskCB *runTask, LosTaskCB *newTask)
392 {
393     SchedSwitchCheck(runTask, newTask);
394 
395     runTask->taskStatus &= ~OS_TASK_STATUS_RUNNING;
396     newTask->taskStatus |= OS_TASK_STATUS_RUNNING;
397 
398 #ifdef LOSCFG_KERNEL_SMP
399     /* mask new running task's owner processor */
400     runTask->currCpu = OS_TASK_INVALID_CPUID;
401     newTask->currCpu = ArchCurrCpuid();
402 #endif
403 
404     OsCurrTaskSet((VOID *)newTask);
405 #ifdef LOSCFG_KERNEL_VM
406     if (newTask->archMmu != runTask->archMmu) {
407         LOS_ArchMmuContextSwitch((LosArchMmu *)newTask->archMmu);
408     }
409 #endif
410 
411 #ifdef LOSCFG_KERNEL_CPUP
412     OsCpupCycleEndStart(runTask, newTask);
413 #endif
414 
415 #ifdef LOSCFG_SCHED_HPF_DEBUG
416     UINT64 waitStartTime = newTask->startTime;
417 #endif
418     if (runTask->taskStatus & OS_TASK_STATUS_READY) {
419         /* When a thread enters the ready queue, its slice of time is updated */
420         newTask->startTime = runTask->startTime;
421     } else {
422         /* The currently running task is blocked */
423         newTask->startTime = OsGetCurrSchedTimeCycle();
424         /* The task is in a blocking state and needs to update its time slice before pend */
425         runTask->ops->timeSliceUpdate(rq, runTask, newTask->startTime);
426 
427         if (runTask->taskStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY)) {
428             OsSchedTimeoutQueueAdd(runTask, runTask->ops->waitTimeGet(runTask));
429         }
430     }
431 
432     UINT64 deadline = newTask->ops->deadlineGet(newTask);
433     SchedNextExpireTimeSet(newTask->taskID, deadline, runTask->taskID);
434 
435 #ifdef LOSCFG_SCHED_HPF_DEBUG
436     newTask->schedStat.waitSchedTime += newTask->startTime - waitStartTime;
437     newTask->schedStat.waitSchedCount++;
438     runTask->schedStat.runTime = runTask->schedStat.allRuntime;
439     runTask->schedStat.switchCount++;
440 #endif
441     /* do the task context switch */
442     OsTaskSchedule(newTask, runTask);
443 }
444 
OsSchedIrqEndCheckNeedSched(VOID)445 VOID OsSchedIrqEndCheckNeedSched(VOID)
446 {
447     SchedRunqueue *rq = OsSchedRunqueue();
448     LosTaskCB *runTask = OsCurrTaskGet();
449 
450     runTask->ops->timeSliceUpdate(rq, runTask, OsGetCurrSchedTimeCycle());
451 
452     if (OsPreemptable() && (rq->schedFlag & INT_PEND_RESCH)) {
453         rq->schedFlag &= ~INT_PEND_RESCH;
454 
455         LOS_SpinLock(&g_taskSpin);
456 
457         runTask->ops->enqueue(rq, runTask);
458 
459         LosTaskCB *newTask = TopTaskGet(rq);
460         if (runTask != newTask) {
461             SchedTaskSwitch(rq, runTask, newTask);
462             LOS_SpinUnlock(&g_taskSpin);
463             return;
464         }
465 
466         LOS_SpinUnlock(&g_taskSpin);
467     }
468 
469     if (rq->schedFlag & INT_PEND_TICK) {
470         OsSchedExpireTimeUpdate();
471     }
472 }
473 
OsSchedResched(VOID)474 VOID OsSchedResched(VOID)
475 {
476     LOS_ASSERT(LOS_SpinHeld(&g_taskSpin));
477     SchedRunqueue *rq = OsSchedRunqueue();
478 #ifdef LOSCFG_KERNEL_SMP
479     LOS_ASSERT(rq->taskLockCnt == 1);
480 #else
481     LOS_ASSERT(rq->taskLockCnt == 0);
482 #endif
483 
484     rq->schedFlag &= ~INT_PEND_RESCH;
485     LosTaskCB *runTask = OsCurrTaskGet();
486     LosTaskCB *newTask = TopTaskGet(rq);
487     if (runTask == newTask) {
488         return;
489     }
490 
491     SchedTaskSwitch(rq, runTask, newTask);
492 }
493 
LOS_Schedule(VOID)494 VOID LOS_Schedule(VOID)
495 {
496     UINT32 intSave;
497     LosTaskCB *runTask = OsCurrTaskGet();
498     SchedRunqueue *rq = OsSchedRunqueue();
499 
500     if (OS_INT_ACTIVE) {
501         OsSchedRunqueuePendingSet();
502         return;
503     }
504 
505     if (!OsPreemptable()) {
506         return;
507     }
508 
509     /*
510      * trigger schedule in task will also do the slice check
511      * if necessary, it will give up the timeslice more in time.
512      * otherwise, there's no other side effects.
513      */
514     SCHEDULER_LOCK(intSave);
515 
516     runTask->ops->timeSliceUpdate(rq, runTask, OsGetCurrSchedTimeCycle());
517 
518     /* add run task back to ready queue */
519     runTask->ops->enqueue(rq, runTask);
520 
521     /* reschedule to new thread */
522     OsSchedResched();
523 
524     SCHEDULER_UNLOCK(intSave);
525 }
526 
SchedLockPendFindPosSub(const LosTaskCB * runTask,const LOS_DL_LIST * lockList)527 STATIC INLINE LOS_DL_LIST *SchedLockPendFindPosSub(const LosTaskCB *runTask, const LOS_DL_LIST *lockList)
528 {
529     LosTaskCB *pendedTask = NULL;
530 
531     LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, lockList, LosTaskCB, pendList) {
532         INT32 ret = OsSchedParamCompare(pendedTask, runTask);
533         if (ret < 0) {
534             continue;
535         } else if (ret > 0) {
536             return &pendedTask->pendList;
537         } else {
538             return pendedTask->pendList.pstNext;
539         }
540     }
541     return NULL;
542 }
543 
OsSchedLockPendFindPos(const LosTaskCB * runTask,LOS_DL_LIST * lockList)544 LOS_DL_LIST *OsSchedLockPendFindPos(const LosTaskCB *runTask, LOS_DL_LIST *lockList)
545 {
546     if (LOS_ListEmpty(lockList)) {
547         return lockList;
548     }
549 
550     LosTaskCB *pendedTask1 = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(lockList));
551     INT32 ret = OsSchedParamCompare(pendedTask1, runTask);
552     if (ret > 0) {
553         return lockList->pstNext;
554     }
555 
556     LosTaskCB *pendedTask2 = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_LAST(lockList));
557     ret = OsSchedParamCompare(pendedTask2, runTask);
558     if (ret <= 0) {
559         return lockList;
560     }
561 
562     return SchedLockPendFindPosSub(runTask, lockList);
563 }
564