00001
00002
00011
00012
00013
00014
00015
00029
00030
00031
00032 #include <l4/env/errno.h>
00033 #include <l4/thread/thread.h>
00034
00035 #include <l4/dde_linux/dde.h>
00036
00037
00038 #include <linux/sched.h>
00039
00040
00041 #include "__config.h"
00042 #include "internal.h"
00043
00045 static int _key = -L4_ENOKEY;
00046
00048 static struct task_struct _data = INIT_TASK(_data);
00049
00051 static int _initialized = 0;
00052
00061 struct task_struct * get_current()
00062 {
00063 void *p = l4thread_data_get_current(_key);
00064 Assert(p);
00065 return (struct task_struct *) p;
00066 }
00067
00075 int l4dde_process_add_worker()
00076 {
00077 int err;
00078 void *data;
00079
00080
00081 if (_key < 0)
00082 return _key;
00083
00084
00085 data = vmalloc(sizeof(struct task_struct));
00086 if (!data)
00087 return -L4_ENOMEM;
00088 memcpy(data, &_data, sizeof(struct task_struct));
00089
00090 if ((err = l4thread_data_set_current(_key, data)))
00091 return err;
00092
00093 #if DEBUG_PROCESS
00094 LOG("additional task struct @ %p\n", data);
00095 #endif
00096
00097 return 0;
00098 }
00099
00107 int l4dde_process_remove_worker()
00108 {
00109 void *data = NULL;
00110
00111
00112 if (_key < 0)
00113 return _key;
00114
00115
00116 data = l4thread_data_get_current(_key);
00117 vfree(data);
00118
00119 #if DEBUG_PROCESS
00120 LOG("removed task struct @ %p\n", data);
00121 #endif
00122
00123 return 0;
00124 }
00125
00135 int l4dde_process_init()
00136 {
00137 int err;
00138 void *data;
00139
00140 if (_initialized)
00141 return -L4_ESKIPPED;
00142
00143
00144 if ((_key = l4thread_data_allocate_key()) < 0)
00145 return _key;
00146
00147
00148 data = vmalloc(sizeof(struct task_struct));
00149 if (!data)
00150 return -L4_ENOMEM;
00151 memcpy(data, &_data, sizeof(struct task_struct));
00152
00153 if ((err = l4thread_data_set_current(_key, data)))
00154 return err;
00155
00156 #if DEBUG_PROCESS
00157 LOG("task struct @ %p\n", data);
00158 #endif
00159
00160 ++_initialized;
00161 return 0;
00162 }
00163
00165 struct kernel_thread_data
00166 {
00167 int (*fn)(void *);
00168 void *arg;
00169 };
00170
00172 static void __start_kernel_thread(struct kernel_thread_data *data)
00173 {
00174 int ret;
00175
00176 if (l4dde_process_add_worker())
00177 Panic("add_worker() failed");
00178 if (l4thread_started(NULL))
00179 Panic("l4thread_started() failed");
00180 ret = data->fn(data->arg);
00181 vfree(data);
00182 }
00183
00184
00185
00188 long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
00189 {
00190 int err;
00191 struct kernel_thread_data *data;
00192
00193 data = vmalloc(sizeof(struct kernel_thread_data));
00194 data->fn = fn;
00195 data->arg = arg;
00196
00197 err = l4thread_create_long(L4THREAD_INVALID_ID,
00198 (l4thread_fn_t) __start_kernel_thread,
00199 ".kthread%.2X",
00200 L4THREAD_INVALID_SP,
00201 L4THREAD_DEFAULT_SIZE,
00202 L4THREAD_DEFAULT_PRIO,
00203 (void *) data,
00204 L4THREAD_CREATE_SYNC);
00205
00206 #if 0
00207 if ( err < 0 )
00208
00209 return -EAGAIN;
00210
00211
00212
00213 #endif
00214 return err;
00215 }