1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2016 Joyent, Inc.
14 */
15
16 /*
17 * The illumos kernel provides two clock backends: CLOCK_REALTIME, the
18 * adjustable system wall clock; and CLOCK_HIGHRES, the monotonically
19 * increasing time source that is not subject to drift or adjustment. By
20 * contrast, the Linux kernel is furnished with an overabundance of narrowly
21 * differentiated clock types.
22 *
23 * Fortunately, most of the commonly used Linux clock types are either similar
24 * enough to the native clock backends that they can be directly mapped, or
25 * represent queries to the per-process and per-LWP microstate counters.
26 *
27 * CLOCK_BOOTTIME is identical to CLOCK_MONOTONIC, except that it takes into
28 * account time that the system is suspended. Since that is uninteresting to
29 * us, we treat it the same.
30 */
31
32 #include <sys/time.h>
33 #include <sys/systm.h>
34 #include <sys/cmn_err.h>
35 #include <sys/brand.h>
36 #include <sys/lx_brand.h>
37 #include <sys/lx_impl.h>
38 #include <lx_signum.h>
39
40 /*
41 * From "uts/common/os/timer.c":
42 */
43 extern int clock_settime(clockid_t, timespec_t *);
44 extern int clock_gettime(clockid_t, timespec_t *);
45 extern int clock_getres(clockid_t, timespec_t *);
46 extern int nanosleep(timespec_t *, timespec_t *);
66 int tz_dsttime; /* type of dst correction */
67 };
68
69 /*
70 * Use the native clock_* system call implementation, but with a translated
71 * clock identifier:
72 */
73 #define NATIVE(ntv_id) \
74 { ntv_id, clock_getres, clock_gettime, clock_settime }
75
76 /*
77 * This backend is not supported, so we provide an emulation handler:
78 */
79 #define EMUL(ntv_id) \
80 { ntv_id, lx_emul_clock_getres, lx_emul_clock_gettime, \
81 lx_emul_clock_settime }
82
83 static lx_clock_backend_t lx_clock_backends[] = {
84 NATIVE(CLOCK_REALTIME), /* LX_CLOCK_REALTIME */
85 NATIVE(CLOCK_HIGHRES), /* LX_CLOCK_MONOTONIC */
86 EMUL(CLOCK_PROCESS_CPUTIME_ID), /* LX_CLOCK_PROCESS_CPUTIME_ID */
87 EMUL(CLOCK_THREAD_CPUTIME_ID), /* LX_CLOCK_THREAD_CPUTIME_ID */
88 NATIVE(CLOCK_HIGHRES), /* LX_CLOCK_MONOTONIC_RAW */
89 NATIVE(CLOCK_REALTIME), /* LX_CLOCK_REALTIME_COARSE */
90 NATIVE(CLOCK_HIGHRES), /* LX_CLOCK_MONOTONIC_COARSE */
91 NATIVE(CLOCK_HIGHRES) /* LX_CLOCK_BOOTTIME */
92 };
93
94 #define LX_CLOCK_MAX \
95 (sizeof (lx_clock_backends) / sizeof (lx_clock_backends[0]))
96 #define LX_CLOCK_BACKEND(clk) (((clk) < LX_CLOCK_MAX && (clk) >= 0) ? \
97 &lx_clock_backends[(clk)] : NULL)
98
99 /*
100 * Linux defines the size of the sigevent structure to be 64 bytes. In order
101 * to meet that definition, the trailing union includes a member which pads it
102 * out to the desired length for the given architecture.
103 */
104 #define LX_SIGEV_PAD_SIZE ((64 - \
105 (sizeof (int) * 2 + sizeof (union sigval))) / sizeof (int))
106
107 typedef struct {
|
1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2020 Joyent, Inc.
14 */
15
16 /*
17 * The illumos kernel provides two clock backends: CLOCK_REALTIME, the
18 * adjustable system wall clock; and CLOCK_HIGHRES, the monotonically
19 * increasing time source that is not subject to drift or adjustment. By
20 * contrast, the Linux kernel is furnished with an overabundance of narrowly
21 * differentiated clock types.
22 *
23 * Fortunately, most of the commonly used Linux clock types are similar
24 * enough to the native clock backends that they can be directly mapped.
25 *
26 * Unfortunately, while CLOCK_{THREAD,PROCESS}_CPUTIME_ID are *somewhat*
27 * implemented in the main illumos kernel as itimers (see setitimer(2)), we
28 * would need to entirely bringup of CLOCK_{THREAD,PROCESS}_CPUTIME_ID to
29 * implement timer_create() and friends. For now, we opt to map it to
30 * CLOCK_HIGHRES for timer_create() and friends, but continue to emulate
31 * more-accurate queries to per-process or per-LWP microstate accounting for
32 * getres, gettime, or settime.
33 *
34 * CLOCK_BOOTTIME is identical to CLOCK_MONOTONIC, except that it takes into
35 * account time that the system is suspended. Since that is uninteresting to
36 * us, we treat it the same.
37 */
38
39 #include <sys/time.h>
40 #include <sys/systm.h>
41 #include <sys/cmn_err.h>
42 #include <sys/brand.h>
43 #include <sys/lx_brand.h>
44 #include <sys/lx_impl.h>
45 #include <lx_signum.h>
46
47 /*
48 * From "uts/common/os/timer.c":
49 */
50 extern int clock_settime(clockid_t, timespec_t *);
51 extern int clock_gettime(clockid_t, timespec_t *);
52 extern int clock_getres(clockid_t, timespec_t *);
53 extern int nanosleep(timespec_t *, timespec_t *);
73 int tz_dsttime; /* type of dst correction */
74 };
75
76 /*
77 * Use the native clock_* system call implementation, but with a translated
78 * clock identifier:
79 */
80 #define NATIVE(ntv_id) \
81 { ntv_id, clock_getres, clock_gettime, clock_settime }
82
83 /*
84 * This backend is not supported, so we provide an emulation handler:
85 */
86 #define EMUL(ntv_id) \
87 { ntv_id, lx_emul_clock_getres, lx_emul_clock_gettime, \
88 lx_emul_clock_settime }
89
90 static lx_clock_backend_t lx_clock_backends[] = {
91 NATIVE(CLOCK_REALTIME), /* LX_CLOCK_REALTIME */
92 NATIVE(CLOCK_HIGHRES), /* LX_CLOCK_MONOTONIC */
93 EMUL(CLOCK_HIGHRES), /* LX_CLOCK_PROCESS_CPUTIME_ID */
94 EMUL(CLOCK_HIGHRES), /* LX_CLOCK_THREAD_CPUTIME_ID */
95 NATIVE(CLOCK_HIGHRES), /* LX_CLOCK_MONOTONIC_RAW */
96 NATIVE(CLOCK_REALTIME), /* LX_CLOCK_REALTIME_COARSE */
97 NATIVE(CLOCK_HIGHRES), /* LX_CLOCK_MONOTONIC_COARSE */
98 NATIVE(CLOCK_HIGHRES) /* LX_CLOCK_BOOTTIME */
99 };
100
101 #define LX_CLOCK_MAX \
102 (sizeof (lx_clock_backends) / sizeof (lx_clock_backends[0]))
103 #define LX_CLOCK_BACKEND(clk) (((clk) < LX_CLOCK_MAX && (clk) >= 0) ? \
104 &lx_clock_backends[(clk)] : NULL)
105
106 /*
107 * Linux defines the size of the sigevent structure to be 64 bytes. In order
108 * to meet that definition, the trailing union includes a member which pads it
109 * out to the desired length for the given architecture.
110 */
111 #define LX_SIGEV_PAD_SIZE ((64 - \
112 (sizeof (int) * 2 + sizeof (union sigval))) / sizeof (int))
113
114 typedef struct {
|