• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2022 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 #ifndef _LOS_SCHED_PRI_H
33 #define _LOS_SCHED_PRI_H
34 
35 #include "los_sortlink_pri.h"
36 #include "los_sys_pri.h"
37 #include "los_hwi.h"
38 #include "hal_timer.h"
39 #ifdef LOSCFG_SCHED_DEBUG
40 #include "los_statistics_pri.h"
41 #endif
42 #include "los_stackinfo_pri.h"
43 #include "los_futex_pri.h"
44 #ifdef LOSCFG_KERNEL_PM
45 #include "los_pm_pri.h"
46 #endif
47 #include "los_signal.h"
48 #ifdef LOSCFG_KERNEL_CPUP
49 #include "los_cpup_pri.h"
50 #endif
51 #ifdef LOSCFG_KERNEL_LITEIPC
52 #include "hm_liteipc.h"
53 #endif
54 #include "los_mp.h"
55 
56 #ifdef __cplusplus
57 #if __cplusplus
58 extern "C" {
59 #endif /* __cplusplus */
60 #endif /* __cplusplus */
61 
62 #define OS_SCHED_MINI_PERIOD          (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI)
63 #define OS_TICK_RESPONSE_PRECISION    (UINT32)((OS_SCHED_MINI_PERIOD * 75) / 100)
64 #define OS_SCHED_MAX_RESPONSE_TIME    OS_SORT_LINK_INVALID_TIME
65 #define OS_SCHED_TICK_TO_CYCLE(ticks) ((UINT64)ticks * OS_CYCLE_PER_TICK)
66 #define AFFI_MASK_TO_CPUID(mask)      ((UINT16)((mask) - 1))
67 
68 extern UINT32 g_taskScheduled;
69 #define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))
70 #define OS_SCHEDULER_ALL_ACTIVE (g_taskScheduled == LOSCFG_KERNEL_CPU_MASK)
71 
72 typedef struct TagTaskCB LosTaskCB;
73 typedef BOOL (*SCHED_TL_FIND_FUNC)(UINTPTR, UINTPTR);
74 
OsGetCurrSchedTimeCycle(VOID)75 STATIC INLINE UINT64 OsGetCurrSchedTimeCycle(VOID)
76 {
77     return HalClockGetCycles();
78 }
79 
80 typedef enum {
81     INT_NO_RESCH = 0x0,   /* no needs to schedule */
82     INT_PEND_RESCH = 0x1, /* pending schedule flag */
83     INT_PEND_TICK = 0x2,  /* pending tick */
84 } SchedFlag;
85 
86 #define OS_PRIORITY_QUEUE_NUM 32
87 typedef struct {
88     LOS_DL_LIST priQueList[OS_PRIORITY_QUEUE_NUM];
89     UINT32      readyTasks[OS_PRIORITY_QUEUE_NUM];
90     UINT32      queueBitmap;
91 } HPFQueue;
92 
93 typedef struct {
94     HPFQueue queueList[OS_PRIORITY_QUEUE_NUM];
95     UINT32   queueBitmap;
96 } HPFRunqueue;
97 
98 typedef struct {
99     SortLinkAttribute timeoutQueue; /* task timeout queue */
100     HPFRunqueue       *hpfRunqueue;
101     UINT64            responseTime; /* Response time for current CPU tick interrupts */
102     UINT32            responseID;   /* The response ID of the current CPU tick interrupt */
103     UINT32            idleTaskID;   /* idle task id */
104     UINT32            taskLockCnt;  /* task lock flag */
105     UINT32            schedFlag;    /* pending scheduler flag */
106 } SchedRunqueue;
107 
108 extern SchedRunqueue g_schedRunqueue[LOSCFG_KERNEL_CORE_NUM];
109 
110 VOID OsSchedExpireTimeUpdate(VOID);
111 
OsSchedRunqueue(VOID)112 STATIC INLINE SchedRunqueue *OsSchedRunqueue(VOID)
113 {
114     return &g_schedRunqueue[ArchCurrCpuid()];
115 }
116 
OsSchedRunqueueByID(UINT16 id)117 STATIC INLINE SchedRunqueue *OsSchedRunqueueByID(UINT16 id)
118 {
119     return &g_schedRunqueue[id];
120 }
121 
OsSchedLockCountGet(VOID)122 STATIC INLINE UINT32 OsSchedLockCountGet(VOID)
123 {
124     return OsSchedRunqueue()->taskLockCnt;
125 }
126 
OsSchedLockSet(UINT32 count)127 STATIC INLINE VOID OsSchedLockSet(UINT32 count)
128 {
129     OsSchedRunqueue()->taskLockCnt = count;
130 }
131 
OsSchedLock(VOID)132 STATIC INLINE VOID OsSchedLock(VOID)
133 {
134     OsSchedRunqueue()->taskLockCnt++;
135 }
136 
OsSchedUnlock(VOID)137 STATIC INLINE VOID OsSchedUnlock(VOID)
138 {
139     OsSchedRunqueue()->taskLockCnt--;
140 }
141 
OsSchedUnlockResch(VOID)142 STATIC INLINE BOOL OsSchedUnlockResch(VOID)
143 {
144     SchedRunqueue *rq = OsSchedRunqueue();
145     if (rq->taskLockCnt > 0) {
146         rq->taskLockCnt--;
147         if ((rq->taskLockCnt == 0) && (rq->schedFlag & INT_PEND_RESCH) && OS_SCHEDULER_ACTIVE) {
148             return TRUE;
149         }
150     }
151 
152     return FALSE;
153 }
154 
OsSchedIsLock(VOID)155 STATIC INLINE BOOL OsSchedIsLock(VOID)
156 {
157     return (OsSchedRunqueue()->taskLockCnt != 0);
158 }
159 
160 /* Check if preemptible with counter flag */
OsPreemptable(VOID)161 STATIC INLINE BOOL OsPreemptable(VOID)
162 {
163     SchedRunqueue *rq = OsSchedRunqueue();
164     /*
165      * Unlike OsPreemptableInSched, the int may be not disabled when OsPreemptable
166      * is called, needs manually disable interrupt, to prevent current task from
167      * being migrated to another core, and get the wrong preemptable status.
168      */
169     UINT32 intSave = LOS_IntLock();
170     BOOL preemptible = (rq->taskLockCnt == 0);
171     if (!preemptible) {
172         /* Set schedule flag if preemption is disabled */
173         rq->schedFlag |= INT_PEND_RESCH;
174     }
175     LOS_IntRestore(intSave);
176     return preemptible;
177 }
178 
OsPreemptableInSched(VOID)179 STATIC INLINE BOOL OsPreemptableInSched(VOID)
180 {
181     BOOL preemptible = FALSE;
182     SchedRunqueue *rq = OsSchedRunqueue();
183 
184 #ifdef LOSCFG_KERNEL_SMP
185     /*
186      * For smp systems, schedule must hold the task spinlock, and this counter
187      * will increase by 1 in that case.
188      */
189     preemptible = (rq->taskLockCnt == 1);
190 
191 #else
192     preemptible = (rq->taskLockCnt == 0);
193 #endif
194     if (!preemptible) {
195         /* Set schedule flag if preemption is disabled */
196         rq->schedFlag |= INT_PEND_RESCH;
197     }
198 
199     return preemptible;
200 }
201 
OsSchedRunqueueIdleGet(VOID)202 STATIC INLINE UINT32 OsSchedRunqueueIdleGet(VOID)
203 {
204     return OsSchedRunqueue()->idleTaskID;
205 }
206 
OsSchedRunqueuePendingSet(VOID)207 STATIC INLINE VOID OsSchedRunqueuePendingSet(VOID)
208 {
209     OsSchedRunqueue()->schedFlag |= INT_PEND_RESCH;
210 }
211 
212 #define LOS_SCHED_NORMAL  0U
213 #define LOS_SCHED_FIFO    1U
214 #define LOS_SCHED_RR      2U
215 #define LOS_SCHED_IDLE    3U
216 
217 typedef struct {
218     UINT16 policy;
219     UINT16 basePrio;
220     UINT16 priority;
221     UINT32 timeSlice;
222 } SchedParam;
223 
224 typedef struct {
225     UINT16  policy; /* This field must be present for all scheduling policies and must be the first in the structure */
226     UINT16  basePrio;
227     UINT16  priority;
228     UINT32  initTimeSlice;
229     UINT32  priBitmap; /**< Bitmap for recording the change of task priority, the priority can not be greater than 31 */
230 } SchedHPF;
231 
232 typedef struct {
233     union {
234         SchedHPF hpf;
235     } Policy;
236 } SchedPolicy;
237 
238 typedef struct {
239     VOID (*dequeue)(SchedRunqueue *rq, LosTaskCB *taskCB);
240     VOID (*enqueue)(SchedRunqueue *rq, LosTaskCB *taskCB);
241     VOID (*start)(SchedRunqueue *rq, LosTaskCB *taskCB);
242     VOID (*exit)(LosTaskCB *taskCB);
243     UINT32 (*wait)(LosTaskCB *runTask, LOS_DL_LIST *list, UINT32 timeout);
244     VOID (*wake)(LosTaskCB *taskCB);
245     BOOL (*schedParamModify)(LosTaskCB *taskCB, const SchedParam *param);
246     UINT32 (*schedParamGet)(const LosTaskCB *taskCB, SchedParam *param);
247     UINT32 (*delay)(LosTaskCB *taskCB, UINT64 waitTime);
248     VOID (*yield)(LosTaskCB *taskCB);
249     UINT32 (*suspend)(LosTaskCB *taskCB);
250     UINT32 (*resume)(LosTaskCB *taskCB, BOOL *needSched);
251     UINT64 (*deadlineGet)(const LosTaskCB *taskCB);
252     VOID (*timeSliceUpdate)(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 currTime);
253     INT32 (*schedParamCompare)(const SchedPolicy *sp1, const SchedPolicy *sp2);
254     VOID (*priorityInheritance)(LosTaskCB *owner, const SchedParam *param);
255     VOID (*priorityRestore)(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param);
256 } SchedOps;
257 
258 /**
259  * @ingroup los_sched
260  * Define a usable task priority.
261  *
262  * Highest task priority.
263  */
264 #define OS_TASK_PRIORITY_HIGHEST    0
265 
266 /**
267  * @ingroup los_sched
268  * Define a usable task priority.
269  *
270  * Lowest task priority.
271  */
272 #define OS_TASK_PRIORITY_LOWEST     31
273 
274 /**
275  * @ingroup los_sched
276  * Flag that indicates the task or task control block status.
277  *
278  * The task is init.
279  */
280 #define OS_TASK_STATUS_INIT         0x0001U
281 
282 /**
283  * @ingroup los_sched
284  * Flag that indicates the task or task control block status.
285  *
286  * The task is ready.
287  */
288 #define OS_TASK_STATUS_READY        0x0002U
289 
290 /**
291  * @ingroup los_sched
292  * Flag that indicates the task or task control block status.
293  *
294  * The task is running.
295  */
296 #define OS_TASK_STATUS_RUNNING      0x0004U
297 
298 /**
299  * @ingroup los_sched
300  * Flag that indicates the task or task control block status.
301  *
302  * The task is suspended.
303  */
304 #define OS_TASK_STATUS_SUSPENDED    0x0008U
305 
306 /**
307  * @ingroup los_sched
308  * Flag that indicates the task or task control block status.
309  *
310  * The task is blocked.
311  */
312 #define OS_TASK_STATUS_PENDING      0x0010U
313 
314 /**
315  * @ingroup los_sched
316  * Flag that indicates the task or task control block status.
317  *
318  * The task is delayed.
319  */
320 #define OS_TASK_STATUS_DELAY        0x0020U
321 
322 /**
323  * @ingroup los_sched
324  * Flag that indicates the task or task control block status.
325  *
326  * The time for waiting for an event to occur expires.
327  */
328 #define OS_TASK_STATUS_TIMEOUT      0x0040U
329 
330 /**
331  * @ingroup los_sched
332  * Flag that indicates the task or task control block status.
333  *
334  * The task is pend for a period of time.
335  */
336 #define OS_TASK_STATUS_PEND_TIME    0x0080U
337 
338 /**
339  * @ingroup los_sched
340  * Flag that indicates the task or task control block status.
341  *
342  * The task is exit.
343  */
344 #define OS_TASK_STATUS_EXIT         0x0100U
345 
346 #define OS_TASK_STATUS_BLOCKED     (OS_TASK_STATUS_INIT | OS_TASK_STATUS_PENDING | \
347                                     OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND_TIME)
348 
349 /**
350  * @ingroup los_task
351  * Flag that indicates the task or task control block status.
352  *
353  * The delayed operation of this task is frozen.
354  */
355 #define OS_TASK_STATUS_FROZEN       0x0200U
356 
357 #define OS_TCB_NAME_LEN             32
358 
359 typedef struct TagTaskCB {
360     VOID            *stackPointer;      /**< Task stack pointer */
361     UINT16          taskStatus;         /**< Task status */
362 
363     UINT64          startTime;          /**< The start time of each phase of task */
364     UINT64          waitTime;           /**< Task delay time, tick number */
365     UINT64          irqStartTime;       /**< Interrupt start time */
366     UINT32          irqUsedTime;        /**< Interrupt consumption time */
367     INT32           timeSlice;          /**< Task remaining time slice */
368     SortLinkList    sortList;           /**< Task sortlink node */
369     const SchedOps  *ops;
370     SchedPolicy     sp;
371 
372     UINT32          stackSize;          /**< Task stack size */
373     UINTPTR         topOfStack;         /**< Task stack top */
374     UINT32          taskID;             /**< Task ID */
375     TSK_ENTRY_FUNC  taskEntry;          /**< Task entrance function */
376     VOID            *joinRetval;        /**< pthread adaption */
377     VOID            *taskMux;           /**< Task-held mutex */
378     VOID            *taskEvent;         /**< Task-held event */
379     UINTPTR         args[4];            /**< Parameter, of which the maximum number is 4 */
380     CHAR            taskName[OS_TCB_NAME_LEN]; /**< Task name */
381     LOS_DL_LIST     pendList;           /**< Task pend node */
382     LOS_DL_LIST     threadList;         /**< thread list */
383     UINT32          eventMask;          /**< Event mask */
384     UINT32          eventMode;          /**< Event mode */
385 #ifdef LOSCFG_KERNEL_CPUP
386     OsCpupBase      taskCpup;           /**< task cpu usage */
387 #endif
388     INT32           errorNo;            /**< Error Num */
389     UINT32          signal;             /**< Task signal */
390     sig_cb          sig;
391 #ifdef LOSCFG_KERNEL_SMP
392     UINT16          currCpu;            /**< CPU core number of this task is running on */
393     UINT16          lastCpu;            /**< CPU core number of this task is running on last time */
394     UINT16          cpuAffiMask;        /**< CPU affinity mask, support up to 16 cores */
395 #ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
396     UINT32          syncSignal;         /**< Synchronization for signal handling */
397 #endif
398 #ifdef LOSCFG_KERNEL_SMP_LOCKDEP
399     LockDep         lockDep;
400 #endif
401 #endif
402 #ifdef LOSCFG_SCHED_DEBUG
403     SchedStat       schedStat;          /**< Schedule statistics */
404 #endif
405 #ifdef LOSCFG_KERNEL_VM
406     UINTPTR         archMmu;
407     UINTPTR         userArea;
408     UINTPTR         userMapBase;
409     UINT32          userMapSize;        /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */
410     FutexNode       futex;
411 #endif
412     UINT32          processID;          /**< Which belong process */
413     LOS_DL_LIST     joinList;           /**< join list */
414     LOS_DL_LIST     lockList;           /**< Hold the lock list */
415     UINTPTR         waitID;             /**< Wait for the PID or GID of the child process */
416     UINT16          waitFlag;           /**< The type of child process that is waiting, belonging to a group or parent,
417                                              a specific child process, or any child process */
418 #ifdef LOSCFG_KERNEL_LITEIPC
419     IpcTaskInfo     *ipcTaskInfo;
420 #endif
421 #ifdef LOSCFG_KERNEL_PERF
422     UINTPTR         pc;
423     UINTPTR         fp;
424 #endif
425 } LosTaskCB;
426 
OsTaskIsRunning(const LosTaskCB * taskCB)427 STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB)
428 {
429     return ((taskCB->taskStatus & OS_TASK_STATUS_RUNNING) != 0);
430 }
431 
OsTaskIsReady(const LosTaskCB * taskCB)432 STATIC INLINE BOOL OsTaskIsReady(const LosTaskCB *taskCB)
433 {
434     return ((taskCB->taskStatus & OS_TASK_STATUS_READY) != 0);
435 }
436 
OsTaskIsInactive(const LosTaskCB * taskCB)437 STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB)
438 {
439     return ((taskCB->taskStatus & (OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) != 0);
440 }
441 
OsTaskIsPending(const LosTaskCB * taskCB)442 STATIC INLINE BOOL OsTaskIsPending(const LosTaskCB *taskCB)
443 {
444     return ((taskCB->taskStatus & OS_TASK_STATUS_PENDING) != 0);
445 }
446 
OsTaskIsSuspended(const LosTaskCB * taskCB)447 STATIC INLINE BOOL OsTaskIsSuspended(const LosTaskCB *taskCB)
448 {
449     return ((taskCB->taskStatus & OS_TASK_STATUS_SUSPENDED) != 0);
450 }
451 
OsTaskIsBlocked(const LosTaskCB * taskCB)452 STATIC INLINE BOOL OsTaskIsBlocked(const LosTaskCB *taskCB)
453 {
454     return ((taskCB->taskStatus & (OS_TASK_STATUS_SUSPENDED | OS_TASK_STATUS_PENDING | OS_TASK_STATUS_DELAY)) != 0);
455 }
456 
OsCurrTaskGet(VOID)457 STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID)
458 {
459     return (LosTaskCB *)ArchCurrTaskGet();
460 }
461 
OsCurrTaskSet(LosTaskCB * task)462 STATIC INLINE VOID OsCurrTaskSet(LosTaskCB *task)
463 {
464     ArchCurrTaskSet(task);
465 }
466 
OsCurrUserTaskSet(UINTPTR thread)467 STATIC INLINE VOID OsCurrUserTaskSet(UINTPTR thread)
468 {
469     ArchCurrUserTaskSet(thread);
470 }
471 
OsSchedIrqUsedTimeUpdate(VOID)472 STATIC INLINE VOID OsSchedIrqUsedTimeUpdate(VOID)
473 {
474     LosTaskCB *runTask = OsCurrTaskGet();
475     runTask->irqUsedTime = OsGetCurrSchedTimeCycle() - runTask->irqStartTime;
476 }
477 
OsSchedIrqStartTime(VOID)478 STATIC INLINE VOID OsSchedIrqStartTime(VOID)
479 {
480     LosTaskCB *runTask = OsCurrTaskGet();
481     runTask->irqStartTime = OsGetCurrSchedTimeCycle();
482 }
483 
484 #ifdef LOSCFG_KERNEL_SMP
IdleRunqueueFind(UINT16 * idleCpuid)485 STATIC INLINE VOID IdleRunqueueFind(UINT16 *idleCpuid)
486 {
487     SchedRunqueue *idleRq = OsSchedRunqueueByID(0);
488     UINT32 nodeNum = OsGetSortLinkNodeNum(&idleRq->timeoutQueue);
489     UINT16 cpuid = 1;
490     do {
491         SchedRunqueue *rq = OsSchedRunqueueByID(cpuid);
492         UINT32 temp = OsGetSortLinkNodeNum(&rq->timeoutQueue);
493         if (nodeNum > temp) {
494             *idleCpuid = cpuid;
495             nodeNum = temp;
496         }
497         cpuid++;
498     } while (cpuid < LOSCFG_KERNEL_CORE_NUM);
499 }
500 #endif
501 
OsSchedTimeoutQueueAdd(LosTaskCB * taskCB,UINT64 responseTime)502 STATIC INLINE VOID OsSchedTimeoutQueueAdd(LosTaskCB *taskCB, UINT64 responseTime)
503 {
504 #ifdef LOSCFG_KERNEL_SMP
505     UINT16 cpuid = AFFI_MASK_TO_CPUID(taskCB->cpuAffiMask);
506     if (cpuid >= LOSCFG_KERNEL_CORE_NUM) {
507         cpuid = 0;
508         IdleRunqueueFind(&cpuid);
509     }
510 #else
511     UINT16 cpuid = 0;
512 #endif
513 
514     SchedRunqueue *rq = OsSchedRunqueueByID(cpuid);
515     OsAdd2SortLink(&rq->timeoutQueue, &taskCB->sortList, responseTime, cpuid);
516 #ifdef LOSCFG_KERNEL_SMP
517     if ((cpuid != ArchCurrCpuid()) && (responseTime < rq->responseTime)) {
518         rq->schedFlag |= INT_PEND_TICK;
519         LOS_MpSchedule(CPUID_TO_AFFI_MASK(cpuid));
520     }
521 #endif
522 }
523 
OsSchedTimeoutQueueDelete(LosTaskCB * taskCB)524 STATIC INLINE VOID OsSchedTimeoutQueueDelete(LosTaskCB *taskCB)
525 {
526     SortLinkList *node = &taskCB->sortList;
527 #ifdef LOSCFG_KERNEL_SMP
528     SchedRunqueue *rq = OsSchedRunqueueByID(node->cpuid);
529 #else
530     SchedRunqueue *rq = OsSchedRunqueueByID(0);
531 #endif
532     UINT64 oldResponseTime = GET_SORTLIST_VALUE(node);
533     OsDeleteFromSortLink(&rq->timeoutQueue, node);
534     if (oldResponseTime <= rq->responseTime) {
535         rq->responseTime = OS_SCHED_MAX_RESPONSE_TIME;
536     }
537 }
538 
OsSchedTimeoutQueueAdjust(LosTaskCB * taskCB,UINT64 responseTime)539 STATIC INLINE UINT32 OsSchedTimeoutQueueAdjust(LosTaskCB *taskCB, UINT64 responseTime)
540 {
541     UINT32 ret;
542     SortLinkList *node = &taskCB->sortList;
543 #ifdef LOSCFG_KERNEL_SMP
544     UINT16 cpuid = node->cpuid;
545 #else
546     UINT16 cpuid = 0;
547 #endif
548     SchedRunqueue *rq = OsSchedRunqueueByID(cpuid);
549     ret = OsSortLinkAdjustNodeResponseTime(&rq->timeoutQueue, node, responseTime);
550     if (ret == LOS_OK) {
551         rq->schedFlag |= INT_PEND_TICK;
552     }
553     return ret;
554 }
555 
SchedTaskFreeze(LosTaskCB * taskCB)556 STATIC INLINE VOID SchedTaskFreeze(LosTaskCB *taskCB)
557 {
558     UINT64 responseTime;
559 
560 #ifdef LOSCFG_KERNEL_PM
561     if (!OsIsPmMode()) {
562         return;
563     }
564 #endif
565 
566     if (!(taskCB->taskStatus & (OS_TASK_STATUS_PEND_TIME | OS_TASK_STATUS_DELAY))) {
567         return;
568     }
569 
570     responseTime = GET_SORTLIST_VALUE(&taskCB->sortList);
571     OsSchedTimeoutQueueDelete(taskCB);
572     SET_SORTLIST_VALUE(&taskCB->sortList, responseTime);
573     taskCB->taskStatus |= OS_TASK_STATUS_FROZEN;
574     return;
575 }
576 
SchedTaskUnfreeze(LosTaskCB * taskCB)577 STATIC INLINE VOID SchedTaskUnfreeze(LosTaskCB *taskCB)
578 {
579     UINT64 currTime, responseTime;
580 
581     if (!(taskCB->taskStatus & OS_TASK_STATUS_FROZEN)) {
582         return;
583     }
584 
585     taskCB->taskStatus &= ~OS_TASK_STATUS_FROZEN;
586     currTime = OsGetCurrSchedTimeCycle();
587     responseTime = GET_SORTLIST_VALUE(&taskCB->sortList);
588     if (responseTime > currTime) {
589         OsSchedTimeoutQueueAdd(taskCB, responseTime);
590         return;
591     }
592 
593     SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME);
594     if (taskCB->taskStatus & OS_TASK_STATUS_PENDING) {
595         LOS_ListDelete(&taskCB->pendList);
596     }
597     taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED;
598     return;
599 }
600 
601 /*
602  * Schedule flag, one bit represents one core.
603  * This flag is used to prevent kernel scheduling before OSStartToRun.
604  */
605 #define OS_SCHEDULER_SET(cpuid) do {     \
606     g_taskScheduled |= (1U << (cpuid));  \
607 } while (0);
608 
609 #define OS_SCHEDULER_CLR(cpuid) do {     \
610     g_taskScheduled &= ~(1U << (cpuid)); \
611 } while (0);
612 
HPFRunqueueTopTaskGet(HPFRunqueue * rq)613 STATIC INLINE LosTaskCB *HPFRunqueueTopTaskGet(HPFRunqueue *rq)
614 {
615     LosTaskCB *newTask = NULL;
616     UINT32 baseBitmap = rq->queueBitmap;
617 #ifdef LOSCFG_KERNEL_SMP
618     UINT32 cpuid = ArchCurrCpuid();
619 #endif
620 
621     while (baseBitmap) {
622         UINT32 basePrio = CLZ(baseBitmap);
623         HPFQueue *queueList = &rq->queueList[basePrio];
624         UINT32 bitmap = queueList->queueBitmap;
625         while (bitmap) {
626             UINT32 priority = CLZ(bitmap);
627             LOS_DL_LIST_FOR_EACH_ENTRY(newTask, &queueList->priQueList[priority], LosTaskCB, pendList) {
628 #ifdef LOSCFG_KERNEL_SMP
629                 if (newTask->cpuAffiMask & (1U << cpuid)) {
630 #endif
631                     return newTask;
632 #ifdef LOSCFG_KERNEL_SMP
633                 }
634 #endif
635             }
636             bitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - priority - 1));
637         }
638         baseBitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - basePrio - 1));
639     }
640 
641     return NULL;
642 }
643 
644 VOID HPFSchedPolicyInit(SchedRunqueue *rq);
645 VOID HPFTaskSchedParamInit(LosTaskCB *taskCB, UINT16 policy,
646                            const SchedParam *parentParam, const TSK_INIT_PARAM_S *param);
647 VOID HPFProcessDefaultSchedParamGet(SchedParam *param);
648 
649 VOID IdleTaskSchedParamInit(LosTaskCB *taskCB);
650 
651 INT32 OsSchedParamCompare(const LosTaskCB *task1, const LosTaskCB *task2);
652 VOID OsSchedPriorityInheritance(LosTaskCB *owner, const SchedParam *param);
653 UINT32 OsSchedParamInit(LosTaskCB *taskCB, UINT16 policy,
654                         const SchedParam *parentParam, const TSK_INIT_PARAM_S *param);
655 VOID OsSchedProcessDefaultSchedParamGet(UINT16 policy, SchedParam *param);
656 
657 VOID OsSchedResponseTimeReset(UINT64 responseTime);
658 VOID OsSchedToUserReleaseLock(VOID);
659 VOID OsSchedTick(VOID);
660 UINT32 OsSchedInit(VOID);
661 VOID OsSchedStart(VOID);
662 
663 VOID OsSchedRunqueueIdleInit(UINT32 idleTaskID);
664 VOID OsSchedRunqueueInit(VOID);
665 
666 /*
667  * This function simply picks the next task and switches to it.
668  * Current task needs to already be in the right state or the right
669  * queues it needs to be in.
670  */
671 VOID OsSchedResched(VOID);
672 VOID OsSchedIrqEndCheckNeedSched(VOID);
673 
674 /*
675 * This function inserts the runTask to the lock pending list based on the
676 * task priority.
677 */
678 LOS_DL_LIST *OsSchedLockPendFindPos(const LosTaskCB *runTask, LOS_DL_LIST *lockList);
679 
680 #ifdef __cplusplus
681 #if __cplusplus
682 }
683 #endif /* __cplusplus */
684 #endif /* __cplusplus */
685 
686 #endif /* _LOS_SCHED_PRI_H */
687