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