Index: sys/sys/callout.h =================================================================== --- sys/sys/callout.h (revision 237202) +++ sys/sys/callout.h (working copy) @@ -54,6 +54,8 @@ struct callout *callout; }; +#define C_DIRECT 0x0001 /* direct execution of callout */ + #ifdef _KERNEL extern int ncallout; @@ -69,9 +71,16 @@ _callout_init_lock((c), ((rw) != NULL) ? &(rw)->lock_object : \ NULL, (flags)) #define callout_pending(c) ((c)->c_flags & CALLOUT_PENDING) -int callout_reset_bt_on(struct callout *, struct bintime, void(*)(void *), - void *, int, int); -int callout_reset_on(struct callout *, int, void (*)(void *), void *, int); +int _callout_reset_on(struct callout *, struct bintime *, int, + void (*)(void *), void *, int, int); +#define callout_reset_on(c, to_ticks, fn, arg, cpu) \ + _callout_reset_on((c), (NULL), (to_ticks), (fn), (arg), (cpu), \ + (0)) +#define callout_reset_flags_on(c, to_ticks, fn, arg, cpu, flags) \ + _callout_reset_on((c), (NULL), (to_ticks), (fn), (arg), (cpu), \ + (flags)) +#define callout_reset_bt_on(c, bt, fn, arg, cpu, direct) \ + _callout_reset_on((c), (bt), (0), (fn), (arg), (cpu), (direct)) #define callout_reset(c, on_tick, fn, arg) \ callout_reset_on((c), (on_tick), (fn), (arg), (c)->c_cpu) #define callout_reset_curcpu(c, on_tick, fn, arg) \ Index: sys/kern/subr_sleepqueue.c =================================================================== --- sys/kern/subr_sleepqueue.c (revision 237202) +++ sys/kern/subr_sleepqueue.c (working copy) @@ -378,7 +378,7 @@ callout_reset_curcpu(&td->td_slpcallout, timo, sleepq_timeout, td); else - callout_reset_bt_on(&td->td_slpcallout, *bt, + callout_reset_bt_on(&td->td_slpcallout, bt, sleepq_timeout, td, PCPU_GET(cpuid), 0); } Index: sys/kern/kern_timeout.c =================================================================== --- sys/kern/kern_timeout.c (revision 237233) +++ sys/kern/kern_timeout.c (working copy) @@ -475,7 +475,8 @@ static void callout_cc_add(struct callout *c, struct callout_cpu *cc, - struct bintime to_bintime, void (*func)(void *), void *arg, int cpu, int direct) + struct bintime to_bintime, void (*func)(void *), void *arg, int cpu, + int flags) { int bucket; @@ -485,7 +486,7 @@ } c->c_arg = arg; c->c_flags |= (CALLOUT_ACTIVE | CALLOUT_PENDING); - if (direct) + if (flags & C_DIRECT) c->c_flags |= CALLOUT_DIRECT; c->c_flags &= ~CALLOUT_PROCESSED; c->c_func = func; @@ -831,13 +832,22 @@ * callout_deactivate() - marks the callout as having been serviced */ int -callout_reset_bt_on(struct callout *c, struct bintime bt, void (*ftn)(void *), - void *arg, int cpu, int direct) +_callout_reset_on(struct callout *c, struct bintime *bt, int to_ticks, + void (*ftn)(void *), void *arg, int cpu, int flags) { + struct bintime now, to_bt; struct callout_cpu *cc; int cancelled = 0; int bucket; + if (bt == NULL) { + FREQ2BT(hz,&to_bt); + getbinuptime(&now); + bintime_mul(&to_bt,to_ticks); + bintime_add(&to_bt,&now); + } + else + to_bt = *bt; /* * Don't allow migration of pre-allocated callouts lest they * become unbalanced. @@ -892,14 +902,14 @@ if (c->c_cpu != cpu) { if (cc->cc_curr == c) { cc->cc_migration_cpu = cpu; - cc->cc_migration_time = bt; + cc->cc_migration_time = to_bt; cc->cc_migration_func = ftn; cc->cc_migration_arg = arg; c->c_flags |= CALLOUT_DFRMIGRATION; CTR6(KTR_CALLOUT, "migration of %p func %p arg %p in %d.%08x to %u deferred", - c, c->c_func, c->c_arg, (int)(bt.sec), - (u_int)(bt.frac >> 32), cpu); + c, c->c_func, c->c_arg, (int)(to_bt.sec), + (u_int)(to_bt.frac >> 32), cpu); CC_UNLOCK(cc); return (cancelled); } @@ -907,28 +917,15 @@ } #endif - callout_cc_add(c, cc, bt, ftn, arg, cpu, direct); + callout_cc_add(c, cc, to_bt, ftn, arg, cpu, flags); CTR6(KTR_CALLOUT, "%sscheduled %p func %p arg %p in %d.%08x", - cancelled ? "re" : "", c, c->c_func, c->c_arg, (int)(bt.sec), - (u_int)(bt.frac >> 32)); + cancelled ? "re" : "", c, c->c_func, c->c_arg, (int)(to_bt.sec), + (u_int)(to_bt.frac >> 32)); CC_UNLOCK(cc); return (cancelled); } -int -callout_reset_on(struct callout *c, int to_ticks, void (*ftn)(void *), - void *arg, int cpu) -{ - struct bintime bt, now; - - FREQ2BT(hz,&bt); - getbinuptime(&now); - bintime_mul(&bt,to_ticks); - bintime_add(&bt,&now); - return (callout_reset_bt_on(c, bt, ftn, arg, cpu, 0)); -} - /* * Common idioms that can be optimized in the future. */