xref: /illumos-gate/usr/src/uts/common/os/clock_process.c (revision bbf215553c7233fbab8a0afdf1fac74c44781867)
1dea9f5e6SRobert Mustacchi /*
2dea9f5e6SRobert Mustacchi  * This file and its contents are supplied under the terms of the
3dea9f5e6SRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4dea9f5e6SRobert Mustacchi  * You may only use this file in accordance with the terms of version
5dea9f5e6SRobert Mustacchi  * 1.0 of the CDDL.
6dea9f5e6SRobert Mustacchi  *
7dea9f5e6SRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8dea9f5e6SRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9dea9f5e6SRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10dea9f5e6SRobert Mustacchi  */
11dea9f5e6SRobert Mustacchi 
12dea9f5e6SRobert Mustacchi /*
13dea9f5e6SRobert Mustacchi  * Copyright 2021 Oxide Computer Company
14dea9f5e6SRobert Mustacchi  */
15dea9f5e6SRobert Mustacchi 
16dea9f5e6SRobert Mustacchi /*
17dea9f5e6SRobert Mustacchi  * This clock backend implements basic support for the CLOCK_PROCESS_CPUTIME_ID
18dea9f5e6SRobert Mustacchi  * clock. This clock is weakly defined by POSIX as "The identifier of the
19dea9f5e6SRobert Mustacchi  * CPU-time clock associated with the process making a clock() or timer*()
20dea9f5e6SRobert Mustacchi  * function call". We interpret that as including LMS_USER, LMS_SYSTEM, and
21*bbf21555SRichard Lowe  * LMS_TRAP microstates. This is similar to what we do in proc(5) for the
22dea9f5e6SRobert Mustacchi  * lwpstatus_t and the prstatus_t.
23dea9f5e6SRobert Mustacchi  *
24dea9f5e6SRobert Mustacchi  * At this time, we only provide the ability to read the current time (e.g.
25dea9f5e6SRobert Mustacchi  * through a call to clock_gettime(3C)). There is never a case where being able
26dea9f5e6SRobert Mustacchi  * to set the time makes sense today and even if so, the privileges required for
27dea9f5e6SRobert Mustacchi  * that are circumspect. Today, we do not support the ability to create interval
28dea9f5e6SRobert Mustacchi  * timers based on this backend (e.g. timer_create(3C) and timer_settime(3C)).
29dea9f5e6SRobert Mustacchi  * However, there is no reason that couldn't be added.
30dea9f5e6SRobert Mustacchi  *
31dea9f5e6SRobert Mustacchi  * To implement this, we leverage the existing microstate aggregation time that
32dea9f5e6SRobert Mustacchi  * is done in /proc.
33dea9f5e6SRobert Mustacchi  */
34dea9f5e6SRobert Mustacchi 
35dea9f5e6SRobert Mustacchi #include <sys/timer.h>
36dea9f5e6SRobert Mustacchi #include <sys/cyclic.h>
37dea9f5e6SRobert Mustacchi #include <sys/msacct.h>
38dea9f5e6SRobert Mustacchi 
39dea9f5e6SRobert Mustacchi static clock_backend_t clock_process;
40dea9f5e6SRobert Mustacchi 
41dea9f5e6SRobert Mustacchi static int
clock_process_settime(timespec_t * ts)42dea9f5e6SRobert Mustacchi clock_process_settime(timespec_t *ts)
43dea9f5e6SRobert Mustacchi {
44dea9f5e6SRobert Mustacchi 	return (EINVAL);
45dea9f5e6SRobert Mustacchi }
46dea9f5e6SRobert Mustacchi 
47dea9f5e6SRobert Mustacchi static int
clock_process_gettime(timespec_t * ts)48dea9f5e6SRobert Mustacchi clock_process_gettime(timespec_t *ts)
49dea9f5e6SRobert Mustacchi {
50dea9f5e6SRobert Mustacchi 	hrtime_t hrt;
51dea9f5e6SRobert Mustacchi 	proc_t *p = curproc;
52dea9f5e6SRobert Mustacchi 
53dea9f5e6SRobert Mustacchi 	/*
54dea9f5e6SRobert Mustacchi 	 * mstate_aggr_state() automatically includes LMS_TRAP when we ask for
55dea9f5e6SRobert Mustacchi 	 * LMS_SYSTEM below.
56dea9f5e6SRobert Mustacchi 	 */
57dea9f5e6SRobert Mustacchi 	mutex_enter(&p->p_lock);
58dea9f5e6SRobert Mustacchi 	hrt = mstate_aggr_state(p, LMS_USER);
59dea9f5e6SRobert Mustacchi 	hrt += mstate_aggr_state(p, LMS_SYSTEM);
60dea9f5e6SRobert Mustacchi 	mutex_exit(&p->p_lock);
61dea9f5e6SRobert Mustacchi 
62dea9f5e6SRobert Mustacchi 	hrt2ts(hrt, ts);
63dea9f5e6SRobert Mustacchi 
64dea9f5e6SRobert Mustacchi 	return (0);
65dea9f5e6SRobert Mustacchi }
66dea9f5e6SRobert Mustacchi 
67dea9f5e6SRobert Mustacchi /*
68dea9f5e6SRobert Mustacchi  * See the discussion in clock_thread_getres() for the why of using
69dea9f5e6SRobert Mustacchi  * cyclic_getres() here.
70dea9f5e6SRobert Mustacchi  */
71dea9f5e6SRobert Mustacchi static int
clock_process_getres(timespec_t * ts)72dea9f5e6SRobert Mustacchi clock_process_getres(timespec_t *ts)
73dea9f5e6SRobert Mustacchi {
74dea9f5e6SRobert Mustacchi 	hrt2ts(cyclic_getres(), (timestruc_t *)ts);
75dea9f5e6SRobert Mustacchi 
76dea9f5e6SRobert Mustacchi 	return (0);
77dea9f5e6SRobert Mustacchi }
78dea9f5e6SRobert Mustacchi 
79dea9f5e6SRobert Mustacchi static int
clock_process_timer_create(itimer_t * it,void (* fire)(itimer_t *))80dea9f5e6SRobert Mustacchi clock_process_timer_create(itimer_t *it, void (*fire)(itimer_t *))
81dea9f5e6SRobert Mustacchi {
82dea9f5e6SRobert Mustacchi 	return (EINVAL);
83dea9f5e6SRobert Mustacchi }
84dea9f5e6SRobert Mustacchi 
85dea9f5e6SRobert Mustacchi static int
clock_process_timer_settime(itimer_t * it,int flags,const struct itimerspec * when)86dea9f5e6SRobert Mustacchi clock_process_timer_settime(itimer_t *it, int flags,
87dea9f5e6SRobert Mustacchi     const struct itimerspec *when)
88dea9f5e6SRobert Mustacchi {
89dea9f5e6SRobert Mustacchi 	return (EINVAL);
90dea9f5e6SRobert Mustacchi }
91dea9f5e6SRobert Mustacchi 
92dea9f5e6SRobert Mustacchi static int
clock_process_timer_gettime(itimer_t * it,struct itimerspec * when)93dea9f5e6SRobert Mustacchi clock_process_timer_gettime(itimer_t *it, struct itimerspec *when)
94dea9f5e6SRobert Mustacchi {
95dea9f5e6SRobert Mustacchi 	return (EINVAL);
96dea9f5e6SRobert Mustacchi }
97dea9f5e6SRobert Mustacchi 
98dea9f5e6SRobert Mustacchi static int
clock_process_timer_delete(itimer_t * it)99dea9f5e6SRobert Mustacchi clock_process_timer_delete(itimer_t *it)
100dea9f5e6SRobert Mustacchi {
101dea9f5e6SRobert Mustacchi 	return (EINVAL);
102dea9f5e6SRobert Mustacchi }
103dea9f5e6SRobert Mustacchi 
104dea9f5e6SRobert Mustacchi static void
clock_process_timer_lwpbind(itimer_t * it)105dea9f5e6SRobert Mustacchi clock_process_timer_lwpbind(itimer_t *it)
106dea9f5e6SRobert Mustacchi {
107dea9f5e6SRobert Mustacchi }
108dea9f5e6SRobert Mustacchi 
109dea9f5e6SRobert Mustacchi void
clock_process_init(void)110dea9f5e6SRobert Mustacchi clock_process_init(void)
111dea9f5e6SRobert Mustacchi {
112dea9f5e6SRobert Mustacchi 	/*
113dea9f5e6SRobert Mustacchi 	 * While this clock backend doesn't support notifications right now, we
114dea9f5e6SRobert Mustacchi 	 * still fill out the default for what it would be.
115dea9f5e6SRobert Mustacchi 	 */
116dea9f5e6SRobert Mustacchi 	clock_process.clk_default.sigev_signo = SIGALRM;
117dea9f5e6SRobert Mustacchi 	clock_process.clk_default.sigev_notify = SIGEV_SIGNAL;
118dea9f5e6SRobert Mustacchi 	clock_process.clk_default.sigev_value.sival_ptr = NULL;
119dea9f5e6SRobert Mustacchi 
120dea9f5e6SRobert Mustacchi 	clock_process.clk_clock_settime = clock_process_settime;
121dea9f5e6SRobert Mustacchi 	clock_process.clk_clock_gettime = clock_process_gettime;
122dea9f5e6SRobert Mustacchi 	clock_process.clk_clock_getres = clock_process_getres;
123dea9f5e6SRobert Mustacchi 	clock_process.clk_timer_create = clock_process_timer_create;
124dea9f5e6SRobert Mustacchi 	clock_process.clk_timer_settime = clock_process_timer_settime;
125dea9f5e6SRobert Mustacchi 	clock_process.clk_timer_gettime = clock_process_timer_gettime;
126dea9f5e6SRobert Mustacchi 	clock_process.clk_timer_delete = clock_process_timer_delete;
127dea9f5e6SRobert Mustacchi 	clock_process.clk_timer_lwpbind = clock_process_timer_lwpbind;
128dea9f5e6SRobert Mustacchi 
129dea9f5e6SRobert Mustacchi 	clock_add_backend(CLOCK_PROCESS_CPUTIME_ID, &clock_process);
130dea9f5e6SRobert Mustacchi }
131