]>
Commit | Line | Data |
---|---|---|
3e170ce0 | 1 | /* |
5ba3f43e | 2 | * Copyright (c) 2015-2017 Apple Inc. All rights reserved. |
3e170ce0 A |
3 | * |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. The rights granted to you under the License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
14 | * | |
15 | * Please obtain a copy of the License at | |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
18 | * The Original Code and all software distributed under the License are | |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
23 | * Please see the License for the specific language governing rights and | |
24 | * limitations under the License. | |
25 | * | |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ | |
27 | */ | |
28 | ||
29 | #ifndef _SYS_WORK_INTERVAL_H | |
30 | #define _SYS_WORK_INTERVAL_H | |
31 | ||
32 | #include <stdint.h> | |
3e170ce0 | 33 | #include <sys/cdefs.h> |
5ba3f43e A |
34 | #include <sys/_types/_size_t.h> |
35 | ||
36 | #include <mach/port.h> | |
3e170ce0 A |
37 | |
38 | __BEGIN_DECLS | |
39 | ||
40 | /* | |
5ba3f43e A |
41 | * A work interval is a repeatable unit of work characterized by a |
42 | * start, finish, and deadline. | |
43 | * | |
3e170ce0 A |
44 | * Trusted clients with deadline-sensitive work may report information |
45 | * about the execution of their work using the work interval facility. | |
46 | * This is intended to be a higher-level semantic than realtime scheduling, | |
47 | * which operates at the level of thread block/unblock. A high level | |
48 | * operation may have many blocking points, including IPC to other tasks, | |
49 | * and this this metric will capture the overall time to complete a unit of | |
50 | * work. | |
51 | * | |
52 | * A work interval is defined by several timestamps, namely (S)tart, | |
53 | * (F)inish, (D)eadline, and (N)ext start. | |
54 | * | |
55 | * ... ----+==================+--------+--+==== ... | |
56 | * | | | | | |
57 | * S F D N | |
58 | * | |
59 | * \__________________/ | |
60 | * Active | |
61 | * \___________________________/ | |
62 | * Work Interval | |
63 | * | |
64 | * \_________/ | |
65 | * | | |
66 | * report information here ---------+ | |
67 | * | |
68 | * Definitions: | |
69 | * | |
70 | * Start: Absolute time when the current deadline-oriented work began. Due | |
71 | * to scheduling latency, preemption, and blocking points, the | |
72 | * thread controlling the work interval may actually begin | |
73 | * executing after this ideal time (which may be the previous work | |
74 | * interval's "next start") | |
75 | * Finish: Absolute time when the current deadline-oriented work finished. | |
76 | * This will typically be a timestamp taken before reporting using | |
77 | * the work interval interface. | |
78 | * Deadline: Absolute time by which the current work was expected to finish. | |
79 | * In cases where the amount of computation (or preemption, or time | |
80 | * spent blocked) causes the active period to take longer than | |
81 | * expected, F may be greater than D. | |
82 | * Next start: Absolute time when the next deadline-oriented work is | |
83 | * expected to begin. This is typically the same as Deadline. | |
84 | * Active: The fraction of the work interval spent completing the work. In | |
85 | * cases where the Finish time exceeded the Deadline, this fraction | |
86 | * will be >1.0. | |
87 | * | |
88 | * Basic Use: | |
89 | * | |
90 | * Clients should report information for a work interval after finishing | |
91 | * work for the current interval but before the next work interval begins. | |
92 | * | |
93 | * If Finish far exceeds the previously expected Deadline, the | |
94 | * caller may adjust Next Start to align to a multiple of the period | |
95 | * (and skip over several work intervals that could not be | |
96 | * executed). | |
97 | * | |
98 | * Caution (!): | |
99 | * | |
100 | * Because the information supplied via this facility directly influences power | |
101 | * management decisions, clients should strive to be as accurate as possible. | |
102 | * Failure to do so will adversely impact system power and performance. | |
103 | * | |
104 | */ | |
5ba3f43e A |
105 | |
106 | /* Flags to be passed with work_interval_create() */ | |
107 | ||
108 | /* If interval is joinable, create no longer implicitly joins, you must use work_interval_join */ | |
109 | #define WORK_INTERVAL_FLAG_JOINABLE (0x1) | |
110 | /* Only threads that join the group are measured together, otherwise the group is the creator's home group */ | |
111 | #define WORK_INTERVAL_FLAG_GROUP (0x2) | |
112 | ||
113 | /* Flags to describe the interval flavor to the performance controller */ | |
114 | #define WORK_INTERVAL_TYPE_MASK (0xF0000000) | |
115 | #define WORK_INTERVAL_TYPE_DEFAULT (0x0 << 28) | |
116 | #define WORK_INTERVAL_TYPE_COREAUDIO (0x1 << 28) | |
117 | #define WORK_INTERVAL_TYPE_COREANIMATION (0x2 << 28) | |
a39ff7e2 A |
118 | #define WORK_INTERVAL_TYPE_CA_RENDER_SERVER (0x2 << 28) |
119 | #define WORK_INTERVAL_TYPE_CA_CLIENT (0x3 << 28) | |
d9a64523 | 120 | #define WORK_INTERVAL_TYPE_HID_DELIVERY (0x4 << 28) |
cb323159 | 121 | #define WORK_INTERVAL_TYPE_COREMEDIA (0x5 << 28) |
5ba3f43e A |
122 | #define WORK_INTERVAL_TYPE_LAST (0xF << 28) |
123 | ||
3e170ce0 A |
124 | #ifndef KERNEL |
125 | ||
126 | typedef struct work_interval *work_interval_t; | |
a39ff7e2 | 127 | typedef struct work_interval_instance *work_interval_instance_t; |
3e170ce0 | 128 | |
5ba3f43e A |
129 | /* |
130 | * Create a new work interval handle. | |
131 | * | |
132 | * May fail with EALREADY if the current group already has a work interval. | |
133 | * | |
134 | * With no flags: | |
135 | * Auto-joins the work interval to the creating thread | |
136 | * May only use interval_handle from creating thread | |
137 | * Data provided affects native thread group | |
138 | * | |
139 | * With the JOINABLE flag | |
140 | * interval_handle is usable by the process | |
141 | * creating thread does not auto-join | |
142 | * notifying thread must have joined when notifying | |
143 | * | |
144 | * With the GROUP flag | |
145 | * creates a new thread group to isolate the joined threads from | |
146 | * the rest of the process for performance controller analysis | |
147 | * Threads which join the work interval become members of this new group | |
148 | * | |
149 | * TODO: Add a name parameter so that clients can name the work interval | |
150 | * Can also take the thread name from the notifying thread | |
151 | * | |
152 | * Requires the 'com.apple.private.kernel.work-interval' entitlement (PRIV_WORK_INTERVAL) | |
153 | * | |
154 | * Note that joining a work interval supersedes automatic thread group management via vouchers | |
155 | */ | |
156 | int work_interval_create(work_interval_t *interval_handle, uint32_t flags); | |
3e170ce0 | 157 | |
a39ff7e2 | 158 | |
5ba3f43e A |
159 | /* |
160 | * Notify the power management subsystem that the work for a current interval has completed | |
161 | * | |
162 | * Only the process which created the work interval may notify | |
163 | */ | |
164 | int work_interval_notify(work_interval_t interval_handle, | |
0a7de745 A |
165 | uint64_t start, uint64_t finish, |
166 | uint64_t deadline, uint64_t next_start, | |
167 | uint32_t flags); | |
3e170ce0 | 168 | |
5ba3f43e A |
169 | /* |
170 | * Notify, with "finish" implicitly set to the current time | |
171 | * | |
172 | * Only the process which created the work interval may notify | |
173 | */ | |
174 | int work_interval_notify_simple(work_interval_t interval_handle, | |
0a7de745 A |
175 | uint64_t start, uint64_t deadline, |
176 | uint64_t next_start); | |
3e170ce0 | 177 | |
5ba3f43e A |
178 | /* |
179 | * Deallocate work interval handle | |
180 | * For non-JOINABLE, also removes thread from work interval | |
181 | * For JOINABLE, does not remove thread (needs a leave as well) | |
182 | */ | |
183 | int work_interval_destroy(work_interval_t interval_handle); | |
3e170ce0 | 184 | |
5ba3f43e A |
185 | /* |
186 | * Join work interval via work interval handle | |
187 | * Only allowed if interval is using the joinable and group flags | |
188 | * | |
189 | * Supersedes automatic thread group management via vouchers | |
190 | */ | |
191 | int work_interval_join(work_interval_t interval_handle); | |
192 | ||
193 | /* | |
194 | * extract Mach send right representing work interval thread group | |
195 | * Returns a +1 send right ref, which must be deallocated via mach_port_deallocate | |
196 | * Only allowed if interval is joinable, otherwise returns ENOTSUP | |
197 | * | |
198 | * Supersedes automatic thread group management via vouchers | |
199 | */ | |
200 | int work_interval_copy_port(work_interval_t interval_handle, mach_port_t *port); | |
201 | ||
202 | /* | |
203 | * Join work interval via Mach send right | |
204 | * | |
205 | * Does NOT consume Mach send right, must deallocate with mach_port_deallocate after using | |
206 | * It's safe to deallocate the right after joining, the thread will stay joined | |
207 | * | |
208 | * Can be sent to clients via xpc_dictionary_copy_mach_send, and similar | |
209 | * | |
210 | * Supersedes automatic thread group management via vouchers | |
211 | * | |
212 | * If the underlying work interval object is terminated then this may return ENOENT | |
213 | * <rdar://problem/31819320> | |
214 | */ | |
215 | int work_interval_join_port(mach_port_t port); | |
216 | ||
217 | /* | |
218 | * Leave the current thread's work interval | |
219 | */ | |
220 | int work_interval_leave(void); | |
221 | ||
5ba3f43e | 222 | #endif /* !KERNEL */ |
3e170ce0 A |
223 | |
224 | #if PRIVATE | |
225 | ||
226 | /* Private interface between Libsyscall and xnu */ | |
5ba3f43e A |
227 | #define WORK_INTERVAL_OPERATION_CREATE 0x00000001 /* deprecated */ |
228 | #define WORK_INTERVAL_OPERATION_DESTROY 0x00000002 /* arg is NULL */ | |
229 | #define WORK_INTERVAL_OPERATION_NOTIFY 0x00000003 /* arg is a work_interval_notification_t */ | |
230 | #define WORK_INTERVAL_OPERATION_CREATE2 0x00000004 /* arg is a work_interval_create_params */ | |
231 | #define WORK_INTERVAL_OPERATION_JOIN 0x00000005 /* arg is a port_name */ | |
3e170ce0 A |
232 | |
233 | struct work_interval_notification { | |
0a7de745 A |
234 | uint64_t start; |
235 | uint64_t finish; | |
236 | uint64_t deadline; | |
237 | uint64_t next_start; | |
238 | uint32_t notify_flags; | |
239 | uint32_t create_flags; | |
3e170ce0 A |
240 | }; |
241 | typedef struct work_interval_notification *work_interval_notification_t; | |
242 | ||
5ba3f43e A |
243 | struct work_interval_create_params { |
244 | uint64_t wicp_id; /* out param */ | |
245 | uint32_t wicp_port; /* out param */ | |
246 | uint32_t wicp_create_flags; | |
247 | }; | |
248 | ||
a39ff7e2 | 249 | |
5ba3f43e | 250 | int __work_interval_ctl(uint32_t operation, uint64_t work_interval_id, void *arg, size_t len); |
3e170ce0 A |
251 | |
252 | #endif /* PRIVATE */ | |
253 | ||
254 | __END_DECLS | |
255 | ||
256 | #endif /* _SYS_WORK_INTERVAL_H */ |