• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *   Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  * Description: wait
15  *
16  * Create: 2021-12-16
17  */
18 
19 #include <los_event.h>
20 #include <los_spinlock.h>
21 #include <los_memory.h>
22 #include <linux/wait.h>
23 
24 #include "soc_osal.h"
25 #include "osal_errno.h"
26 #include "osal_inner.h"
27 
osal_wait_init(osal_wait * wait)28 int osal_wait_init(osal_wait *wait)
29 {
30     if (wait == NULL || wait->wait != NULL) {
31         osal_log("parameter invalid!\n");
32         return OSAL_FAILURE;
33     }
34     wait_queue_head_t *wq =
35         (wait_queue_head_t *)LOS_MemAlloc((void *)m_aucSysMem0, sizeof(wait_queue_head_t));
36     if (wq == NULL) {
37         osal_log("LOS_MemAlloc failed!\n");
38         return OSAL_FAILURE;
39     }
40 
41     unsigned int ret = LOS_EventInit(&wq->stEvent);
42     if (ret != LOS_OK) {
43         osal_log("LOS_EventInit failed! ret = %#x.\n", ret);
44         LOS_MemFree((void*)m_aucSysMem0, (void *)wq);
45         return OSAL_FAILURE;
46     }
47     LOS_SpinInit(&wq->lock);
48     LOS_ListInit(&wq->poll_queue);
49     wait->wait = wq;
50     return OSAL_SUCCESS;
51 }
52 
osal_wait_interruptible(osal_wait * wait,osal_wait_condition_func func,const void * param)53 int osal_wait_interruptible(osal_wait *wait, osal_wait_condition_func func, const void *param)
54 {
55     // not support interruptible wait in liteos
56     return osal_wait_uninterruptible(wait, func, param);
57 }
58 
osal_wait_uninterruptible(osal_wait * wait,osal_wait_condition_func func,const void * param)59 int osal_wait_uninterruptible(osal_wait *wait, osal_wait_condition_func func, const void *param)
60 {
61     if (wait == NULL || wait->wait == NULL) {
62         osal_log("parameter invalid!\n");
63         return OSAL_FAILURE;
64     }
65     wait_queue_head_t *wq = (wait_queue_head_t *)(wait->wait);
66 
67     while (func != NULL && func(param) == 0) {
68         (VOID)LOS_EventRead(&wq->stEvent, 0x1U, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
69     }
70 
71     return OSAL_SUCCESS;
72 }
73 
74 /**
75  * @par Description: same as <wait_event_interruptible_timeout> from liteos
76  * This API is used to sleep a process until the condition evaluates to true or a timeout elapses.
77  * The condition is checked each time when the waitqueue wait is woken up.
78  * @attention
79  * The value range of parameter timeout is [0, 0xFFFFFFFF], and 0xFFFFFFFF means waiting forever.</li>
80  * @param  wait [IN] the waitqueue to wait on.
81  * @param  condition [IN] a condition evaluates to true or false.
82  * @param  timeout [IN] the max sleep time unit is ms.
83  *
84  * @retval #0 return 0 if the condition evaluated to false after the timeout elapsed
85  * @retval #1 return 1 if the condition evaluated to true after the timeout elapsed
86  * @retval #others return the remaining ticks if the condition evaluated to true before the timeout elapsed
87  */
osal_wait_timeout_interruptible(osal_wait * wait,osal_wait_condition_func func,const void * param,unsigned long ms)88 int osal_wait_timeout_interruptible(osal_wait *wait, osal_wait_condition_func func, const void *param, unsigned long ms)
89 {
90     if (wait == NULL || wait->wait == NULL) {
91         osal_log("parameter invalid!\n");
92         return OSAL_FAILURE;
93     }
94     wait_queue_head_t *wq = (wait_queue_head_t *)(wait->wait);
95 
96     unsigned long long ticksnow = LOS_TickCountGet();
97     unsigned int timetick = LOS_MS2Tick(ms);
98     if (timetick > INT32_MAX) {
99         osal_log("ms parameter invalid!\n");
100         return OSAL_FAILURE;
101     }
102     int timeout = (int)timetick;
103     int tmp_timeout = timeout;
104     int ret = timeout;
105     if (func == NULL) {
106         return ret; /* default return timeout if condition func NULL */
107     }
108     if (ms == 0 && func(param)) {
109         return 1;
110     }
111     while (!func(param)) {
112         unsigned int event_ret = LOS_EventRead(&wq->stEvent, 0x1U, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, (tmp_timeout));
113         if (ms == OSAL_WAIT_FOREVER) {
114             if (!func(param)) {
115                 continue;
116             }
117             break;
118         }
119 
120         tmp_timeout = (int)(timeout - (unsigned int)(LOS_TickCountGet() - ticksnow));
121         if (tmp_timeout <= 0 || event_ret == LOS_ERRNO_EVENT_READ_TIMEOUT) {
122             ret = (func(param) == FALSE) ? FALSE : TRUE;
123             break;
124         }
125         if (func(param) != 0) {
126             ret = tmp_timeout;
127             break;
128         }
129     }
130 
131     return ret;
132 }
133 
134 
osal_wait_timeout_uninterruptible(osal_wait * wait,osal_wait_condition_func func,const void * param,unsigned long ms)135 int osal_wait_timeout_uninterruptible(osal_wait *wait, osal_wait_condition_func func, const void *param,
136     unsigned long ms)
137 {
138     return osal_wait_timeout_interruptible(wait, func, param, ms);
139 }
140 
osal_wait_wakeup(osal_wait * wait)141 void osal_wait_wakeup(osal_wait *wait)
142 {
143     if (wait == NULL || wait->wait == NULL) {
144         osal_log("parameter invalid!\n");
145         return;
146     }
147 
148     wait_queue_head_t *wq = (wait_queue_head_t *)(wait->wait);
149     (VOID)LOS_EventWrite(&wq->stEvent, 0x1);
150 }
151 
osal_wait_wakeup_interruptible(osal_wait * wait)152 void osal_wait_wakeup_interruptible(osal_wait *wait)
153 {
154     osal_wait_wakeup(wait);
155 }
156 
osal_wait_destroy(osal_wait * wait)157 void osal_wait_destroy(osal_wait *wait)
158 {
159     if (wait == NULL || wait->wait == NULL) {
160         osal_log("parameter invalid!\n");
161         return;
162     }
163 
164     wait_queue_head_t *wq = (wait_queue_head_t *)(wait->wait);
165 
166     LOS_EventDestroy(&wq->stEvent);
167     LOS_ListDelInit(&wq->poll_queue);
168     LOS_MemFree((void *)m_aucSysMem0, (void *)wq);
169     wait->wait = NULL;
170 }
171