• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_event.h"
33 #include "los_hook.h"
34 #include "los_interrupt.h"
35 #include "los_task.h"
36 #include "los_sched.h"
37 
38 
LOS_EventInit(PEVENT_CB_S eventCB)39 LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
40 {
41     if (eventCB == NULL) {
42         return LOS_ERRNO_EVENT_PTR_NULL;
43     }
44     eventCB->uwEventID = 0;
45     LOS_ListInit(&eventCB->stEventList);
46     OsHookCall(LOS_HOOK_TYPE_EVENT_INIT, eventCB);
47     return LOS_OK;
48 }
49 
LOS_EventPoll(UINT32 * eventID,UINT32 eventMask,UINT32 mode)50 LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode)
51 {
52     UINT32 ret = 0;
53     UINT32 intSave;
54 
55     if (eventID == NULL) {
56         return LOS_ERRNO_EVENT_PTR_NULL;
57     }
58     intSave = LOS_IntLock();
59     if (mode & LOS_WAITMODE_OR) {
60         if ((*eventID & eventMask) != 0) {
61             ret = *eventID & eventMask;
62         }
63     } else {
64         if ((eventMask != 0) && (eventMask == (*eventID & eventMask))) {
65             ret = *eventID & eventMask;
66         }
67     }
68     if (ret && (mode & LOS_WAITMODE_CLR)) {
69         *eventID = *eventID & ~(ret);
70     }
71     LOS_IntRestore(intSave);
72     return ret;
73 }
74 
OsEventReadParamCheck(PEVENT_CB_S eventCB,UINT32 eventMask,UINT32 mode)75 LITE_OS_SEC_TEXT STATIC_INLINE UINT32 OsEventReadParamCheck(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode)
76 {
77     if (eventCB == NULL) {
78         return LOS_ERRNO_EVENT_PTR_NULL;
79     }
80     if ((eventCB->stEventList.pstNext == NULL) || (eventCB->stEventList.pstPrev == NULL)) {
81         return LOS_ERRNO_EVENT_NOT_INITIALIZED;
82     }
83     if (eventMask == 0) {
84         return LOS_ERRNO_EVENT_EVENTMASK_INVALID;
85     }
86     if (eventMask & LOS_ERRTYPE_ERROR) {
87         return LOS_ERRNO_EVENT_SETBIT_INVALID;
88     }
89     if (((mode & LOS_WAITMODE_OR) && (mode & LOS_WAITMODE_AND)) ||
90         (mode & ~(LOS_WAITMODE_OR | LOS_WAITMODE_AND | LOS_WAITMODE_CLR)) ||
91         !(mode & (LOS_WAITMODE_OR | LOS_WAITMODE_AND))) {
92         return LOS_ERRNO_EVENT_FLAGS_INVALID;
93     }
94     return LOS_OK;
95 }
96 
LOS_EventRead(PEVENT_CB_S eventCB,UINT32 eventMask,UINT32 mode,UINT32 timeOut)97 LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeOut)
98 {
99     UINT32 ret;
100     UINT32 intSave;
101     LosTaskCB *runTsk = NULL;
102 
103     ret = OsEventReadParamCheck(eventCB, eventMask, mode);
104     if (ret != LOS_OK) {
105         return ret;
106     }
107 
108     if (OS_INT_ACTIVE) {
109         return LOS_ERRNO_EVENT_READ_IN_INTERRUPT;
110     }
111     if (g_losTask.runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
112         return LOS_ERRNO_EVENT_READ_IN_SYSTEM_TASK;
113     }
114     intSave = LOS_IntLock();
115     ret = LOS_EventPoll(&(eventCB->uwEventID), eventMask, mode);
116     OsHookCall(LOS_HOOK_TYPE_EVENT_READ, eventCB, eventMask, mode, timeOut);
117     if (ret == 0) {
118         if (timeOut == 0) {
119             LOS_IntRestore(intSave);
120             return ret;
121         }
122 
123         if (g_losTaskLock) {
124             LOS_IntRestore(intSave);
125             return LOS_ERRNO_EVENT_READ_IN_LOCK;
126         }
127         runTsk = g_losTask.runTask;
128         runTsk->eventMask = eventMask;
129         runTsk->eventMode = mode;
130         OsSchedTaskWait(&eventCB->stEventList, timeOut);
131         LOS_IntRestore(intSave);
132         LOS_Schedule();
133 
134         intSave = LOS_IntLock();
135         if (runTsk->taskStatus & OS_TASK_STATUS_TIMEOUT) {
136             runTsk->taskStatus &= ~OS_TASK_STATUS_TIMEOUT;
137             LOS_IntRestore(intSave);
138             return LOS_ERRNO_EVENT_READ_TIMEOUT;
139         }
140 
141         ret = LOS_EventPoll(&eventCB->uwEventID, eventMask, mode);
142     }
143 
144     LOS_IntRestore(intSave);
145     return ret;
146 }
147 
LOS_EventWrite(PEVENT_CB_S eventCB,UINT32 events)148 LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events)
149 {
150     LosTaskCB *resumedTask = NULL;
151     LosTaskCB *nextTask = (LosTaskCB *)NULL;
152     UINT32 intSave;
153     UINT8 exitFlag = 0;
154     if (eventCB == NULL) {
155         return LOS_ERRNO_EVENT_PTR_NULL;
156     }
157     if ((eventCB->stEventList.pstNext == NULL) || (eventCB->stEventList.pstPrev == NULL)) {
158         return LOS_ERRNO_EVENT_NOT_INITIALIZED;
159     }
160     if (events & LOS_ERRTYPE_ERROR) {
161         return LOS_ERRNO_EVENT_SETBIT_INVALID;
162     }
163     intSave = LOS_IntLock();
164     OsHookCall(LOS_HOOK_TYPE_EVENT_WRITE, eventCB, events);
165     eventCB->uwEventID |= events;
166     if (!LOS_ListEmpty(&eventCB->stEventList)) {
167         for (resumedTask = LOS_DL_LIST_ENTRY((&eventCB->stEventList)->pstNext, LosTaskCB, pendList);
168              &resumedTask->pendList != (&eventCB->stEventList);) {
169             nextTask = LOS_DL_LIST_ENTRY(resumedTask->pendList.pstNext, LosTaskCB, pendList);
170 
171             if (((resumedTask->eventMode & LOS_WAITMODE_OR) && (resumedTask->eventMask & events) != 0) ||
172                 ((resumedTask->eventMode & LOS_WAITMODE_AND) &&
173                  ((resumedTask->eventMask & eventCB->uwEventID) == resumedTask->eventMask))) {
174                 exitFlag = 1;
175 
176                 OsSchedTaskWake(resumedTask);
177             }
178             resumedTask = nextTask;
179         }
180 
181         if (exitFlag == 1) {
182             LOS_IntRestore(intSave);
183             LOS_Schedule();
184             return LOS_OK;
185         }
186     }
187 
188     LOS_IntRestore(intSave);
189     return LOS_OK;
190 }
191 
LOS_EventDestroy(PEVENT_CB_S eventCB)192 LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB)
193 {
194     UINT32 intSave;
195     if (eventCB == NULL) {
196         return LOS_ERRNO_EVENT_PTR_NULL;
197     }
198     intSave = LOS_IntLock();
199 
200     if (!LOS_ListEmpty(&eventCB->stEventList)) {
201         LOS_IntRestore(intSave);
202         return LOS_ERRNO_EVENT_SHOULD_NOT_DESTROYED;
203     }
204     eventCB->stEventList.pstNext = (LOS_DL_LIST *)NULL;
205     eventCB->stEventList.pstPrev = (LOS_DL_LIST *)NULL;
206     LOS_IntRestore(intSave);
207     OsHookCall(LOS_HOOK_TYPE_EVENT_DESTROY, eventCB);
208     return LOS_OK;
209 }
210 
LOS_EventClear(PEVENT_CB_S eventCB,UINT32 eventMask)211 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 eventMask)
212 {
213     UINT32 intSave;
214     if (eventCB == NULL) {
215         return LOS_ERRNO_EVENT_PTR_NULL;
216     }
217     OsHookCall(LOS_HOOK_TYPE_EVENT_CLEAR, eventCB, eventMask);
218     intSave = LOS_IntLock();
219     eventCB->uwEventID &= eventMask;
220     LOS_IntRestore(intSave);
221     return LOS_OK;
222 }
223