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