Thu Dec 15 03:42:33 2011 UTC ()
Improve usermode timecounter. It's unreasonable to assume that we'll get
100 "SIGALRM" per second with an ITIMER_REAL at 100Hz on a HZ=100 host as
the timer may expire before a pending signal has been delivered.

Instead of setitimer, use timer_create + timer_settime and from our
intr handler use timer_getoverrun to determine how many ticks we have
missed.


(jmcneill)
diff -r1.22 -r1.23 src/sys/arch/usermode/dev/clock.c
diff -r1.54 -r1.55 src/sys/arch/usermode/dev/cpu.c
diff -r1.40 -r1.41 src/sys/arch/usermode/include/thunk.h
diff -r1.46 -r1.47 src/sys/arch/usermode/usermode/thunk.c

cvs diff -r1.22 -r1.23 src/sys/arch/usermode/dev/clock.c (expand / switch to unified diff)

--- src/sys/arch/usermode/dev/clock.c 2011/12/13 22:22:08 1.22
+++ src/sys/arch/usermode/dev/clock.c 2011/12/15 03:42:32 1.23
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: clock.c,v 1.22 2011/12/13 22:22:08 jmcneill Exp $ */ 1/* $NetBSD: clock.c,v 1.23 2011/12/15 03:42:32 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -16,128 +16,132 @@ @@ -16,128 +16,132 @@
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
 29#include "opt_hz.h"
 30
29#include <sys/cdefs.h> 31#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.22 2011/12/13 22:22:08 jmcneill Exp $"); 32__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.23 2011/12/15 03:42:32 jmcneill Exp $");
31 33
32#include <sys/param.h> 34#include <sys/param.h>
33#include <sys/proc.h> 35#include <sys/proc.h>
34#include <sys/systm.h> 36#include <sys/systm.h>
35#include <sys/device.h> 37#include <sys/device.h>
36#include <sys/lwp.h> 38#include <sys/lwp.h>
37#include <sys/cpu.h> 39#include <sys/cpu.h>
38#include <sys/malloc.h> 40#include <sys/malloc.h>
39#include <sys/timetc.h> 41#include <sys/timetc.h>
40#include <sys/time.h> 42#include <sys/time.h>
41 43
42#include <machine/pcb.h> 44#include <machine/pcb.h>
43#include <machine/mainbus.h> 45#include <machine/mainbus.h>
44#include <machine/thunk.h> 46#include <machine/thunk.h>
45 47
46#include <dev/clock_subr.h> 48#include <dev/clock_subr.h>
47 49
48static int clock_match(device_t, cfdata_t, void *); 50static int clock_match(device_t, cfdata_t, void *);
49static void clock_attach(device_t, device_t, void *); 51static void clock_attach(device_t, device_t, void *);
50 52
51static void clock(void); 53static void clock(void);
52static void clock_signal(int sig, siginfo_t *info, void *ctx); 54static void clock_signal(int sig, siginfo_t *info, void *ctx);
53static unsigned int clock_getcounter(struct timecounter *); 55static unsigned int clock_getcounter(struct timecounter *);
54 56
55static int clock_todr_gettime(struct todr_chip_handle *, struct timeval *); 57static int clock_todr_gettime(struct todr_chip_handle *, struct timeval *);
56 58
57typedef struct clock_softc { 59struct clock_softc {
58 device_t sc_dev; 60 device_t sc_dev;
59 struct todr_chip_handle sc_todr; 61 struct todr_chip_handle sc_todr;
60} clock_softc_t; 62};
61 63
62static struct timecounter clock_timecounter = { 64static struct timecounter clock_timecounter = {
63 clock_getcounter, /* get_timecount */ 65 clock_getcounter, /* get_timecount */
64 0, /* no poll_pps */ 66 0, /* no poll_pps */
65 ~0u, /* counter_mask */ 67 ~0u, /* counter_mask */
66 1000000000ULL, /* frequency */ 68 1000000000ULL, /* frequency */
67 "CLOCK_MONOTONIC", /* name */ 69 "CLOCK_MONOTONIC", /* name */
68 -100, /* quality */ 70 -100, /* quality */
69 NULL, /* prev */ 71 NULL, /* prev */
70 NULL, /* next */ 72 NULL, /* next */
71}; 73};
72 74
73static struct clock_softc *clock_sc; 75timer_t clock_timerid;
74 
75 76
76 77CFATTACH_DECL_NEW(clock, sizeof(struct clock_softc),
77CFATTACH_DECL_NEW(clock, sizeof(clock_softc_t), 
78 clock_match, clock_attach, NULL, NULL); 78 clock_match, clock_attach, NULL, NULL);
79 79
80static int 80static int
81clock_match(device_t parent, cfdata_t match, void *opaque) 81clock_match(device_t parent, cfdata_t match, void *opaque)
82{ 82{
83 struct thunkbus_attach_args *taa = opaque; 83 struct thunkbus_attach_args *taa = opaque;
84 84
85 if (taa->taa_type != THUNKBUS_TYPE_CLOCK) 85 if (taa->taa_type != THUNKBUS_TYPE_CLOCK)
86 return 0; 86 return 0;
87 87
88 return 1; 88 return 1;
89} 89}
90 90
91static void 91static void
92clock_attach(device_t parent, device_t self, void *opaque) 92clock_attach(device_t parent, device_t self, void *opaque)
93{ 93{
94 static struct sigaction sa; 94 static struct sigaction sa;
95 clock_softc_t *sc = device_private(self); 95 struct clock_softc *sc = device_private(self);
96 long tcres; 
97 96
98 aprint_naive("\n"); 97 aprint_naive("\n");
99 aprint_normal("\n"); 98 aprint_normal("\n");
100 99
101 KASSERT(clock_sc == NULL); 
102 clock_sc = sc; 
103 
104 sc->sc_dev = self; 100 sc->sc_dev = self;
105 101
106 sc->sc_todr.todr_gettime = clock_todr_gettime; 102 sc->sc_todr.todr_gettime = clock_todr_gettime;
107 todr_attach(&sc->sc_todr); 103 todr_attach(&sc->sc_todr);
108 104
109 memset(&sa, 0, sizeof(sa)); 105 memset(&sa, 0, sizeof(sa));
110 thunk_sigemptyset(&sa.sa_mask); 106 thunk_sigemptyset(&sa.sa_mask);
111 sa.sa_sigaction = clock_signal; 107 sa.sa_sigaction = clock_signal;
112 sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; 108 sa.sa_flags = SA_RESTART | SA_ONSTACK;
113 if (thunk_sigaction(SIGALRM, &sa, NULL) == -1) 109 if (thunk_sigaction(SIGALRM, &sa, NULL) == -1)
114 panic("couldn't register SIGALRM handler : %d", 110 panic("couldn't register SIGALRM handler : %d",
115 thunk_geterrno()); 111 thunk_geterrno());
116 112
117 tcres = thunk_clock_getres_monotonic(); 113 clock_timerid = thunk_timer_attach();
118 if (tcres > 0) { 114
119 clock_timecounter.tc_quality = 1000; 115 clock_timecounter.tc_quality = 1000;
120 } 
121 tc_init(&clock_timecounter); 116 tc_init(&clock_timecounter);
122} 117}
123 118
124static void 119static void
125clock(void) 120clock_intr(void *priv)
126{ 121{
127 struct clockframe cf; 122 struct clockframe cf;
 123 int nticks = thunk_timer_getoverrun(clock_timerid) + 1;
 124
 125 while (nticks-- > 0) {
 126 hardclock(&cf);
 127 };
 128}
128 129
 130static void
 131clock(void)
 132{
129 curcpu()->ci_idepth++; 133 curcpu()->ci_idepth++;
130 spl_intr(IPL_SOFTCLOCK, (void (*)(void *)) hardclock, &cf); 134 spl_intr(IPL_SOFTCLOCK, clock_intr, NULL);
131 curcpu()->ci_idepth--; 135 curcpu()->ci_idepth--;
132} 136}
133 137
134static void 138static void
135clock_signal(int sig, siginfo_t *info, void *ctx) 139clock_signal(int sig, siginfo_t *info, void *ctx)
136{ 140{
137#if 0 141#if 0
138 ucontext_t *uct = ctx; 142 ucontext_t *uct = ctx;
139 struct lwp *l; 143 struct lwp *l;
140 struct pcb *pcb; 144 struct pcb *pcb;
141 145
142 l = curlwp; 146 l = curlwp;
143 pcb = lwp_getpcb(l); 147 pcb = lwp_getpcb(l);

cvs diff -r1.54 -r1.55 src/sys/arch/usermode/dev/cpu.c (expand / switch to unified diff)

--- src/sys/arch/usermode/dev/cpu.c 2011/12/15 02:09:15 1.54
+++ src/sys/arch/usermode/dev/cpu.c 2011/12/15 03:42:32 1.55
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cpu.c,v 1.54 2011/12/15 02:09:15 jmcneill Exp $ */ 1/* $NetBSD: cpu.c,v 1.55 2011/12/15 03:42:32 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include "opt_cpu.h" 29#include "opt_cpu.h"
30#include "opt_hz.h" 30#include "opt_hz.h"
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.54 2011/12/15 02:09:15 jmcneill Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.55 2011/12/15 03:42:32 jmcneill Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/conf.h> 36#include <sys/conf.h>
37#include <sys/proc.h> 37#include <sys/proc.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/device.h> 39#include <sys/device.h>
40#include <sys/reboot.h> 40#include <sys/reboot.h>
41#include <sys/lwp.h> 41#include <sys/lwp.h>
42#include <sys/cpu.h> 42#include <sys/cpu.h>
43#include <sys/mbuf.h> 43#include <sys/mbuf.h>
44#include <sys/msgbuf.h> 44#include <sys/msgbuf.h>
45#include <sys/kmem.h> 45#include <sys/kmem.h>
46 46
@@ -354,32 +354,29 @@ cpu_lwp_fork(struct lwp *l1, struct lwp  @@ -354,32 +354,29 @@ cpu_lwp_fork(struct lwp *l1, struct lwp
354 354
355 /* set up the ucontext for the pagefault */ 355 /* set up the ucontext for the pagefault */
356 pcb2->pcb_pagefault_ucp.uc_stack.ss_sp = stack_pagefault_ucp; 356 pcb2->pcb_pagefault_ucp.uc_stack.ss_sp = stack_pagefault_ucp;
357 pcb2->pcb_pagefault_ucp.uc_stack.ss_size = stacksize; 357 pcb2->pcb_pagefault_ucp.uc_stack.ss_size = stacksize;
358 pcb2->pcb_pagefault_ucp.uc_flags = _UC_STACK | _UC_CPU; 358 pcb2->pcb_pagefault_ucp.uc_flags = _UC_STACK | _UC_CPU;
359 pcb2->pcb_pagefault_ucp.uc_link = &pcb2->pcb_trapret_ucp; 359 pcb2->pcb_pagefault_ucp.uc_link = &pcb2->pcb_trapret_ucp;
360 thunk_makecontext(&pcb2->pcb_pagefault_ucp, (void (*)(void)) pagefault, 360 thunk_makecontext(&pcb2->pcb_pagefault_ucp, (void (*)(void)) pagefault,
361 0, NULL, NULL, NULL); 361 0, NULL, NULL, NULL);
362} 362}
363 363
364void 364void
365cpu_initclocks(void) 365cpu_initclocks(void)
366{ 366{
367 struct thunk_itimerval itimer; 367 extern timer_t clock_timerid;
368 368
369 itimer.it_interval.tv_sec = 0; 369 thunk_timer_start(clock_timerid, HZ);
370 itimer.it_interval.tv_usec = 1000000 / HZ; 
371 itimer.it_value = itimer.it_interval; 
372 thunk_setitimer(ITIMER_REAL, &itimer, NULL); 
373} 370}
374 371
375void 372void
376cpu_startup(void) 373cpu_startup(void)
377{ 374{
378 size_t stacksize, msgbufsize = 32 * 1024; 375 size_t stacksize, msgbufsize = 32 * 1024;
379 void *stack_pagefault_ucp; 376 void *stack_pagefault_ucp;
380 377
381 um_msgbuf = kmem_zalloc(msgbufsize, KM_SLEEP); 378 um_msgbuf = kmem_zalloc(msgbufsize, KM_SLEEP);
382 if (um_msgbuf == NULL) 379 if (um_msgbuf == NULL)
383 panic("couldn't allocate msgbuf"); 380 panic("couldn't allocate msgbuf");
384 initmsgbuf(um_msgbuf, msgbufsize); 381 initmsgbuf(um_msgbuf, msgbufsize);
385 382

cvs diff -r1.40 -r1.41 src/sys/arch/usermode/include/thunk.h (expand / switch to unified diff)

--- src/sys/arch/usermode/include/thunk.h 2011/12/15 01:30:04 1.40
+++ src/sys/arch/usermode/include/thunk.h 2011/12/15 03:42:32 1.41
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: thunk.h,v 1.40 2011/12/15 01:30:04 jmcneill Exp $ */ 1/* $NetBSD: thunk.h,v 1.41 2011/12/15 03:42:32 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -67,26 +67,30 @@ struct thunk_termios { @@ -67,26 +67,30 @@ struct thunk_termios {
67#define THUNK_PROT_WRITE 0x02 67#define THUNK_PROT_WRITE 0x02
68#define THUNK_PROT_EXEC 0x04 68#define THUNK_PROT_EXEC 0x04
69 69
70struct aiocb; 70struct aiocb;
71 71
72void dprintf_debug(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2))); 72void dprintf_debug(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2)));
73 73
74int thunk_setitimer(int, const struct thunk_itimerval *, struct thunk_itimerval *); 74int thunk_setitimer(int, const struct thunk_itimerval *, struct thunk_itimerval *);
75int thunk_gettimeofday(struct thunk_timeval *, void *); 75int thunk_gettimeofday(struct thunk_timeval *, void *);
76unsigned int thunk_getcounter(void); 76unsigned int thunk_getcounter(void);
77long thunk_clock_getres_monotonic(void); 77long thunk_clock_getres_monotonic(void);
78int thunk_usleep(useconds_t); 78int thunk_usleep(useconds_t);
79 79
 80timer_t thunk_timer_attach(void);
 81int thunk_timer_start(timer_t, int);
 82int thunk_timer_getoverrun(timer_t);
 83
80void thunk_exit(int); 84void thunk_exit(int);
81void thunk_abort(void); 85void thunk_abort(void);
82 86
83int thunk_geterrno(void); 87int thunk_geterrno(void);
84void thunk_seterrno(int err); 88void thunk_seterrno(int err);
85 89
86int thunk_getcontext(ucontext_t *); 90int thunk_getcontext(ucontext_t *);
87int thunk_setcontext(const ucontext_t *); 91int thunk_setcontext(const ucontext_t *);
88void thunk_makecontext(ucontext_t *ucp, void (*func)(void),  92void thunk_makecontext(ucontext_t *ucp, void (*func)(void),
89 int nargs, void *arg1, void *arg2, void *arg3); 93 int nargs, void *arg1, void *arg2, void *arg3);
90int thunk_swapcontext(ucontext_t *, ucontext_t *); 94int thunk_swapcontext(ucontext_t *, ucontext_t *);
91 95
92int thunk_tcgetattr(int, struct thunk_termios *); 96int thunk_tcgetattr(int, struct thunk_termios *);

cvs diff -r1.46 -r1.47 src/sys/arch/usermode/usermode/thunk.c (expand / switch to unified diff)

--- src/sys/arch/usermode/usermode/thunk.c 2011/12/15 01:30:04 1.46
+++ src/sys/arch/usermode/usermode/thunk.c 2011/12/15 03:42:33 1.47
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: thunk.c,v 1.46 2011/12/15 01:30:04 jmcneill Exp $ */ 1/* $NetBSD: thunk.c,v 1.47 2011/12/15 03:42:33 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -18,27 +18,27 @@ @@ -18,27 +18,27 @@
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30#ifdef __NetBSD__ 30#ifdef __NetBSD__
31__RCSID("$NetBSD: thunk.c,v 1.46 2011/12/15 01:30:04 jmcneill Exp $"); 31__RCSID("$NetBSD: thunk.c,v 1.47 2011/12/15 03:42:33 jmcneill Exp $");
32#endif 32#endif
33 33
34#include <sys/types.h> 34#include <sys/types.h>
35#include <sys/mman.h> 35#include <sys/mman.h>
36#include <sys/reboot.h> 36#include <sys/reboot.h>
37#include <sys/poll.h> 37#include <sys/poll.h>
38#include <machine/vmparam.h> 38#include <machine/vmparam.h>
39 39
40#include <aio.h> 40#include <aio.h>
41#include <assert.h> 41#include <assert.h>
42#include <errno.h> 42#include <errno.h>
43#include <fcntl.h> 43#include <fcntl.h>
44#include <sched.h> 44#include <sched.h>
@@ -219,26 +219,59 @@ thunk_getcounter(void) @@ -219,26 +219,59 @@ thunk_getcounter(void)
219long 219long
220thunk_clock_getres_monotonic(void) 220thunk_clock_getres_monotonic(void)
221{ 221{
222 struct timespec res; 222 struct timespec res;
223 int error; 223 int error;
224 224
225 error = clock_getres(CLOCK_MONOTONIC, &res); 225 error = clock_getres(CLOCK_MONOTONIC, &res);
226 if (error) 226 if (error)
227 return -1; 227 return -1;
228 228
229 return (long)(res.tv_sec * 1000000000ULL + res.tv_nsec); 229 return (long)(res.tv_sec * 1000000000ULL + res.tv_nsec);
230} 230}
231 231
 232timer_t
 233thunk_timer_attach(void)
 234{
 235 timer_t timerid;
 236 int error;
 237
 238 error = timer_create(CLOCK_MONOTONIC, NULL, &timerid);
 239 if (error) {
 240 perror("timer_create CLOCK_MONOTONIC");
 241 abort();
 242 }
 243
 244 return timerid;
 245}
 246
 247int
 248thunk_timer_start(timer_t timerid, int freq)
 249{
 250 struct itimerspec tim;
 251
 252 tim.it_interval.tv_sec = 0;
 253 tim.it_interval.tv_nsec = 1000000000 / freq;
 254 tim.it_value = tim.it_interval;
 255
 256 return timer_settime(timerid, TIMER_RELTIME, &tim, NULL);
 257}
 258
 259int
 260thunk_timer_getoverrun(timer_t timerid)
 261{
 262 return timer_getoverrun(timerid);
 263}
 264
232int 265int
233thunk_usleep(useconds_t microseconds) 266thunk_usleep(useconds_t microseconds)
234{ 267{
235 return usleep(microseconds); 268 return usleep(microseconds);
236} 269}
237 270
238void 271void
239thunk_exit(int status) 272thunk_exit(int status)
240{ 273{
241 return exit(status); 274 return exit(status);
242} 275}
243 276
244void 277void