From 9290f1fe99c91ba6c57dec956ff73d1741d81b45 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Tue, 17 Nov 2009 10:29:23 +0100 Subject: Add DDEKit headers. --- libddekit/include/ddekit/timer.h | 55 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 libddekit/include/ddekit/timer.h (limited to 'libddekit/include/ddekit/timer.h') diff --git a/libddekit/include/ddekit/timer.h b/libddekit/include/ddekit/timer.h new file mode 100644 index 00000000..c352475c --- /dev/null +++ b/libddekit/include/ddekit/timer.h @@ -0,0 +1,55 @@ +#ifndef _ddekit_timer_h +#define _ddekit_timer_h + +#include + +enum +{ + DDEKIT_INVALID_TIMER_ID = -1, +}; + +/** \defgroup DDEKit_timer + * + * Timer subsystem + * + * DDEKit provides a generic timer implementation that enables users + * to execute a function with some arguments after a certain period + * of time. DDEKit therefore starts a timer thread that executes these + * functions and keeps track of the currently running timers. + */ + +/** Add a timer event. After the absolute timeout has expired, function fn + * is called with args as arguments. + * + * \ingroup DDEKit_timer + * + * \return >=0 valid timer ID + * \return < 0 error + */ +int ddekit_add_timer(void (*fn)(void *), void *args, unsigned long timeout); + +/** Delete timer with the corresponding timer id. + * + * \ingroup DDEKit_timer + */ +int ddekit_del_timer(int timer); + +/** Check whether a timer is pending + * + * \ingroup DDEKit_timer + * + * Linux needs this. + */ +int ddekit_timer_pending(int timer); + +/** Initialization function, startup timer thread + * + * \ingroup DDEKit_timer + */ +void ddekit_init_timers(void); + +/** Get the timer thread. + */ +ddekit_thread_t *ddekit_get_timer_thread(void); + +#endif -- cgit v1.2.3 From b537f6cede63b0e55e82a2ee1467d094200d953e Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Sat, 21 Nov 2009 00:47:01 +0100 Subject: Emulate the timer in the Hurd. --- libddekit/include/ddekit/timer.h | 4 +- libddekit/timer.c | 107 ++++++++++++++++++++------------------- 2 files changed, 59 insertions(+), 52 deletions(-) (limited to 'libddekit/include/ddekit/timer.h') 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 +#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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include +#include +#include +#include + +#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); } -- cgit v1.2.3 From 974a402ed6a28e7801f3c6202516ef232d73256a Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Sun, 6 Dec 2009 19:13:54 +0100 Subject: Redefine HZ. --- libddekit/include/ddekit/timer.h | 1 + libddekit/timer.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'libddekit/include/ddekit/timer.h') diff --git a/libddekit/include/ddekit/timer.h b/libddekit/include/ddekit/timer.h index a57c8fce..bb30e1f9 100644 --- a/libddekit/include/ddekit/timer.h +++ b/libddekit/include/ddekit/timer.h @@ -4,6 +4,7 @@ #include "ddekit/thread.h" #define jiffies fetch_jiffies() +#define HZ 100 enum { diff --git a/libddekit/timer.c b/libddekit/timer.c index f8bfc7a1..be23ee14 100644 --- a/libddekit/timer.c +++ b/libddekit/timer.c @@ -19,7 +19,6 @@ long long root_jiffies; * So, if someone schedules a timeout to expire in 2 seconds, * this expires date will be in jiffies + 2 * HZ. */ -extern unsigned long HZ; typedef struct _timer { -- cgit v1.2.3 From 3d4eb7565f63ec437a6c74f42cfa092cfb192f16 Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Fri, 11 Dec 2009 13:52:23 +0100 Subject: Use ddekit lock instead of mutex. --- libddekit/include/ddekit/timer.h | 2 +- libddekit/timer.c | 38 ++++++++++++++++++++++++-------------- 2 files changed, 25 insertions(+), 15 deletions(-) (limited to 'libddekit/include/ddekit/timer.h') diff --git a/libddekit/include/ddekit/timer.h b/libddekit/include/ddekit/timer.h index bb30e1f9..c0bea6bf 100644 --- a/libddekit/include/ddekit/timer.h +++ b/libddekit/include/ddekit/timer.h @@ -3,7 +3,7 @@ #include "ddekit/thread.h" -#define jiffies fetch_jiffies() +#define jiffies (fetch_jiffies()) #define HZ 100 enum diff --git a/libddekit/timer.c b/libddekit/timer.c index be23ee14..4944be69 100644 --- a/libddekit/timer.c +++ b/libddekit/timer.c @@ -2,6 +2,7 @@ #include #include +#include "ddekit/lock.h" #include "ddekit/memory.h" #include "ddekit/assert.h" #include "ddekit/semaphore.h" @@ -31,7 +32,7 @@ typedef struct _timer static ddekit_timer_t *timer_list = NULL; ///< list of pending timers -static struct mutex timer_lock = MUTEX_INITIALIZER; ///< lock to access timer_list +static ddekit_lock_t timer_lock; ///< 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 @@ -53,11 +54,13 @@ static void dump_list(char *msg) #endif } -int fetch_jiffies () +long long fetch_jiffies () { struct timeval tv; long long j; + if (mapped_time == NULL) + ddekit_init_timers (); maptime_read (mapped_time, &tv); j = (long long) tv.tv_sec * HZ + ((long long) tv.tv_usec * HZ) / 1000000; @@ -86,6 +89,7 @@ int ddekit_add_timer(void (*fn)(void *), void *args, unsigned long timeout) ddekit_timer_t *t = ddekit_simple_malloc(sizeof(ddekit_timer_t)); Assert(t); + printf ("add a timer at %ld\n", timeout); /* fill in values */ t->fn = fn; @@ -93,7 +97,7 @@ int ddekit_add_timer(void (*fn)(void *), void *args, unsigned long timeout) t->expires = timeout; t->next = NULL; - mutex_lock (&timer_lock); + ddekit_lock_lock (&timer_lock); t->id = timer_id_ctr++; @@ -124,7 +128,7 @@ int ddekit_add_timer(void (*fn)(void *), void *args, unsigned long timeout) __notify_timer_thread(); } - mutex_unlock (&timer_lock); + ddekit_lock_unlock (&timer_lock); dump_list("after add"); @@ -137,7 +141,7 @@ int ddekit_del_timer(int timer) ddekit_timer_t *it, *it_next; int ret = -1; - mutex_lock (&timer_lock); + ddekit_lock_lock (&timer_lock); /* no timer? */ if (!timer_list) { @@ -178,7 +182,7 @@ int ddekit_del_timer(int timer) } out: - mutex_unlock (&timer_lock); + ddekit_lock_unlock (&timer_lock); dump_list("after del"); @@ -197,7 +201,7 @@ int ddekit_timer_pending(int timer) ddekit_timer_t *t = NULL; int r = 0; - mutex_lock (&timer_lock); + ddekit_lock_lock (&timer_lock); t = timer_list; while (t) { @@ -208,7 +212,7 @@ int ddekit_timer_pending(int timer) t = t->next; } - mutex_unlock (&timer_lock); + ddekit_lock_unlock (&timer_lock); return r; } @@ -224,7 +228,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(timer_lock.holder == timer_thread); + Assert(ddekit_lock_owner (&timer_lock) == (int) timer_thread); if (timer_list && (timer_list->expires <= jiffies)) { @@ -251,7 +255,7 @@ static inline int __timer_sleep(unsigned to) { int err = 0; - mutex_unlock (&timer_lock); + ddekit_lock_unlock (&timer_lock); if (to == DDEKIT_TIMEOUT_NEVER) { ddekit_sem_down(notify_semaphore); @@ -266,7 +270,7 @@ static inline int __timer_sleep(unsigned to) #endif } - mutex_lock (&timer_lock); + ddekit_lock_lock (&timer_lock); return (err ? 1 : 0); } @@ -283,7 +287,7 @@ static void ddekit_timer_thread(void *arg) // l4thread_started(0); - mutex_lock (&timer_lock); + ddekit_lock_lock (&timer_lock); while (1) { ddekit_timer_t *timer = NULL; unsigned long to = DDEKIT_TIMEOUT_NEVER; @@ -301,11 +305,11 @@ static void ddekit_timer_thread(void *arg) __timer_sleep(to); while ((timer = get_next_timer()) != NULL) { - mutex_unlock (&timer_lock); + ddekit_lock_unlock (&timer_lock); //ddekit_printf("doing timer fn @ %p\n", timer->fn); timer->fn(timer->args); ddekit_simple_free(timer); - mutex_lock (&timer_lock); + ddekit_lock_lock (&timer_lock); } } // TODO how is the thread terminated? @@ -321,7 +325,12 @@ void ddekit_init_timers(void) { error_t err; struct timeval tp; + static boolean_t initialized = FALSE; + if (initialized) + return; + + initialized = TRUE; err = maptime_map (0, 0, &mapped_time); if (err) error (2, err, "cannot map time device"); @@ -331,6 +340,7 @@ void ddekit_init_timers(void) root_jiffies = (long long) tp.tv_sec * HZ + ((long long) tp.tv_usec * HZ) / 1000000; + ddekit_lock_init (&timer_lock); timer_thread = cthread_fork ((cthread_fn_t) ddekit_timer_thread, 0); cthread_detach (timer_thread); } -- cgit v1.2.3 From f3b3a2ca7ee85517888940a35e652325fa38293f Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Tue, 5 Jan 2010 16:07:54 +0100 Subject: Declare fetch_jiffies in the header file. --- libddekit/include/ddekit/timer.h | 1 + 1 file changed, 1 insertion(+) (limited to 'libddekit/include/ddekit/timer.h') diff --git a/libddekit/include/ddekit/timer.h b/libddekit/include/ddekit/timer.h index c0bea6bf..435ba8aa 100644 --- a/libddekit/include/ddekit/timer.h +++ b/libddekit/include/ddekit/timer.h @@ -54,5 +54,6 @@ void ddekit_init_timers(void); /** Get the timer thread. */ ddekit_thread_t *ddekit_get_timer_thread(void); +extern long long fetch_jiffies (void); #endif -- cgit v1.2.3 From b168f41d6eab6319bb5a2fcc065541ba2b18926e Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Thu, 22 Apr 2010 15:07:28 +0200 Subject: jiffies in the type of unsigned long. --- libddekit/include/ddekit/timer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libddekit/include/ddekit/timer.h') diff --git a/libddekit/include/ddekit/timer.h b/libddekit/include/ddekit/timer.h index 435ba8aa..387f2078 100644 --- a/libddekit/include/ddekit/timer.h +++ b/libddekit/include/ddekit/timer.h @@ -54,6 +54,6 @@ void ddekit_init_timers(void); /** Get the timer thread. */ ddekit_thread_t *ddekit_get_timer_thread(void); -extern long long fetch_jiffies (void); +extern unsigned long fetch_jiffies (void); #endif -- cgit v1.2.3