00001 #include <l4/dde/ddekit/thread.h>
00002 #include <l4/dde/ddekit/condvar.h>
00003 #include <l4/dde/ddekit/panic.h>
00004 #include <l4/dde/ddekit/memory.h>
00005 #include <l4/dde/ddekit/printf.h>
00006
00007 #include <l4/dde/dde.h>
00008 #include <l4/thread/thread.h>
00009 #include <l4/log/l4log.h>
00010 #include <l4/sys/syscalls.h>
00011 #include <l4/util/rdtsc.h>
00012
00013 #include <stdio.h>
00014 #include <string.h>
00015
00016 #define DDEKIT_THREAD_STACK_SIZE 0x2000
00017
00018 static struct ddekit_slab *ddekit_stack_slab = NULL;
00019
00020 struct ddekit_thread {
00021 l4thread_t l4thread;
00022 void *data;
00023 void *stack;
00024 ddekit_condvar_t *sleep_cv;
00025 const char *name;
00026 };
00027
00028
00029
00030
00031 static int tlskey_thread;
00032
00033 struct startup_args {
00034 void (*fun)(void *);
00035 void *arg;
00036 const char *name;
00037 };
00038
00039 ddekit_thread_t *ddekit_thread_setup_myself(const char *name) {
00040 ddekit_thread_t *td;
00041 int namelen = strlen(name);
00042 char *pname;
00043
00044 td = ddekit_simple_malloc(sizeof(*td) + (namelen+1));
00045 pname = (char *) td + sizeof(*td);
00046
00047 td->data=NULL;
00048 td->sleep_cv = ddekit_condvar_init();
00049 td->l4thread = l4thread_myself();
00050 td->name = pname;
00051
00052 strcpy(pname, name);
00053
00054 l4thread_data_set_current(tlskey_thread, td);
00055
00056 return td;
00057 }
00058
00059 static void ddekit_thread_startup(void *arg) {
00060 struct startup_args su;
00061 ddekit_thread_t *td;
00062
00063
00064 su = *((struct startup_args*)arg);
00065
00066
00067 td = ddekit_thread_setup_myself(su.name);
00068
00069 l4thread_started(td);
00070
00071
00072 su.fun(su.arg);
00073 }
00074
00075 ddekit_thread_t *ddekit_thread_create(void (*fun)(void *), void *arg, const char *name) {
00076 struct startup_args su;
00077 ddekit_thread_t *td;
00078 l4thread_t l4td;
00079 char l4name[20];
00080 void *stack;
00081
00082 su.fun = fun;
00083 su.arg = arg;
00084 su.name = name;
00085
00086 snprintf(l4name, 20, ".%s", name);
00087
00088 stack = ddekit_slab_alloc(ddekit_stack_slab);
00089
00090
00091 l4td = l4thread_create_long(L4THREAD_INVALID_ID, ddekit_thread_startup, l4name,
00092 (l4_addr_t) stack + (DDEKIT_THREAD_STACK_SIZE-1 )* sizeof (void *),
00093 DDEKIT_THREAD_STACK_SIZE,
00094 L4THREAD_DEFAULT_PRIO, &su, L4THREAD_CREATE_SYNC);
00095
00096 if (l4td < 0)
00097 ddekit_panic("error creating thread");
00098
00099 td = (ddekit_thread_t*) l4thread_startup_return(l4td);
00100
00101 td->stack = stack;
00102
00103 return td;
00104 }
00105
00106 ddekit_thread_t *ddekit_thread_myself(void) {
00107 return (ddekit_thread_t *) l4thread_data_get_current(tlskey_thread);
00108 }
00109
00110 void ddekit_thread_set_data(ddekit_thread_t *thread, void *data) {
00111 thread->data = data;
00112 }
00113
00114 void ddekit_thread_set_my_data(void *data) {
00115 ddekit_thread_set_data(ddekit_thread_myself(), data);
00116 }
00117
00118 void *ddekit_thread_get_data(ddekit_thread_t *thread) {
00119 return thread->data;
00120 }
00121
00122 void *ddekit_thread_get_my_data() {
00123 return ddekit_thread_get_data(ddekit_thread_myself());
00124 }
00125
00126 void ddekit_thread_msleep(unsigned long msecs) {
00127 l4thread_sleep(msecs);
00128 }
00129
00130 void ddekit_thread_usleep(unsigned long usecs) {
00131 l4_busy_wait_us(usecs);
00132 }
00133
00134
00135 void ddekit_thread_nsleep(unsigned long nsecs) {
00136 l4_busy_wait_ns(nsecs);
00137 }
00138
00139 void ddekit_thread_sleep(ddekit_lock_t *lock) {
00140 ddekit_thread_t *td;
00141
00142 td = ddekit_thread_myself();
00143
00144 ddekit_condvar_wait(td->sleep_cv, lock);
00145 }
00146
00147 void ddekit_thread_wakeup(ddekit_thread_t *td) {
00148 ddekit_condvar_signal(td->sleep_cv);
00149 }
00150
00151 void ddekit_thread_exit() {
00152 ddekit_thread_t *td;
00153
00154 td = ddekit_thread_myself();
00155
00156 l4thread_exit();
00157
00158 ddekit_slab_free(ddekit_stack_slab ,td->stack);
00159
00160 }
00161
00162 void ddekit_thread_terminate(ddekit_thread_t *t)
00163 {
00164 l4thread_shutdown(t->l4thread);
00165 }
00166
00167 const char *ddekit_thread_get_name(ddekit_thread_t *thread) {
00168 return thread->name;
00169 }
00170
00171 int ddekit_thread_get_id(ddekit_thread_t *t)
00172 {
00173 return t->l4thread;
00174 }
00175
00176 void ddekit_thread_schedule(void)
00177 {
00178 l4_yield();
00179 }
00180
00181 void ddekit_yield(void)
00182 {
00183 l4_yield();
00184 }
00185
00186 void ddekit_init_threads() {
00187
00188 tlskey_thread = l4thread_data_allocate_key();
00189
00190
00191 ddekit_thread_setup_myself("main");
00192
00193
00194 ddekit_stack_slab = ddekit_slab_init(DDEKIT_THREAD_STACK_SIZE, 1);
00195 }