From 8a6d48c0542876eb3acfc0970c0ab7872db08d5f Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Sun, 6 Dec 2009 05:26:23 +0100 Subject: check in the original version of dde linux26. --- libdde_linux26/lib/src/arch/l4/process.c | 347 +++++++++++++++++++++++++++++++ 1 file changed, 347 insertions(+) create mode 100644 libdde_linux26/lib/src/arch/l4/process.c (limited to 'libdde_linux26/lib/src/arch/l4/process.c') diff --git a/libdde_linux26/lib/src/arch/l4/process.c b/libdde_linux26/lib/src/arch/l4/process.c new file mode 100644 index 00000000..5fe43b32 --- /dev/null +++ b/libdde_linux26/lib/src/arch/l4/process.c @@ -0,0 +1,347 @@ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "local.h" + +/***************************************************************************** + ** Current() implementation ** + *****************************************************************************/ +struct thread_info *current_thread_info(void) +{ + dde26_thread_data *cur = (dde26_thread_data *)ddekit_thread_get_my_data(); + return &LX_THREAD(cur); +} + +struct task_struct *get_current(void) +{ + return current_thread_info()->task; +} + +/***************************************************************************** + ** PID-related stuff ** + ** ** + ** Linux manages lists of PIDs that are handed out to processes so that at ** + ** a later point it is able to determine which task_struct belongs to a ** + ** certain PID. We implement this with a single list holding the mappings ** + ** for all our threads. ** + *****************************************************************************/ + +LIST_HEAD(_pid_task_list); +ddekit_lock_t _pid_task_list_lock; + +/** PID to task_struct mapping */ +struct pid2task +{ + struct list_head list; /**< list data */ + struct pid *pid; /**< PID */ + struct task_struct *ts; /**< task struct */ +}; + +struct pid init_struct_pid = INIT_STRUCT_PID; + +void put_pid(struct pid *pid) +{ + if (pid) + atomic_dec(&pid->count); + // no freeing here, our struct pid's are always allocated as + // part of the dde26_thread_data +} + +/** Attach PID to a certain task struct. */ +void attach_pid(struct task_struct *task, enum pid_type type + __attribute__((unused)), struct pid *pid) +{ + /* Initialize a new pid2task mapping */ + struct pid2task *pt = kmalloc(sizeof(struct pid2task), GFP_KERNEL); + pt->pid = get_pid(pid); + pt->ts = task; + + /* add to list */ + ddekit_lock_lock(&_pid_task_list_lock); + list_add(&pt->list, &_pid_task_list); + ddekit_lock_unlock(&_pid_task_list_lock); +} + +/** Detach PID from a task struct. */ +void detach_pid(struct task_struct *task, enum pid_type type __attribute__((unused))) +{ + struct list_head *p, *n, *h; + + h = &_pid_task_list; + + ddekit_lock_lock(&_pid_task_list_lock); + /* search for mapping with given task struct and free it if necessary */ + list_for_each_safe(p, n, h) { + struct pid2task *pt = list_entry(p, struct pid2task, list); + if (pt->ts == task) { + put_pid(pt->pid); + list_del(p); + kfree(pt); + break; + } + } + ddekit_lock_unlock(&_pid_task_list_lock); +} + +struct task_struct *find_task_by_pid_type(int type, int nr) +{ + struct list_head *h, *p; + h = &_pid_task_list; + + ddekit_lock_lock(&_pid_task_list_lock); + list_for_each(p, h) { + struct pid2task *pt = list_entry(p, struct pid2task, list); + if (pid_nr(pt->pid) == nr) { + ddekit_lock_unlock(&_pid_task_list_lock); + return pt->ts; + } + } + ddekit_lock_unlock(&_pid_task_list_lock); + + return NULL; +} + + +struct task_struct *find_task_by_pid_ns(int nr, struct pid_namespace *ns) +{ + /* we don't implement PID name spaces */ + return find_task_by_pid_type(0, nr); +} + +struct task_struct *find_task_by_pid(int nr) +{ + return find_task_by_pid_type(0, nr); +} + +/***************************************************************************** + ** kernel_thread() implementation ** + *****************************************************************************/ +/* Struct containing thread data for a newly created kthread. */ +struct __kthread_data +{ + int (*fn)(void *); + void *arg; + ddekit_lock_t lock; + dde26_thread_data *kthread; +}; + +/** Counter for running kthreads. It is used to create unique names + * for kthreads. + */ +static atomic_t kthread_count = ATOMIC_INIT(0); + +/** Entry point for new kernel threads. Make this thread a DDE26 + * worker and then execute the real thread fn. + */ +static void __kthread_helper(void *arg) +{ + struct __kthread_data *k = (struct __kthread_data *)arg; + + /* + * Make a copy of the fn and arg pointers, as the kthread struct is + * deleted by our parent after notifying it and this may happen before we + * get to execute the function. + */ + int (*_fn)(void*) = k->fn; + void *_arg = k->arg; + + l4dde26_process_add_worker(); + + /* + * Handshake with creator - we store our thread data in the + * kthread struct and then unlock the lock to notify our + * creator about completing setup + */ + k->kthread = (dde26_thread_data *)ddekit_thread_get_my_data(); + ddekit_lock_unlock(&k->lock); + + do_exit(_fn(_arg)); +} + +/** Our implementation of Linux' kernel_thread() function. Setup a new + * thread running our __kthread_helper() function. + */ +int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) +{ + ddekit_thread_t *t; + char name[20]; + struct __kthread_data *kt = vmalloc(sizeof(struct __kthread_data)); + ddekit_lock_t lock; + + /* Initialize (and grab) handshake lock */ + ddekit_lock_init(&lock); + ddekit_lock_lock(&lock); + + int threadnum = atomic_inc_return(&kthread_count); + kt->fn = fn; + kt->arg = arg; + kt->lock = lock; // Copy lock ptr, note that kt is freed by the + // new thread, so we MUST NOT use kt->lock after + // this point! + + snprintf(name, 20, ".kthread%x", threadnum); + t = ddekit_thread_create(__kthread_helper, + (void *)kt, name); + Assert(t); + + ddekit_lock_lock(&lock); + ddekit_lock_deinit(&lock); + + return pid_nr(VPID_P(kt->kthread)); +} + +/** Our implementation of exit(). For DDE purposes this only relates + * to kernel threads. + */ +void do_exit(long code) +{ + ddekit_thread_t *t = DDEKIT_THREAD(lxtask_to_ddethread(current)); +// printk("Thread %s exits with code %x\n", ddekit_thread_get_name(t), code); + + /* do some cleanup */ + detach_pid(current, 0); + + /* goodbye, cruel world... */ + ddekit_thread_exit(); +} + +/***************************************************************************** + ** Misc functions ** + *****************************************************************************/ + +void dump_stack(void) +{ +} + + +char *get_task_comm(char *buf, struct task_struct *tsk) +{ + char *ret; + /* buf must be at least sizeof(tsk->comm) in size */ + task_lock(tsk); + ret = strncpy(buf, tsk->comm, sizeof(tsk->comm)); + task_unlock(tsk); + return ret; +} + + +void set_task_comm(struct task_struct *tsk, char *buf) +{ + task_lock(tsk); + strlcpy(tsk->comm, buf, sizeof(tsk->comm)); + task_unlock(tsk); +} + + +/***************************************************************************** + ** DDEKit gluecode, init functions ** + *****************************************************************************/ +/* Initialize a dde26 thread. + * + * - Allocate thread data, as well as a Linux task struct, + * - Fill in default values for thread_info, and task, + * - Adapt task struct's thread_info backreference + * - Initialize the DDE sleep lock + */ +static dde26_thread_data *init_dde26_thread(void) +{ + /* + * Virtual PID counter + */ + static atomic_t pid_counter = ATOMIC_INIT(0); + dde26_thread_data *t = vmalloc(sizeof(dde26_thread_data)); + Assert(t); + + memcpy(&t->_vpid, &init_struct_pid, sizeof(struct pid)); + t->_vpid.numbers[0].nr = atomic_inc_return(&pid_counter); + + memcpy(&LX_THREAD(t), &init_thread, sizeof(struct thread_info)); + + LX_TASK(t) = vmalloc(sizeof(struct task_struct)); + Assert(LX_TASK(t)); + + memcpy(LX_TASK(t), &init_task, sizeof(struct task_struct)); + + /* nice: Linux backreferences a task`s thread_info from the + * task struct (which in turn can be found using the + * thread_info...) */ + LX_TASK(t)->stack = &LX_THREAD(t); + + /* initialize this thread's sleep lock */ + SLEEP_LOCK(t) = ddekit_sem_init(0); + + return t; +} + +/* Process setup for worker threads */ +int l4dde26_process_add_worker(void) +{ + dde26_thread_data *cur = init_dde26_thread(); + + /* If this function is called for a kernel_thread, the thread already has + * been set up and we just need to store a reference to the ddekit struct. + * However, this function may also be called directly to turn an L4 thread + * into a DDE thread. Then, we need to initialize here. */ + cur->_ddekit_thread = ddekit_thread_myself(); + if (cur->_ddekit_thread == NULL) + cur->_ddekit_thread = ddekit_thread_setup_myself(".dde26_thread"); + Assert(cur->_ddekit_thread); + + ddekit_thread_set_my_data(cur); + + attach_pid(LX_TASK(cur), 0, &cur->_vpid); + + /* Linux' default is to have this set to 1 initially and let the + * scheduler set this to 0 later on. + */ + current_thread_info()->preempt_count = 0; + + return 0; +} + + +/** + * Add an already existing DDEKit thread to the set of threads known to the + * Linux environment. This is used for the timer thread, which is actually a + * DDEKit thread, but Linux code shall see it as a Linux thread as well. + */ +int l4dde26_process_from_ddekit(ddekit_thread_t *t) +{ + Assert(t); + + dde26_thread_data *cur = init_dde26_thread(); + cur->_ddekit_thread = t; + ddekit_thread_set_data(t, cur); + attach_pid(LX_TASK(cur), 0, &cur->_vpid); + + return 0; +} + +/** Function to initialize the first DDE process. + */ +int __init l4dde26_process_init(void) +{ + ddekit_lock_init_unlocked(&_pid_task_list_lock); + + int kthreadd_pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); + kthreadd_task = find_task_by_pid(kthreadd_pid); + + l4dde26_process_add_worker(); + + return 0; +} + +DEFINE_PER_CPU(int, cpu_number); + +//dde_process_initcall(l4dde26_process_init); -- cgit v1.2.3 From 16b4a9b6e25500f2da14839b4494f82df4b0fc7f Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Tue, 5 Jan 2010 16:30:03 +0100 Subject: correct the path of header files. --- libdde_linux26/lib/src/arch/l4/irq.c | 4 ---- libdde_linux26/lib/src/arch/l4/kmalloc.c | 6 ++---- libdde_linux26/lib/src/arch/l4/kmem_cache.c | 4 +--- libdde_linux26/lib/src/arch/l4/mm-helper.c | 5 ----- libdde_linux26/lib/src/arch/l4/net.c | 2 +- libdde_linux26/lib/src/arch/l4/page_alloc.c | 5 ----- libdde_linux26/lib/src/arch/l4/process.c | 4 ++-- libdde_linux26/lib/src/arch/l4/vmalloc.c | 4 +--- libdde_linux26/lib/src/net/core/dev.c | 2 +- 9 files changed, 8 insertions(+), 28 deletions(-) (limited to 'libdde_linux26/lib/src/arch/l4/process.c') diff --git a/libdde_linux26/lib/src/arch/l4/irq.c b/libdde_linux26/lib/src/arch/l4/irq.c index 0e565e54..9594b05c 100644 --- a/libdde_linux26/lib/src/arch/l4/irq.c +++ b/libdde_linux26/lib/src/arch/l4/irq.c @@ -12,10 +12,6 @@ #include #include /* memset() */ -/* DDEKit */ -#include -#include - /* local */ #include "dde26.h" #include "local.h" diff --git a/libdde_linux26/lib/src/arch/l4/kmalloc.c b/libdde_linux26/lib/src/arch/l4/kmalloc.c index 065c13c7..87d64878 100644 --- a/libdde_linux26/lib/src/arch/l4/kmalloc.c +++ b/libdde_linux26/lib/src/arch/l4/kmalloc.c @@ -20,11 +20,9 @@ #include #include -/* DDEKit */ -#include -#include +#include "local.h" -#include +#include /* dummy */ int forbid_dac; diff --git a/libdde_linux26/lib/src/arch/l4/kmem_cache.c b/libdde_linux26/lib/src/arch/l4/kmem_cache.c index 1465ac6c..5e44c140 100644 --- a/libdde_linux26/lib/src/arch/l4/kmem_cache.c +++ b/libdde_linux26/lib/src/arch/l4/kmem_cache.c @@ -14,9 +14,7 @@ /* Linux */ #include -/* DDEKit */ -#include -#include +#include "local.h" /******************* diff --git a/libdde_linux26/lib/src/arch/l4/mm-helper.c b/libdde_linux26/lib/src/arch/l4/mm-helper.c index 68c0213b..cc4cc1d1 100644 --- a/libdde_linux26/lib/src/arch/l4/mm-helper.c +++ b/libdde_linux26/lib/src/arch/l4/mm-helper.c @@ -3,11 +3,6 @@ #include #include -/* DDEKit */ -#include -#include -#include - #include "local.h" int ioprio_best(unsigned short aprio, unsigned short bprio) diff --git a/libdde_linux26/lib/src/arch/l4/net.c b/libdde_linux26/lib/src/arch/l4/net.c index d6637d96..6e799119 100644 --- a/libdde_linux26/lib/src/arch/l4/net.c +++ b/libdde_linux26/lib/src/arch/l4/net.c @@ -8,7 +8,7 @@ * GNU General Public License 2. Please see the COPYING file for details. * ******************************************************************************/ -#include +#include #include #include diff --git a/libdde_linux26/lib/src/arch/l4/page_alloc.c b/libdde_linux26/lib/src/arch/l4/page_alloc.c index 0a2e3fdf..e887bd51 100644 --- a/libdde_linux26/lib/src/arch/l4/page_alloc.c +++ b/libdde_linux26/lib/src/arch/l4/page_alloc.c @@ -25,11 +25,6 @@ #include #include -/* DDEKit */ -#include -#include -#include - #include "local.h" unsigned long max_low_pfn; diff --git a/libdde_linux26/lib/src/arch/l4/process.c b/libdde_linux26/lib/src/arch/l4/process.c index 5fe43b32..b5189cd4 100644 --- a/libdde_linux26/lib/src/arch/l4/process.c +++ b/libdde_linux26/lib/src/arch/l4/process.c @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include diff --git a/libdde_linux26/lib/src/arch/l4/vmalloc.c b/libdde_linux26/lib/src/arch/l4/vmalloc.c index 134b80c3..4fa063f0 100644 --- a/libdde_linux26/lib/src/arch/l4/vmalloc.c +++ b/libdde_linux26/lib/src/arch/l4/vmalloc.c @@ -15,9 +15,7 @@ /* Linux */ #include -/* DDEKit */ -#include -#include +#include "local.h" void *vmalloc(unsigned long size) { diff --git a/libdde_linux26/lib/src/net/core/dev.c b/libdde_linux26/lib/src/net/core/dev.c index 22fdf4d7..1e9247c2 100644 --- a/libdde_linux26/lib/src/net/core/dev.c +++ b/libdde_linux26/lib/src/net/core/dev.c @@ -74,7 +74,7 @@ #ifdef DDE_LINUX #include "local.h" -#include +#include #endif #include -- cgit v1.2.3 From d31e486426aed7952b3468a63f2e81735d09943c Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Tue, 6 Apr 2010 04:33:16 +0200 Subject: implement dump_stack in libddekit with backtrace. --- libdde_linux26/lib/src/arch/l4/process.c | 4 ---- libddekit/include/ddekit/printf.h | 2 ++ libddekit/printf.c | 12 ++++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'libdde_linux26/lib/src/arch/l4/process.c') diff --git a/libdde_linux26/lib/src/arch/l4/process.c b/libdde_linux26/lib/src/arch/l4/process.c index b5189cd4..ac700f82 100644 --- a/libdde_linux26/lib/src/arch/l4/process.c +++ b/libdde_linux26/lib/src/arch/l4/process.c @@ -220,10 +220,6 @@ void do_exit(long code) ** Misc functions ** *****************************************************************************/ -void dump_stack(void) -{ -} - char *get_task_comm(char *buf, struct task_struct *tsk) { diff --git a/libddekit/include/ddekit/printf.h b/libddekit/include/ddekit/printf.h index 35b0dfa1..6dafa18d 100644 --- a/libddekit/include/ddekit/printf.h +++ b/libddekit/include/ddekit/printf.h @@ -18,6 +18,8 @@ int ddekit_printf(const char *fmt, ...); */ int ddekit_vprintf(const char *fmt, va_list va); +void dump_stack(void); + /** Log function and message. * \ingroup DDEKit_util */ diff --git a/libddekit/printf.c b/libddekit/printf.c index dacc65e6..c4a8b718 100644 --- a/libddekit/printf.c +++ b/libddekit/printf.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "ddekit/printf.h" @@ -93,3 +94,14 @@ int log_init () return 0; } + +void dump_stack() +{ +#define NUM_TRACES 16 + void *trace[NUM_TRACES]; + int trace_size = 0; + + fprintf (stderr, "dump the stack\n"); + trace_size = backtrace(trace, NUM_TRACES); + backtrace_symbols_fd(trace, trace_size, 2); +} -- cgit v1.2.3