BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 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  
45 u32_t sys_jiffies(void)
46 {
47 return (u32_t)0; /* todo */
48 }
49  
50 u32_t sys_now(void)
51 {
52 return (u32_t)0; /* todo */
53 }
54  
55 void sys_init(void)
56 {
57 }
58  
59 #if !NO_SYS
60  
61 test_sys_arch_waiting_fn the_waiting_fn;
62  
63 void test_sys_arch_wait_callback(test_sys_arch_waiting_fn waiting_fn)
64 {
65 the_waiting_fn = waiting_fn;
66 }
67  
68 err_t sys_sem_new(sys_sem_t *sem, u8_t count)
69 {
70 LWIP_ASSERT("sem != NULL", sem != NULL);
71 *sem = count + 1;
72 return ERR_OK;
73 }
74  
75 void sys_sem_free(sys_sem_t *sem)
76 {
77 LWIP_ASSERT("sem != NULL", sem != NULL);
78 *sem = 0;
79 }
80  
81 void sys_sem_set_invalid(sys_sem_t *sem)
82 {
83 LWIP_ASSERT("sem != NULL", sem != NULL);
84 *sem = 0;
85 }
86  
87 /* semaphores are 1-based because RAM is initialized as 0, which would be valid */
88 u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
89 {
90 u32_t ret = 0;
91 LWIP_ASSERT("sem != NULL", sem != NULL);
92 LWIP_ASSERT("*sem > 0", *sem > 0);
93 if (*sem == 1) {
94 /* need to wait */
95 if(!timeout)
96 {
97 /* wait infinite */
98 LWIP_ASSERT("cannot wait without waiting callback", the_waiting_fn != NULL);
99 do {
100 int expectSomething = the_waiting_fn(sem, NULL);
101 LWIP_ASSERT("*sem > 0", *sem > 0);
102 LWIP_ASSERT("expecting a semaphore count but it's 0", !expectSomething || (*sem > 1));
103 ret++;
104 if (ret == SYS_ARCH_TIMEOUT) {
105 ret--;
106 }
107 } while(*sem == 1);
108 }
109 else
110 {
111 if (the_waiting_fn) {
112 int expectSomething = the_waiting_fn(sem, NULL);
113 LWIP_ASSERT("expecting a semaphore count but it's 0", !expectSomething || (*sem > 1));
114 }
115 LWIP_ASSERT("*sem > 0", *sem > 0);
116 if (*sem == 1) {
117 return SYS_ARCH_TIMEOUT;
118 }
119 ret = 1;
120 }
121 }
122 LWIP_ASSERT("*sem > 0", *sem > 0);
123 (*sem)--;
124 LWIP_ASSERT("*sem > 0", *sem > 0);
125 /* return the time we waited for the sem */
126 return ret;
127 }
128  
129 void sys_sem_signal(sys_sem_t *sem)
130 {
131 LWIP_ASSERT("sem != NULL", sem != NULL);
132 LWIP_ASSERT("*sem > 0", *sem > 0);
133 (*sem)++;
134 LWIP_ASSERT("*sem > 0", *sem > 0);
135 }
136  
137 err_t sys_mutex_new(sys_mutex_t *mutex)
138 {
139 LWIP_ASSERT("mutex != NULL", mutex != NULL);
140 *mutex = 1; /* 1 allocated */
141 return ERR_OK;
142 }
143  
144 void sys_mutex_free(sys_mutex_t *mutex)
145 {
146 /* parameter check */
147 LWIP_ASSERT("mutex != NULL", mutex != NULL);
148 LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
149 *mutex = 0;
150 }
151  
152 void sys_mutex_set_invalid(sys_mutex_t *mutex)
153 {
154 LWIP_ASSERT("mutex != NULL", mutex != NULL);
155 *mutex = 0;
156 }
157  
158 void sys_mutex_lock(sys_mutex_t *mutex)
159 {
160 /* nothing to do, no multithreading supported */
161 LWIP_ASSERT("mutex != NULL", mutex != NULL);
162 /* check that the mutext is valid and unlocked (no nested locking) */
163 LWIP_ASSERT("*mutex >= 1", *mutex == 1);
164 /* we count up just to check the correct pairing of lock/unlock */
165 (*mutex)++;
166 LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
167 }
168  
169 void sys_mutex_unlock(sys_mutex_t *mutex)
170 {
171 /* nothing to do, no multithreading supported */
172 LWIP_ASSERT("mutex != NULL", mutex != NULL);
173 LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
174 /* we count down just to check the correct pairing of lock/unlock */
175 (*mutex)--;
176 LWIP_ASSERT("*mutex >= 1", *mutex >= 1);
177 }
178  
179  
180 sys_thread_t sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
181 {
182 LWIP_UNUSED_ARG(name);
183 LWIP_UNUSED_ARG(function);
184 LWIP_UNUSED_ARG(arg);
185 LWIP_UNUSED_ARG(stacksize);
186 LWIP_UNUSED_ARG(prio);
187 /* threads not supported */
188 return 0;
189 }
190  
191 err_t sys_mbox_new(sys_mbox_t *mbox, int size)
192 {
193 int mboxsize = size;
194 LWIP_ASSERT("mbox != NULL", mbox != NULL);
195 LWIP_ASSERT("size >= 0", size >= 0);
196 if (size == 0) {
197 mboxsize = 1024;
198 }
199 mbox->head = mbox->tail = 0;
200 mbox->sem = mbox; /* just point to something for sys_mbox_valid() */
201 mbox->q_mem = (void**)malloc(sizeof(void*)*mboxsize);
202 mbox->size = mboxsize;
203 mbox->used = 0;
204  
205 memset(mbox->q_mem, 0, sizeof(void*)*mboxsize);
206 return ERR_OK;
207 }
208  
209 void sys_mbox_free(sys_mbox_t *mbox)
210 {
211 /* parameter check */
212 LWIP_ASSERT("mbox != NULL", mbox != NULL);
213 LWIP_ASSERT("mbox->sem != NULL", mbox->sem != NULL);
214 LWIP_ASSERT("mbox->sem == mbox", mbox->sem == mbox);
215 LWIP_ASSERT("mbox->q_mem != NULL", mbox->q_mem != NULL);
216 mbox->sem = NULL;
217 free(mbox->q_mem);
218 mbox->q_mem = NULL;
219 }
220  
221 void sys_mbox_set_invalid(sys_mbox_t *mbox)
222 {
223 LWIP_ASSERT("mbox != NULL", mbox != NULL);
224 LWIP_ASSERT("mbox->q_mem == NULL", mbox->q_mem == NULL);
225 mbox->sem = NULL;
226 mbox->q_mem = NULL;
227 }
228  
229 void sys_mbox_post(sys_mbox_t *q, void *msg)
230 {
231 LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
232 LWIP_ASSERT("q->sem == q", q->sem == q);
233 LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
234 LWIP_ASSERT("q->used >= 0", q->used >= 0);
235 LWIP_ASSERT("q->size > 0", q->size > 0);
236  
237 LWIP_ASSERT("mbox already full", q->used < q->size);
238  
239 q->q_mem[q->head] = msg;
240 q->head++;
241 if (q->head >= (unsigned int)q->size) {
242 q->head = 0;
243 }
244 LWIP_ASSERT("mbox is full!", q->head != q->tail);
245 q->used++;
246 }
247  
248 err_t sys_mbox_trypost(sys_mbox_t *q, void *msg)
249 {
250 LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
251 LWIP_ASSERT("q->sem == q", q->sem == q);
252 LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
253 LWIP_ASSERT("q->used >= 0", q->used >= 0);
254 LWIP_ASSERT("q->size > 0", q->size > 0);
255 LWIP_ASSERT("q->used <= q->size", q->used <= q->size);
256  
257 if (q->used == q->size) {
258 return ERR_MEM;
259 }
260 sys_mbox_post(q, msg);
261 return ERR_OK;
262 }
263  
264 u32_t sys_arch_mbox_fetch(sys_mbox_t *q, void **msg, u32_t timeout)
265 {
266 u32_t ret = 0;
267 u32_t ret2;
268 LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
269 LWIP_ASSERT("q->sem == q", q->sem == q);
270 LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
271 LWIP_ASSERT("q->used >= 0", q->used >= 0);
272 LWIP_ASSERT("q->size > 0", q->size > 0);
273  
274 if (q->used == 0) {
275 /* need to wait */
276 /* need to wait */
277 if(!timeout)
278 {
279 /* wait infinite */
280 LWIP_ASSERT("cannot wait without waiting callback", the_waiting_fn != NULL);
281 do {
282 int expectSomething = the_waiting_fn(NULL, q);
283 LWIP_ASSERT("q->used >= 0", q->used >= 0);
284 LWIP_ASSERT("expecting item available but it's 0", !expectSomething || (q->used > 0));
285 ret++;
286 if (ret == SYS_ARCH_TIMEOUT) {
287 ret--;
288 }
289 } while(q->used == 0);
290 }
291 else
292 {
293 if (the_waiting_fn) {
294 int expectSomething = the_waiting_fn(NULL, q);
295 LWIP_ASSERT("expecting item available count but it's 0", !expectSomething || (q->used > 0));
296 }
297 LWIP_ASSERT("q->used >= 0", q->used >= 0);
298 if (q->used == 0) {
299 if(msg) {
300 *msg = NULL;
301 }
302 return SYS_ARCH_TIMEOUT;
303 }
304 ret = 1;
305 }
306 }
307 LWIP_ASSERT("q->used > 0", q->used > 0);
308 ret2 = sys_arch_mbox_tryfetch(q, msg);
309 LWIP_ASSERT("got no message", ret2 == 0);
310 return ret;
311 }
312  
313 u32_t sys_arch_mbox_tryfetch(sys_mbox_t *q, void **msg)
314 {
315 LWIP_ASSERT("q != SYS_MBOX_NULL", q != SYS_MBOX_NULL);
316 LWIP_ASSERT("q->sem == q", q->sem == q);
317 LWIP_ASSERT("q->q_mem != NULL", q->q_mem != NULL);
318 LWIP_ASSERT("q->used >= 0", q->used >= 0);
319 LWIP_ASSERT("q->size > 0", q->size > 0);
320  
321 if (!q->used) {
322 return SYS_ARCH_TIMEOUT;
323 }
324 if(msg) {
325 *msg = q->q_mem[q->tail];
326 }
327  
328 q->tail++;
329 if (q->tail >= (unsigned int)q->size) {
330 q->tail = 0;
331 }
332 q->used--;
333 LWIP_ASSERT("q->used >= 0", q->used >= 0);
334 return 0;
335 }
336  
337 #if LWIP_NETCONN_SEM_PER_THREAD
338 #error LWIP_NETCONN_SEM_PER_THREAD==1 not supported
339 #endif /* LWIP_NETCONN_SEM_PER_THREAD */
340  
341 #endif /* !NO_SYS */