4 #define CALLOUT_ACTIVE 0x0002 /* callout is currently active */
5 #define CALLOUT_MPSAFE 0x0008 /* callout handler is mp safe */
7 #ifndef _WIN32 /* this is the linux version */
8 /* callout support, in <sys/callout.h> on FreeBSD */
10 * callout support on linux module is done using timers
12 #include <linux/timer.h>
14 #include <linux/sched.h> /* jiffies definition is here in 2.4 */
16 #define callout timer_list
18 callout_reset_on(struct callout *co, int ticks, void (*fn)(void *), void *arg, int cpu)
20 co->expires = jiffies + ticks;
21 co->function = (void (*)(unsigned long))fn;
22 co->data = (unsigned long)arg;
24 * Linux 2.6.31 and above has add_timer_on(co, cpu),
25 * otherwise add_timer() always schedules a callout on the same
26 * CPU used the first time, so we don't need more.
32 #define callout_init(co, safe) init_timer(co)
33 #define callout_drain(co) del_timer(co)
34 #define callout_stop(co) del_timer(co)
39 /* This is the windows part for callout support */
44 LARGE_INTEGER duetime;
47 void dummynet (void*);
49 __in struct _KDPC *Dpc,
50 __in_opt PVOID DeferredContext,
51 __in_opt PVOID SystemArgument1,
52 __in_opt PVOID SystemArgument2
56 __in struct _KDPC *Dpc,
57 __in_opt PVOID DeferredContext,
58 __in_opt PVOID SystemArgument1,
59 __in_opt PVOID SystemArgument2
62 /* callout_reset must handle two problems:
63 * - dummynet() scheduler must be run always on the same processor
64 * because do_gettimeofday() is based on cpu performance counter, and
65 * _occasionally_ can leap backward in time if we query another cpu.
66 * typically this won't happen that much, and the cpu will almost always
67 * be the same even without the affinity restriction, but better to be sure.
68 * - ipfw_tick() does not have the granularity requirements of dummynet()
69 * but we need to pass a pointer as argument.
71 * for these reasons, if we are called for dummynet() timer,
72 * KeInitializeDpc is called only once as it should be, and the thread
73 * is forced on cpu0 (which is always present), while if we're called
74 * for ipfw_tick(), we re-initialize the DPC each time, using
75 * parameter DeferredContext to pass the needed pointer. since this
76 * timer is called only once a sec, this won't hurt that much.
79 callout_reset_on(struct callout *co, int ticks, void (*fn)(void *), void *arg, int cpu)
83 if(co->dpcinitialized == 0)
85 KeInitializeDpc(&co->timerdpc, dummynet_dpc, NULL);
86 KeSetTargetProcessorDpc(&co->timerdpc, cpu);
87 co->dpcinitialized = 1;
92 KeInitializeDpc(&co->timerdpc, ipfw_dpc, arg);
94 co->duetime.QuadPart = (-ticks)*10000;
95 KeSetTimer(&co->thetimer, co->duetime, &co->timerdpc);
100 callout_init(struct callout* co, int safe)
102 printf("%s: initializing timer at %p\n",__FUNCTION__,co);
103 KeInitializeTimer(&co->thetimer);
107 callout_drain(struct callout* co)
109 BOOLEAN canceled = KeCancelTimer(&co->thetimer);
110 while (canceled != TRUE)
112 canceled = KeCancelTimer(&co->thetimer);
114 printf("%s: stopping timer at %p\n",__FUNCTION__,co);
119 callout_stop(struct callout* co)
121 return callout_drain(co);
126 #endif /* _SYS_SYSTM_H_ */