From: art Date: Thu, 23 Mar 2000 09:59:52 +0000 (+0000) Subject: New API for timeouts. Replaces the old timeout()/untimeout() API and X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=d66eba84aa3b18595c10a5b245b64a9ffcd3bc86;p=openbsd New API for timeouts. Replaces the old timeout()/untimeout() API and makes it the callers responsibility to allocate resources for the timeouts. This is a KISS implementation and does _not_ solve the problems of slow handling of a large number of pending timeouts (this will be solved in future work) (although hardclock is now guarateed to take constant time for handling of timeouts). Old timeout() and untimeout() are implemented as wrappers around the new API and kept for compatibility. They will be removed as soon as all subsystems are converted to use the new API. --- diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c index e80f92db679..1cb6f85bb26 100644 --- a/sys/arch/alpha/alpha/machdep.c +++ b/sys/arch/alpha/alpha/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.31 2000/02/22 19:27:40 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.32 2000/03/23 09:59:52 art Exp $ */ /* $NetBSD: machdep.c,v 1.61 1996/12/07 01:54:49 cgd Exp $ */ /* @@ -42,7 +42,7 @@ #ifdef REAL_CLISTS #include #endif -#include +#include #include #include #include @@ -456,7 +456,7 @@ unknown_cputype: #ifdef REAL_CLISTS valloc(cfree, struct cblock, nclist); #endif - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif @@ -702,12 +702,9 @@ cpu_startup() mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, VM_MBUF_SIZE, FALSE); /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; - callout[i-1].c_next = NULL; + timeout_init(); #if defined(DEBUG) pmapdebug = opmapdebug; diff --git a/sys/arch/amiga/amiga/machdep.c b/sys/arch/amiga/amiga/machdep.c index 7aabe71fc55..b8a3b324583 100644 --- a/sys/arch/amiga/amiga/machdep.c +++ b/sys/arch/amiga/amiga/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.36 2000/02/22 19:27:42 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.37 2000/03/23 09:59:53 art Exp $ */ /* $NetBSD: machdep.c,v 1.95 1997/08/27 18:31:17 is Exp $ */ /* @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include #include @@ -362,7 +362,7 @@ again: #define valloclim(name, type, num, lim) \ (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) /* valloc(cfree, struct cblock, nclist); */ - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif @@ -479,11 +479,9 @@ again: VM_MBUF_SIZE, FALSE); /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i - 1].c_next = &callout[i]; + timeout_init(); #ifdef DEBUG pmapdebug = opmapdebug; diff --git a/sys/arch/arc/arc/machdep.c b/sys/arch/arc/arc/machdep.c index f991f33ae9c..a9115abc7b5 100644 --- a/sys/arch/arc/arc/machdep.c +++ b/sys/arch/arc/arc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.36 1999/05/22 21:22:19 weingart Exp $ */ +/* $OpenBSD: machdep.c,v 1.37 2000/03/23 09:59:53 art Exp $ */ /* * Copyright (c) 1988 University of Utah. * Copyright (c) 1992, 1993 @@ -38,7 +38,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 8.3 (Berkeley) 1/12/94 - * $Id: machdep.c,v 1.36 1999/05/22 21:22:19 weingart Exp $ + * $Id: machdep.c,v 1.37 2000/03/23 09:59:53 art Exp $ */ /* from: Utah Hdr: machdep.c 1.63 91/04/24 */ @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include #include @@ -482,7 +482,7 @@ mips_init(argc, argv, envv) #ifdef REAL_CLISTS valloc(cfree, struct cblock, nclist); #endif - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif @@ -818,12 +818,9 @@ cpu_startup() mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, VM_MBUF_SIZE, FALSE); /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; - callout[i-1].c_next = NULL; + timeout_init(); #ifdef DEBUG pmapdebug = opmapdebug; diff --git a/sys/arch/arm32/arm32/machdep.c b/sys/arch/arm32/arm32/machdep.c index 91c7331ee35..812d0aedcfc 100644 --- a/sys/arch/arm32/arm32/machdep.c +++ b/sys/arch/arm32/arm32/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.5 1999/05/22 21:22:20 weingart Exp $ */ +/* $OpenBSD: machdep.c,v 1.6 2000/03/23 09:59:53 art Exp $ */ /* $NetBSD: machdep.c,v 1.6 1996/03/13 21:32:39 mark Exp $ */ /* @@ -50,7 +50,7 @@ #include #include #include -#include +#include #include #include #include @@ -1368,13 +1368,9 @@ cpu_startup() */ /* - * Initialise callouts + * Initialise timeouts */ - - callfree = callout; - - for (loop = 1; loop < ncallout; ++loop) - callout[loop - 1].c_next = &callout[loop]; + timeout_init(); printf("avail mem = %d (%d pages)\n", (int)ptoa(cnt.v_free_count), (int)ptoa(cnt.v_free_count) / NBPG); @@ -1471,7 +1467,7 @@ allocsys(v) (caddr_t)(name) = (type *)v; \ v = (caddr_t)((name) + (num)); - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); diff --git a/sys/arch/atari/atari/machdep.c b/sys/arch/atari/atari/machdep.c index 2ead98665bd..fce889d2bf7 100644 --- a/sys/arch/atari/atari/machdep.c +++ b/sys/arch/atari/atari/machdep.c @@ -53,7 +53,7 @@ #include #include #include -#include +#include #include #include #include @@ -213,7 +213,7 @@ again: #define valloclim(name, type, num, lim) \ (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) /* valloc(cfree, struct cblock, nclist); */ - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif @@ -327,11 +327,9 @@ again: VM_MBUF_SIZE, FALSE); /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; + timeout_init(); #ifdef DEBUG pmapdebug = opmapdebug; diff --git a/sys/arch/hp300/hp300/machdep.c b/sys/arch/hp300/hp300/machdep.c index 170b07c5137..a6b85a3c25d 100644 --- a/sys/arch/hp300/hp300/machdep.c +++ b/sys/arch/hp300/hp300/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.39 2000/02/22 19:27:46 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.40 2000/03/23 09:59:54 art Exp $ */ /* $NetBSD: machdep.c,v 1.94 1997/06/12 15:46:29 mrg Exp $ */ /* @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #include #include @@ -320,12 +320,9 @@ cpu_startup() mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, VM_MBUF_SIZE, FALSE); /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; - callout[i-1].c_next = NULL; + timeout_init(); #ifdef DEBUG pmapdebug = opmapdebug; @@ -400,7 +397,7 @@ allocsys(v) #ifdef REAL_CLISTS valloc(cfree, struct cblock, nclist); #endif - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif diff --git a/sys/arch/hppa/hppa/machdep.c b/sys/arch/hppa/hppa/machdep.c index 48facbcf808..c972583aae3 100644 --- a/sys/arch/hppa/hppa/machdep.c +++ b/sys/arch/hppa/hppa/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.23 2000/03/16 22:11:03 art Exp $ */ +/* $OpenBSD: machdep.c,v 1.24 2000/03/23 09:59:54 art Exp $ */ /* * Copyright (c) 1999-2000 Michael Shalayeff @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include #include @@ -310,7 +310,7 @@ hppa_init(start) valloc(cfree, struct cblock, nclist); #endif - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); valloc(buf, struct buf, nbuf); #ifdef SYSVSHM @@ -525,12 +525,9 @@ cpu_startup() VM_MBUF_SIZE, VM_MAP_INTRSAFE, FALSE, NULL); /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; - callout[i-1].c_next = NULL; + timeout_init(); #ifdef DEBUG pmapdebug = opmapdebug; diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 18910c9448e..7835c4c89d5 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.127 2000/03/16 22:11:03 art Exp $ */ +/* $OpenBSD: machdep.c,v 1.128 2000/03/23 09:59:54 art Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -90,7 +90,7 @@ #include #include #include -#include +#include #include #include #include @@ -388,11 +388,9 @@ cpu_startup() #endif /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; + timeout_init(); #if defined(UVM) printf("avail mem = %lu (%uK)\n", ptoa(uvmexp.free), @@ -463,7 +461,7 @@ allocsys(v) #ifdef REAL_CLISTS valloc(cfree, struct cblock, nclist); #endif - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif diff --git a/sys/arch/kbus/kbus/machdep.c b/sys/arch/kbus/kbus/machdep.c index 03bb797b874..390f9e83f79 100644 --- a/sys/arch/kbus/kbus/machdep.c +++ b/sys/arch/kbus/kbus/machdep.c @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include #include @@ -460,11 +460,9 @@ cpu_startup(void) mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, VM_MBUF_SIZE, FALSE); /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; + timeout_init(); printf("avail mem = 0x%x\n", ptoa(cnt.v_free_count)); printf("using %d buffers containing %d bytes of memory\n", @@ -504,7 +502,7 @@ allocsys(v) (name) = (type *)v; v = (caddr_t)((name)+(num)) #define valloclim(name, type, num, lim) \ (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif diff --git a/sys/arch/mac68k/mac68k/machdep.c b/sys/arch/mac68k/mac68k/machdep.c index 88f09533e26..9fb3112faf4 100644 --- a/sys/arch/mac68k/mac68k/machdep.c +++ b/sys/arch/mac68k/mac68k/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.65 2000/02/22 19:27:52 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.66 2000/03/23 09:59:54 art Exp $ */ /* $NetBSD: machdep.c,v 1.134 1997/02/14 06:15:30 scottr Exp $ */ /* @@ -93,7 +93,7 @@ #include #include #include -#include +#include #include #include #include @@ -363,7 +363,7 @@ again: #ifdef REAL_CLISTS valloc(cfree, struct cblock, nclist); #endif - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif @@ -479,11 +479,9 @@ again: VM_MBUF_SIZE, FALSE); /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i - 1].c_next = &callout[i]; + timeout_init(); printf("avail mem = %ld\n", ptoa(cnt.v_free_count)); printf("using %d buffers containing %d bytes of memory\n", diff --git a/sys/arch/mvme68k/mvme68k/machdep.c b/sys/arch/mvme68k/mvme68k/machdep.c index 101d54be691..6ea693627e1 100644 --- a/sys/arch/mvme68k/mvme68k/machdep.c +++ b/sys/arch/mvme68k/mvme68k/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.32 2000/02/22 19:27:54 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.33 2000/03/23 09:59:55 art Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -83,7 +83,7 @@ #include #include #include -#include +#include #include #include #include @@ -296,7 +296,7 @@ cpu_startup() #ifdef REAL_CLISTS valloc(cfree, struct cblock, nclist); #endif - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif @@ -403,12 +403,9 @@ cpu_startup() mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, VM_MBUF_SIZE, FALSE); /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; - callout[i-1].c_next = NULL; + timeout_init(); #ifdef DEBUG pmapdebug = opmapdebug; diff --git a/sys/arch/mvme88k/mvme88k/machdep.c b/sys/arch/mvme88k/mvme88k/machdep.c index 700140a76ba..e0b04f9cb5e 100644 --- a/sys/arch/mvme88k/mvme88k/machdep.c +++ b/sys/arch/mvme88k/mvme88k/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.19 2000/02/22 19:27:55 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.20 2000/03/23 09:59:55 art Exp $ */ /* * Copyright (c) 1998, 1999 Steve Murphree, Jr. * Copyright (c) 1996 Nivas Madhur @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include #include @@ -636,12 +636,9 @@ cpu_startup() VM_MBUF_SIZE, FALSE); /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; - callout[i-1].c_next = NULL; + timeout_init(); printf("avail mem = %d\n", ptoa(cnt.v_free_count)); printf("using %d buffers containing %d bytes of memory\n", @@ -700,7 +697,7 @@ register caddr_t v; #ifdef REAL_CLISTS valloc(cfree, struct cblock, nclist); #endif - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #if 0 valloc(swapmap, struct map, nswapmap = maxproc * 2); #endif diff --git a/sys/arch/pc532/pc532/machdep.c b/sys/arch/pc532/pc532/machdep.c index 9462904d85d..eb26828fb67 100644 --- a/sys/arch/pc532/pc532/machdep.c +++ b/sys/arch/pc532/pc532/machdep.c @@ -56,7 +56,7 @@ static char rcsid[] = "/b/source/CVS/src/sys/arch/pc532/pc532/machdep.c,v 1.2 19 #include #include #include -#include +#include #include #include #include @@ -349,7 +349,7 @@ again: (name) = (type *)v; v = (caddr_t)((name)+(num)) #define valloclim(name, type, num, lim) \ (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num))) - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif @@ -460,11 +460,9 @@ again: mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, VM_MBUF_SIZE, FALSE); /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; + timeout_init(); printf("avail mem = 0x%x\n", ptoa(cnt.v_free_count)); printf("using %d buffers containing %d bytes of memory\n", diff --git a/sys/arch/pmax/pmax/machdep.c b/sys/arch/pmax/pmax/machdep.c index 29a7914ed30..2ae10f121da 100644 --- a/sys/arch/pmax/pmax/machdep.c +++ b/sys/arch/pmax/pmax/machdep.c @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include #include @@ -700,7 +700,7 @@ mach_init(argc, argv, code, cv) #ifdef REAL_CLISTS valloc(cfree, struct cblock, nclist); #endif - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif @@ -856,12 +856,9 @@ cpu_startup() mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, VM_MBUF_SIZE, FALSE); /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; - callout[i-1].c_next = NULL; + timeout_init(); #ifdef DEBUG pmapdebug = opmapdebug; diff --git a/sys/arch/powerpc/powerpc/machdep.c b/sys/arch/powerpc/powerpc/machdep.c index 50d6b0c693e..7a3e6a65b96 100644 --- a/sys/arch/powerpc/powerpc/machdep.c +++ b/sys/arch/powerpc/powerpc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.35 2000/03/23 04:01:55 rahnds Exp $ */ +/* $OpenBSD: machdep.c,v 1.36 2000/03/23 09:59:56 art Exp $ */ /* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */ /* @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include #include @@ -515,11 +515,9 @@ cpu_startup() #endif /* - * Initialize callouts. + * Initialize timeouts. */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i - 1].c_next = &callout[i]; + timeout_init(); #ifdef UVM printf("avail mem = %d\n", ptoa(uvmexp.free)); @@ -564,7 +562,7 @@ allocsys(v) #define valloc(name, type, num) \ v = (caddr_t)(((name) = (type *)v) + (num)) - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif diff --git a/sys/arch/sparc/sparc/machdep.c b/sys/arch/sparc/sparc/machdep.c index 8051d02965f..d063046906f 100644 --- a/sys/arch/sparc/sparc/machdep.c +++ b/sys/arch/sparc/sparc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.47 2000/03/16 22:11:02 art Exp $ */ +/* $OpenBSD: machdep.c,v 1.48 2000/03/23 09:59:56 art Exp $ */ /* $NetBSD: machdep.c,v 1.85 1997/09/12 08:55:02 pk Exp $ */ /* @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include @@ -353,12 +353,9 @@ cpu_startup() VM_MBUF_SIZE, FALSE); #endif /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; - callout[i-1].c_next = NULL; + timeout_init(); #ifdef DEBUG pmapdebug = opmapdebug; @@ -408,7 +405,7 @@ allocsys(v) #define valloc(name, type, num) \ v = (caddr_t)(((name) = (type *)v) + (num)) - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif diff --git a/sys/arch/sun3/sun3/machdep.c b/sys/arch/sun3/sun3/machdep.c index 26d49c789e7..2c48c2c7481 100644 --- a/sys/arch/sun3/sun3/machdep.c +++ b/sys/arch/sun3/sun3/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.25 2000/03/02 23:02:14 todd Exp $ */ +/* $OpenBSD: machdep.c,v 1.26 2000/03/23 09:59:56 art Exp $ */ /* $NetBSD: machdep.c,v 1.77 1996/10/13 03:47:51 christos Exp $ */ /* @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include #include #include @@ -187,7 +187,7 @@ allocsys(v) #ifdef REAL_CLISTS valloc(cfree, struct cblock, nclist); #endif - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeoutout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif @@ -346,12 +346,9 @@ cpu_startup() VM_MBUF_SIZE, FALSE); /* - * Initialize callouts + * Initialize timeouts */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; - callout[i-1].c_next = NULL; + timeout_init(); printf("avail mem = %ld\n", ptoa(cnt.v_free_count)); printf("using %d buffers containing %d bytes of memory\n", diff --git a/sys/arch/vax/vax/machdep.c b/sys/arch/vax/vax/machdep.c index c3e616a680f..8c7bde72a14 100644 --- a/sys/arch/vax/vax/machdep.c +++ b/sys/arch/vax/vax/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.20 1999/12/08 06:50:17 itojun Exp $ */ +/* $OpenBSD: machdep.c,v 1.21 2000/03/23 09:59:56 art Exp $ */ /* $NetBSD: machdep.c,v 1.45 1997/07/26 10:12:49 ragge Exp $ */ /* @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include @@ -254,13 +254,7 @@ cpu_startup() phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, VM_PHYS_SIZE, TRUE); - /* - * Initialize callouts - */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i - 1].c_next = &callout[i]; - callout[i - 1].c_next = NULL; + timeout_init(); printf("avail mem = %d\n", (int)ptoa(cnt.v_free_count)); printf("Using %d buffers containing %d bytes of memory.\n", nbuf, @@ -342,7 +336,7 @@ allocsys(v) #ifdef REAL_CLISTS valloc(cfree, struct cblock, nclist); #endif - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif diff --git a/sys/arch/wgrisc/wgrisc/machdep.c b/sys/arch/wgrisc/wgrisc/machdep.c index 7135ba0199c..38f61f10fe8 100644 --- a/sys/arch/wgrisc/wgrisc/machdep.c +++ b/sys/arch/wgrisc/wgrisc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.5 1999/05/22 21:22:32 weingart Exp $ */ +/* $OpenBSD: machdep.c,v 1.6 2000/03/23 09:59:56 art Exp $ */ /* * Copyright (c) 1988 University of Utah. * Copyright (c) 1992, 1993 @@ -38,7 +38,7 @@ * SUCH DAMAGE. * * from: @(#)machdep.c 8.3 (Berkeley) 1/12/94 - * $Id: machdep.c,v 1.5 1999/05/22 21:22:32 weingart Exp $ + * $Id: machdep.c,v 1.6 2000/03/23 09:59:56 art Exp $ */ /* from: Utah Hdr: machdep.c 1.63 91/04/24 */ @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include #include @@ -417,7 +417,7 @@ mips_init(argc, argv, code) #ifdef REAL_CLISTS valloc(cfree, struct cblock, nclist); #endif - valloc(callout, struct callout, ncallout); + valloc(timeouts, struct timeout, ntimeout); #ifdef SYSVSHM valloc(shmsegs, struct shmid_ds, shminfo.shmmni); #endif @@ -573,13 +573,8 @@ cpu_startup() bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES); mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, VM_MBUF_SIZE, FALSE); - /* - * Initialize callouts - */ - callfree = callout; - for (i = 1; i < ncallout; i++) - callout[i-1].c_next = &callout[i]; - callout[i-1].c_next = NULL; + + timeout_init(); #ifdef DEBUG pmapdebug = opmapdebug; diff --git a/sys/conf/files b/sys/conf/files index f9da9127d31..38973293fbd 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.154 2000/03/19 06:53:40 deraadt Exp $ +# $OpenBSD: files,v 1.155 2000/03/23 09:59:56 art Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -346,6 +346,7 @@ file kern/kern_subr.c file kern/kern_sysctl.c file kern/kern_synch.c file kern/kern_time.c +file kern/kern_timeout.c file kern/kern_xxx.c file kern/subr_autoconf.c file kern/subr_disk.c diff --git a/sys/conf/param.c b/sys/conf/param.c index db37665a492..2805b2ff517 100644 --- a/sys/conf/param.c +++ b/sys/conf/param.c @@ -1,4 +1,4 @@ -/* $OpenBSD: param.c,v 1.8 2000/03/21 14:55:52 deraadt Exp $ */ +/* $OpenBSD: param.c,v 1.9 2000/03/23 09:59:56 art Exp $ */ /* $NetBSD: param.c,v 1.16 1996/03/12 03:08:40 mrg Exp $ */ /* @@ -47,7 +47,7 @@ #include #include #include -#include +#include #ifdef REAL_CLISTS #include #endif @@ -96,7 +96,7 @@ int vm_cache_max = NTEXT; /* XXX these probably needs some measurements */ #define NVNODE (NPROC * 2 + NTEXT + 100) int desiredvnodes = NVNODE; int maxfiles = 3 * (NPROC + MAXUSERS) + 80; -int ncallout = (16 + NPROC) * 2; +int ntimeout = (16 + NPROC) * 2; #ifdef REAL_CLISTS int nclist = 60 + 12 * MAXUSERS; #endif @@ -166,7 +166,7 @@ int nbuf, nswbuf; * them here forces loader errors if this file is omitted * (if they've been externed everywhere else; hah!). */ -struct callout *callout; +struct timeout *timeouts; struct cblock *cfree; struct buf *buf, *swbuf; char *buffers; diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 51c088df066..b706f6e9c82 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_clock.c,v 1.21 1999/08/15 00:07:43 pjanzen Exp $ */ +/* $OpenBSD: kern_clock.c,v 1.22 2000/03/23 09:59:57 art Exp $ */ /* $NetBSD: kern_clock.c,v 1.34 1996/06/09 04:51:03 briggs Exp $ */ /*- @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include #include @@ -351,7 +351,6 @@ void hardclock(frame) register struct clockframe *frame; { - register struct callout *p1; register struct proc *p; register int delta, needsoft; extern int tickdelta; @@ -364,22 +363,8 @@ hardclock(frame) /* * Update real-time timeout queue. - * At front of queue are some number of events which are ``due''. - * The time to these is <= 0 and if negative represents the - * number of ticks which have passed since it was supposed to happen. - * The rest of the q elements (times > 0) are events yet to happen, - * where the time for each is given as a delta from the previous. - * Decrementing just the first of these serves to decrement the time - * to all events. */ - needsoft = 0; - for (p1 = calltodo.c_next; p1 != NULL; p1 = p1->c_next) { - if (--p1->c_time > 0) - break; - needsoft = 1; - if (p1->c_time == 0) - break; - } + needsoft = timeout_hardclock_update(); p = curproc; if (p) { @@ -703,114 +688,6 @@ hardclock(frame) } } -/* - * Software (low priority) clock interrupt. - * Run periodic events from timeout queue. - */ -/*ARGSUSED*/ -void -softclock() -{ - register struct callout *c; - register void *arg; - register void (*func) __P((void *)); - register int s; - - s = splhigh(); - while ((c = calltodo.c_next) != NULL && c->c_time <= 0) { - func = c->c_func; - arg = c->c_arg; - calltodo.c_next = c->c_next; - c->c_next = callfree; - callfree = c; - splx(s); - (*func)(arg); - (void) splhigh(); - } - splx(s); -} - -/* - * timeout -- - * Execute a function after a specified length of time. - * - * untimeout -- - * Cancel previous timeout function call. - * - * See AT&T BCI Driver Reference Manual for specification. This - * implementation differs from that one in that no identification - * value is returned from timeout, rather, the original arguments - * to timeout are used to identify entries for untimeout. - */ -void -timeout(ftn, arg, ticks) - void (*ftn) __P((void *)); - void *arg; - register int ticks; -{ - register struct callout *new, *p, *t; - register int s; - - if (ticks <= 0) - ticks = 1; - - /* Lock out the clock. */ - s = splhigh(); - - /* Fill in the next free callout structure. */ - if (callfree == NULL) - panic("timeout table full"); - new = callfree; - callfree = new->c_next; - new->c_arg = arg; - new->c_func = ftn; - - /* - * The time for each event is stored as a difference from the time - * of the previous event on the queue. Walk the queue, correcting - * the ticks argument for queue entries passed. Correct the ticks - * value for the queue entry immediately after the insertion point - * as well. Watch out for negative c_time values; these represent - * overdue events. - */ - for (p = &calltodo; - (t = p->c_next) != NULL && ticks > t->c_time; p = t) - if (t->c_time > 0) - ticks -= t->c_time; - new->c_time = ticks; - if (t != NULL) - t->c_time -= ticks; - - /* Insert the new entry into the queue. */ - p->c_next = new; - new->c_next = t; - splx(s); -} - -void -untimeout(ftn, arg) - void (*ftn) __P((void *)); - void *arg; -{ - register struct callout *p, *t; - register int s; - - s = splhigh(); - for (p = &calltodo; (t = p->c_next) != NULL; p = t) - if (t->c_func == ftn && t->c_arg == arg) { - /* Increment next entry's tick count. */ - if (t->c_next && t->c_time > 0) - t->c_next->c_time += t->c_time; - - /* Move entry from callout queue to callfree queue. */ - p->c_next = t->c_next; - t->c_next = callfree; - callfree = t; - break; - } - splx(s); -} - /* * Compute number of hz until specified time. Used to * compute third argument to timeout() from an absolute time. @@ -1329,42 +1206,3 @@ sysctl_clockrate(where, sizep) clkinfo.stathz = stathz ? stathz : hz; return (sysctl_rdstruct(where, sizep, NULL, &clkinfo, sizeof(clkinfo))); } - -#ifdef DDB -#include - -#include -#include -#include -#include - -void db_show_callout(addr, haddr, count, modif) - db_expr_t addr; - int haddr; - db_expr_t count; - char *modif; -{ - register struct callout *p1; - register int cum; - register int s; - db_expr_t offset; - char *name; - - db_printf(" cum ticks arg func\n"); - s = splhigh(); - for (cum = 0, p1 = calltodo.c_next; p1; p1 = p1->c_next) { - register int t = p1->c_time; - - if (t > 0) - cum += t; - - db_find_sym_and_offset((db_addr_t)p1->c_func, &name, &offset); - if (name == NULL) - name = "?"; - - db_printf("%9d %9d %8x %s (%x)\n", - cum, t, p1->c_arg, name, p1->c_func); - } - splx(s); -} -#endif diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c new file mode 100644 index 00000000000..9ebbc55ddd6 --- /dev/null +++ b/sys/kern/kern_timeout.c @@ -0,0 +1,300 @@ +/* $OpenBSD: kern_timeout.c,v 1.1 2000/03/23 09:59:57 art Exp $ */ +/* + * Copyright (c) 2000 Artur Grabowski + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#ifdef DDB +#include +#include +#include +#include +#include +#endif + +/* + * Timeouts are kept on a queue. The to_time is the value of the global + * variable "ticks" when the timeout should be called. + * + * In the future we might want to build a timer wheel to improve the speed + * of timeout_add (right now it's linear). See "Redesigning the BSD Callout + * and Timer Facilities" by Adam M. Costello and Geroge Varghese. + */ + +TAILQ_HEAD(,timeout) timeout_todo; /* Queue of timeouts. */ +TAILQ_HEAD(,timeout) timeout_static; /* Static pool of timeouts. */ + +/* + * All lists are locked with the same lock (which must also block out all + * interrupts). + */ +struct simplelock _timeout_lock; + +#define timeout_list_lock(s) \ + do { *(s) = splhigh(); simple_lock(&_timeout_lock); } while (0) +#define timeout_list_unlock(s) \ + do { simple_unlock(&_timeout_lock); splx(s); } while (0) + +/* + * Some of the "math" in here is a bit tricky. + * + * We have to beware of wrapping ints. + * We use the fact that any element added to the list must be added with a + * positive time. That means that any element `to' on the list cannot be + * scheduled to timeout further in time than INT_MAX, but to->to_time can + * be positive or negative so comparing it with anything is dangerous. + * The only way we can use the to->to_time value in any predictable way + * is when we caluculate how far in the future `to' will timeout - + *"to->to_time - ticks". The result will always be positive for future + * timeouts and 0 or negative for due timeouts. + */ +extern int ticks; /* XXX - move to sys/X.h */ + +void +timeout_init() +{ + int i; + + TAILQ_INIT(&timeout_todo); + TAILQ_INIT(&timeout_static); + simple_lock_init(&_timeout_lock); + + for (i = 0; i < ntimeout; i++) + TAILQ_INSERT_HEAD(&timeout_static, &timeouts[i], to_list); +} + +void +timeout_set(to, fn, arg) + struct timeout *to; + void (*fn)(void *); + void *arg; +{ + + to->to_func = fn; + to->to_arg = arg; + to->to_flags = 0; +} + +void +timeout_add(new, to_ticks) + struct timeout *new; + int to_ticks; +{ + struct timeout *to; + int s; + + /* + * You are supposed to understand this function before you fiddle. + */ + +#ifdef DIAGNOSTIC + if (to_ticks < 0) + panic("timeout_add: to_ticks < 0"); +#endif + + timeout_list_lock(&s); + + /* + * First we prepare the now timeout so that we can return right + * after the insertion in the queue (makes the code simpler). + */ + + /* If this timeout was already on a queue we remove it. */ + if (new->to_flags & TIMEOUT_ONQUEUE) + TAILQ_REMOVE(&timeout_todo, to, to_list); + else + new->to_flags |= TIMEOUT_ONQUEUE; + /* Initialize the time here, it won't change. */ + new->to_time = to_ticks + ticks; + + /* + * Walk the list of pending timeouts and find an entry which + * will timeout after we do, insert the new timeout there. + */ + TAILQ_FOREACH(to, &timeout_todo, to_list) { + if (to->to_time - ticks >= to_ticks) { + TAILQ_INSERT_BEFORE(to, new, to_list); + goto out; + } + } + + /* We can only get here if we're the last (or only) entry */ + TAILQ_INSERT_TAIL(&timeout_todo, new, to_list); +out: + timeout_list_unlock(s); +} + +void +timeout_del(to) + struct timeout *to; +{ + int s; + + timeout_list_lock(&s); + if (to->to_flags & TIMEOUT_ONQUEUE) { + TAILQ_REMOVE(&timeout_todo, to, to_list); + to->to_flags &= ~TIMEOUT_ONQUEUE; + } + timeout_list_unlock(s); +} + +/* + * This is called from hardclock() once every tick. + * We return !0 if we need to schedule a softclock. + * + * We don't need locking in here. + */ +int +timeout_hardclock_update() +{ + return (TAILQ_FIRST(&timeout_todo)->to_time - ticks <= 0); +} + +void +softclock() +{ + int s; + struct timeout *to; + void (*fn) __P((void *)); + void *arg; + + timeout_list_lock(&s); + while ((to = TAILQ_FIRST(&timeout_todo)) != NULL && + to->to_time - ticks <= 0) { + + TAILQ_REMOVE(&timeout_todo, to, to_list); + to->to_flags &= ~TIMEOUT_ONQUEUE; + + fn = to->to_func; + arg = to->to_arg; + + if (to->to_flags & TIMEOUT_STATIC) + TAILQ_INSERT_HEAD(&timeout_static, to, to_list); + timeout_list_unlock(s); + fn(arg); + timeout_list_lock(&s); + } + timeout_list_unlock(s); +} + +/* + * Legacy interfaces. timeout() and untimeout() + * + * Kill those when everything is converted. They are slow and use the + * static pool (which causes (potential and real) problems). + */ + +void +timeout(fn, arg, to_ticks) + void (*fn) __P((void *)); + void *arg; + int to_ticks; +{ + struct timeout *to; + int s; + + if (to_ticks <= 0) + to_ticks = 1; + + /* + * Get a timeout struct from the static list. + */ + timeout_list_lock(&s); + + to = TAILQ_FIRST(&timeout_static); + if (to == NULL) + panic("timeout table full"); + TAILQ_REMOVE(&timeout_static, to, to_list); + + timeout_list_unlock(s); + + timeout_set(to, fn, arg); + to->to_flags = TIMEOUT_STATIC; + timeout_add(to, to_ticks); +} + +void +untimeout(fn, arg) + void (*fn) __P((void *)); + void *arg; +{ + int s; + struct timeout *to; + + timeout_list_lock(&s); + TAILQ_FOREACH(to, &timeout_todo, to_list) { + if (to->to_func == fn && to->to_arg == arg) { +#ifdef DIAGNOSTIC + if ((to->to_flags & TIMEOUT_ONQUEUE) == 0) + panic("untimeout: not TIMEOUT_ONQUEUE"); + if ((to->to_flags & TIMEOUT_STATIC) == 0) + panic("untimeout: not static"); +#endif + TAILQ_REMOVE(&timeout_todo, to, to_list); + to->to_flags &= ~TIMEOUT_ONQUEUE; + /* return it to the static pool */ + TAILQ_INSERT_HEAD(&timeout_static, to, to_list); + break; + } + } + timeout_list_unlock(s); +} + +#ifdef DDB +void +db_show_callout(addr, haddr, count, modif) + db_expr_t addr; + int haddr; + db_expr_t count; + char *modif; +{ + struct timeout *to; + int s; + db_expr_t offset; + char *name; + + db_printf("ticks now: %d\n", ticks); + db_printf(" ticks arg func\n"); + + timeout_list_lock(&s); + + TAILQ_FOREACH(to, &timeout_todo, to_list) { + db_find_sym_and_offset((db_addr_t)to->to_func, &name, &offset); + + name = name ? name : "?"; + + db_printf("%9d %8x %s\n", to->to_time, to->to_arg, name); + } + + timeout_list_unlock(s); + +} +#endif diff --git a/sys/sys/callout.h b/sys/sys/callout.h deleted file mode 100644 index b7b2cce66f0..00000000000 --- a/sys/sys/callout.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $OpenBSD: callout.h,v 1.2 1996/03/03 12:11:22 niklas Exp $ */ -/* $NetBSD: callout.h,v 1.10 1995/03/26 20:23:56 jtc Exp $ */ - -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)callout.h 8.2 (Berkeley) 1/21/94 - */ - -struct callout { - struct callout *c_next; /* next callout in queue */ - void *c_arg; /* function argument */ - void (*c_func) __P((void *)); /* function to call */ - int c_time; /* ticks to the event */ -}; - -#ifdef _KERNEL -struct callout *callfree, *callout, calltodo; -int ncallout; -#endif diff --git a/sys/sys/timeout.h b/sys/sys/timeout.h new file mode 100644 index 00000000000..9b3364dd2b3 --- /dev/null +++ b/sys/sys/timeout.h @@ -0,0 +1,94 @@ +/* $OpenBSD: timeout.h,v 1.1 2000/03/23 09:59:57 art Exp $ */ +/* + * Copyright (c) 2000 Artur Grabowski + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +/* + * Interface for handling time driven events in the kernel. + * + * The basic component of this API is the struct timeout. The user should + * touch the internals of this structure, but it's the users responsibility + * to allocate and deallocate timeouts. + * + * Ther functions used to manipulate timeouts are: + * - timeout_set(timeout, function, argument) + * Initializes a timeout struct to call the function with the argument. + * A timeout only needs to be initialized once. + * - timeout_add(timeout, ticks) + * Schedule this timeout to run in "ticks" ticks (there are hz ticks in + * one second). You may not touch the timeout with timeout_set once the + * timeout is scheduled. A second call to timeout_add with an already + * scheduled timeout will cause the old timeout to be canceled and the + * new will be scheduled. + * - timeout_del(timeout) + * Remove the timeout from the timeout queue. It's legal to remove + * a timeout that has already happened. + * + * These functions may be called in interrupt context (anything below splhigh). + * + * XXX - the old timeout()/untimeout() API is kept for compatibility, you may + * not use the new API if there is a risk that the same function/argument + * pairs are mixed in the new and old API. + */ + +struct timeout { + TAILQ_ENTRY(timeout) to_list; /* timeout queue */ + void (*to_func) __P((void *)); /* function to call */ + void *to_arg; /* function argument */ + int to_time; /* ticks on event */ + int to_flags; /* misc flags */ +}; + +/* + * flags in the to_flags field. + */ +#define TIMEOUT_STATIC 1 /* allocated from static pool */ +#define TIMEOUT_ONQUEUE 2 /* timeout is on the todo queue */ + +void timeout_set __P((struct timeout *, void (*)(void *), void *)); +void timeout_add __P((struct timeout *, int)); +void timeout_del __P((struct timeout *)); + +/* + * timeout_init - called by the machine dependent code to initialize a static + * list of preallocated timeout structures. + */ +void timeout_init __P((void)); + +/* + * called once every hardclock. returns non-zero if we need to schedule a + * softclock. + */ +int timeout_hardclock_update __P((void)); + +/* + * XXX - this should go away. + */ +extern int ntimeout; +extern struct timeout *timeouts;