00001 #include <l4/dde/dde.h>
00002 #include <l4/dde/linux26/dde26.h>
00003
00004 #include <asm/atomic.h>
00005
00006 #include <linux/init_task.h>
00007 #include <linux/kernel.h>
00008 #include <linux/kthread.h>
00009 #include <linux/list.h>
00010 #include <linux/thread_info.h>
00011 #include <linux/sched.h>
00012 #include <linux/pid.h>
00013 #include <linux/vmalloc.h>
00014
00015 #include "local.h"
00016
00017
00018
00019
00020 struct thread_info *current_thread_info(void)
00021 {
00022 dde26_thread_data *cur = (dde26_thread_data *)ddekit_thread_get_my_data();
00023 return &LX_THREAD(cur);
00024 }
00025
00026 struct task_struct *get_current(void)
00027 {
00028 return current_thread_info()->task;
00029 }
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 LIST_HEAD(_pid_task_list);
00041 ddekit_lock_t _pid_task_list_lock;
00042
00043
00044 struct pid2task
00045 {
00046 struct list_head list;
00047 struct pid *pid;
00048 struct task_struct *ts;
00049 };
00050
00051 struct pid init_struct_pid = INIT_STRUCT_PID;
00052
00053 void put_pid(struct pid *pid)
00054 {
00055 if (pid)
00056 atomic_dec(&pid->count);
00057
00058
00059 }
00060
00061
00062 void attach_pid(struct task_struct *task, enum pid_type type
00063 __attribute__((unused)), struct pid *pid)
00064 {
00065
00066 struct pid2task *pt = kmalloc(sizeof(struct pid2task), GFP_KERNEL);
00067 pt->pid = get_pid(pid);
00068 pt->ts = task;
00069
00070
00071 ddekit_lock_lock(&_pid_task_list_lock);
00072 list_add(&pt->list, &_pid_task_list);
00073 ddekit_lock_unlock(&_pid_task_list_lock);
00074 }
00075
00076
00077 void detach_pid(struct task_struct *task, enum pid_type type __attribute__((unused)))
00078 {
00079 struct list_head *p, *n, *h;
00080
00081 h = &_pid_task_list;
00082
00083 ddekit_lock_lock(&_pid_task_list_lock);
00084
00085 list_for_each_safe(p, n, h) {
00086 struct pid2task *pt = list_entry(p, struct pid2task, list);
00087 if (pt->ts == task) {
00088 put_pid(pt->pid);
00089 list_del(p);
00090 kfree(pt);
00091 break;
00092 }
00093 }
00094 ddekit_lock_unlock(&_pid_task_list_lock);
00095 }
00096
00097 struct task_struct *find_task_by_pid_type(int type, int nr)
00098 {
00099 struct list_head *h, *p;
00100 h = &_pid_task_list;
00101
00102 ddekit_lock_lock(&_pid_task_list_lock);
00103 list_for_each(p, h) {
00104 struct pid2task *pt = list_entry(p, struct pid2task, list);
00105 if (pid_nr(pt->pid) == nr) {
00106 ddekit_lock_unlock(&_pid_task_list_lock);
00107 return pt->ts;
00108 }
00109 }
00110 ddekit_lock_unlock(&_pid_task_list_lock);
00111
00112 return NULL;
00113 }
00114
00115
00116 struct task_struct *find_task_by_pid_ns(int nr, struct pid_namespace *ns)
00117 {
00118
00119 return find_task_by_pid_type(0, nr);
00120 }
00121
00122 struct task_struct *find_task_by_pid(int nr)
00123 {
00124 return find_task_by_pid_type(0, nr);
00125 }
00126
00127
00128
00129
00130
00131 struct __kthread_data
00132 {
00133 int (*fn)(void *);
00134 void *arg;
00135 ddekit_lock_t lock;
00136 dde26_thread_data *kthread;
00137 };
00138
00139
00140
00141
00142 static atomic_t kthread_count = ATOMIC_INIT(0);
00143
00144
00145
00146
00147 static void __kthread_helper(void *arg)
00148 {
00149 struct __kthread_data *k = (struct __kthread_data *)arg;
00150
00151
00152
00153
00154
00155
00156 int (*_fn)(void*) = k->fn;
00157 void *_arg = k->arg;
00158
00159 l4dde26_process_add_worker();
00160
00161
00162
00163
00164
00165
00166 k->kthread = (dde26_thread_data *)ddekit_thread_get_my_data();
00167 ddekit_lock_unlock(&k->lock);
00168
00169 do_exit(_fn(_arg));
00170 }
00171
00172
00173
00174
00175 int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
00176 {
00177 ddekit_thread_t *t;
00178 char name[20];
00179 struct __kthread_data *kt = vmalloc(sizeof(struct __kthread_data));
00180 ddekit_lock_t lock;
00181
00182
00183 ddekit_lock_init(&lock);
00184 ddekit_lock_lock(&lock);
00185
00186 int threadnum = atomic_inc_return(&kthread_count);
00187 kt->fn = fn;
00188 kt->arg = arg;
00189 kt->lock = lock;
00190
00191
00192
00193 snprintf(name, 20, ".kthread%x", threadnum);
00194 t = ddekit_thread_create(__kthread_helper,
00195 (void *)kt, name);
00196 Assert(t);
00197
00198 ddekit_lock_lock(&lock);
00199 ddekit_lock_deinit(&lock);
00200
00201 return pid_nr(VPID_P(kt->kthread));
00202 }
00203
00204
00205
00206
00207 void do_exit(long code)
00208 {
00209 ddekit_thread_t *t = DDEKIT_THREAD(lxtask_to_ddethread(current));
00210
00211
00212
00213 detach_pid(current, 0);
00214
00215
00216 ddekit_thread_exit();
00217 }
00218
00219
00220
00221
00222
00223 void dump_stack(void)
00224 {
00225 }
00226
00227
00228 char *get_task_comm(char *buf, struct task_struct *tsk)
00229 {
00230 char *ret;
00231
00232 task_lock(tsk);
00233 ret = strncpy(buf, tsk->comm, sizeof(tsk->comm));
00234 task_unlock(tsk);
00235 return ret;
00236 }
00237
00238
00239 void set_task_comm(struct task_struct *tsk, char *buf)
00240 {
00241 task_lock(tsk);
00242 strlcpy(tsk->comm, buf, sizeof(tsk->comm));
00243 task_unlock(tsk);
00244 }
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 static dde26_thread_data *init_dde26_thread(void)
00258 {
00259
00260
00261
00262 static atomic_t pid_counter = ATOMIC_INIT(0);
00263 dde26_thread_data *t = vmalloc(sizeof(dde26_thread_data));
00264 Assert(t);
00265
00266 memcpy(&t->_vpid, &init_struct_pid, sizeof(struct pid));
00267 t->_vpid.numbers[0].nr = atomic_inc_return(&pid_counter);
00268
00269 memcpy(&LX_THREAD(t), &init_thread, sizeof(struct thread_info));
00270
00271 LX_TASK(t) = vmalloc(sizeof(struct task_struct));
00272 Assert(LX_TASK(t));
00273
00274 memcpy(LX_TASK(t), &init_task, sizeof(struct task_struct));
00275
00276
00277
00278
00279 LX_TASK(t)->stack = &LX_THREAD(t);
00280
00281
00282 SLEEP_LOCK(t) = ddekit_sem_init(0);
00283
00284 return t;
00285 }
00286
00287
00288 int l4dde26_process_add_worker(void)
00289 {
00290 dde26_thread_data *cur = init_dde26_thread();
00291
00292
00293
00294
00295
00296 cur->_ddekit_thread = ddekit_thread_myself();
00297 if (cur->_ddekit_thread == NULL)
00298 cur->_ddekit_thread = ddekit_thread_setup_myself(".dde26_thread");
00299 Assert(cur->_ddekit_thread);
00300
00301 ddekit_thread_set_my_data(cur);
00302
00303 attach_pid(LX_TASK(cur), 0, &cur->_vpid);
00304
00305
00306
00307
00308 current_thread_info()->preempt_count = 0;
00309
00310 return 0;
00311 }
00312
00313
00314
00315
00316
00317
00318
00319 int l4dde26_process_from_ddekit(ddekit_thread_t *t)
00320 {
00321 Assert(t);
00322
00323 dde26_thread_data *cur = init_dde26_thread();
00324 cur->_ddekit_thread = t;
00325 ddekit_thread_set_data(t, cur);
00326 attach_pid(LX_TASK(cur), 0, &cur->_vpid);
00327
00328 return 0;
00329 }
00330
00331
00332
00333 int __init l4dde26_process_init(void)
00334 {
00335 ddekit_lock_init_unlocked(&_pid_task_list_lock);
00336
00337 int kthreadd_pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
00338 kthreadd_task = find_task_by_pid(kthreadd_pid);
00339
00340 l4dde26_process_add_worker();
00341
00342 return 0;
00343 }
00344
00345 DEFINE_PER_CPU(int, cpu_number);
00346
00347