diff options
author | Zheng Da <zhengda1936@gmail.com> | 2009-11-21 00:47:01 +0100 |
---|---|---|
committer | Zheng Da <zhengda1936@gmail.com> | 2009-11-21 00:47:01 +0100 |
commit | b537f6cede63b0e55e82a2ee1467d094200d953e (patch) | |
tree | f2296a90b61e1c4f86c8c53db0621972d4649ea8 | |
parent | 31452a09c0cf1e9488b75bcff156923ea4fc1a08 (diff) |
Emulate the timer in the Hurd.
-rw-r--r-- | libddekit/include/ddekit/timer.h | 4 | ||||
-rw-r--r-- | libddekit/timer.c | 107 |
2 files changed, 59 insertions, 52 deletions
diff --git a/libddekit/include/ddekit/timer.h b/libddekit/include/ddekit/timer.h index c352475c..a57c8fce 100644 --- a/libddekit/include/ddekit/timer.h +++ b/libddekit/include/ddekit/timer.h @@ -1,7 +1,9 @@ #ifndef _ddekit_timer_h #define _ddekit_timer_h -#include <l4/dde/ddekit/thread.h> +#include "ddekit/thread.h" + +#define jiffies fetch_jiffies() enum { diff --git a/libddekit/timer.c b/libddekit/timer.c index b1af99bf..d0a6ccc0 100644 --- a/libddekit/timer.c +++ b/libddekit/timer.c @@ -1,20 +1,14 @@ -#include <l4/dde/ddekit/timer.h> -#include <l4/dde/ddekit/thread.h> -#include <l4/dde/ddekit/printf.h> -#include <l4/dde/ddekit/panic.h> -#include <l4/dde/ddekit/assert.h> -#include <l4/dde/ddekit/memory.h> -#include <l4/dde/ddekit/semaphore.h> - -#include <l4/thread/thread.h> -#include <l4/lock/lock.h> -#include <l4/env/errno.h> -#include <l4/generic_io/libio.h> -#include <l4/sys/ipc.h> -#include <l4/util/rdtsc.h> +#include <error.h> +#include <maptime.h> +#include <cthreads.h> + +#include "ddekit/timer.h" #define __DEBUG 0 +volatile struct mapped_time_value *mapped_time; +long long root_jiffies; + /* Just to remind BjoernD of what this is: * HZ = clock ticks per second * jiffies = clock ticks counter. @@ -22,7 +16,6 @@ * So, if someone schedules a timeout to expire in 2 seconds, * this expires date will be in jiffies + 2 * HZ. */ -extern volatile unsigned long jiffies; extern unsigned long HZ; typedef struct _timer @@ -36,8 +29,8 @@ typedef struct _timer static ddekit_timer_t *timer_list = NULL; ///< list of pending timers -static l4lock_t timer_lock = L4LOCK_UNLOCKED; ///< lock to access timer_list -static l4_threadid_t timer_thread = L4_NIL_ID; ///< the timer thread +static struct mutex timer_lock = MUTEX_INITIALIZER; ///< lock to access timer_list +static cthread_t timer_thread; ///< the timer thread static ddekit_thread_t *timer_thread_ddekit = NULL; ///< ddekit ID of timer thread static ddekit_sem_t *notify_semaphore = NULL; ///< timer thread's wait semaphore @@ -58,20 +51,27 @@ static void dump_list(char *msg) #endif } +int fetch_jiffies () +{ + struct timeval tv; + long long j; + + maptime_read (mapped_time, &tv); + + j = (long long) tv.tv_sec * HZ + ((long long) tv.tv_usec * HZ) / 1000000; + return j - root_jiffies; +} /** Notify the timer thread there is a new timer at the beginning of the * timer list. */ static inline void __notify_timer_thread(void) { - int err; - l4_msgdope_t result; - /* Do not notify if there is no timer thread. * XXX: Perhaps we should better assert that there is a timer * thread before allowing users to add a timer. */ - if (l4_is_nil_id(timer_thread)) + if (timer_thread == NULL) return; ddekit_sem_up(notify_semaphore); @@ -91,7 +91,7 @@ int ddekit_add_timer(void (*fn)(void *), void *args, unsigned long timeout) t->expires = timeout; t->next = NULL; - l4lock_lock(&timer_lock); + mutex_lock (&timer_lock); t->id = timer_id_ctr++; @@ -122,7 +122,7 @@ int ddekit_add_timer(void (*fn)(void *), void *args, unsigned long timeout) __notify_timer_thread(); } - l4lock_unlock(&timer_lock); + mutex_unlock (&timer_lock); dump_list("after add"); @@ -135,7 +135,7 @@ int ddekit_del_timer(int timer) ddekit_timer_t *it, *it_next; int ret = -1; - l4lock_lock(&timer_lock); + mutex_lock (&timer_lock); /* no timer? */ if (!timer_list) { @@ -176,7 +176,7 @@ int ddekit_del_timer(int timer) } out: - l4lock_unlock(&timer_lock); + mutex_unlock (&timer_lock); dump_list("after del"); @@ -195,7 +195,7 @@ int ddekit_timer_pending(int timer) ddekit_timer_t *t = NULL; int r = 0; - l4lock_lock(&timer_lock); + mutex_lock (&timer_lock); t = timer_list; while (t) { @@ -206,7 +206,7 @@ int ddekit_timer_pending(int timer) t = t->next; } - l4lock_unlock(&timer_lock); + mutex_unlock (&timer_lock); return r; } @@ -222,8 +222,7 @@ static ddekit_timer_t *get_next_timer(void) ddekit_timer_t *t = NULL; /* This function must be called with the timer_lock held. */ - Assert(l4_thread_equal(l4thread_l4_id(l4lock_owner(&timer_lock)), - timer_thread)); + Assert(timer_lock.holder == timer_thread); if (timer_list && (timer_list->expires <= jiffies)) { @@ -248,27 +247,24 @@ enum */ static inline int __timer_sleep(unsigned to) { - l4_umword_t dummy; - l4_msgdope_t res; - int err = 0; - l4lock_unlock(&timer_lock); + mutex_unlock (&timer_lock); - if (to == DDEKIT_TIMEOUT_NEVER) { - ddekit_sem_down(notify_semaphore); - } - else { + if (to == DDEKIT_TIMEOUT_NEVER) { + ddekit_sem_down(notify_semaphore); + } + else { #if 0 - ddekit_printf("Going to sleep for %lu µs (%lu ms)\n", to * 1000, to); + ddekit_printf("Going to sleep for %lu µs (%lu ms)\n", to * 1000, to); #endif - err = ddekit_sem_down_timed(notify_semaphore, to); + err = ddekit_sem_down_timed(notify_semaphore, to); #if 0 - ddekit_printf("err: %x\n", err); + ddekit_printf("err: %x\n", err); #endif - } + } - l4lock_lock(&timer_lock); + mutex_lock (&timer_lock); return (err ? 1 : 0); } @@ -283,9 +279,9 @@ static void ddekit_timer_thread(void *arg) l4thread_set_prio(l4thread_myself(), 0x11); #endif - l4thread_started(0); +// l4thread_started(0); - l4lock_lock(&timer_lock); + mutex_lock (&timer_lock); while (1) { ddekit_timer_t *timer = NULL; unsigned long to = DDEKIT_TIMEOUT_NEVER; @@ -303,13 +299,14 @@ static void ddekit_timer_thread(void *arg) __timer_sleep(to); while ((timer = get_next_timer()) != NULL) { - l4lock_unlock(&timer_lock); + mutex_unlock (&timer_lock); //ddekit_printf("doing timer fn @ %p\n", timer->fn); timer->fn(timer->args); ddekit_simple_free(timer); - l4lock_lock(&timer_lock); + mutex_lock (&timer_lock); } } + // TODO how is the thread terminated? } ddekit_thread_t *ddekit_get_timer_thread() @@ -320,10 +317,18 @@ ddekit_thread_t *ddekit_get_timer_thread() void ddekit_init_timers(void) { - l4_tsc_init(L4_TSC_INIT_AUTO); + error_t err; + struct timeval tp; + + err = maptime_map (0, 0, &mapped_time); + if (err) + error (2, err, "cannot map time device"); + + maptime_read (mapped_time, &tp); + + root_jiffies = (long long) tp.tv_sec * HZ + + ((long long) tp.tv_usec * HZ) / 1000000; - /* XXX this module needs HZ and jiffies to work - so l4io info page must be mapped */ - timer_thread = l4thread_l4_id( l4thread_create_named(ddekit_timer_thread, - "ddekit_timer", 0, - L4THREAD_CREATE_SYNC)); + timer_thread = cthread_fork ((cthread_fn_t) timer_function, 0); + cthread_detach (timer_thread); } |