2 * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 /* sysctl interface for paramters from user-land */
31 #include <sys/param.h>
34 #include <sys/sysctl.h>
35 #include <libkern/libkern.h>
37 #include <kperf/context.h>
38 #include <kperf/action.h>
39 #include <kperf/timetrigger.h>
40 #include <kperf/pet.h>
41 #include <kperf/filter.h>
42 #include <kperf/kperfbsd.h>
43 #include <kperf/kperf.h>
45 #define REQ_SAMPLING (1)
46 #define REQ_ACTION_COUNT (2)
47 #define REQ_ACTION_SAMPLERS (3)
48 #define REQ_TIMER_COUNT (4)
49 #define REQ_TIMER_PERIOD (5)
50 #define REQ_TIMER_PET (6)
54 sysctl_timer_period( __unused
struct sysctl_oid
*oidp
, struct sysctl_req
*req
)
57 uint64_t inputs
[2], retval
;
58 unsigned timer
, set
= 0;
60 /* get 2x 64-bit words */
61 error
= SYSCTL_IN( req
, inputs
, 2*sizeof(inputs
[0]) );
64 printf( "error in\n" );
69 timer
= (unsigned) inputs
[0];
70 if( inputs
[1] != ~0ULL )
73 printf( "%s timer: %u, inp[0] %llu\n", set
? "set" : "get",
78 printf( "timer set period\n" );
79 error
= kperf_timer_set_period( timer
, inputs
[1] );
84 error
= kperf_timer_get_period(timer
, &retval
);
87 printf( "error get period\n" );
95 error
= SYSCTL_OUT( req
, inputs
, 2*sizeof(inputs
[0]) );
97 printf( "error out\n" );
104 sysctl_action_samplers( __unused
struct sysctl_oid
*oidp
,
105 struct sysctl_req
*req
)
110 unsigned actionid
, set
= 0;
112 /* get 3x 64-bit words */
113 error
= SYSCTL_IN( req
, inputs
, 3*sizeof(inputs
[0]) );
116 printf( "error in\n" );
121 set
= (unsigned) inputs
[0];
122 actionid
= (unsigned) inputs
[1];
126 error
= kperf_action_set_samplers( actionid
, inputs
[2] );
131 printf("set %d actionid %u samplers val %u\n",
132 set
, actionid
, (unsigned) inputs
[2] );
134 error
= kperf_action_get_samplers(actionid
, &retval
);
137 printf( "error get samplers\n" );
145 error
= SYSCTL_OUT( req
, inputs
, 3*sizeof(inputs
[0]) );
147 printf( "error out\n" );
154 sysctl_sampling( struct sysctl_oid
*oidp
, struct sysctl_req
*req
)
159 /* get the old value and process it */
160 value
= kperf_sampling_status();
162 /* copy out the old value, get the new value */
163 error
= sysctl_handle_int(oidp
, &value
, 0, req
);
164 if (error
|| !req
->newptr
)
167 printf( "setting sampling to %d\n", value
);
169 /* if that worked, and we're writing... */
171 error
= kperf_sampling_enable();
173 error
= kperf_sampling_disable();
179 sysctl_action_count( struct sysctl_oid
*oidp
, struct sysctl_req
*req
)
184 /* get the old value and process it */
185 value
= kperf_action_get_count();
187 /* copy out the old value, get the new value */
188 error
= sysctl_handle_int(oidp
, &value
, 0, req
);
189 if (error
|| !req
->newptr
)
192 printf( "setting action count to %d\n", value
);
194 /* if that worked, and we're writing... */
195 return kperf_action_set_count(value
);
199 sysctl_timer_count( struct sysctl_oid
*oidp
, struct sysctl_req
*req
)
204 /* get the old value and process it */
205 value
= kperf_timer_get_count();
207 /* copy out the old value, get the new value */
208 error
= sysctl_handle_int(oidp
, &value
, 0, req
);
209 if (error
|| !req
->newptr
)
212 printf( "setting timer count to %d\n", value
);
214 /* if that worked, and we're writing... */
215 return kperf_timer_set_count(value
);
219 sysctl_timer_pet( struct sysctl_oid
*oidp
, struct sysctl_req
*req
)
224 /* get the old value and process it */
225 value
= kperf_timer_get_petid();
227 /* copy out the old value, get the new value */
228 error
= sysctl_handle_int(oidp
, &value
, 0, req
);
229 if (error
|| !req
->newptr
)
232 printf( "setting timer petid to %d\n", value
);
234 /* if that worked, and we're writing... */
235 return kperf_timer_set_petid(value
);
239 * #define SYSCTL_HANDLER_ARGS (struct sysctl_oid *oidp, \
240 * void *arg1, int arg2, \
241 * struct sysctl_req *req )
244 kperf_sysctl SYSCTL_HANDLER_ARGS
246 // __unused struct sysctl_oid *unused_oidp = oidp;
250 switch( (uintptr_t) arg1
)
252 case REQ_ACTION_COUNT
:
253 return sysctl_action_count( oidp
, req
);
254 case REQ_ACTION_SAMPLERS
:
255 return sysctl_action_samplers( oidp
, req
);
256 case REQ_TIMER_COUNT
:
257 return sysctl_timer_count( oidp
, req
);
258 case REQ_TIMER_PERIOD
:
259 return sysctl_timer_period( oidp
, req
);
261 return sysctl_timer_pet( oidp
, req
);
263 return sysctl_sampling( oidp
, req
);
267 return sysctl_timer_period( req
);
269 return sysctl_pet_period( req
);
276 /* root kperf node */
277 SYSCTL_NODE(, OID_AUTO
, kperf
, CTLFLAG_RW
|CTLFLAG_LOCKED
, 0,
280 /* action sub-section */
281 SYSCTL_NODE(_kperf
, OID_AUTO
, action
, CTLFLAG_RW
|CTLFLAG_LOCKED
, 0,
284 SYSCTL_PROC(_kperf_action
, OID_AUTO
, count
,
285 CTLTYPE_INT
|CTLFLAG_RW
|CTLFLAG_ANYBODY
,
286 (void*)REQ_ACTION_COUNT
,
287 sizeof(int), kperf_sysctl
, "I", "Number of actions");
289 SYSCTL_PROC(_kperf_action
, OID_AUTO
, samplers
,
290 CTLFLAG_RW
|CTLFLAG_ANYBODY
,
291 (void*)REQ_ACTION_SAMPLERS
,
292 3*sizeof(uint64_t), kperf_sysctl
, "UQ",
293 "What to sample what a trigger fires an action");
295 /* timer sub-section */
296 SYSCTL_NODE(_kperf
, OID_AUTO
, timer
, CTLFLAG_RW
|CTLFLAG_LOCKED
, 0,
299 SYSCTL_PROC(_kperf_timer
, OID_AUTO
, count
,
300 CTLTYPE_INT
|CTLFLAG_RW
|CTLFLAG_ANYBODY
,
301 (void*)REQ_TIMER_COUNT
,
302 sizeof(int), kperf_sysctl
, "I", "Number of time triggers");
304 SYSCTL_PROC(_kperf_timer
, OID_AUTO
, period
,
305 CTLFLAG_RW
|CTLFLAG_ANYBODY
,
306 (void*)REQ_TIMER_PERIOD
,
307 2*sizeof(uint64_t), kperf_sysctl
, "UQ", "Timer number and period");
309 SYSCTL_PROC(_kperf_timer
, OID_AUTO
, pet_timer
,
310 CTLTYPE_INT
|CTLFLAG_RW
|CTLFLAG_ANYBODY
,
311 (void*)REQ_TIMER_PET
,
312 sizeof(int), kperf_sysctl
, "I", "Which timer ID does PET");
315 SYSCTL_PROC(_kperf
, OID_AUTO
, sampling
,
316 CTLTYPE_INT
|CTLFLAG_RW
|CTLFLAG_ANYBODY
,
318 sizeof(int), kperf_sysctl
, "I", "Sampling running");
321 SYSCTL_INT(_kperf
, OID_AUTO
, legacy_mode
, CTLFLAG_RW
, &legacy_mode
, 0, "legacy_mode");
324 SYSCTL_PROC(_kperf
, OID_AUTO
, timer_period
,
325 CTLFLAG_RW
, (void*)REQ_TIMER
,
326 sizeof(uint64_t), kperf_sysctl
, "QU", "nanoseconds");
328 SYSCTL_PROC(_kperf
, OID_AUTO
, pet_period
,
329 CTLFLAG_RW
, (void*)REQ_PET
,
330 sizeof(uint64_t), kperf_sysctl
, "QU", "nanoseconds");
332 /* FIXME: do real stuff */
333 SYSCTL_INT(_kperf
, OID_AUTO
, filter_pid0
,
334 CTLFLAG_RW
, &pid_list
[0], 0, "");
335 SYSCTL_INT(_kperf
, OID_AUTO
, filter_pid1
,
336 CTLFLAG_RW
, &pid_list
[1], 0, "");
337 SYSCTL_INT(_kperf
, OID_AUTO
, filter_pid2
,
338 CTLFLAG_RW
, &pid_list
[2], 0, "");
339 SYSCTL_INT(_kperf
, OID_AUTO
, filter_pid3
,
340 CTLFLAG_RW
, &pid_list
[3], 0, "");