]> rtime.felk.cvut.cz Git - arc.git/blob - system/kernel/sleep.c
Fixes to Sleep()
[arc.git] / system / kernel / sleep.c
1 \r
2 #include "Os.h"\r
3 #include "application.h"\r
4 #include "internal.h"\r
5 #include "task_i.h"\r
6 #include "sys.h"\r
7 #include <assert.h>\r
8 #include <string.h>\r
9 \r
10 /**\r
11  * Will sleep for sleep ticks. This works only for extended\r
12  * tasks. If sleep is 0 it will just call the dispatcher to\r
13  * see if there is anything with higher priority to run.\r
14  *\r
15  * Sleep(0) only makes sense from a NON task (since they highest\r
16  * prio task is always running). SetEvent() nor ActivateTask() will\r
17  * activate a sleeping task.\r
18  *
19  * @param sleep
20  * @return E_OS_ACCESS if called from a basic task\r
21  *         E_OS_RESOURCE called while holding a resource\r
22  *         E_OS_CALLEVEL if called from interrupt context\r
23  *         E_OK if called from a FULL task\r
24  */\r
25 \r
26 StatusType Sleep( TickType sleep ) {\r
27         StatusType rv = E_OK;\r
28         OsTaskVarType *pcbPtr;\r
29         uint32_t flags;\r
30 \r
31 \r
32         pcbPtr = Os_SysTaskGetCurr();\r
33 \r
34         if (pcbPtr->constPtr->proc_type != PROC_EXTENDED) {\r
35                 rv = E_OS_ACCESS;\r
36                 goto err;\r
37         }\r
38 \r
39         /* Check that we are not calling from interrupt context */\r
40         if( Os_Sys.intNestCnt != 0 ) {\r
41                 rv =  E_OS_CALLEVEL;\r
42                 goto err;\r
43         }\r
44 \r
45         if ( Os_TaskOccupiesResources(pcbPtr) ) {\r
46                 rv =  E_OS_RESOURCE;\r
47                 goto err;\r
48         }\r
49 \r
50         Irq_Save(flags);\r
51 \r
52         if ( Os_SchedulerResourceIsFree() ) {\r
53                 if( sleep != 0 ) {\r
54                         TAILQ_INSERT_TAIL(&Os_Sys.timerHead,pcbPtr,timerEntry);\r
55                         pcbPtr->timerDec = sleep;\r
56                         Os_Dispatch(OP_SLEEP);\r
57                 } else {\r
58 \r
59                         if( Os_SysTaskGetCurr()->constPtr->scheduling != NON ) {\r
60                                 return E_OK;\r
61                         }\r
62 \r
63                         OsTaskVarType *topTask = Os_TaskGetTop();\r
64                         if( topTask->activePriority  != pcbPtr->activePriority ) {\r
65                                 Os_Dispatch(OP_SCHEDULE);\r
66                         }\r
67                 }\r
68         }\r
69 \r
70         Irq_Restore(flags);\r
71 \r
72         OS_STD_END_1(OSServiceId_Sleep,sleep);\r
73 }\r