summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2002-10-02 23:33:06 -0700
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-10-02 23:33:06 -0700
commitafc141063a5b0f4e5a45e7e68060918daa69a859 (patch)
treeb93b5a9f5a15d8973090087c6abf1a1d129ac770 /include/linux
parent794aa320b79d2cb8643ecb6058f0f3fadd51955d (diff)
[PATCH] timer-2.5.40-F7
This does a number of timer subsystem enhancements: - simplified timer initialization, now it's the cheapest possible thing: static inline void init_timer(struct timer_list * timer) { timer->base = NULL; } since the timer functions already did a !timer->base check this did not have any effect on their fastpath. - the rule from now on is that timer->base is set upon activation of the timer, and cleared upon deactivation. This also made it possible to: - reorganize all the timer handling code to not assume anything about timer->entry.next and timer->entry.prev - this also removed lots of unnecessery cleaning of these fields. Removed lots of unnecessary list operations from the fastpath. - simplified del_timer_sync(): it now uses del_timer() plus some simple synchronization code. Note that this also fixes a bug: if mod_timer (or add_timer) moves a currently executing timer to another CPU's timer vector, then del_timer_sync() does not synchronize with the handler properly. - bugfix: moved run_local_timers() from scheduler_tick() into update_process_times() .. scheduler_tick() might be called from the fork code which will not quite have the intended effect ... - removed the APIC-timer-IRQ shifting done on SMP, Dipankar Sarma's testing shows no negative effects. - cleaned up include/linux/timer.h: - removed the timer_t typedef, and fixes up kernel/workqueue.c to use the 'struct timer_list' name instead. - removed unnecessery includes - renamed the 'list' field to 'entry' (it's an entry not a list head) - exchanged the 'function' and 'data' fields. This, besides being more logical, also unearthed the last few remaining places that initialized timers by assuming some given field ordering, the patch also fixes these places. (fs/xfs/pagebuf/page_buf.c, net/core/profile.c and net/ipv4/inetpeer.c) - removed the defunct sync_timers(), timer_enter() and timer_exit() prototypes. - added docbook-style comments. - other kernel/timer.c changes: - base->running_timer does not have to be volatile ... - added consistent comments to all the important functions. - made the sync-waiting in del_timer_sync preempt- and lowpower- friendly. i've compiled, booted & tested the patched kernel on x86 UP and SMP. I have tried moderately high networking load as well, to make sure the timer changes are correct - they appear to be.
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/timer.h89
-rw-r--r--include/linux/workqueue.h2
2 files changed, 40 insertions, 51 deletions
diff --git a/include/linux/timer.h b/include/linux/timer.h
index f890f4f3d668..cfedb5e8bb07 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -2,70 +2,59 @@
#define _LINUX_TIMER_H
#include <linux/config.h>
-#include <linux/smp.h>
-#include <linux/stddef.h>
#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/cache.h>
struct tvec_t_base_s;
-/*
- * Timers may be dynamically created and destroyed, and should be initialized
- * by a call to init_timer() upon creation.
- *
- * The "data" field enables use of a common timeout function for several
- * timeouts. You can use this field to distinguish between the different
- * invocations.
- */
-typedef struct timer_list {
- struct list_head list;
+struct timer_list {
+ struct list_head entry;
unsigned long expires;
- unsigned long data;
+
void (*function)(unsigned long);
+ unsigned long data;
+
struct tvec_t_base_s *base;
-} timer_t;
+};
-extern void add_timer(timer_t * timer);
-extern int del_timer(timer_t * timer);
-
-#ifdef CONFIG_SMP
-extern int del_timer_sync(timer_t * timer);
-extern void sync_timers(void);
-#define timer_enter(base, t) do { base->running_timer = t; mb(); } while (0)
-#define timer_exit(base) do { base->running_timer = NULL; } while (0)
-#define timer_is_running(base,t) (base->running_timer == t)
-#define timer_synchronize(base,t) while (timer_is_running(base,t)) barrier()
-#else
-#define del_timer_sync(t) del_timer(t)
-#define sync_timers() do { } while (0)
-#define timer_enter(base,t) do { } while (0)
-#define timer_exit(base) do { } while (0)
-#endif
-
-/*
- * mod_timer is a more efficient way to update the expire field of an
- * active timer (if the timer is inactive it will be activated)
- * mod_timer(a,b) is equivalent to del_timer(a); a->expires = b; add_timer(a).
- * If the timer is known to be not pending (ie, in the handler), mod_timer
- * is less efficient than a->expires = b; add_timer(a).
+/***
+ * init_timer - initialize a timer.
+ * @timer: the timer to be initialized
+ *
+ * init_timer() must be done to a timer prior calling *any* of the
+ * other timer functions.
*/
-int mod_timer(timer_t *timer, unsigned long expires);
-
-extern void it_real_fn(unsigned long);
-
-extern void init_timers(void);
-extern void run_local_timers(void);
-
-static inline void init_timer(timer_t * timer)
+static inline void init_timer(struct timer_list * timer)
{
- timer->list.next = timer->list.prev = NULL;
timer->base = NULL;
}
-static inline int timer_pending(const timer_t * timer)
+/***
+ * timer_pending - is a timer pending?
+ * @timer: the timer in question
+ *
+ * timer_pending will tell whether a given timer is currently pending,
+ * or not. Callers must ensure serialization wrt. other operations done
+ * to this timer, eg. interrupt contexts, or other CPUs on SMP.
+ *
+ * return value: 1 if the timer is pending, 0 if not.
+ */
+static inline int timer_pending(const struct timer_list * timer)
{
- return timer->list.next != NULL;
+ return timer->base != NULL;
}
+extern void add_timer(struct timer_list * timer);
+extern int del_timer(struct timer_list * timer);
+extern int mod_timer(struct timer_list *timer, unsigned long expires);
+
+#if CONFIG_SMP
+ extern int del_timer_sync(struct timer_list * timer);
+#else
+# define del_timer_sync(t) del_timer(t)
+#endif
+
+extern void init_timers(void);
+extern void run_local_timers(void);
+extern void it_real_fn(unsigned long);
+
#endif
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 7828c7bef55f..3e466894179f 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -15,7 +15,7 @@ struct work_struct {
void (*func)(void *);
void *data;
void *wq_data;
- timer_t timer;
+ struct timer_list timer;
};
#define __WORK_INITIALIZER(n, f, d) { \