00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <string.h>
00039 #include <sys/time.h>
00040 #include <sys/types.h>
00041 #include <stdlib.h>
00042 #include <unistd.h>
00043
00044 #include <l4/thread/thread.h>
00045 #include <l4/lock/lock.h>
00046 #include <l4/semaphore/semaphore.h>
00047
00048 #include "lwip/sys.h"
00049 #include "lwip/opt.h"
00050 #include "lwip/stats.h"
00051 #include "lwip/debug.h"
00052
00053 #define UMAX(a, b) ((a) > (b) ? (a) : (b))
00054
00055 static struct sys_thread *threads = NULL;
00056 static l4lock_t threads_mutex = L4LOCK_UNLOCKED;
00057
00058 struct sys_mbox_msg {
00059 struct sys_mbox_msg *next;
00060 void *msg;
00061 };
00062
00063 #define SYS_MBOX_SIZE 128
00064
00065 struct sys_mbox {
00066 int first, last;
00067 void *msgs[SYS_MBOX_SIZE];
00068 struct sys_sem *mail;
00069 struct sys_sem *mutex;
00070 int wait_send;
00071 };
00072
00073 struct sys_sem {
00074 unsigned int c;
00075 l4semaphore_t cond;
00076 l4lock_t mutex;
00077 };
00078
00079 struct sys_thread {
00080 struct sys_thread *next;
00081 struct sys_timeouts timeouts;
00082 l4thread_t thread;
00083 };
00084
00085
00086 static struct timeval starttime;
00087
00088 static l4lock_t lwprot_mutex = L4LOCK_UNLOCKED;
00089 static l4thread_t lwprot_thread = (l4thread_t) 0xDEAD;
00090 static int lwprot_count = 0;
00091
00092 static struct sys_sem *sys_sem_new_(u8_t count);
00093 static void sys_sem_free_(struct sys_sem *sem);
00094
00095 static u32_t cond_wait(l4semaphore_t * cond, l4lock_t * mutex,
00096 u32_t timeout);
00097
00098 sys_prot_t sys_arch_protect(void);
00099 void sys_arch_unprotect(sys_prot_t pval);
00100 unsigned long sys_unix_now(void);
00101
00102
00103 static struct sys_thread *
00104 introduce_thread(l4thread_t id)
00105 {
00106 struct sys_thread *thread;
00107
00108 thread = malloc(sizeof(struct sys_thread));
00109
00110 if (thread != NULL) {
00111 l4lock_lock(&threads_mutex);
00112 thread->next = threads;
00113 thread->timeouts.next = NULL;
00114 thread->thread = id;
00115 threads = thread;
00116 l4lock_unlock(&threads_mutex);
00117 }
00118
00119 return thread;
00120 }
00121
00122 static struct sys_thread *
00123 current_thread(void)
00124 {
00125 struct sys_thread *st;
00126 l4thread_t pt;
00127 pt = l4thread_myself();
00128 l4lock_lock(&threads_mutex);
00129
00130 for(st = threads; st != NULL; st = st->next) {
00131 if (l4thread_equal(st->thread, pt)) {
00132 l4lock_unlock(&threads_mutex);
00133
00134 return st;
00135 }
00136 }
00137
00138 l4lock_unlock(&threads_mutex);
00139
00140 st = introduce_thread(pt);
00141
00142 if (!st) {
00143 printf("current_thread???\n");
00144 abort();
00145 }
00146
00147 return st;
00148 }
00149
00150 sys_thread_t
00151 sys_thread_new(void (*function)(void *arg), void *arg, int prio)
00152 {
00153 struct sys_thread *st = NULL;
00154 l4thread_t tmp = l4thread_create(function, arg, prio);
00155
00156 if (tmp > 0) {
00157 st = introduce_thread(tmp);
00158 }
00159
00160 if (NULL == st) {
00161 LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: l4thread_create %d, st = 0x%x",
00162 code, (int)st));
00163 abort();
00164 }
00165 return st;
00166 }
00167
00168 struct sys_mbox *
00169 sys_mbox_new()
00170 {
00171 struct sys_mbox *mbox;
00172
00173 mbox = malloc(sizeof(struct sys_mbox));
00174 if (mbox != NULL) {
00175 mbox->first = mbox->last = 0;
00176 mbox->mail = sys_sem_new_(0);
00177 mbox->mutex = sys_sem_new_(1);
00178 mbox->wait_send = 0;
00179
00180 #if SYS_STATS
00181 lwip_stats.sys.mbox.used++;
00182 if (lwip_stats.sys.mbox.used > lwip_stats.sys.mbox.max) {
00183 lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
00184 }
00185 #endif
00186 }
00187 return mbox;
00188 }
00189
00190 void
00191 sys_mbox_free(struct sys_mbox *mbox)
00192 {
00193 if (mbox != SYS_MBOX_NULL) {
00194 #if SYS_STATS
00195 lwip_stats.sys.mbox.used--;
00196 #endif
00197 sys_sem_wait(mbox->mutex);
00198
00199 sys_sem_free_(mbox->mail);
00200 sys_sem_free_(mbox->mutex);
00201 mbox->mail = mbox->mutex = NULL;
00202
00203 free(mbox);
00204 }
00205 }
00206
00207
00208 void
00209 sys_mbox_post(struct sys_mbox *mbox, void *msg)
00210 {
00211 u8_t first;
00212
00213 sys_sem_wait(mbox->mutex);
00214
00215 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mbox, (void *)msg));
00216
00217 while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
00218 mbox->wait_send++;
00219 sys_sem_signal(mbox->mutex);
00220 sys_arch_sem_wait(mbox->mail, 0);
00221 sys_arch_sem_wait(mbox->mutex, 0);
00222 mbox->wait_send--;
00223 }
00224
00225 mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
00226
00227 if (mbox->last == mbox->first) {
00228 first = 1;
00229 } else {
00230 first = 0;
00231 }
00232
00233 mbox->last++;
00234
00235 if (first) {
00236 sys_sem_signal(mbox->mail);
00237 }
00238
00239 sys_sem_signal(mbox->mutex);
00240 }
00241
00242 u32_t
00243 sys_arch_mbox_fetch(struct sys_mbox *mbox, void **msg, u32_t timeout)
00244 {
00245 u32_t time = 0;
00246
00247
00248
00249 sys_arch_sem_wait(mbox->mutex, 0);
00250
00251 while (mbox->first == mbox->last) {
00252 sys_sem_signal(mbox->mutex);
00253
00254
00255
00256 if (timeout != 0) {
00257 time = sys_arch_sem_wait(mbox->mail, timeout);
00258
00259 if (time == SYS_ARCH_TIMEOUT) {
00260 return SYS_ARCH_TIMEOUT;
00261 }
00262 } else {
00263 sys_arch_sem_wait(mbox->mail, 0);
00264 }
00265
00266 sys_arch_sem_wait(mbox->mutex, 0);
00267 }
00268
00269 if (msg != NULL) {
00270 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void *)mbox, *msg));
00271 *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
00272 }
00273 else{
00274 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void *)mbox));
00275 }
00276
00277 mbox->first++;
00278
00279 if (mbox->wait_send) {
00280 sys_sem_signal(mbox->mail);
00281 }
00282
00283 sys_sem_signal(mbox->mutex);
00284
00285 return time;
00286 }
00287
00288 struct sys_sem *
00289 sys_sem_new(u8_t count)
00290 {
00291 #if SYS_STATS
00292 lwip_stats.sys.sem.used++;
00293 if (lwip_stats.sys.sem.used > lwip_stats.sys.sem.max) {
00294 lwip_stats.sys.sem.max = lwip_stats.sys.sem.used;
00295 }
00296 #endif
00297 return sys_sem_new_(count);
00298 }
00299
00300
00301 static struct sys_sem *
00302 sys_sem_new_(u8_t count)
00303 {
00304 struct sys_sem *sem;
00305
00306 sem = malloc(sizeof(struct sys_sem));
00307 if (sem != NULL) {
00308 sem->c = count;
00309 sem->cond = L4SEMAPHORE_UNLOCKED;
00310 sem->mutex = L4LOCK_UNLOCKED;
00311 }
00312 return sem;
00313 }
00314
00315
00316 static u32_t
00317 cond_wait(l4semaphore_t *cond, l4lock_t *mutex, u32_t timeout)
00318 {
00319 int tdiff;
00320 struct timeval rtime1, rtime2;
00321 int retval;
00322
00323 if (timeout > 0) {
00324
00325 gettimeofday(&rtime1, NULL);
00326
00327 l4lock_unlock(mutex);
00328 retval = l4semaphore_down_timed(cond, timeout);
00329 l4lock_lock(mutex);
00330
00331 if (retval < 0) {
00332 return SYS_ARCH_TIMEOUT;
00333 } else {
00334
00335 gettimeofday(&rtime2, NULL);
00336 tdiff = (rtime2.tv_sec - rtime1.tv_sec) * 1000 +
00337 (rtime2.tv_usec - rtime1.tv_usec) / 1000;
00338
00339 if (tdiff <= 0) {
00340 return 0;
00341 }
00342
00343 return tdiff;
00344 }
00345 } else {
00346 l4lock_unlock(mutex);
00347 l4semaphore_down(cond);
00348 l4lock_lock(mutex);
00349 return SYS_ARCH_TIMEOUT;
00350 }
00351 }
00352
00353 u32_t
00354 sys_arch_sem_wait(struct sys_sem *sem, u32_t timeout)
00355 {
00356 u32_t time = 0;
00357
00358 l4lock_lock(&(sem->mutex));
00359 while (sem->c <= 0) {
00360 if (timeout > 0) {
00361 time = cond_wait(&(sem->cond), &(sem->mutex), timeout);
00362
00363 if (time == SYS_ARCH_TIMEOUT) {
00364 l4lock_unlock(&(sem->mutex));
00365 return SYS_ARCH_TIMEOUT;
00366 }
00367
00368
00369 } else {
00370 cond_wait(&(sem->cond), &(sem->mutex), 0);
00371 }
00372 }
00373 sem->c--;
00374 l4lock_unlock(&(sem->mutex));
00375 return time;
00376 }
00377
00378 void
00379 sys_sem_signal(struct sys_sem *sem)
00380 {
00381 l4lock_lock(&(sem->mutex));
00382 sem->c++;
00383
00384 if (sem->c > 1) {
00385 sem->c = 1;
00386 }
00387
00388 l4semaphore_up(&(sem->cond));
00389 l4lock_unlock(&(sem->mutex));
00390 }
00391
00392 void
00393 sys_sem_free(struct sys_sem *sem)
00394 {
00395 if (sem != SYS_SEM_NULL) {
00396 #if SYS_STATS
00397 lwip_stats.sys.sem.used--;
00398 #endif
00399 sys_sem_free_(sem);
00400 }
00401 }
00402
00403
00404 static void
00405 sys_sem_free_(struct sys_sem *sem)
00406 {
00407 free(sem);
00408 }
00409
00410 unsigned long
00411 sys_unix_now(void)
00412 {
00413 struct timeval tv;
00414 struct timezone tz;
00415 long sec, usec;
00416 unsigned long msec;
00417 gettimeofday(&tv, &tz);
00418
00419 sec = tv.tv_sec - starttime.tv_sec;
00420 usec = tv.tv_usec - starttime.tv_usec;
00421 msec = sec * 1000 + usec / 1000;
00422
00423 return msec;
00424 }
00425
00426 void
00427 sys_init()
00428 {
00429 struct timezone tz;
00430 gettimeofday(&starttime, &tz);
00431 }
00432
00433 struct sys_timeouts *
00434 sys_arch_timeouts(void)
00435 {
00436 struct sys_thread *thread;
00437
00438 thread = current_thread();
00439 return &thread->timeouts;
00440 }
00441
00456 sys_prot_t
00457 sys_arch_protect(void)
00458 {
00459
00460
00461
00462 if (lwprot_thread != l4thread_myself())
00463 {
00464
00465
00466 l4lock_lock(&lwprot_mutex);
00467 lwprot_thread = l4thread_myself();
00468 lwprot_count = 1;
00469 }
00470 else
00471
00472 lwprot_count++;
00473 return 0;
00474 }
00475
00483 void
00484 sys_arch_unprotect(sys_prot_t pval)
00485 {
00486 if (lwprot_thread == l4thread_myself())
00487 {
00488 if (--lwprot_count == 0)
00489 {
00490 lwprot_thread = (l4thread_t) 0xDEAD;
00491 l4lock_unlock(&lwprot_mutex);
00492 }
00493 }
00494 }
00495
00496
00497
00498 #ifndef MAX_JIFFY_OFFSET
00499 #define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
00500 #endif
00501
00502 #ifndef HZ
00503 #define HZ 100
00504 #endif
00505
00506 unsigned long
00507 sys_jiffies(void)
00508 {
00509 struct timeval tv;
00510 unsigned long sec = tv.tv_sec;
00511 long usec = tv.tv_usec;
00512
00513 gettimeofday(&tv,NULL);
00514
00515 if (sec >= (MAX_JIFFY_OFFSET / HZ))
00516 return MAX_JIFFY_OFFSET;
00517 usec += 1000000L / HZ - 1;
00518 usec /= 1000000L / HZ;
00519 return HZ * sec + usec;
00520 }
00521
00522 #if PPP_DEBUG
00523
00524 #include <stdarg.h>
00525
00526 void ppp_trace(int level, const char *format, ...)
00527 {
00528 va_list args;
00529
00530 (void)level;
00531 va_start(args, format);
00532 vprintf(format, args);
00533 va_end(args);
00534 }
00535 #endif