Expose a slightly-lower-level interface to timeouts which allows callers

to manage their own memory.  Tested on my machine (make buildworld).
I've made analogous changes on the alpha, but don't have a machine
to test.

Not-objected-to by:	dg, gibbs
This commit is contained in:
Garrett Wollman 1999-03-06 04:46:20 +00:00
parent c07760c6a4
commit acc8326d0c
5 changed files with 119 additions and 28 deletions

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: machdep.c,v 1.32 1999/02/22 15:13:33 bde Exp $
* $Id: machdep.c,v 1.33 1999/02/27 18:41:40 dfr Exp $
*/
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -409,6 +409,8 @@ again:
*/
SLIST_INIT(&callfree);
for (i = 0; i < ncallout; i++) {
callout_init(&callout[i]);
callout[i].c_flags = CALLOUT_LOCAL_ALLOC;
SLIST_INSERT_HEAD(&callfree, &callout[i], c_links.sle);
}

View File

@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
* $Id: machdep.c,v 1.325 1999/02/11 07:53:28 msmith Exp $
* $Id: machdep.c,v 1.326 1999/02/13 17:45:15 bde Exp $
*/
#include "apm.h"
@ -431,6 +431,8 @@ again:
*/
SLIST_INIT(&callfree);
for (i = 0; i < ncallout; i++) {
callout_init(&callout[i]);
callout[i].c_flags = CALLOUT_LOCAL_ALLOC;
SLIST_INSERT_HEAD(&callfree, &callout[i], c_links.sle);
}

View File

@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
* $Id: machdep.c,v 1.325 1999/02/11 07:53:28 msmith Exp $
* $Id: machdep.c,v 1.326 1999/02/13 17:45:15 bde Exp $
*/
#include "apm.h"
@ -431,6 +431,8 @@ again:
*/
SLIST_INIT(&callfree);
for (i = 0; i < ncallout; i++) {
callout_init(&callout[i]);
callout[i].c_flags = CALLOUT_LOCAL_ALLOC;
SLIST_INSERT_HEAD(&callfree, &callout[i], c_links.sle);
}

View File

@ -35,8 +35,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
* $Id: kern_timeout.c,v 1.54 1998/02/25 06:13:32 bde Exp $
* From: @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
* $Id: kern_timeout.c,v 1.55 1998/05/17 20:08:04 bde Exp $
*/
#include <sys/param.h>
@ -119,7 +119,15 @@ softclock()
c_func = c->c_func;
c_arg = c->c_arg;
c->c_func = NULL;
SLIST_INSERT_HEAD(&callfree, c, c_links.sle);
if (c->c_flags & CALLOUT_LOCAL_ALLOC) {
c->c_flags = CALLOUT_LOCAL_ALLOC;
SLIST_INSERT_HEAD(&callfree, c,
c_links.sle);
} else {
c->c_flags =
(c->c_flags & ~CALLOUT_PENDING)
| CALLOUT_FIRED;
}
splx(s);
c_func(c_arg);
s = splhigh();
@ -158,10 +166,6 @@ timeout(ftn, arg, to_ticks)
struct callout *new;
struct callout_handle handle;
if (to_ticks <= 0)
to_ticks = 1;
/* Lock out the clock. */
s = splhigh();
/* Fill in the next free callout structure. */
@ -169,16 +173,12 @@ timeout(ftn, arg, to_ticks)
if (new == NULL)
/* XXX Attempt to malloc first */
panic("timeout table full");
SLIST_REMOVE_HEAD(&callfree, c_links.sle);
new->c_arg = arg;
new->c_func = ftn;
new->c_time = ticks + to_ticks;
TAILQ_INSERT_TAIL(&callwheel[new->c_time & callwheelmask],
new, c_links.tqe);
callout_reset(new, to_ticks, ftn, arg);
splx(s);
handle.callout = new;
splx(s);
return (handle);
}
@ -199,16 +199,8 @@ untimeout(ftn, arg, handle)
return;
s = splhigh();
if ((handle.callout->c_func == ftn)
&& (handle.callout->c_arg == arg)) {
if (nextsoftcheck == handle.callout) {
nextsoftcheck = TAILQ_NEXT(handle.callout, c_links.tqe);
}
TAILQ_REMOVE(&callwheel[handle.callout->c_time & callwheelmask],
handle.callout, c_links.tqe);
handle.callout->c_func = NULL;
SLIST_INSERT_HEAD(&callfree, handle.callout, c_links.sle);
}
if (handle.callout->c_func == ftn && handle.callout->c_arg == arg)
callout_stop(handle.callout);
splx(s);
}
@ -218,6 +210,86 @@ callout_handle_init(struct callout_handle *handle)
handle->callout = NULL;
}
/*
* New interface; clients allocate their own callout structures.
*
* callout_reset() - establish or change a timeout
* callout_stop() - disestablish a timeout
* callout_init() - initialize a callout structure so that it can
* safely be passed to callout_reset() and callout_stop()
*
* <sys/callout.h> defines two convenience macros:
*
* callout_pending() - returns number of ticks until callout fires, or 0
* if not scheduled
* callout_fired() - returns truth if callout has already been fired
*/
void
callout_reset(c, to_ticks, ftn, arg)
struct callout *c;
int to_ticks;
void (*ftn) __P((void *));
void *arg;
{
int s;
s = splhigh();
if (c->c_flags & CALLOUT_PENDING)
callout_stop(c);
/*
* We could spl down here and back up at the TAILQ_INSERT_TAIL,
* but there's no point since doing this setup doesn't take much
^ time.
*/
if (to_ticks <= 0)
to_ticks = 1;
c->c_arg = arg;
c->c_flags = (c->c_flags & ~CALLOUT_FIRED) | CALLOUT_PENDING;
c->c_func = ftn;
c->c_time = ticks + to_ticks;
TAILQ_INSERT_TAIL(&callwheel[c->c_time & callwheelmask],
c, c_links.tqe);
splx(s);
}
void
callout_stop(c)
struct callout *c;
{
int s;
s = splhigh();
/*
* Don't attempt to delete a callout that's not on the queue.
*/
if (!(c->c_flags & CALLOUT_PENDING)) {
splx(s);
return;
}
c->c_flags &= ~CALLOUT_PENDING;
if (nextsoftcheck == c) {
nextsoftcheck = TAILQ_NEXT(c, c_links.tqe);
}
TAILQ_REMOVE(&callwheel[c->c_time & callwheelmask], c, c_links.tqe);
c->c_func = NULL;
if (c->c_flags & CALLOUT_LOCAL_ALLOC) {
SLIST_INSERT_HEAD(&callfree, c, c_links.sle);
}
splx(s);
}
void
callout_init(c)
struct callout *c;
{
bzero(c, sizeof c);
}
#ifdef APM_FIXUP_CALLTODO
/*
* Adjust the kernel calltodo timeout list. This routine is used after

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)callout.h 8.2 (Berkeley) 1/21/94
* $Id: callout.h,v 1.10 1997/12/01 05:45:15 davidg Exp $
* $Id: callout.h,v 1.11 1998/01/11 00:43:51 phk Exp $
*/
#ifndef _SYS_CALLOUT_H_
@ -55,8 +55,13 @@ struct callout {
int c_time; /* ticks to the event */
void *c_arg; /* function argument */
void (*c_func) __P((void *)); /* function to call */
int c_flags; /* state of this entry */
};
#define CALLOUT_LOCAL_ALLOC 0x0001 /* was allocated from callfree */
#define CALLOUT_PENDING 0x0002 /* callout is currently active */
#define CALLOUT_FIRED 0x0004 /* callout has been fired */
struct callout_handle {
struct callout *callout;
};
@ -67,6 +72,14 @@ extern struct callout *callout;
extern int ncallout;
extern struct callout_tailq *callwheel;
extern int callwheelsize, callwheelbits, callwheelmask, softticks;
#define callout_fired(c) ((c)->c_flags & CALLOUT_FIRED)
void callout_init __P((struct callout *));
#define callout_pending(c) (((c)->c_flags & CALLOUT_PENDING) ? \
((c)->c_time - ticks) : 0)
void callout_reset __P((struct callout *, int, void (*)(void *), void *));
void callout_stop __P((struct callout *));
#endif /* KERNEL */
#endif /* _SYS_CALLOUT_H_ */