N-sim
Emulation and simulation of
Wireless Sensor Networks



   Home


   Project Page


   Download


   CVS



   Installation


   Configuration


   Plug-ins




 Hosted by
SourceForge.net Logo

/home/brennan/n-sim/OrbisQuartus/server/l4/patches/lwip-ore/sys_arch.c

Go to the documentation of this file.
00001 
00014 /*
00015  * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
00016  *
00017  * Copyright 2007. Los Alamos National Security, LLC. This material
00018  * was produced under U.S. Government contract DE-AC52-06NA25396 for
00019  * Los Alamos National Laboratory (LANL), which is operated by Los
00020  * Alamos National Security, LLC, for the Department of Energy. The
00021  * U.S. Government has rights to use, reproduce, and distribute this
00022  * software. NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY,
00023  * LLC, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
00024  * LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified to
00025  * produce derivative works, such modified software should be clearly
00026  * marked, so as not to confuse it with the version available from LANL.
00027  *
00028  * Additionally, this program is free software; you can redistribute
00029  * it and/or modify it under the terms of the GNU General Public
00030  * License as published by the Free Software Foundation; version 2 of
00031  * the License. Accordingly, this program is distributed in the hope
00032  * it will be useful, but WITHOUT ANY WARRANTY; without even the
00033  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00034  * PURPOSE. See the GNU General Public License for more details.
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 /* SYS_STATS */
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 /* SYS_STATS */
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     /*  LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
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   /* The mutex lock is quick so we don't bother with the timeout
00248      stuff here. */
00249   sys_arch_sem_wait(mbox->mutex, 0);
00250 
00251   while (mbox->first == mbox->last) {
00252     sys_sem_signal(mbox->mutex);
00253     
00254     /* We block while waiting for a mail to arrive in the mailbox. We
00255        must be prepared to timeout. */
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 /* SYS_STATS */
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     /* Get a timestamp. */
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       /* Calculate for how long we waited for the cond. */
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       /*      l4lock_unlock(&(sem->mutex));
00368               return time; */
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 /* SYS_STATS */
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     /* Note that for the UNIX port, we are using a lightweight mutex, and our
00460      * own counter (which is locked by the mutex). The return code is not actually
00461      * used. */
00462     if (lwprot_thread != l4thread_myself())
00463     {
00464         /* We are locking the mutex where it has not been locked before *
00465         * or is being locked by another thread */
00466         l4lock_lock(&lwprot_mutex);
00467         lwprot_thread = l4thread_myself();
00468         lwprot_count = 1;
00469     }
00470     else
00471         /* It is already locked by THIS thread */
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


© 2007, Los Alamos National Security, LLC.