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.diff -r1.22 -r1.23 src/sys/arch/usermode/dev/clock.c
(jmcneill)
--- 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 | |||
48 | static int clock_match(device_t, cfdata_t, void *); | 50 | static int clock_match(device_t, cfdata_t, void *); | |
49 | static void clock_attach(device_t, device_t, void *); | 51 | static void clock_attach(device_t, device_t, void *); | |
50 | 52 | |||
51 | static void clock(void); | 53 | static void clock(void); | |
52 | static void clock_signal(int sig, siginfo_t *info, void *ctx); | 54 | static void clock_signal(int sig, siginfo_t *info, void *ctx); | |
53 | static unsigned int clock_getcounter(struct timecounter *); | 55 | static unsigned int clock_getcounter(struct timecounter *); | |
54 | 56 | |||
55 | static int clock_todr_gettime(struct todr_chip_handle *, struct timeval *); | 57 | static int clock_todr_gettime(struct todr_chip_handle *, struct timeval *); | |
56 | 58 | |||
57 | typedef struct clock_softc { | 59 | struct 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 | |||
62 | static struct timecounter clock_timecounter = { | 64 | static 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 | |||
73 | static struct clock_softc *clock_sc; | 75 | timer_t clock_timerid; | |
74 | ||||
75 | 76 | |||
76 | 77 | CFATTACH_DECL_NEW(clock, sizeof(struct clock_softc), | ||
77 | CFATTACH_DECL_NEW(clock, sizeof(clock_softc_t), | |||
78 | clock_match, clock_attach, NULL, NULL); | 78 | clock_match, clock_attach, NULL, NULL); | |
79 | 79 | |||
80 | static int | 80 | static int | |
81 | clock_match(device_t parent, cfdata_t match, void *opaque) | 81 | clock_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 | |||
91 | static void | 91 | static void | |
92 | clock_attach(device_t parent, device_t self, void *opaque) | 92 | clock_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 | |||
124 | static void | 119 | static void | |
125 | clock(void) | 120 | clock_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 | |||
130 | static void | |||
131 | clock(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 | |||
134 | static void | 138 | static void | |
135 | clock_signal(int sig, siginfo_t *info, void *ctx) | 139 | clock_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); |
--- 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 | |||
364 | void | 364 | void | |
365 | cpu_initclocks(void) | 365 | cpu_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 | |||
375 | void | 372 | void | |
376 | cpu_startup(void) | 373 | cpu_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 |
--- 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 | |||
70 | struct aiocb; | 70 | struct aiocb; | |
71 | 71 | |||
72 | void dprintf_debug(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2))); | 72 | void dprintf_debug(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2))); | |
73 | 73 | |||
74 | int thunk_setitimer(int, const struct thunk_itimerval *, struct thunk_itimerval *); | 74 | int thunk_setitimer(int, const struct thunk_itimerval *, struct thunk_itimerval *); | |
75 | int thunk_gettimeofday(struct thunk_timeval *, void *); | 75 | int thunk_gettimeofday(struct thunk_timeval *, void *); | |
76 | unsigned int thunk_getcounter(void); | 76 | unsigned int thunk_getcounter(void); | |
77 | long thunk_clock_getres_monotonic(void); | 77 | long thunk_clock_getres_monotonic(void); | |
78 | int thunk_usleep(useconds_t); | 78 | int thunk_usleep(useconds_t); | |
79 | 79 | |||
80 | timer_t thunk_timer_attach(void); | |||
81 | int thunk_timer_start(timer_t, int); | |||
82 | int thunk_timer_getoverrun(timer_t); | |||
83 | ||||
80 | void thunk_exit(int); | 84 | void thunk_exit(int); | |
81 | void thunk_abort(void); | 85 | void thunk_abort(void); | |
82 | 86 | |||
83 | int thunk_geterrno(void); | 87 | int thunk_geterrno(void); | |
84 | void thunk_seterrno(int err); | 88 | void thunk_seterrno(int err); | |
85 | 89 | |||
86 | int thunk_getcontext(ucontext_t *); | 90 | int thunk_getcontext(ucontext_t *); | |
87 | int thunk_setcontext(const ucontext_t *); | 91 | int thunk_setcontext(const ucontext_t *); | |
88 | void thunk_makecontext(ucontext_t *ucp, void (*func)(void), | 92 | void 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); | |
90 | int thunk_swapcontext(ucontext_t *, ucontext_t *); | 94 | int thunk_swapcontext(ucontext_t *, ucontext_t *); | |
91 | 95 | |||
92 | int thunk_tcgetattr(int, struct thunk_termios *); | 96 | int thunk_tcgetattr(int, struct thunk_termios *); |
--- 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) | |||
219 | long | 219 | long | |
220 | thunk_clock_getres_monotonic(void) | 220 | thunk_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 | |||
232 | timer_t | |||
233 | thunk_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 | ||||
247 | int | |||
248 | thunk_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 | ||||
259 | int | |||
260 | thunk_timer_getoverrun(timer_t timerid) | |||
261 | { | |||
262 | return timer_getoverrun(timerid); | |||
263 | } | |||
264 | ||||
232 | int | 265 | int | |
233 | thunk_usleep(useconds_t microseconds) | 266 | thunk_usleep(useconds_t microseconds) | |
234 | { | 267 | { | |
235 | return usleep(microseconds); | 268 | return usleep(microseconds); | |
236 | } | 269 | } | |
237 | 270 | |||
238 | void | 271 | void | |
239 | thunk_exit(int status) | 272 | thunk_exit(int status) | |
240 | { | 273 | { | |
241 | return exit(status); | 274 | return exit(status); | |
242 | } | 275 | } | |
243 | 276 | |||
244 | void | 277 | void |