VSF Documented
vsf_eda_sync.c
Go to the documentation of this file.
1/*****************************************************************************
2 * Copyright(C)2009-2022 by VSF Team *
3 * *
4 * Licensed under the Apache License, Version 2.0 (the "License"); *
5 * you may not use this file except in compliance with the License. *
6 * You may obtain a copy of the License at *
7 * *
8 * http://www.apache.org/licenses/LICENSE-2.0 *
9 * *
10 * Unless required by applicable law or agreed to in writing, software *
11 * distributed under the License is distributed on an "AS IS" BASIS, *
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
13 * See the License for the specific language governing permissions and *
14 * limitations under the License. *
15 * *
16 ****************************************************************************/
17
18
19/*============================ INCLUDES ======================================*/
20
22
23#if VSF_USE_KERNEL == ENABLED && defined(__EDA_GADGET__)
24
25/*============================ MACROS ========================================*/
26/*============================ MACROFIED FUNCTIONS ===========================*/
27/*============================ TYPES =========================================*/
28/*============================ GLOBAL VARIABLES ==============================*/
29/*============================ LOCAL VARIABLES ===============================*/
30/*============================ PROTOTYPES ====================================*/
31
32VSF_CAL_SECTION(".text.vsf.kernel.__vsf_teda_cancel_timer")
34
35/*============================ IMPLEMENTATION ================================*/
36
37
38#if VSF_KERNEL_CFG_SUPPORT_SYNC == ENABLED
39
40/*-----------------------------------------------------------------------------*
41 * vsf_sync_t for critical_section, semaphore, event *
42 *-----------------------------------------------------------------------------*/
43
44VSF_CAL_SECTION(".text.vsf.kernel.vsf_sync")
45vsf_eda_t * __vsf_eda_sync_set_timeout(vsf_eda_t *eda, vsf_timeout_tick_t timeout)
46{
47 eda = __vsf_eda_get_valid_eda(eda);
48
49 if (timeout > 0) {
50#if VSF_KERNEL_CFG_EDA_SUPPORT_TIMER == ENABLED
51 eda->flag.state.is_limitted = true;
52# ifdef __VSF_OS_CFG_EVTQ_LIST
53 // If timeout is too close, VSF_EVT_TIMER will be issued before eda->flag.state.is_ready cleared,
54 // __vsf_evtq_post(evtq_list) will ignore the VSF_EVT_TIMER event.
55 // So just record due and set is_to_set_due,
56 // timer will be set after eda->flag.state.is_ready cleared in vsf_evtq_poll(evtq_list).
57 eda->flag.state.is_to_set_due = true;
58 ((vsf_teda_t *)eda)->due = vsf_systimer_get_tick() + timeout;
59# else
61# endif
62#else
63 #ifndef WEAK_VSF_KERNEL_ERR_REPORT
65 #else
66 WEAK_VSF_KERNEL_ERR_REPORT(VSF_KERNEL_ERR_EDA_DOES_NOT_SUPPORT_TIMER);
67 #endif
68#endif
69 }
70 return eda;
71}
72
73VSF_CAL_SECTION(".text.vsf.kernel.vsf_sync")
75{
76 eda = __vsf_eda_get_valid_eda(eda);
77 VSF_KERNEL_ASSERT(eda != NULL);
78
80 vsf_eda_t, pending_node,
81 &sync->pending_list,
82 eda);
83
84 __vsf_eda_sync_set_timeout(eda, timeout);
85}
86
87VSF_CAL_SECTION(".text.vsf.kernel.vsf_sync")
88static vsf_eda_t *__vsf_eda_sync_get_eda_pending(vsf_sync_t *sync)
89{
90 vsf_eda_t *eda;
91
93 vsf_eda_t, pending_node,
94 &sync->pending_list,
95 eda);
96 return eda;
97}
98
99#if __IS_COMPILER_LLVM__ || __IS_COMPILER_ARM_COMPILER_6__
100# pragma clang diagnostic push
101# pragma clang diagnostic ignored "-Wcast-align"
102#endif
103
104#if __IS_COMPILER_GCC__
105# pragma GCC diagnostic push
106# pragma GCC diagnostic ignored "-Wcast-align"
107#endif
108
109VSF_CAL_SECTION(".text.vsf.kernel.vsf_sync")
110static vsf_sync_reason_t __vsf_eda_sync_get_reason( vsf_sync_t *sync,
111 vsf_evt_t evt,
112 bool dequeue_eda)
113{
114 vsf_eda_t *eda = vsf_eda_get_cur();
115 VSF_KERNEL_ASSERT(eda != NULL);
117
118 VSF_KERNEL_ASSERT((sync != NULL) && (eda != NULL));
119
120#if VSF_KERNEL_CFG_EDA_SUPPORT_TIMER == ENABLED
121 if (evt == VSF_EVT_TIMER) {
122 vsf_protect_t origlevel = vsf_protect_sched();
123 if (eda->flag.state.is_sync_got) {
124 vsf_unprotect_sched(origlevel);
125 return VSF_SYNC_PENDING;
126 }
127 if (dequeue_eda) {
129 vsf_eda_t, pending_node,
130 &sync->pending_list,
131 eda);
132 }
133 vsf_unprotect_sched(origlevel);
134 reason = VSF_SYNC_TIMEOUT;
135 } else {
137#else
138 {
139#endif
140 if (evt == VSF_EVT_SYNC) {
141 reason = VSF_SYNC_GET;
142 eda->flag.state.is_sync_got = false;
143 } else if (evt == VSF_EVT_SYNC_CANCEL) {
144 reason = VSF_SYNC_CANCEL;
145 } else {
146 VSF_KERNEL_ASSERT(false);
147 }
148 }
149 eda->flag.state.is_limitted = false;
150 return reason;
151}
152
153#if __IS_COMPILER_LLVM__ || __IS_COMPILER_ARM_COMPILER_6__
154# pragma clang diagnostic pop
155#endif
156#if __IS_COMPILER_GCC__
157# pragma GCC diagnostic pop
158#endif
159
160VSF_CAL_SECTION(".text.vsf.kernel.vsf_sync")
162{
163 VSF_KERNEL_ASSERT(pthis != NULL);
164
165 pthis->cur_union.cur_value = cur;
166 pthis->max_union.max_value = max;
167 vsf_dlist_init(&pthis->pending_list);
168 if (pthis->cur_union.bits.has_owner) {
169 ((vsf_sync_owner_t *)pthis)->eda_owner = NULL;
170 }
171 return VSF_ERR_NONE;
172}
173
174#if VSF_SYNC_CFG_SUPPORT_ISR == ENABLED
175VSF_CAL_SECTION(".text.vsf.kernel.vsf_sync")
177{
178 VSF_KERNEL_ASSERT(pthis != NULL);
179 return vsf_eda_post_msg((vsf_eda_t *)&__vsf_eda.task, pthis);
180}
181#endif // VSF_SYNC_CFG_SUPPORT_ISR
182
183VSF_CAL_SECTION(".text.vsf.kernel.vsf_sync")
185{
186 vsf_protect_t origlevel;
187 vsf_eda_t *eda_pending;
188
189 VSF_KERNEL_ASSERT(pthis != NULL);
190
191 origlevel = vsf_protect_sched();
192 if (pthis->cur_union.bits.cur >= pthis->max_union.bits.max) {
193 vsf_unprotect_sched(origlevel);
194 return VSF_ERR_OVERRUN;
195 }
196 pthis->cur_union.bits.cur++;
197#if VSF_KERNEL_CFG_SUPPORT_DYNAMIC_PRIOTIRY == ENABLED
198 if (pthis->cur_union.bits.has_owner) {
199 eda = __vsf_eda_get_valid_eda(eda);
200// although not good to remove the assertion below,
201// but some applications use mutex as sem or trigger, and will assert here
202// VSF_KERNEL_ASSERT(((vsf_sync_owner_t *)pthis)->eda_owner == eda);
203 ((vsf_sync_owner_t *)pthis)->eda_owner = NULL;
204 if (eda->cur_priority != eda->priority) {
205 __vsf_eda_set_priority(eda, (vsf_prio_t)eda->priority);
206 } else if (eda->flag.state.is_new_prio) {
207 vsf_evtq_t *evtq;
208 // assert new_priority is a priority boost
209 VSF_KERNEL_ASSERT(eda->new_priority > eda->priority);
210 eda->flag.state.is_new_prio = false;
211
212 evtq = __vsf_os_evtq_get((vsf_prio_t)eda->priority);
213 VSF_KERNEL_ASSERT(evtq != NULL);
214 __vsf_os_evtq_set_priority(evtq, eda->priority);
215 }
216 }
217#endif
218
219 while (1) {
220 if (pthis->cur_union.bits.cur > 0) {
221 eda_pending = __vsf_eda_sync_get_eda_pending(pthis);
222 if (eda_pending != NULL) {
223 eda_pending->flag.state.is_sync_got = true;
224 if (!manual) {
225 pthis->cur_union.bits.cur--;
226 }
227#if VSF_KERNEL_CFG_SUPPORT_DYNAMIC_PRIOTIRY == ENABLED
228 if (pthis->cur_union.bits.has_owner) {
229 ((vsf_sync_owner_t *)pthis)->eda_owner = eda_pending;
230 }
231#endif
232 }
233 vsf_unprotect_sched(origlevel);
234
235 if (eda_pending != NULL) {
236 vsf_err_t err = __vsf_eda_post_evt_ex(eda_pending, VSF_EVT_SYNC, true);
237 VSF_KERNEL_ASSERT(!err);
238 VSF_UNUSED_PARAM(err);
239 origlevel = vsf_protect_sched();
240 continue;
241 } else {
242 break;
243 }
244 } else {
245 vsf_unprotect_sched(origlevel);
246 break;
247 }
248 }
249 return VSF_ERR_NONE;
250}
251
252VSF_CAL_SECTION(".text.vsf.kernel.vsf_sync")
254{
255 return __vsf_eda_sync_increase_ex(pthis, eda, pthis->max_union.bits.manual_rst);
256}
257
258VSF_CAL_SECTION(".text.vsf.kernel.vsf_sync")
260{
261 return vsf_eda_sync_increase_ex(pthis, NULL);
262}
263
264VSF_CAL_SECTION(".text.vsf.kernel.vsf_sync")
266{
267 vsf_protect_t origlevel = vsf_protect_sched();
268 pthis->cur_union.bits.cur = 0;
269 vsf_unprotect_sched(origlevel);
270}
271
272VSF_CAL_SECTION(".text.vsf.kernel.vsf_sync")
274{
275 vsf_protect_t origlevel;
276
277 VSF_KERNEL_ASSERT(pthis != NULL);
278
279 eda = __vsf_eda_get_valid_eda(eda);
280
281 origlevel = vsf_protect_sched();
282 if ((pthis->cur_union.bits.cur > 0) && vsf_dlist_is_empty(&pthis->pending_list)) {
283 if (!manual) {
284 pthis->cur_union.bits.cur--;
285 }
286#if VSF_KERNEL_CFG_SUPPORT_DYNAMIC_PRIOTIRY == ENABLED
287 if (pthis->cur_union.bits.has_owner) {
288 VSF_KERNEL_ASSERT((NULL == ((vsf_sync_owner_t *)pthis)->eda_owner) && (0 == pthis->cur_union.bits.cur));
289 ((vsf_sync_owner_t *)pthis)->eda_owner = eda;
290 }
291#endif
292 vsf_unprotect_sched(origlevel);
293 return VSF_ERR_NONE;
294 }
295
296 if (timeout != 0) {
297#if VSF_KERNEL_CFG_SUPPORT_DYNAMIC_PRIOTIRY == ENABLED
298 if (pthis->cur_union.bits.has_owner) {
300 vsf_prio_t cur_priority = __vsf_eda_get_cur_priority(eda);
302 vsf_eda_t, pending_node,
303 &pthis->pending_list,
304 eda,
305 _->cur_priority < cur_priority);
306 __vsf_eda_sync_set_timeout(eda, timeout);
307 } else
308#endif
309 {
310 __vsf_eda_sync_pend(pthis, eda, timeout);
311 }
312#if VSF_KERNEL_CFG_SUPPORT_DYNAMIC_PRIOTIRY == ENABLED
313 if (pthis->cur_union.bits.has_owner) {
314 vsf_eda_t *eda_owner = ((vsf_sync_owner_t *)pthis)->eda_owner;
315
316 if (eda->cur_priority > eda_owner->cur_priority) {
317 __vsf_eda_set_priority(eda_owner, (vsf_prio_t)eda->cur_priority);
318 }
319 }
320#endif
321 }
322 vsf_unprotect_sched(origlevel);
323 return VSF_ERR_NOT_READY;
324}
325
326VSF_CAL_SECTION(".text.vsf.kernel.vsf_sync")
328{
329 return __vsf_eda_sync_decrease_ex(pthis, timeout, eda, pthis->max_union.bits.manual_rst);
330}
331
332VSF_CAL_SECTION(".text.vsf.kernel.vsf_sync")
334{
335 return vsf_eda_sync_decrease_ex(pthis, timeout, NULL);
336}
337
338VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_sync_cancel")
340{
341 vsf_eda_t *eda;
342 vsf_protect_t origlevel;
343
344 VSF_KERNEL_ASSERT(pthis != NULL);
345
346 do {
347 origlevel = vsf_protect_sched();
348 eda = __vsf_eda_sync_get_eda_pending(pthis);
349 if (eda != NULL) {
350 eda->flag.state.is_sync_got = true;
351 vsf_unprotect_sched(origlevel);
353 } else {
354 vsf_unprotect_sched(origlevel);
355 }
356 } while (eda != NULL);
357}
358
359VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_sync_get_reason")
361{
362 return __vsf_eda_sync_get_reason(pthis, evt, true);
363}
364
365
366#endif
367
368
369#endif
#define VSF_CAL_SECTION(__SEC_STR)
Definition __compiler.h:186
#define VSF_UNUSED_PARAM(__VAL)
Definition __type.h:190
vsf_err_t
Definition __type.h:42
@ VSF_ERR_NONE
none error
Definition __type.h:44
@ VSF_ERR_NOT_READY
service not ready yet
Definition __type.h:43
@ VSF_ERR_OVERRUN
overrun
Definition __type.h:60
Definition vsf_eda.h:769
Definition vsf_eda.h:895
Definition vsf_eda.h:867
Definition vsf_eda.h:837
__le16 timeout
Definition ieee80211.h:94
#define NULL
Definition lvgl.h:26
#define max(x, y)
Definition minmax.h:12
unsigned short uint_fast16_t
Definition stdint.h:25
Definition vsf_evtq.h:51
void sync(void)
Definition vsf_linux_fs.c:2150
uintalu_t vsf_protect_t
Definition vsf_arch_abstraction.h:53
vsf_eda_t * vsf_eda_get_cur(void)
Definition vsf_eda.c:416
vsf_err_t __vsf_os_evtq_set_priority(vsf_evtq_t *pthis, vsf_prio_t priority)
Definition vsf_os.c:339
vsf_err_t vsf_eda_post_msg(vsf_eda_t *pthis, void *msg)
Definition vsf_eda.c:955
vsf_err_t __vsf_eda_post_evt_ex(vsf_eda_t *pthis, vsf_evt_t evt, bool force)
Definition vsf_eda.c:947
void vsf_kernel_err_report(enum vsf_kernel_error_t err)
Definition vsf_eda.c:409
int16_t vsf_evt_t
Definition vsf_eda.h:654
vsf_err_t vsf_eda_sync_init(vsf_sync_t *pthis, uint_fast16_t cur_value, uint_fast16_t max_value)
vsf_sync_reason_t vsf_eda_sync_get_reason(vsf_sync_t *pthis, vsf_evt_t evt)
vsf_err_t vsf_eda_sync_increase(vsf_sync_t *pthis)
@ VSF_KERNEL_ERR_EDA_DOES_NOT_SUPPORT_TIMER
Definition vsf_eda.h:1090
vsf_err_t vsf_eda_sync_decrease(vsf_sync_t *pthis, vsf_timeout_tick_t timeout)
vsf_systimer_tick_t vsf_systimer_get_tick(void)
VSF_KERNEL_TIMEOUT_TICK_T vsf_timeout_tick_t
Definition vsf_eda.h:592
vsf_err_t vsf_teda_set_timer_ex(vsf_teda_t *pthis, vsf_systimer_tick_t tick)
vsf_err_t __vsf_eda_set_priority(vsf_eda_t *pthis, vsf_prio_t prio)
Definition vsf_evtq_list.c:84
vsf_prio_t __vsf_eda_get_cur_priority(vsf_eda_t *pthis)
Definition vsf_evtq_list.c:77
vsf_err_t __vsf_eda_sync_decrease_ex(vsf_sync_t *pthis, vsf_timeout_tick_t timeout, vsf_eda_t *eda, bool manual)
@ VSF_EVT_SYNC_CANCEL
Definition vsf_eda.h:616
@ VSF_EVT_SYNC
Definition vsf_eda.h:615
@ VSF_EVT_TIMER
Definition vsf_eda.h:612
void vsf_eda_sync_force_reset(vsf_sync_t *pthis)
vsf_err_t __vsf_eda_sync_increase_ex(vsf_sync_t *pthis, vsf_eda_t *eda, bool manual)
vsf_err_t vsf_eda_sync_increase_isr(vsf_sync_t *pthis)
vsf_err_t vsf_eda_sync_decrease_ex(vsf_sync_t *pthis, vsf_timeout_tick_t timeout, vsf_eda_t *eda)
vsf_err_t __vsf_teda_cancel_timer(vsf_teda_t *pthis)
vsf_sync_reason_t
Definition vsf_eda.h:1056
@ VSF_SYNC_GET
Definition vsf_eda.h:1060
@ VSF_SYNC_FAIL
Definition vsf_eda.h:1057
@ VSF_SYNC_CANCEL
Definition vsf_eda.h:1061
@ VSF_SYNC_TIMEOUT
Definition vsf_eda.h:1058
@ VSF_SYNC_PENDING
Definition vsf_eda.h:1059
vsf_err_t vsf_eda_sync_increase_ex(vsf_sync_t *pthis, vsf_eda_t *eda)
void vsf_eda_sync_cancel(vsf_sync_t *pthis)
#define VSF_KERNEL_ASSERT
Definition vsf_kernel_cfg.h:32
vsf_prio_t
Definition vsf_kernel_common.h:37
void __vsf_eda_sync_pend(vsf_sync_t *sync, vsf_eda_t *eda, vsf_timeout_tick_t timeout)
#define vsf_dlist_insert( __host_type, __member, __list_ptr, __item_ptr, __cond)
Definition vsf_list.h:769
#define vsf_dlist_queue_dequeue(__host_type, __member, __list_ptr, __item_ref_ptr)
Definition vsf_list.h:859
#define vsf_dlist_remove( __host_type, __member, __list_ptr, __item_ptr)
Definition vsf_list.h:810
#define vsf_dlist_is_empty(__list_ptr)
Definition vsf_list.h:705
#define vsf_dlist_init(__list_ptr)
Definition vsf_list.h:702
#define vsf_dlist_queue_enqueue(__host_type, __member, __list_ptr, __item_ptr)
Definition vsf_list.h:852
struct @799::@818 _
#define vsf_protect_sched()
Definition vsf_os.h:88
#define vsf_unprotect_sched(__prot)
Definition vsf_os.h:89
vsf_evtq_t * __vsf_os_evtq_get(vsf_prio_t priority)
Definition vsf_os.c:322
Generated from commit: vsfteam/vsf@1c19fdc