4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Copyright (c) 2015, Joyent Inc. All rights reserved.
31 #include <sys/timer.h>
32 #include <sys/systm.h>
33 #include <sys/param.h>
35 #include <sys/debug.h>
37 static clock_backend_t clock_realtime
;
40 clock_realtime_settime(timespec_t
*ts
)
42 mutex_enter(&tod_lock
);
45 mutex_exit(&tod_lock
);
51 * We normally won't execute this path; libc will see CLOCK_REALTIME and
52 * fast trap directly into gethrestime().
55 clock_realtime_gettime(timespec_t
*ts
)
63 clock_realtime_getres(timespec_t
*ts
)
66 ts
->tv_nsec
= nsec_per_tick
;
72 clock_realtime_fire(void *arg
)
75 itimer_t
*it
= (itimer_t
*)arg
;
76 timeout_id_t
*tidp
= it
->it_arg
;
77 timespec_t now
, interval2nth
;
78 timespec_t
*val
, *interval
;
79 proc_t
*p
= it
->it_proc
;
83 * First call into the timer subsystem to get the signal going.
86 val
= &it
->it_itime
.it_value
;
87 interval
= &it
->it_itime
.it_interval
;
89 mutex_enter(&p
->p_lock
);
91 if (!timerspecisset(interval
)) {
96 * If this is an interval timer, we need to determine a time
97 * at which to go off in the future. In the event that the
98 * clock has been adjusted, we want to find our new interval
99 * relatively quickly (and we don't want to simply take the
100 * current time and add the interval; it would lead to
101 * unnecessary jitter in the timer). We therefore take steps
102 * from the time we expected to go off into the future;
103 * if the resulting time is still in the past, then we double
104 * our step size and continue. Once the resulting time is
105 * in the future, we subtract our last step, change our step
106 * size back to the original interval, and repeat until we
107 * can get to a valid, future timeout in one step. This
108 * assures that we will get the minimum, valid timeout
109 * value in a reasonable amount of wall time.
112 interval2nth
= *interval
;
115 * We put a floor on interval2nth at nsec_per_tick.
116 * If we don't do this, and the interval is shorter
117 * than the time required to run through this logic,
118 * we'll never catch up to the current time (which
119 * is a moving target).
121 if (interval2nth
.tv_sec
== 0 &&
122 interval2nth
.tv_nsec
< nsec_per_tick
)
123 interval2nth
.tv_nsec
= nsec_per_tick
;
125 for (cnt2nth
= 0; ; cnt2nth
++) {
126 timespecadd(val
, &interval2nth
);
128 if (timerspeccmp(val
, &now
) > 0)
130 timespecadd(&interval2nth
, &interval2nth
);
134 timespecsub(val
, &interval2nth
);
137 ticks
= timespectohz(val
, now
);
138 *tidp
= realtime_timeout(clock_realtime_fire
, it
, ticks
);
140 mutex_exit(&p
->p_lock
);
144 * See the block comment in clock_realtime_timer_settime(), below.
147 clock_realtime_fire_first(void *arg
)
149 itimer_t
*it
= (itimer_t
*)arg
;
151 timespec_t
*val
= &it
->it_itime
.it_value
;
152 timeout_id_t
*tidp
= it
->it_arg
;
153 proc_t
*p
= it
->it_proc
;
157 if ((val
->tv_sec
> now
.tv_sec
) ||
158 (val
->tv_sec
== now
.tv_sec
&& val
->tv_nsec
> now
.tv_nsec
)) {
160 * We went off too early. We'll go to bed for one more tick,
161 * regardless of the actual difference; if the difference
162 * is greater than one tick, then we must have seen an adjtime.
164 mutex_enter(&p
->p_lock
);
165 *tidp
= realtime_timeout(clock_realtime_fire
, it
, 1);
166 mutex_exit(&p
->p_lock
);
170 clock_realtime_fire(arg
);
175 clock_realtime_timer_create(itimer_t
*it
, void (*fire
)(itimer_t
*))
177 it
->it_arg
= kmem_zalloc(sizeof (timeout_id_t
), KM_SLEEP
);
184 clock_realtime_timer_settime(itimer_t
*it
, int flags
,
185 const struct itimerspec
*when
)
187 timeout_id_t tid
, *tidp
= it
->it_arg
;
189 proc_t
*p
= it
->it_proc
;
194 mutex_enter(&p
->p_lock
);
196 while ((tid
= *tidp
) != 0) {
198 mutex_exit(&p
->p_lock
);
199 (void) untimeout(tid
);
200 mutex_enter(&p
->p_lock
);
204 * The timeout has been removed; it is safe to update it_itime.
206 it
->it_itime
= *when
;
208 if (timerspecisset(&it
->it_itime
.it_value
)) {
209 if (!(flags
& TIMER_ABSTIME
))
210 timespecadd(&it
->it_itime
.it_value
, &now
);
212 ticks
= timespectohz(&it
->it_itime
.it_value
, now
);
215 * gethrestime() works by reading hres_last_tick, and
216 * adding in the current time delta (that is, the amount of
217 * time which has passed since the last tick of the clock).
218 * As a result, the time returned in "now", above, represents
219 * an hrestime sometime after lbolt was last bumped.
220 * The "ticks" we've been returned from timespectohz(), then,
221 * reflects the number of times the clock will tick between
222 * "now" and our desired execution time.
224 * However, when we call into realtime_timeout(), below,
225 * "ticks" will be interpreted against lbolt. That is,
226 * if we specify 1 tick, we will be registering a callout
227 * for the next tick of the clock -- which may occur in
228 * less than (1 / hz) seconds. More generally, we are
229 * registering a callout for "ticks" of the clock, which
230 * may be less than ("ticks" / hz) seconds (but not more than
231 * (1 / hz) seconds less). In other words, we may go off
234 * This is only a problem for the initial firing of the
235 * timer, so we have the initial firing go through a
236 * different handler which implements a nanosleep-esque
239 *tidp
= realtime_timeout(clock_realtime_fire_first
, it
, ticks
);
242 mutex_exit(&p
->p_lock
);
248 clock_realtime_timer_gettime(itimer_t
*it
, struct itimerspec
*when
)
251 proc_t
*p
= it
->it_proc
;
254 * We always keep it_itime up to date, so we just need to snapshot
255 * the time under p_lock, and clean it up.
257 mutex_enter(&p
->p_lock
);
259 *when
= it
->it_itime
;
260 mutex_exit(&p
->p_lock
);
262 if (!timerspecisset(&when
->it_value
))
265 if (timerspeccmp(&when
->it_value
, &now
) < 0) {
267 * If this timer should have already gone off, set it_value
270 timerspecclear(&when
->it_value
);
272 timespecsub(&when
->it_value
, &now
);
279 clock_realtime_timer_delete(itimer_t
*it
)
281 proc_t
*p
= it
->it_proc
;
282 timeout_id_t tid
, *tidp
= it
->it_arg
;
284 mutex_enter(&p
->p_lock
);
286 while ((tid
= *tidp
) != 0) {
288 mutex_exit(&p
->p_lock
);
289 (void) untimeout(tid
);
290 mutex_enter(&p
->p_lock
);
293 mutex_exit(&p
->p_lock
);
295 kmem_free(tidp
, sizeof (timeout_id_t
));
302 clock_realtime_timer_lwpbind(itimer_t
*it
)
307 clock_realtime_init()
309 clock_backend_t
*be
= &clock_realtime
;
310 struct sigevent
*ev
= &be
->clk_default
;
312 ev
->sigev_signo
= SIGALRM
;
313 ev
->sigev_notify
= SIGEV_SIGNAL
;
314 ev
->sigev_value
.sival_ptr
= NULL
;
316 be
->clk_clock_settime
= clock_realtime_settime
;
317 be
->clk_clock_gettime
= clock_realtime_gettime
;
318 be
->clk_clock_getres
= clock_realtime_getres
;
319 be
->clk_timer_gettime
= clock_realtime_timer_gettime
;
320 be
->clk_timer_settime
= clock_realtime_timer_settime
;
321 be
->clk_timer_delete
= clock_realtime_timer_delete
;
322 be
->clk_timer_lwpbind
= clock_realtime_timer_lwpbind
;
323 be
->clk_timer_create
= clock_realtime_timer_create
;
324 clock_add_backend(CLOCK_REALTIME
, &clock_realtime
);
326 * For binary compatibility with old statically linked
327 * applications, we make the behavior of __CLOCK_REALTIME0
328 * the same as CLOCK_REALTIME.
330 clock_add_backend(__CLOCK_REALTIME0
, &clock_realtime
);