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