Functonal webserver with supporting code changes. WIP COMMIT
[akaros.git] / user / lwip / core / sys_arch.c
1 /*
2 t * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
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: Adam Dunkels <adam@sics.se>
30  *
31  */
32
33 #include "lwip/debug.h"
34
35 #include "lwip/sys.h"
36 #include "lwip/opt.h"
37 #include "lwip/stats.h"
38 #include "netif/ethernetif.h"
39
40 #include <pthread.h>
41 #include <arch/arch.h>
42
43 #define sys_debug(...) //printf(__VA_ARGS__)
44
45 pthread_mutex_t sys_lock;
46
47 uint8_t protection_status;
48
49 __thread struct sys_timeouts local_timeouts;
50
51 typedef struct sys_hart_startup {
52
53         void (*hart_startup)(void* arg);
54         void *arg;
55
56 } sys_hart_startup_t;
57
58
59 void  sys_recv_thread(void) {
60
61         while(1) {
62
63                 if (sys_eth_recv_check() == 1) {
64
65                         extern struct netif* registered_netif;
66
67                         ethernetif_input(registered_netif);
68                 }
69         }
70
71 }
72
73 // HACK
74 void sys_init(void) {
75         sys_debug("In sys_init\n");
76
77         pthread_mutex_init(&sys_lock, NULL);
78         
79         protection_status = 0;
80
81         extern void (*hart_startup)();
82         extern void *hart_startup_arg;
83
84         hart_startup = sys_recv_thread;
85         hart_startup_arg = NULL;
86
87         hart_request(1);
88 }
89
90 // HACK
91 u32_t sys_now(void) {
92
93         sys_debug("In sys_now\n");
94
95         uint64_t now = read_tsc();
96
97         now = now / procinfo.tsc_freq;
98
99         now = now * 1000;
100
101         return (uint32_t)now;
102 }
103
104 // OK
105 sys_sem_t sys_sem_new(u8_t count) {
106
107         sys_debug("In sys_sem_new\n");
108
109         sys_sem_t sem = (sys_sem_t)malloc(sizeof(struct sys_sem));
110
111         if (sem == NULL)
112                 return SYS_SEM_NULL;
113
114         pthread_mutex_init(&(sem->lock), NULL);
115
116         sem->count = count;
117
118         return sem;
119 }
120
121 // OK
122 void sys_sem_free(sys_sem_t sem) {
123
124         sys_debug("In sys_sem_free\n");
125
126         pthread_mutex_destroy(&(sem->lock));    
127
128         free(sem);
129
130         return;
131 }
132
133 // OK
134 void sys_sem_signal(sys_sem_t sem) {
135
136         sys_debug("In sys_sem_signal. Signal on %x\n", sem);
137
138         pthread_mutex_lock(&(sem->lock));
139
140         sem->count = sem->count + 1;
141
142         pthread_mutex_unlock(&(sem->lock));
143         
144         return;
145 }
146
147 // OK
148 u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout) {
149
150         sys_debug("In sys_arch_sem_wait. Wait on sem\n");
151
152         uint32_t start = sys_now();
153         uint32_t current = 0;
154
155         pthread_mutex_lock(&(sem->lock));
156
157         while (sem->count == 0) {
158
159                 pthread_mutex_unlock(&(sem->lock));
160
161                 current = sys_now();
162                 
163                 if (((current - start) > timeout) && (timeout != 0)) {
164                         return SYS_ARCH_TIMEOUT;
165                 }
166
167                 hart_relax();
168                 
169                 pthread_mutex_lock(&(sem->lock));
170         }
171
172         sem->count = sem->count - 1;
173
174         pthread_mutex_unlock(&(sem->lock));
175
176         return sys_now() - start;
177 }
178
179
180 //HACK
181 sys_mbox_t sys_mbox_new(int size) {
182
183         sys_debug("In sys_mbox_new\n");
184
185         if (size == 0) {
186                 printf("DANGER. BAD MBOX SIZE\n");
187                 size = 20;
188         }
189
190         sys_mbox_t new_box = (sys_mbox_t)malloc(sizeof(struct sys_mbox) + size * sizeof(char*));
191
192         if (new_box == NULL)
193                 return SYS_MBOX_NULL;
194         memset(new_box, 0x00, sizeof(struct sys_mbox) + size * sizeof(char*));
195
196         pthread_mutex_init(&(new_box->lock), NULL);
197
198         new_box->size = size;
199         new_box->count = 0;
200         new_box->first = 0;
201         
202         return new_box;
203 }
204
205 // HACK
206 void sys_mbox_free(sys_mbox_t mbox) {
207
208         sys_debug("In sys_mbox_new\n");
209
210         // Should we aquire the lock here?
211         if (mbox->count != 0) {
212                 printf("LWIP Stack errror. Bad.\n");
213                 return;
214         }
215
216         pthread_mutex_destroy(&(mbox->lock));
217
218         free(mbox);
219
220         return;
221 }
222
223
224 // HACK
225 void sys_mbox_post(sys_mbox_t mbox, void *msg) {
226
227         sys_debug("In sys_mbox_post. Post on %x\n", mbox);
228
229         pthread_mutex_lock(&(mbox->lock));
230
231         while(mbox->count >= mbox->size) {
232                 
233                 pthread_mutex_unlock(&(mbox->lock));
234                 
235                 hart_relax();
236                 
237                 pthread_mutex_lock(&(mbox->lock));
238         }
239
240         mbox->buf[(mbox->first + mbox->count) % mbox->size] = msg;
241         mbox->count = mbox->count + 1;
242         
243         pthread_mutex_unlock(&(mbox->lock));
244
245         return;
246 }
247
248 // HACK
249 err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg) {
250
251         sys_debug("In sys_mbox_trypost. Post on %x\n", mbox);
252
253         pthread_mutex_lock(&(mbox->lock));
254
255         if (mbox->count >= mbox->size) {
256                 
257                 pthread_mutex_unlock(&(mbox->lock));
258
259                 return ERR_MEM;
260         }
261
262         mbox->buf[(mbox->first + mbox->count) % mbox->size] = msg;
263         mbox->count = mbox->count + 1;
264
265         pthread_mutex_unlock(&(mbox->lock));
266
267         return ERR_OK;
268 }
269
270 // HACK
271 u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout) {
272
273         sys_debug("In sys_arch_mbox_fetch. Fetch on mbox %x\n", mbox);
274
275         uint32_t start = sys_now();
276         uint32_t current = 0;
277
278         pthread_mutex_lock(&(mbox->lock));
279
280         while (mbox->count == 0) {
281
282                 pthread_mutex_unlock(&(mbox->lock));
283
284                 current = sys_now();
285
286                 if (((current - start) > timeout) && (timeout != 0)) {
287                         return SYS_ARCH_TIMEOUT;
288                 }
289
290                 hart_relax();
291
292                 pthread_mutex_lock(&(mbox->lock));
293
294         }
295
296         *msg = mbox->buf[mbox->first];
297
298         mbox->first = (mbox->first + 1) % mbox->size;
299
300         mbox->count = mbox->count - 1;
301
302         pthread_mutex_unlock(&(mbox->lock));
303
304         return sys_now() - start;
305 }
306
307 // HACK
308 u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg) {
309
310         sys_debug("In sys_arch_mbox_tryfetch. Fetch on %x\n", &mbox);
311
312         pthread_mutex_lock(&(mbox->lock));
313
314         if (mbox->count == 0) {
315
316                 pthread_mutex_unlock(&(mbox->lock));
317
318                 return SYS_MBOX_EMPTY;
319         }
320
321         *msg = mbox->buf[mbox->first];
322
323         mbox->first = (mbox->first + 1) % (mbox->size);
324
325         mbox->count = mbox->count - 1;
326
327         pthread_mutex_unlock(&(mbox->lock));
328
329         return 0;
330 }
331
332 // HACK
333 struct sys_timeouts *sys_arch_timeouts(void) {
334
335         sys_debug("In sys_timeouts\n");
336
337         return &local_timeouts;
338 }
339
340 void sys_thread_wrapper(void *arg) {
341
342         sys_hart_startup_t* ptr = arg;
343
344         local_timeouts.next = NULL;
345
346         ptr->hart_startup(ptr->arg);
347
348         free(ptr);
349 }
350
351 // HACK
352 sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio) {
353
354         sys_debug("In sys_thread_new");
355
356         extern void (*hart_startup)();
357         extern void *hart_startup_arg;
358
359         sys_hart_startup_t* wrapper_arg = malloc(sizeof(sys_hart_startup_t));
360
361         if (wrapper_arg == NULL)
362                 return NULL;
363
364         wrapper_arg->hart_startup = thread;
365         wrapper_arg->arg = arg;
366
367         hart_startup = sys_thread_wrapper;
368         hart_startup_arg = wrapper_arg;
369
370         hart_request(1);
371
372         return 0;
373 }
374
375 // HACK
376 sys_prot_t sys_arch_protect(void) {
377
378         sys_debug("In sys_arch_protect\n");
379
380         pthread_mutex_lock(&sys_lock);
381
382         sys_prot_t old = protection_status;
383
384         protection_status = 1;
385
386         pthread_mutex_unlock(&sys_lock);
387
388         return old;
389 }
390
391 // HACK
392 void sys_arch_unprotect(sys_prot_t pval) {
393
394         sys_debug("In sys_arch_unprotect\n");
395
396         pthread_mutex_lock(&sys_lock);
397
398         protection_status = pval;
399
400         pthread_mutex_unlock(&sys_lock);
401
402 }
403