Remove the deprecated timeout(9) interface.

All in-tree consumers have been converted to callout(9).

Reviewed by:	kib, markj
Differential Revision:	https://reviews.freebsd.org/D22602
This commit is contained in:
John Baldwin 2019-12-13 21:03:12 +00:00
parent c0236bd93d
commit 4b28d96e5d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=355732
9 changed files with 132 additions and 313 deletions

View file

@ -36,6 +36,9 @@
# xargs -n1 | sort | uniq -d;
# done
# 20191213: remove timeout(9)
OLD_FILES+=usr/share/man/man9/timeout.9.gz
OLD_FILES+=usr/share/man/man9/untimeout.9.gz
# 20191128: Removal of trm(4)
OLD_FILES+=usr/share/man/man4/trm.4.gz
# 20191121: Removal of sio(4)

View file

@ -56,6 +56,7 @@ MAN= accept_filter.9 \
BUS_SETUP_INTR.9 \
bus_space.9 \
byteorder.9 \
callout.9 \
casuword.9 \
cd.9 \
cnv.9 \
@ -315,7 +316,6 @@ MAN= accept_filter.9 \
tcp_functions.9 \
thread_exit.9 \
time.9 \
timeout.9 \
tvtohz.9 \
ucred.9 \
uidinfo.9 \
@ -766,6 +766,30 @@ MLINKS+=byteorder.9 be16dec.9 \
byteorder.9 le64dec.9 \
byteorder.9 le64enc.9 \
byteorder.9 le64toh.9
MLINKS+=callout.9 callout_active.9 \
callout.9 callout_async_drain.9 \
callout.9 callout_deactivate.9 \
callout.9 callout_drain.9 \
callout.9 callout_handle_init.9 \
callout.9 callout_init.9 \
callout.9 callout_init_mtx.9 \
callout.9 callout_init_rm.9 \
callout.9 callout_init_rw.9 \
callout.9 callout_pending.9 \
callout.9 callout_reset.9 \
callout.9 callout_reset_curcpu.9 \
callout.9 callout_reset_on.9 \
callout.9 callout_reset_sbt.9 \
callout.9 callout_reset_sbt_curcpu.9 \
callout.9 callout_reset_sbt_on.9 \
callout.9 callout_schedule.9 \
callout.9 callout_schedule_curcpu.9 \
callout.9 callout_schedule_on.9 \
callout.9 callout_schedule_sbt.9 \
callout.9 callout_schedule_sbt_curcpu.9 \
callout.9 callout_schedule_sbt_on.9 \
callout.9 callout_stop.9 \
callout.9 callout_when.9
MLINKS+=cnv.9 cnvlist.9 \
cnv.9 cnvlist_free_binary.9 \
cnv.9 cnvlist_free_bool.9 \
@ -2097,32 +2121,6 @@ MLINKS+=tcp_functions.9 register_tcp_functions.9 \
MLINKS+=time.9 boottime.9 \
time.9 time_second.9 \
time.9 time_uptime.9
MLINKS+=timeout.9 callout.9 \
timeout.9 callout_active.9 \
timeout.9 callout_async_drain.9 \
timeout.9 callout_deactivate.9 \
timeout.9 callout_drain.9 \
timeout.9 callout_handle_init.9 \
timeout.9 callout_init.9 \
timeout.9 callout_init_mtx.9 \
timeout.9 callout_init_rm.9 \
timeout.9 callout_init_rw.9 \
timeout.9 callout_pending.9 \
timeout.9 callout_reset.9 \
timeout.9 callout_reset_curcpu.9 \
timeout.9 callout_reset_on.9 \
timeout.9 callout_reset_sbt.9 \
timeout.9 callout_reset_sbt_curcpu.9 \
timeout.9 callout_reset_sbt_on.9 \
timeout.9 callout_schedule.9 \
timeout.9 callout_schedule_curcpu.9 \
timeout.9 callout_schedule_on.9 \
timeout.9 callout_schedule_sbt.9 \
timeout.9 callout_schedule_sbt_curcpu.9 \
timeout.9 callout_schedule_sbt_on.9 \
timeout.9 callout_stop.9 \
timeout.9 callout_when.9 \
timeout.9 untimeout.9
MLINKS+=ucred.9 crcopy.9 \
ucred.9 crcopysafe.9 \
ucred.9 crdup.9 \

View file

@ -29,8 +29,8 @@
.\"
.\" $FreeBSD$
.\"
.Dd December 10, 2019
.Dt TIMEOUT 9
.Dd December 13, 2019
.Dt CALLOUT 9
.Os
.Sh NAME
.Nm callout_active ,
@ -56,17 +56,13 @@
.Nm callout_schedule_sbt_curcpu ,
.Nm callout_schedule_sbt_on ,
.Nm callout_stop ,
.Nm callout_when ,
.Nm timeout ,
.Nm untimeout
.Nm callout_when
.Nd execute a function after a specified length of time
.Sh SYNOPSIS
.In sys/types.h
.In sys/callout.h
.In sys/systm.h
.Bd -literal
typedef void callout_func_t (void *);
typedef void timeout_t (void *);
.Ed
.Ft int
.Fn callout_active "struct callout *c"
@ -179,10 +175,6 @@ struct callout_handle handle = CALLOUT_HANDLE_INITIALIZER(&handle);
.Fa "sbintime_t *sbt_res"
.Fa "sbintime_t *precision_res"
.Fc
.Ft struct callout_handle
.Fn timeout "timeout_t *func" "void *arg" "int ticks"
.Ft void
.Fn untimeout "timeout_t *func" "void *arg" "struct callout_handle handle"
.Sh DESCRIPTION
The
.Nm callout
@ -808,99 +800,6 @@ should be used.
In particular,
a callout should always be drained prior to destroying its associated lock
or releasing the storage for the callout structure.
.Sh LEGACY API
.Bf Sy
The functions below are a legacy API that will be removed in a future release.
New code should not use these routines.
.Ef
.Pp
The function
.Fn timeout
schedules a call to the function given by the argument
.Fa func
to take place after
.Fa ticks Ns No /hz
seconds.
Non-positive values of
.Fa ticks
are silently converted to the value
.Sq 1 .
.Fa func
should be a pointer to a function that takes a
.Fa void *
argument.
Upon invocation,
.Fa func
will receive
.Fa arg
as its only argument.
The return value from
.Fn timeout
is a
.Ft struct callout_handle
which can be used in conjunction with the
.Fn untimeout
function to request that a scheduled timeout be canceled.
.Pp
The function
.Fn callout_handle_init
can be used to initialize a handle to a state which will cause
any calls to
.Fn untimeout
with that handle to return with no side
effects.
.Pp
Assigning a callout handle the value of
.Fn CALLOUT_HANDLE_INITIALIZER
performs the same function as
.Fn callout_handle_init
and is provided for use on statically declared or global callout handles.
.Pp
The function
.Fn untimeout
cancels the timeout associated with
.Fa handle
using the
.Fa func
and
.Fa arg
arguments to validate the handle.
If the handle does not correspond to a timeout with
the function
.Fa func
taking the argument
.Fa arg
no action is taken.
.Fa handle
must be initialized by a previous call to
.Fn timeout ,
.Fn callout_handle_init ,
or assigned the value of
.Fn CALLOUT_HANDLE_INITIALIZER "&handle"
before being passed to
.Fn untimeout .
The behavior of calling
.Fn untimeout
with an uninitialized handle
is undefined.
.Pp
As handles are recycled by the system, it is possible (although unlikely)
that a handle from one invocation of
.Fn timeout
may match the handle of another invocation of
.Fn timeout
if both calls used the same function pointer and argument, and the first
timeout is expired or canceled before the second call.
The timeout facility offers O(1) running time for
.Fn timeout
and
.Fn untimeout .
Timeouts are executed from
.Fn softclock
with the
.Va Giant
lock held.
Thus they are protected from re-entrancy.
.Sh RETURN VALUES
The
.Fn callout_active
@ -928,24 +827,28 @@ and
functions return a value of one if the callout was still pending when it was
called, a zero if the callout could not be stopped and a negative one is it
was either not running or has already completed.
The
.Fn timeout
function returns a
.Ft struct callout_handle
that can be passed to
.Fn untimeout .
.Sh HISTORY
The current timeout and untimeout routines are based on the work of
.Fx
initially used the long standing
.Bx
linked list
callout mechanism which offered O(n) insertion and removal running time
but did not generate or require handles for untimeout operations.
.Pp
.Fx 3.0
introduced a new set of timeout and untimeout routines from
.Nx
based on the work of
.An Adam M. Costello
and
.An George Varghese ,
published in a technical report entitled
.%T "Redesigning the BSD Callout and Timer Facilities"
and modified slightly for inclusion in
and modified for inclusion in
.Fx
by
.An Justin T. Gibbs .
The original work on the data structures used in this implementation
The original work on the data structures used in that implementation
was published by
.An G. Varghese
and
@ -954,8 +857,66 @@ in the paper
.%T "Hashed and Hierarchical Timing Wheels: Data Structures for the Efficient Implementation of a Timer Facility"
in the
.%B "Proceedings of the 11th ACM Annual Symposium on Operating Systems Principles" .
The current implementation replaces the long standing
.Bx
linked list
callout mechanism which offered O(n) insertion and removal running time
but did not generate or require handles for untimeout operations.
.Pp
.Fx 3.3
introduced the first implementations of
.Fn callout_init ,
.Fn callout_reset ,
and
.Fn callout_stop
which permitted callers to allocate dedicated storage for callouts.
This ensured that a callout would always fire unlike
.Fn timeout
which would silently fail if it was unable to allocate a callout.
.Pp
.Fx 5.0
permitted callout handlers to be tagged as MPSAFE via
.Fn callout_init .
.Pp
.Fx 5.3
introduced
.Fn callout_drain .
.Pp
.Fx 6.0
introduced
.Fn callout_init_mtx .
.Pp
.Fx 8.0
introduced per-CPU callout wheels,
.Fn callout_init_rw ,
and
.Fn callout_schedule .
.Pp
.Fx 9.0
changed the underlying timer interrupts used to drive callouts to prefer
one-shot event timers instead of a periodic timer interrupt.
.Pp
.Fx 10.0
switched the callout wheel to support tickless operation.
These changes introduced
.Vt sbintime_t
and the
.Fn callout_reset_sbt*
family of functions.
.Fx 10.0 also added
.Dv C_DIRECT_EXEC
and
.Fn callout_init_rm .
.Pp
.Fx 10.2
introduced the
.Fn callout_schedule_sbt*
family of functions.
.Pp
.Fx 11.0
introduced
.Fn callout_async_drain .
.Fx 11.1
introduced
.Fn callout_when .
.Fx 13.0
removed
.Vt timeout_t ,
.Fn timeout ,
and
.Fn untimeout .

View file

@ -84,7 +84,6 @@ struct intr_entropy {
uintptr_t event;
};
struct intr_event *clk_intr_event;
struct intr_event *tty_intr_event;
void *vm_ih;
struct proc *intrproc;

View file

@ -167,10 +167,8 @@ struct callout_cpu {
struct mtx_padalign cc_lock;
struct cc_exec cc_exec_entity[2];
struct callout *cc_next;
struct callout *cc_callout;
struct callout_list *cc_callwheel;
struct callout_tailq cc_expireq;
struct callout_slist cc_callfree;
sbintime_t cc_firstevent;
sbintime_t cc_lastscan;
void *cc_cookie;
@ -210,7 +208,7 @@ struct callout_cpu cc_cpu;
#define CC_UNLOCK(cc) mtx_unlock_spin(&(cc)->cc_lock)
#define CC_LOCK_ASSERT(cc) mtx_assert(&(cc)->cc_lock, MA_OWNED)
static int __read_mostly timeout_cpu;
static int __read_mostly cc_default_cpu;
static void callout_cpu_init(struct callout_cpu *cc, int cpu);
static void softclock_call_cc(struct callout *c, struct callout_cpu *cc,
@ -279,6 +277,7 @@ static void
callout_callwheel_init(void *dummy)
{
struct callout_cpu *cc;
int cpu;
/*
* Calculate the size of the callout wheel and the preallocated
@ -304,16 +303,14 @@ callout_callwheel_init(void *dummy)
TUNABLE_INT_FETCH("kern.pin_pcpu_swi", &pin_pcpu_swi);
/*
* Only BSP handles timeout(9) and receives a preallocation.
*
* XXX: Once all timeout(9) consumers are converted this can
* be removed.
* Initialize callout wheels. The software interrupt threads
* are created later.
*/
timeout_cpu = PCPU_GET(cpuid);
cc = CC_CPU(timeout_cpu);
cc->cc_callout = malloc(ncallout * sizeof(struct callout),
M_CALLOUT, M_WAITOK);
callout_cpu_init(cc, timeout_cpu);
cc_default_cpu = PCPU_GET(cpuid);
CPU_FOREACH(cpu) {
cc = CC_CPU(cpu);
callout_cpu_init(cc, cpu);
}
}
SYSINIT(callwheel_init, SI_SUB_CPU, SI_ORDER_ANY, callout_callwheel_init, NULL);
@ -323,11 +320,9 @@ SYSINIT(callwheel_init, SI_SUB_CPU, SI_ORDER_ANY, callout_callwheel_init, NULL);
static void
callout_cpu_init(struct callout_cpu *cc, int cpu)
{
struct callout *c;
int i;
mtx_init(&cc->cc_lock, "callout", NULL, MTX_SPIN | MTX_RECURSE);
SLIST_INIT(&cc->cc_callfree);
cc->cc_inited = 1;
cc->cc_callwheel = malloc_domainset(sizeof(struct callout_list) *
callwheelsize, M_CALLOUT,
@ -342,14 +337,6 @@ callout_cpu_init(struct callout_cpu *cc, int cpu)
snprintf(cc->cc_ktr_event_name, sizeof(cc->cc_ktr_event_name),
"callwheel cpu %d", cpu);
#endif
if (cc->cc_callout == NULL) /* Only BSP handles timeout(9) */
return;
for (i = 0; i < ncallout; i++) {
c = &cc->cc_callout[i];
callout_init(c, 0);
c->c_iflags = CALLOUT_LOCAL_ALLOC;
SLIST_INSERT_HEAD(&cc->cc_callfree, c, c_links.sle);
}
}
#ifdef SMP
@ -383,50 +370,35 @@ callout_cpu_switch(struct callout *c, struct callout_cpu *cc, int new_cpu)
#endif
/*
* Start standard softclock thread.
* Start softclock threads.
*/
static void
start_softclock(void *dummy)
{
struct callout_cpu *cc;
char name[MAXCOMLEN];
#ifdef SMP
int cpu;
bool pin_swi;
struct intr_event *ie;
#endif
cc = CC_CPU(timeout_cpu);
snprintf(name, sizeof(name), "clock (%d)", timeout_cpu);
if (swi_add(&clk_intr_event, name, softclock, cc, SWI_CLOCK,
INTR_MPSAFE, &cc->cc_cookie))
panic("died while creating standard software ithreads");
if (pin_default_swi &&
(intr_event_bind(clk_intr_event, timeout_cpu) != 0)) {
printf("%s: timeout clock couldn't be pinned to cpu %d\n",
__func__,
timeout_cpu);
}
#ifdef SMP
CPU_FOREACH(cpu) {
if (cpu == timeout_cpu)
continue;
cc = CC_CPU(cpu);
cc->cc_callout = NULL; /* Only BSP handles timeout(9). */
callout_cpu_init(cc, cpu);
snprintf(name, sizeof(name), "clock (%d)", cpu);
ie = NULL;
if (swi_add(&ie, name, softclock, cc, SWI_CLOCK,
INTR_MPSAFE, &cc->cc_cookie))
panic("died while creating standard software ithreads");
if (pin_pcpu_swi && (intr_event_bind(ie, cpu) != 0)) {
printf("%s: per-cpu clock couldn't be pinned to "
"cpu %d\n",
if (cpu == cc_default_cpu)
pin_swi = pin_default_swi;
else
pin_swi = pin_pcpu_swi;
if (pin_swi && (intr_event_bind(ie, cpu) != 0)) {
printf("%s: %s clock couldn't be pinned to cpu %d\n",
__func__,
cpu == cc_default_cpu ? "default" : "per-cpu",
cpu);
}
}
#endif
}
SYSINIT(start_softclock, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_softclock, NULL);
@ -638,16 +610,6 @@ callout_cc_add(struct callout *c, struct callout_cpu *cc,
#endif
}
static void
callout_cc_del(struct callout *c, struct callout_cpu *cc)
{
if ((c->c_iflags & CALLOUT_LOCAL_ALLOC) == 0)
return;
c->c_func = NULL;
SLIST_INSERT_HEAD(&cc->cc_callfree, c, c_links.sle);
}
static void
softclock_call_cc(struct callout *c, struct callout_cpu *cc,
#ifdef CALLOUT_PROFILING
@ -692,10 +654,7 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc,
c_func = c->c_func;
c_arg = c->c_arg;
c_iflags = c->c_iflags;
if (c->c_iflags & CALLOUT_LOCAL_ALLOC)
c->c_iflags = CALLOUT_LOCAL_ALLOC;
else
c->c_iflags &= ~CALLOUT_PENDING;
c->c_iflags &= ~CALLOUT_PENDING;
cc_exec_curr(cc, direct) = c;
cc_exec_last_func(cc, direct) = c_func;
@ -795,8 +754,6 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc,
wakeup(&cc_exec_waiting(cc, direct));
CC_LOCK(cc);
} else if (cc_cce_migrating(cc, direct)) {
KASSERT((c_iflags & CALLOUT_LOCAL_ALLOC) == 0,
("Migrating legacy callout %p", c));
#ifdef SMP
/*
* If the callout was scheduled for
@ -819,7 +776,6 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc,
CTR3(KTR_CALLOUT,
"deferred cancelled %p func %p arg %p",
c, new_func, new_arg);
callout_cc_del(c, cc);
return;
}
c->c_iflags &= ~CALLOUT_DFRMIGRATION;
@ -834,19 +790,6 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc,
panic("migration should not happen");
#endif
}
/*
* If the current callout is locally allocated (from
* timeout(9)) then put it on the freelist.
*
* Note: we need to check the cached copy of c_iflags because
* if it was not local, then it's not safe to deref the
* callout pointer.
*/
KASSERT((c_iflags & CALLOUT_LOCAL_ALLOC) == 0 ||
c->c_iflags == CALLOUT_LOCAL_ALLOC,
("corrupted callout"));
if (c_iflags & CALLOUT_LOCAL_ALLOC)
callout_cc_del(c, cc);
}
/*
@ -896,69 +839,6 @@ softclock(void *arg)
CC_UNLOCK(cc);
}
/*
* timeout --
* Execute a function after a specified length of time.
*
* untimeout --
* Cancel previous timeout function call.
*
* callout_handle_init --
* Initialize a handle so that using it with untimeout is benign.
*
* See AT&T BCI Driver Reference Manual for specification. This
* implementation differs from that one in that although an
* identification value is returned from timeout, the original
* arguments to timeout as well as the identifier are used to
* identify entries for untimeout.
*/
struct callout_handle
timeout(timeout_t *ftn, void *arg, int to_ticks)
{
struct callout_cpu *cc;
struct callout *new;
struct callout_handle handle;
cc = CC_CPU(timeout_cpu);
CC_LOCK(cc);
/* Fill in the next free callout structure. */
new = SLIST_FIRST(&cc->cc_callfree);
if (new == NULL)
/* XXX Attempt to malloc first */
panic("timeout table full");
SLIST_REMOVE_HEAD(&cc->cc_callfree, c_links.sle);
callout_reset(new, to_ticks, ftn, arg);
handle.callout = new;
CC_UNLOCK(cc);
return (handle);
}
void
untimeout(timeout_t *ftn, void *arg, struct callout_handle handle)
{
struct callout_cpu *cc;
/*
* Check for a handle that was initialized
* by callout_handle_init, but never used
* for a real timeout.
*/
if (handle.callout == NULL)
return;
cc = callout_lock(handle.callout);
if (handle.callout->c_func == ftn && handle.callout->c_arg == arg)
callout_stop(handle.callout);
CC_UNLOCK(cc);
}
void
callout_handle_init(struct callout_handle *handle)
{
handle->callout = NULL;
}
void
callout_when(sbintime_t sbt, sbintime_t precision, int flags,
sbintime_t *res, sbintime_t *prec_res)
@ -1060,12 +940,9 @@ callout_reset_sbt_on(struct callout *c, sbintime_t sbt, sbintime_t prec,
("%s: direct callout %p has lock", __func__, c));
cc = callout_lock(c);
/*
* Don't allow migration of pre-allocated callouts lest they
* become unbalanced or handle the case where the user does
* not care.
* Don't allow migration if the user does not care.
*/
if ((c->c_iflags & CALLOUT_LOCAL_ALLOC) ||
ignore_cpu) {
if (ignore_cpu) {
cpu = c->c_cpu;
}
@ -1435,7 +1312,6 @@ _callout_stop_safe(struct callout *c, int flags, callout_func_t *drain)
TAILQ_REMOVE(&cc->cc_expireq, c, c_links.tqe);
}
}
callout_cc_del(c, cc);
CC_UNLOCK(cc);
return (cancelled);
}
@ -1451,7 +1327,7 @@ callout_init(struct callout *c, int mpsafe)
c->c_lock = &Giant.lock_object;
c->c_iflags = 0;
}
c->c_cpu = timeout_cpu;
c->c_cpu = cc_default_cpu;
}
void
@ -1467,7 +1343,7 @@ _callout_init_lock(struct callout *c, struct lock_object *lock, int flags)
(LC_SPINLOCK | LC_SLEEPABLE)), ("%s: invalid lock class",
__func__));
c->c_iflags = flags & (CALLOUT_RETURNUNLOCKED | CALLOUT_SHAREDLOCK);
c->c_cpu = timeout_cpu;
c->c_cpu = cc_default_cpu;
}
#ifdef APM_FIXUP_CALLTODO
@ -1559,9 +1435,7 @@ sysctl_kern_callout_stat(SYSCTL_HANDLER_ARGS)
sbintime_t maxpr, maxt, medpr, medt, now, spr, st, t;
int ct[64], cpr[64], ccpbk[32];
int error, val, i, count, tcum, pcum, maxc, c, medc;
#ifdef SMP
int cpu;
#endif
val = 0;
error = sysctl_handle_int(oidp, &val, 0, req);
@ -1573,12 +1447,8 @@ sysctl_kern_callout_stat(SYSCTL_HANDLER_ARGS)
bzero(ct, sizeof(ct));
bzero(cpr, sizeof(cpr));
now = sbinuptime();
#ifdef SMP
CPU_FOREACH(cpu) {
cc = CC_CPU(cpu);
#else
cc = CC_CPU(timeout_cpu);
#endif
CC_LOCK(cc);
for (i = 0; i < callwheelsize; i++) {
sc = &cc->cc_callwheel[i];
@ -1603,9 +1473,7 @@ sysctl_kern_callout_stat(SYSCTL_HANDLER_ARGS)
count += c;
}
CC_UNLOCK(cc);
#ifdef SMP
}
#endif
for (i = 0, tcum = 0; i < 64 && tcum < count / 2; i++)
tcum += ct[i];

View file

@ -3801,7 +3801,7 @@ ng_callout(struct callout *c, node_p node, hook_p hook, int ticks,
return (0);
}
/* A special modified version of untimeout() */
/* A special modified version of callout_stop() */
int
ng_uncallout(struct callout *c, node_p node)
{

View file

@ -151,7 +151,6 @@ struct intr_event {
struct proc;
extern struct intr_event *tty_intr_event;
extern struct intr_event *clk_intr_event;
extern void *vm_ih;
/* Counts and names for statistics (defined in MD code). */

View file

@ -60,7 +60,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
#define __FreeBSD_version 1300066 /* Master, propagated to newvers */
#define __FreeBSD_version 1300067 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,

View file

@ -466,15 +466,6 @@ void usrinfoinit(void);
void kern_reboot(int) __dead2;
void shutdown_nice(int);
/* Timeouts */
typedef void timeout_t(void *); /* timeout function type */
#define CALLOUT_HANDLE_INITIALIZER(handle) \
{ NULL }
void callout_handle_init(struct callout_handle *);
struct callout_handle timeout(timeout_t *, void *, int);
void untimeout(timeout_t *, void *, struct callout_handle);
/* Stubs for obsolete functions that used to be for interrupt management */
static __inline intrmask_t splbio(void) { return 0; }
static __inline intrmask_t splcam(void) { return 0; }