1 /* -----------------------------------------------------------------------------
2 * $Id: Itimer.c,v 1.32 2003/02/22 04:51:50 sof Exp $
4 * (c) The GHC Team, 1995-1999
6 * Interval timer for profiling and pre-emptive scheduling.
8 * ---------------------------------------------------------------------------*/
11 * The interval timer is used for profiling and for context switching in the
12 * threaded build. Though POSIX 1003.1b includes a standard interface for
13 * such things, no one really seems to be implementing them yet. Even
14 * Solaris 2.3 only seems to provide support for @CLOCK_REAL@, whereas we're
15 * keen on getting access to @CLOCK_VIRTUAL@.
17 * Hence, we use the old-fashioned @setitimer@ that just about everyone seems
18 * to support. So much for standards.
21 #if !defined(mingw32_TARGET_OS) /* to the end */
25 #include "Proftimer.h"
28 /* As recommended in the autoconf manual */
29 # ifdef TIME_WITH_SYS_TIME
30 # include <sys/time.h>
33 # ifdef HAVE_SYS_TIME_H
34 # include <sys/time.h>
46 install_vtalrm_handler(void)
48 struct sigaction action;
50 action.sa_handler = handle_tick;
52 sigemptyset(&action.sa_mask);
55 return sigaction(SIGVTALRM, &action, NULL);
61 # ifndef HAVE_SETITIMER
62 /* fprintf(stderr, "No virtual timer on this system\n"); */
67 install_vtalrm_handler();
69 timestamp = getourtimeofday();
71 it.it_value.tv_sec = ms / 1000;
72 it.it_value.tv_usec = 1000 * (ms - (1000 * it.it_value.tv_sec));
73 it.it_interval = it.it_value;
74 return (setitimer(ITIMER_VIRTUAL, &it, NULL));
81 # ifndef HAVE_SETITIMER
82 /* fprintf(stderr, "No virtual timer on this system\n"); */
87 it.it_value.tv_sec = 0;
88 it.it_value.tv_usec = 0;
89 it.it_interval = it.it_value;
90 return (setitimer(ITIMER_VIRTUAL, &it, NULL));
95 /* This is a potential POSIX version */
100 struct itimerspec it;
103 timestamp = getourtimeofday();
105 se.sigev_notify = SIGEV_SIGNAL;
106 se.sigev_signo = SIGVTALRM;
107 se.sigev_value.sival_int = SIGVTALRM;
108 if (timer_create(CLOCK_VIRTUAL, &se, &tid)) {
109 barf("can't create virtual timer");
111 it.it_value.tv_sec = ms / 1000;
112 it.it_value.tv_nsec = 1000000 * (ms - 1000 * it.it_value.tv_sec);
113 it.it_interval = it.it_value;
114 return timer_settime(tid, TIMER_RELTIME, &it, NULL);
121 struct itimerspec it;
124 timestamp = getourtimeofday();
126 se.sigev_notify = SIGEV_SIGNAL;
127 se.sigev_signo = SIGVTALRM;
128 se.sigev_value.sival_int = SIGVTALRM;
129 if (timer_create(CLOCK_VIRTUAL, &se, &tid)) {
130 barf("can't create virtual timer");
132 it.it_value.tv_sec = 0;
133 it.it_value.tv_nsec = 0;
134 it.it_interval = it.it_value;
135 return timer_settime(tid, TIMER_RELTIME, &it, NULL);
140 block_vtalrm_signal(void)
144 sigemptyset(&signals);
145 sigaddset(&signals, SIGVTALRM);
147 (void) sigprocmask(SIG_BLOCK, &signals, NULL);
151 unblock_vtalrm_signal(void)
155 sigemptyset(&signals);
156 sigaddset(&signals, SIGVTALRM);
158 (void) sigprocmask(SIG_UNBLOCK, &signals, NULL);
161 /* gettimeofday() takes around 1us on our 500MHz PIII. Since we're
162 * only calling it 50 times/s, it shouldn't have any great impact.
165 getourtimeofday(void)
168 gettimeofday(&tv, (struct timezone *) NULL);
169 return (tv.tv_sec * TICK_FREQUENCY +
170 tv.tv_usec * TICK_FREQUENCY / 1000000);
173 #endif /* !mingw32_TARGET_OS */