00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
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 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 #include <ubixos/types.h>
00083 #include <ubixos/sched.h>
00084 #include <ubixos/ubthread.h>
00085 #include <ubixos/kpanic.h>
00086 #include <lib/kprintf.h>
00087 #include <lib/kmalloc.h>
00088 
00089 #include "net/debug.h"
00090 #include "net/sys.h"
00091 #include "net/opt.h"
00092 #include "net/stats.h"
00093 
00094 #include <ubixos/spinlock.h>
00095 
00096 #define UMAX(a, b)      ((a) > (b) ? (a) : (b))
00097 
00098 static struct sys_thread *threads = 0x0;
00099 static spinLock_t netThreadSpinlock = SPIN_LOCK_INITIALIZER;
00100 
00101 struct sys_mbox_msg {
00102   struct sys_mbox_msg *next;
00103   void *msg;
00104 };
00105 
00106 #define SYS_MBOX_SIZE 100
00107 
00108 struct sys_mbox {
00109   uInt16 first, last;
00110   void *msgs[SYS_MBOX_SIZE];
00111   struct sys_sem *mail;
00112   struct sys_sem *mutex;
00113 };
00114 
00115 struct sys_sem {
00116   unsigned int c;
00117   ubthread_cond_t cond;
00118   ubthread_mutex_t mutex;
00119 };
00120 
00121 struct sys_thread {
00122   struct sys_thread *next;
00123   struct sys_timeouts timeouts;
00124   kTask_t *ubthread;
00125 };
00126 
00127 
00128 static struct timeval starttime;
00129 
00130 static struct sys_sem *sys_sem_new_(uInt8 count);
00131 static void sys_sem_free_(struct sys_sem *sem);
00132 
00133 static uInt16 cond_wait(ubthread_cond_t *cond, ubthread_mutex_t *mutex, uInt16 timeout);
00134 
00135 static struct sys_thread *current_thread(void) {
00136   struct sys_thread *st;
00137   kTask_t *pt;
00138   pt = ubthread_self();
00139   spinLock(&netThreadSpinlock);
00140   for(st = threads; st != NULL; st = st->next) {
00141     if(st->ubthread == pt) {
00142       spinUnlock(&netThreadSpinlock);
00143       return st;
00144     }
00145   }
00146   spinUnlock(&netThreadSpinlock);
00147   kprintf("sys: current_thread: could not find current thread!\n");
00148   kprintf("This is due to a race condition in the LinuxThreads\n");
00149   kprintf("ubthreads implementation. Start the program again.\n");
00150   
00151   kpanic("ABORT");
00152   return(0x0);
00153   }
00154 
00155 
00156 struct thread_start_param {
00157   struct sys_thread *thread;
00158   void (* function)(void *);
00159   void *arg;
00160   };
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 void sys_thread_new(void (* function)(void), void *arg) {
00173   struct sys_thread *thread = 0x0;
00174   
00175   kprintf("sys_thread: [0x%X]\n",sizeof(struct sys_thread));
00176   
00177   thread = kmalloc(sizeof(struct sys_thread));
00178   kprintf("THREAD: [0x%X]\n",thread);
00179   spinLock(&netThreadSpinlock);
00180   thread->next = threads;
00181   thread->timeouts.next = NULL;
00182   thread->ubthread = 0x0;
00183   threads = thread;
00184   spinUnlock(&netThreadSpinlock);
00185   
00186 
00187   
00188 
00189 
00190 
00191 
00192 
00193 
00194   
00195  
00196   kprintf("thread->ubthread: [0x%X]\n",thread->ubthread);
00197   if(ubthread_create(&thread->ubthread, 0x0,(void *)(function), arg) != 0x0) {
00198     kpanic("sys_thread_new: ubthread_create");
00199     }
00200   kprintf("thread->ubthread: [0x%X]\n",thread->ubthread); 
00201   
00202   }
00203 
00204 struct sys_mbox *sys_mbox_new() {
00205   struct sys_mbox *mbox;
00206 
00207   mbox = kmalloc(sizeof(struct sys_mbox));
00208   mbox->first = mbox->last = 0;
00209   mbox->mail = sys_sem_new_(0);
00210   mbox->mutex = sys_sem_new_(1);
00211   
00212   return(mbox);
00213   }
00214 
00215 void sys_mbox_free(struct sys_mbox *mbox) {
00216   if (mbox != SYS_MBOX_NULL) {
00217     sys_sem_wait(mbox->mutex);
00218     
00219     sys_sem_free_(mbox->mail);
00220     sys_sem_free_(mbox->mutex);
00221     mbox->mail = mbox->mutex = NULL;
00222     
00223     kfree(mbox);
00224     }
00225   }
00226 
00227 void sys_mbox_post(struct sys_mbox *mbox, void *msg) {
00228   uInt8 first;
00229   
00230   sys_sem_wait(mbox->mutex);
00231   
00232   
00233 
00234   mbox->msgs[mbox->last] = msg;
00235 
00236   if (mbox->last == mbox->first) {
00237     first = 1;
00238     }
00239   else {
00240     first = 0;
00241     }
00242   
00243   mbox->last++;
00244   if(mbox->last == SYS_MBOX_SIZE) {
00245     mbox->last = 0;
00246     }
00247 
00248   if(first) {
00249     sys_sem_signal(mbox->mail);
00250     }
00251   sys_sem_signal(mbox->mutex);
00252   }
00253 
00254 uInt16 sys_arch_mbox_fetch(struct sys_mbox *mbox, void **msg, uInt16 timeout) {
00255   uInt16 time = 1;
00256   
00257   
00258 
00259   sys_arch_sem_wait(mbox->mutex, 0);
00260   
00261   while(mbox->first == mbox->last) {
00262     sys_sem_signal(mbox->mutex);
00263     
00264     
00265 
00266     if(timeout != 0) {
00267       time = sys_arch_sem_wait(mbox->mail, timeout);
00268       
00269       
00270       if(time == 0) {
00271         return 0;
00272       }
00273     } else {
00274       sys_arch_sem_wait(mbox->mail, 0);
00275     }
00276     
00277     sys_arch_sem_wait(mbox->mutex, 0);
00278   }
00279   
00280   if(msg != NULL) {
00281     
00282     *msg = mbox->msgs[mbox->first];
00283   }
00284   
00285   mbox->first++;
00286   if(mbox->first == SYS_MBOX_SIZE) {
00287     mbox->first = 0;
00288   }    
00289   
00290   sys_sem_signal(mbox->mutex);
00291   
00292   return(time);
00293   }
00294 
00295 struct sys_sem *sys_sem_new(uInt8 count) {
00296   return sys_sem_new_(count);
00297   }
00298 
00299 static struct sys_sem *sys_sem_new_(uInt8 count) {
00300   struct sys_sem *sem;
00301   
00302   sem = kmalloc(sizeof(struct sys_sem));
00303   sem->c = count;
00304   
00305   ubthread_cond_init(&(sem->cond), NULL);
00306   ubthread_mutex_init(&(sem->mutex), NULL);
00307   
00308   return sem;
00309   }
00310 
00311 static uInt16 cond_wait(ubthread_cond_t *cond, ubthread_mutex_t *mutex, uInt16 timeout) {
00312   unsigned int tdiff;
00313   unsigned long sec, usec;
00314   struct timeval rtime1, rtime2;
00315   struct timespec ts;
00316   struct timezone tz;
00317   int retval;
00318 
00319   if (timeout > 0) {
00320     
00321     gettimeofday(&rtime1, &tz);
00322     sec = rtime1.tv_sec;
00323     usec = rtime1.tv_usec;
00324     usec += timeout % 1000 * 1000;  
00325     sec += (int)(timeout / 1000) + (int)(usec / 1000000);
00326     usec = usec % 1000000;
00327     ts.tv_nsec = usec * 1000;
00328     ts.tv_sec = sec;
00329     
00330     retval = ubthread_cond_timedwait(cond, mutex, &ts);
00331     if (retval == ETIMEDOUT) {
00332       return 0;
00333       }
00334     else {
00335       
00336       gettimeofday(&rtime2, &tz);
00337       tdiff = (rtime2.tv_sec - rtime1.tv_sec) * 1000 +  
00338         (rtime2.tv_usec - rtime1.tv_usec) / 1000;
00339       if (tdiff == 0) {
00340         return 1;
00341         }
00342       return tdiff;
00343       }
00344     }
00345   else {
00346     ubthread_cond_wait(cond, mutex);
00347     return 0;
00348     }
00349   }
00350 
00351 uInt16 sys_arch_sem_wait(struct sys_sem *sem, uInt16 timeout) {
00352   uInt16 time = 1;
00353   ubthread_mutex_lock(&(sem->mutex));
00354   while(sem->c <= 0) {
00355     if(timeout > 0) {
00356       time = cond_wait(&(sem->cond), &(sem->mutex), timeout);
00357       if(time == 0) {
00358         ubthread_mutex_unlock(&(sem->mutex));
00359         return 0;
00360       }
00361     } else {
00362       cond_wait(&(sem->cond), &(sem->mutex), 0);
00363     }
00364   }
00365   sem->c--;
00366   ubthread_mutex_unlock(&(sem->mutex));
00367   return(time);
00368   }
00369 
00370 void sys_sem_signal(struct sys_sem *sem) {
00371   ubthread_mutex_lock(&(sem->mutex));
00372   sem->c++;
00373   if(sem->c > 1)
00374     sem->c = 1;
00375   ubthread_cond_signal(&(sem->cond));
00376   ubthread_mutex_unlock(&(sem->mutex));
00377   }
00378 
00379 void sys_sem_free(struct sys_sem *sem) {
00380   if(sem != SYS_SEM_NULL) {
00381     sys_sem_free_(sem);
00382     } 
00383   }
00384 
00385 static void sys_sem_free_(struct sys_sem *sem) {
00386   ubthread_cond_destroy(&(sem->cond));
00387   ubthread_mutex_destroy(&(sem->mutex));
00388   kfree(sem);
00389   }
00390 
00391 unsigned long sys_unix_now() {
00392   struct timeval tv;
00393   struct timezone tz;
00394   long sec, usec;
00395   unsigned long msec;
00396   gettimeofday(&tv, &tz);
00397 
00398   sec = tv.tv_sec - starttime.tv_sec;
00399   usec = tv.tv_usec - starttime.tv_usec;
00400   msec = sec * 1000 + usec / 1000;
00401   return msec;
00402   }
00403 
00404 void sys_init() {
00405   struct timezone tz;
00406   gettimeofday(&starttime, &tz);
00407   }
00408 
00409 struct sys_timeouts *sys_arch_timeouts(void) {
00410   struct sys_thread *thread;
00411   thread = current_thread();
00412   return(&thread->timeouts);
00413   }
00414 
00415 
00416 
00417