ReactOS 0.4.16-dev-258-g81860b4
sys_arch.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 Simon Goldschmidt
3 * 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,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25 * OF SUCH DAMAGE.
26 *
27 * This file is part of the lwIP TCP/IP stack.
28 *
29 * Author: Simon Goldschmidt
30 *
31 */
32
33
34#include <lwip/opt.h>
35#include <lwip/arch.h>
36#if !NO_SYS
37#include "sys_arch.h"
38#endif
39#include <lwip/stats.h>
40#include <lwip/debug.h>
41#include <lwip/sys.h>
42
43#include <string.h>
44
46
49{
50 return lwip_sys_now;
51}
52
55{
56 return lwip_sys_now;
57}
58
59void
61{
62}
63
64#if !NO_SYS
65
67
68void
70{
71 the_waiting_fn = waiting_fn;
72}
73
76{
77 LWIP_ASSERT("sem != NULL", sem != NULL);
78 *sem = count + 1;
79 return ERR_OK;
80}
81
82void
84{
85 LWIP_ASSERT("sem != NULL", sem != NULL);
86 *sem = 0;
87}
88
89void
91{
92 LWIP_ASSERT("sem != NULL", sem != NULL);
93 *sem = 0;
94}
95
96/* semaphores are 1-based because RAM is initialized as 0, which would be valid */
99{
100 u32_t ret = 0;
101 LWIP_ASSERT("sem != NULL", sem != NULL);
102 LWIP_ASSERT("*sem > 0", *sem > 0);
103 if (*sem == 1) {
104 /* need to wait */
105 if(!timeout)
106 {
107 /* wait infinite */
108 LWIP_ASSERT("cannot wait without waiting callback", the_waiting_fn != NULL);
109 do {
110 int expectSomething = the_waiting_fn(sem, NULL);
111 LWIP_ASSERT("*sem > 0", *sem > 0);
112 LWIP_ASSERT("expecting a semaphore count but it's 0", !expectSomething || (*sem > 1));
113 ret++;
114 if (ret == SYS_ARCH_TIMEOUT) {
115 ret--;
116 }
117 } while(*sem == 1);
118 }
119 else
120 {
121 if (the_waiting_fn) {
122 int expectSomething = the_waiting_fn(sem, NULL);
123 LWIP_ASSERT("expecting a semaphore count but it's 0", !expectSomething || (*sem > 1));
124 }
125 LWIP_ASSERT("*sem > 0", *sem > 0);
126 if (*sem == 1) {
127 return SYS_ARCH_TIMEOUT;
128 }
129 ret = 1;
130 }
131 }
132 LWIP_ASSERT("*sem > 0", *sem > 0);
133 (*sem)--;
134 LWIP_ASSERT("*sem > 0", *sem > 0);
135 /* return the time we waited for the sem */
136 return ret;
137}
138
139void
141{
142 LWIP_ASSERT("sem != NULL", sem != NULL);
143 LWIP_ASSERT("*sem > 0", *sem > 0);
144 (*sem)++;
145 LWIP_ASSERT("*sem > 0", *sem > 0);
146}
147
148err_t
150{
151 LWIP_ASSERT("mutex != NULL", mutex != NULL);
152 *mutex = 1; /* 1 allocated */
153 return ERR_OK;
154}
155
156void
158{
159 /* parameter check */
160 LWIP_ASSERT("mutex != NULL", mutex != NULL);
161 LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
162 *mutex = 0;
163}
164
165void
167{
168 LWIP_ASSERT("mutex != NULL", mutex != NULL);
169 *mutex = 0;
170}
171
172void
174{
175 /* nothing to do, no multithreading supported */
176 LWIP_ASSERT("mutex != NULL", mutex != NULL);
177 /* check that the mutext is valid and unlocked (no nested locking) */
178 LWIP_ASSERT("*mutex >= 1", *mutex == 1);
179 /* we count up just to check the correct pairing of lock/unlock */
180 (*mutex)++;
181 LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
182}
183
184void
186{
187 /* nothing to do, no multithreading supported */
188 LWIP_ASSERT("mutex != NULL", mutex != NULL);
189 LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
190 /* we count down just to check the correct pairing of lock/unlock */
191 (*mutex)--;
192 LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
193}
194
195
197sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
198{
200 LWIP_UNUSED_ARG(function);
202 LWIP_UNUSED_ARG(stacksize);
203 LWIP_UNUSED_ARG(prio);
204 /* threads not supported */
205 return 0;
206}
207
208err_t
210{
211 int mboxsize = size;
212 LWIP_ASSERT("mbox != NULL", mbox != NULL);
213 LWIP_ASSERT("size >= 0", size >= 0);
214 if (size == 0) {
215 mboxsize = 1024;
216 }
217 mbox->head = mbox->tail = 0;
218 mbox->sem = mbox; /* just point to something for sys_mbox_valid() */
219 mbox->q_mem = (void**)malloc(sizeof(void*)*mboxsize);
220 mbox->size = mboxsize;
221 mbox->used = 0;
222
223 memset(mbox->q_mem, 0, sizeof(void*)*mboxsize);
224 return ERR_OK;
225}
226
227void
229{
230 /* parameter check */
231 LWIP_ASSERT("mbox != NULL", mbox != NULL);
232 LWIP_ASSERT("mbox->sem != NULL", mbox->sem != NULL);
233 LWIP_ASSERT("mbox->sem == mbox", mbox->sem == mbox);
234 LWIP_ASSERT("mbox->q_mem != NULL", mbox->q_mem != NULL);
235 mbox->sem = NULL;
236 free(mbox->q_mem);
237 mbox->q_mem = NULL;
238}
239
240void
242{
243 LWIP_ASSERT("mbox != NULL", mbox != NULL);
244 LWIP_ASSERT("mbox->q_mem == NULL", mbox->q_mem == NULL);
245 mbox->sem = NULL;
246 mbox->q_mem = NULL;
247}
248
249void
251{
252 LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
253 LWIP_ASSERT("q->sem == q", q->sem == q);
254 LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
255 LWIP_ASSERT("q->used >= 0", q->used >= 0);
256 LWIP_ASSERT("q->size > 0", q->size > 0);
257
258 LWIP_ASSERT("mbox already full", q->used < q->size);
259
260 q->q_mem[q->head] = msg;
261 q->head++;
262 if (q->head >= (unsigned int)q->size) {
263 q->head = 0;
264 }
265 LWIP_ASSERT("mbox is full!", q->head != q->tail);
266 q->used++;
267}
268
269err_t
271{
272 LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
273 LWIP_ASSERT("q->sem == q", q->sem == q);
274 LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
275 LWIP_ASSERT("q->used >= 0", q->used >= 0);
276 LWIP_ASSERT("q->size > 0", q->size > 0);
277 LWIP_ASSERT("q->used <= q->size", q->used <= q->size);
278
279 if (q->used == q->size) {
280 return ERR_MEM;
281 }
283 return ERR_OK;
284}
285
286err_t
288{
289 return sys_mbox_trypost(q, msg);
290}
291
292u32_t
294{
295 u32_t ret = 0;
296 u32_t ret2;
297 LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
298 LWIP_ASSERT("q->sem == q", q->sem == q);
299 LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
300 LWIP_ASSERT("q->used >= 0", q->used >= 0);
301 LWIP_ASSERT("q->size > 0", q->size > 0);
302
303 if (q->used == 0) {
304 /* need to wait */
305 /* need to wait */
306 if(!timeout)
307 {
308 /* wait infinite */
309 LWIP_ASSERT("cannot wait without waiting callback", the_waiting_fn != NULL);
310 do {
311 int expectSomething = the_waiting_fn(NULL, q);
312 LWIP_ASSERT("q->used >= 0", q->used >= 0);
313 LWIP_ASSERT("expecting item available but it's 0", !expectSomething || (q->used > 0));
314 ret++;
315 if (ret == SYS_ARCH_TIMEOUT) {
316 ret--;
317 }
318 } while(q->used == 0);
319 }
320 else
321 {
322 if (the_waiting_fn) {
323 int expectSomething = the_waiting_fn(NULL, q);
324 LWIP_ASSERT("expecting item available count but it's 0", !expectSomething || (q->used > 0));
325 }
326 LWIP_ASSERT("q->used >= 0", q->used >= 0);
327 if (q->used == 0) {
328 if(msg) {
329 *msg = NULL;
330 }
331 return SYS_ARCH_TIMEOUT;
332 }
333 ret = 1;
334 }
335 }
336 LWIP_ASSERT("q->used > 0", q->used > 0);
338 LWIP_ASSERT("got no message", ret2 == 0);
339 return ret;
340}
341
342u32_t
344{
345 LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
346 LWIP_ASSERT("q->sem == q", q->sem == q);
347 LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
348 LWIP_ASSERT("q->used >= 0", q->used >= 0);
349 LWIP_ASSERT("q->size > 0", q->size > 0);
350
351 if (!q->used) {
352 return SYS_ARCH_TIMEOUT;
353 }
354 if(msg) {
355 *msg = q->q_mem[q->tail];
356 }
357
358 q->tail++;
359 if (q->tail >= (unsigned int)q->size) {
360 q->tail = 0;
361 }
362 q->used--;
363 LWIP_ASSERT("q->used >= 0", q->used >= 0);
364 return 0;
365}
366
367#if LWIP_NETCONN_SEM_PER_THREAD
368/* Simple implementation of this: unit tests only support one thread */
369static sys_sem_t global_netconn_sem;
370
372{
373 return &global_netconn_sem;
374}
375
377{
378 sys_sem_new(&global_netconn_sem, 0);
379}
380
382{
383 sys_sem_free(&global_netconn_sem);
384}
385#endif /* LWIP_NETCONN_SEM_PER_THREAD */
386
387#endif /* !NO_SYS */
#define msg(x)
Definition: auth_time.c:54
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
#define ERR_MEM
Definition: fontsub.h:52
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLsizeiptr size
Definition: glext.h:5919
uint32_t u32_t
Definition: arch.h:129
uint8_t u8_t
Definition: arch.h:125
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:373
s8_t err_t
Definition: err.h:96
@ ERR_OK
Definition: err.h:55
void sys_mbox_set_invalid(sys_mbox_t *mbox)
Definition: sys_arch.c:146
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
Definition: sys_arch.c:177
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
Definition: sys_arch.c:160
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
Definition: sys_arch.c:247
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
Definition: sys_arch.c:128
void sys_mbox_free(sys_mbox_t *mbox)
Definition: sys_arch.c:152
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
Definition: sys_arch.c:238
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
Definition: sys_arch.c:275
void sys_init(void)
Definition: sys_arch.c:305
void sys_mutex_free(sys_mutex_t *mutex)
Definition: sys_arch.c:157
err_t sys_mutex_new(sys_mutex_t *mutex)
Definition: sys_arch.c:149
void sys_mutex_set_invalid(sys_mutex_t *mutex)
Definition: sys_arch.c:166
void sys_mutex_lock(sys_mutex_t *mutex)
Definition: sys_arch.c:173
void sys_mutex_unlock(sys_mutex_t *mutex)
Definition: sys_arch.c:185
void sys_sem_set_invalid(sys_sem_t *sem)
Definition: sys_arch.c:66
void sys_sem_free(sys_sem_t *sem)
Definition: sys_arch.c:72
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
Definition: sys_arch.c:86
void sys_sem_signal(sys_sem_t *sem)
Definition: sys_arch.c:80
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
Definition: sys_arch.c:46
u32_t sys_now(void)
Definition: sys_arch.c:23
#define sys_mbox_trypost_fromisr
Definition: sys_arch.h:31
#define SYS_MBOX_NULL
Definition: sys_arch.h:34
u32_t sys_thread_t
Definition: sys_arch.h:20
void test_sys_arch_wait_callback(test_sys_arch_waiting_fn waiting_fn)
Definition: sys_arch.c:69
u32_t lwip_sys_now
Definition: sys_arch.c:45
u32_t sys_jiffies(void)
Definition: sys_arch.c:48
test_sys_arch_waiting_fn the_waiting_fn
Definition: sys_arch.c:66
sys_sem_t * sys_arch_netconn_sem_get(void)
int sys_mutex_t
Definition: sys_arch.h:38
int(* test_sys_arch_waiting_fn)(sys_sem_t *wait_sem, sys_mbox_t *wait_mbox)
Definition: sys_arch.h:65
void sys_arch_netconn_sem_alloc(void)
void sys_arch_netconn_sem_free(void)
static HANDLE sem
Definition: sync.c:674
#define memset(x, y, z)
Definition: compat.h:39
Definition: module.h:456
Definition: name.c:39
Definition: dhcpd.h:245
#define SYS_ARCH_TIMEOUT
Definition: sys.h:87
void(* lwip_thread_fn)(void *arg)
Definition: sys.h:98
int ret