VSF Documented
vsf_eda_queue.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
27#if VSF_EDA_QUEUE_CFG_REGION != ENABLED
28# if VSF_EDA_QUEUE_CFG_SUPPORT_ISR == ENABLED
29# define __vsf_eda_queue_protect vsf_protect(interrupt)
30# define __vsf_eda_queue_unprotect vsf_unprotect(interrupt)
31# else
32# define __vsf_eda_queue_protect vsf_protect(scheduler)
33# define __vsf_eda_queue_unprotect vsf_unprotect(scheduler)
34# endif
35#else
36# define vsf_protect_eda_queue_region() pthis->region->enter()
37# define vsf_unprotect_eda_queue_region(__orig) pthis->region->leave(__orig)
38# define __vsf_eda_queue_protect vsf_protect(eda_queue_region)
39# define __vsf_eda_queue_unprotect vsf_unprotect(eda_queue_region)
40#endif
41
42/*============================ MACROFIED FUNCTIONS ===========================*/
43/*============================ TYPES =========================================*/
44/*============================ GLOBAL VARIABLES ==============================*/
45/*============================ LOCAL VARIABLES ===============================*/
46/*============================ PROTOTYPES ====================================*/
47/*============================ IMPLEMENTATION ================================*/
48
49#if VSF_KERNEL_CFG_SUPPORT_SYNC == ENABLED && VSF_KERNEL_CFG_SUPPORT_EDA_QUEUE == ENABLED
50/*-----------------------------------------------------------------------------*
51 * vsf_eda_queue_t *
52 *-----------------------------------------------------------------------------*/
53
54VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue")
55static bool __vsf_eda_queue_dequeue(vsf_eda_queue_t *pthis, void **node)
56{
57 bool is_dequeued = false;
58 vsf_protect_t origlevel = __vsf_eda_queue_protect();
59#if VSF_EDA_QUEUE_CFG_SUPPORT_ISR == ENABLED
60 if (pthis->readable_cnt > 0) {
61 pthis->readable_cnt--;
62#else
63 if (pthis->cur_union.cur_value > 0) {
64#endif
65 pthis->cur_union.cur_value--;
66 pthis->op.dequeue(pthis, node);
67 is_dequeued = true;
68 }
69 __vsf_eda_queue_unprotect(origlevel);
70 return is_dequeued;
71}
72
73#if VSF_EDA_QUEUE_CFG_SUPPORT_ISR == ENABLED
74# define __vsf_eda_queue_enqueue(__queue, __node, __readable) \
75 ____vsf_eda_queue_enqueue((__queue), (__node), (__readable))
76
77VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue")
78static bool ____vsf_eda_queue_enqueue(vsf_eda_queue_t *pthis, void *node, bool readable)
79#else
80# define __vsf_eda_queue_enqueue(__queue, __node, __readable) \
81 ____vsf_eda_queue_enqueue((__queue), (__node))
82
83VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue")
84static bool ____vsf_eda_queue_enqueue(vsf_eda_queue_t *pthis, void *node)
85#endif
86{
87 bool is_enqueued = false;
88 vsf_protect_t origlevel = __vsf_eda_queue_protect();
89 if (pthis->cur_union.cur_value < pthis->max_union.max_value) {
90 pthis->cur_union.cur_value++;
91#if VSF_EDA_QUEUE_CFG_SUPPORT_ISR == ENABLED
92 if (readable) {
93 pthis->readable_cnt++;
94 }
95#endif
96 pthis->op.enqueue(pthis, node);
97 is_enqueued = true;
98 }
99 __vsf_eda_queue_unprotect(origlevel);
100 return is_enqueued;
101}
102
103VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue")
104void __vsf_eda_queue_notify(vsf_eda_queue_t *pthis, bool tx, vsf_protect_t orig)
105{
106 vsf_eda_t *eda = tx ?
107#if VSF_KERNEL_CFG_QUEUE_MULTI_TX_EN == ENABLED
108 __vsf_eda_sync_get_eda_pending(&pthis->use_as__vsf_sync_t)
109#else
110 pthis->eda_tx
111#endif
112 : pthis->eda_rx;
113
114 if (eda != NULL) {
115 if (tx) {
116#if VSF_KERNEL_CFG_QUEUE_MULTI_TX_EN == ENABLED
117 pthis->tx_processing = true;
118#else
119 pthis->eda_tx = NULL;
120#endif
121 } else {
122 pthis->eda_rx = NULL;
123#if VSF_KERNEL_CFG_QUEUE_HAS_RX_NOTIFIED == ENABLED
124 pthis->rx_notified = true;
125#endif
126 }
127
128 eda->flag.state.is_sync_got = true;
130
132 } else {
133#if VSF_KERNEL_CFG_QUEUE_MULTI_TX_EN == ENABLED
134 if (tx) {
135 pthis->tx_processing = false;
136 }
137#endif
139 }
140}
141
142VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue_init")
144{
145 VSF_KERNEL_ASSERT((pthis != NULL) && (max > 0));
146#if VSF_KERNEL_CFG_QUEUE_MULTI_TX_EN == ENABLED
147 pthis->tx_processing = false;
148#endif
149 pthis->eda_rx = NULL;
150#if VSF_EDA_QUEUE_CFG_REGION == ENABLED
151 if (NULL == pthis->region) {
153 }
154#endif
155#if VSF_KERNEL_CFG_QUEUE_HAS_RX_NOTIFIED == ENABLED
156 pthis->rx_notified = false;
157#endif
158#if VSF_EDA_QUEUE_CFG_SUPPORT_ISR == ENABLED
159 pthis->readable_cnt = 0;
160#endif
161 return vsf_eda_sync_init(&pthis->use_as__vsf_sync_t, 0, max);
162}
163
164VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue_send_ex")
166{
167 VSF_KERNEL_ASSERT((pthis != NULL) && (node != NULL));
168
169 bool is_enqueued = __vsf_eda_queue_enqueue(pthis, node, true);
170 vsf_protect_t origlevel = vsf_protect_sched();
171 if (is_enqueued) {
172 __vsf_eda_queue_notify(pthis, false, origlevel);
173 return VSF_ERR_NONE;
174 } else {
175 if (timeout != 0) {
176 vsf_sync_t *sync = &pthis->use_as__vsf_sync_t;
178 }
179 vsf_unprotect_sched(origlevel);
180 return VSF_ERR_NOT_READY;
181 }
182}
183
184VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue_send")
186{
187 return vsf_eda_queue_send_ex(pthis, node, timeout, NULL);
188}
189
190VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue_send_get_reason")
192{
193 vsf_sync_t *sync = &pthis->use_as__vsf_sync_t;
195 if (VSF_SYNC_GET == reason) {
196 bool is_enqueued = __vsf_eda_queue_enqueue(pthis, node, true);
197 vsf_protect_t origlevel = vsf_protect_sched();
198 if (is_enqueued) {
199 __vsf_eda_queue_notify(pthis, false, origlevel);
200
201#if VSF_KERNEL_CFG_QUEUE_MULTI_TX_EN == ENABLED
202 origlevel = vsf_protect_sched();
203 if (sync->cur_union.cur_value < sync->max) {
204 __vsf_eda_queue_notify(pthis, true, origlevel);
205 return reason;
206 } else {
207 pthis->tx_processing = false;
208 }
209#else
210 return reason;
211#endif
212 } else {
213 vsf_unprotect_sched(origlevel);
214
215 // TODO: re-send again?
216 VSF_KERNEL_ASSERT(false);
217 }
218 }
219 return reason;
220}
221
222VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue_recv_ex")
224{
225 VSF_KERNEL_ASSERT((pthis != NULL) && (node != NULL));
226
227 bool is_dequeued = __vsf_eda_queue_dequeue(pthis, node);
228 vsf_protect_t origlevel = vsf_protect_sched();
229 if (is_dequeued) {
230#if VSF_KERNEL_CFG_QUEUE_MULTI_TX_EN == ENABLED
231 if (!pthis->tx_processing) {
232 __vsf_eda_queue_notify(pthis, true, origlevel);
233 return VSF_ERR_NONE;
234 }
235 vsf_unprotect_sched(origlevel);
236 return VSF_ERR_NONE;
237#else
238 __vsf_eda_queue_notify(pthis, true, origlevel);
239 return VSF_ERR_NONE;
240#endif
241 } else {
242 if (timeout != 0) {
243 VSF_KERNEL_ASSERT(NULL == pthis->eda_rx);
244 pthis->eda_rx = __vsf_eda_set_timeout(eda, timeout);
245 }
246 vsf_unprotect_sched(origlevel);
247 return VSF_ERR_NOT_READY;
248 }
249}
250
251VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue_recv")
253{
254 return vsf_eda_queue_recv_ex(pthis, node, timeout, NULL);
255}
256
257VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue_recv_get_reason")
259{
260 vsf_sync_t *sync = &pthis->use_as__vsf_sync_t;
261 vsf_sync_reason_t reason = __vsf_eda_sync_get_reason(sync, evt, false);
262 if (VSF_SYNC_GET == reason) {
263 bool is_dequeued = __vsf_eda_queue_dequeue(pthis, node);
264 vsf_protect_t origlevel = vsf_protect_sched();
265 if (is_dequeued) {
266#if VSF_KERNEL_CFG_QUEUE_HAS_RX_NOTIFIED == ENABLED
267 pthis->rx_notified = false;
268#endif
269 __vsf_eda_queue_notify(pthis, true, origlevel);
270 return reason;
271 }
272 vsf_unprotect_sched(origlevel);
273 // this happens when queue is read by other task with 0 timeout after VSF_SYNC_GET is sent to here
274 // TODO: re-recv again?
275 reason = VSF_SYNC_PENDING;
276 } else if (VSF_SYNC_TIMEOUT == reason) {
277 pthis->eda_rx = NULL;
278 }
279 return reason;
280}
281
282VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue_get_cnt")
284{
285 uint_fast16_t cnt;
286 vsf_protect_t origlevel = __vsf_eda_queue_protect();
287 cnt = pthis->cur_union.cur_value;
288 __vsf_eda_queue_unprotect(origlevel);
289 return cnt;
290}
291
292VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue_cancel")
294{
295 vsf_eda_sync_cancel(&pthis->use_as__vsf_sync_t);
296 if (pthis->eda_rx != NULL) {
297 vsf_eda_t *eda = pthis->eda_rx;
298 pthis->eda_rx = NULL;
300 }
301}
302
303#if VSF_EDA_QUEUE_CFG_SUPPORT_ISR == ENABLED
304
305VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue")
306void __vsf_eda_queue_notify_for_isr(vsf_eda_queue_t *pthis, bool tx)
307{
308 if (!tx) {
309 vsf_protect_t origlevel = __vsf_eda_queue_protect();
310 pthis->readable_cnt++;
311 __vsf_eda_queue_unprotect(origlevel);
312 }
313 __vsf_eda_queue_notify(pthis, tx, vsf_protect_sched());
314}
315
316VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue_send_isr")
318{
319 VSF_KERNEL_ASSERT((pthis != NULL) && (node != NULL));
320
321 // send non-readable data to queue, will be readable before notification in kernel_task
322 if (!__vsf_eda_queue_enqueue(pthis, node, false)) {
323 return VSF_ERR_NOT_READY;
324 }
325 return vsf_eda_post_evt_msg((vsf_eda_t *)&__vsf_eda.task, VSF_KERNEL_EVT_QUEUE_SEND_NOTIFY, pthis);
326}
327
328VSF_CAL_SECTION(".text.vsf.kernel.vsf_eda_queue_recv_isr")
330{
331 VSF_KERNEL_ASSERT((pthis != NULL) && (node != NULL));
332
333 if (!__vsf_eda_queue_dequeue(pthis, node)) {
334 return VSF_ERR_NOT_READY;
335 }
336 return vsf_eda_post_evt_msg((vsf_eda_t *)&__vsf_eda.task, VSF_KERNEL_EVT_QUEUE_RECV_NOTIFY, pthis);
337}
338#endif
339
340#endif // VSF_KERNEL_CFG_SUPPORT_SYNC && VSF_KERNEL_CFG_SUPPORT_EDA_QUEUE
341#endif // VSF_USE_KERNEL == ENABLED && __EDA_GADGET__
#define VSF_CAL_SECTION(__SEC)
Definition __compiler.h:181
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
Definition vsf_eda.h:996
Definition vsf_eda.h:766
Definition vsf_eda.h:864
__le16 timeout
Definition ieee80211.h:94
#define NULL
Definition stddef.h:52
#define max(x, y)
Definition minmax.h:12
unsigned short uint_fast16_t
Definition stdint.h:25
Definition vsf_arch_abstraction.h:54
void sync(void)
Definition vsf_linux_fs.c:2146
uintalu_t vsf_protect_t
Definition vsf_arch_abstraction.h:53
vsf_err_t vsf_eda_post_evt_msg(vsf_eda_t *pthis, vsf_evt_t evt, void *msg)
Definition vsf_eda.c:957
vsf_err_t __vsf_eda_post_evt_ex(vsf_eda_t *pthis, vsf_evt_t evt, bool force)
Definition vsf_eda.c:941
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_queue_init(vsf_eda_queue_t *pthis, uint_fast16_t max)
vsf_err_t vsf_eda_queue_recv_isr(vsf_eda_queue_t *pthis, void **node)
void vsf_eda_queue_cancel(vsf_eda_queue_t *pthis)
@ VSF_EVT_SYNC_CANCEL
Definition vsf_eda.h:616
@ VSF_EVT_SYNC
Definition vsf_eda.h:615
vsf_err_t vsf_eda_queue_recv_ex(vsf_eda_queue_t *pthis, void **node, vsf_timeout_tick_t timeout, vsf_eda_t *eda)
VSF_KERNEL_TIMEOUT_TICK_T vsf_timeout_tick_t
Definition vsf_eda.h:592
uint_fast16_t vsf_eda_queue_get_cnt(vsf_eda_queue_t *pthis)
@ VSF_KERNEL_EVT_QUEUE_SEND_NOTIFY
Definition vsf_eda.h:628
@ VSF_KERNEL_EVT_QUEUE_RECV_NOTIFY
Definition vsf_eda.h:629
vsf_err_t vsf_eda_queue_recv(vsf_eda_queue_t *pthis, void **node, vsf_timeout_tick_t timeout)
vsf_sync_reason_t vsf_eda_queue_send_get_reason(vsf_eda_queue_t *pthis, vsf_evt_t evt, void *node)
vsf_err_t vsf_eda_queue_send_isr(vsf_eda_queue_t *pthis, void *node)
vsf_err_t vsf_eda_queue_send_ex(vsf_eda_queue_t *pthis, void *node, vsf_timeout_tick_t timeout, vsf_eda_t *eda)
vsf_sync_reason_t vsf_eda_queue_recv_get_reason(vsf_eda_queue_t *pthis, vsf_evt_t evt, void **node)
vsf_sync_reason_t
Definition vsf_eda.h:1053
@ VSF_SYNC_GET
Definition vsf_eda.h:1057
@ VSF_SYNC_TIMEOUT
Definition vsf_eda.h:1055
@ VSF_SYNC_PENDING
Definition vsf_eda.h:1056
vsf_err_t vsf_eda_queue_send(vsf_eda_queue_t *pthis, void *node, vsf_timeout_tick_t timeout)
void vsf_eda_sync_cancel(vsf_sync_t *pthis)
vsf_err_t vsf_evtq_post_evt_ex(vsf_eda_t *eda, vsf_evt_t evt, bool force)
Definition vsf_evtq_list.c:219
#define VSF_KERNEL_ASSERT
Definition vsf_kernel_cfg.h:32
void __vsf_eda_sync_pend(vsf_sync_t *sync, vsf_eda_t *eda, vsf_timeout_tick_t timeout)
#define vsf_protect_region_sched
Definition vsf_os.h:185
#define vsf_protect_sched()
Definition vsf_os.h:88
#define vsf_unprotect_sched(__prot)
Definition vsf_os.h:89