summaryrefslogtreecommitdiff
path: root/libddekit/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'libddekit/thread.c')
-rw-r--r--libddekit/thread.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/libddekit/thread.c b/libddekit/thread.c
new file mode 100644
index 00000000..db767dc9
--- /dev/null
+++ b/libddekit/thread.c
@@ -0,0 +1,195 @@
+#include <l4/dde/ddekit/thread.h>
+#include <l4/dde/ddekit/condvar.h>
+#include <l4/dde/ddekit/panic.h>
+#include <l4/dde/ddekit/memory.h>
+#include <l4/dde/ddekit/printf.h>
+
+#include <l4/dde/dde.h>
+#include <l4/thread/thread.h>
+#include <l4/log/l4log.h>
+#include <l4/sys/syscalls.h>
+#include <l4/util/rdtsc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#define DDEKIT_THREAD_STACK_SIZE 0x2000 /* 8 KB */
+
+static struct ddekit_slab *ddekit_stack_slab = NULL;
+
+struct ddekit_thread {
+ l4thread_t l4thread;
+ void *data;
+ void *stack;
+ ddekit_condvar_t *sleep_cv;
+ const char *name;
+};
+
+/**
+ * The thread-local-storage key for the BSD struct thread.
+ */
+static int tlskey_thread;
+
+struct startup_args {
+ void (*fun)(void *);
+ void *arg;
+ const char *name;
+};
+
+ddekit_thread_t *ddekit_thread_setup_myself(const char *name) {
+ ddekit_thread_t *td;
+ int namelen = strlen(name);
+ char *pname;
+
+ td = ddekit_simple_malloc(sizeof(*td) + (namelen+1));
+ pname = (char *) td + sizeof(*td);
+
+ td->data=NULL;
+ td->sleep_cv = ddekit_condvar_init();
+ td->l4thread = l4thread_myself();
+ td->name = pname;
+
+ strcpy(pname, name);
+
+ l4thread_data_set_current(tlskey_thread, td);
+
+ return td;
+}
+
+static void ddekit_thread_startup(void *arg) {
+ struct startup_args su;
+ ddekit_thread_t *td;
+
+ /* copy arg to su so that it can bee freed by caller */
+ su = *((struct startup_args*)arg);
+
+ /* init dde thread structure */
+ td = ddekit_thread_setup_myself(su.name);
+ /* inform caller of initialization */
+ l4thread_started(td);
+
+ /* call thread routine */
+ su.fun(su.arg);
+}
+
+ddekit_thread_t *ddekit_thread_create(void (*fun)(void *), void *arg, const char *name) {
+ struct startup_args su;
+ ddekit_thread_t *td;
+ l4thread_t l4td;
+ char l4name[20];
+ void *stack;
+
+ su.fun = fun;
+ su.arg = arg;
+ su.name = name;
+
+ snprintf(l4name, 20, ".%s", name);
+
+ stack = ddekit_slab_alloc(ddekit_stack_slab);
+
+
+ l4td = l4thread_create_long(L4THREAD_INVALID_ID, ddekit_thread_startup, l4name,
+ (l4_addr_t) stack + (DDEKIT_THREAD_STACK_SIZE-1 )* sizeof (void *),
+ DDEKIT_THREAD_STACK_SIZE,
+ L4THREAD_DEFAULT_PRIO, &su, L4THREAD_CREATE_SYNC);
+
+ if (l4td < 0)
+ ddekit_panic("error creating thread");
+
+ td = (ddekit_thread_t*) l4thread_startup_return(l4td);
+
+ td->stack = stack;
+
+ return td;
+}
+
+ddekit_thread_t *ddekit_thread_myself(void) {
+ return (ddekit_thread_t *) l4thread_data_get_current(tlskey_thread);
+}
+
+void ddekit_thread_set_data(ddekit_thread_t *thread, void *data) {
+ thread->data = data;
+}
+
+void ddekit_thread_set_my_data(void *data) {
+ ddekit_thread_set_data(ddekit_thread_myself(), data);
+}
+
+void *ddekit_thread_get_data(ddekit_thread_t *thread) {
+ return thread->data;
+}
+
+void *ddekit_thread_get_my_data() {
+ return ddekit_thread_get_data(ddekit_thread_myself());
+}
+
+void ddekit_thread_msleep(unsigned long msecs) {
+ l4thread_sleep(msecs);
+}
+
+void ddekit_thread_usleep(unsigned long usecs) {
+ l4_busy_wait_us(usecs);
+}
+
+
+void ddekit_thread_nsleep(unsigned long nsecs) {
+ l4_busy_wait_ns(nsecs);
+}
+
+void ddekit_thread_sleep(ddekit_lock_t *lock) {
+ ddekit_thread_t *td;
+
+ td = ddekit_thread_myself();
+
+ ddekit_condvar_wait(td->sleep_cv, lock);
+}
+
+void ddekit_thread_wakeup(ddekit_thread_t *td) {
+ ddekit_condvar_signal(td->sleep_cv);
+}
+
+void ddekit_thread_exit() {
+ ddekit_thread_t *td;
+
+ td = ddekit_thread_myself();
+
+ l4thread_exit();
+
+ ddekit_slab_free(ddekit_stack_slab ,td->stack);
+
+}
+
+void ddekit_thread_terminate(ddekit_thread_t *t)
+{
+ l4thread_shutdown(t->l4thread);
+}
+
+const char *ddekit_thread_get_name(ddekit_thread_t *thread) {
+ return thread->name;
+}
+
+int ddekit_thread_get_id(ddekit_thread_t *t)
+{
+ return t->l4thread;
+}
+
+void ddekit_thread_schedule(void)
+{
+ l4_yield();
+}
+
+void ddekit_yield(void)
+{
+ l4_yield();
+}
+
+void ddekit_init_threads() {
+ /* register TLS key for pointer to dde thread structure */
+ tlskey_thread = l4thread_data_allocate_key();
+
+ /* setup dde part of thread data */
+ ddekit_thread_setup_myself("main");
+
+ /* create slab for stacks */
+ ddekit_stack_slab = ddekit_slab_init(DDEKIT_THREAD_STACK_SIZE, 1);
+}