]> git.saurik.com Git - apple/xnu.git/blame_incremental - osfmk/kperf/kperf.c
xnu-2050.7.9.tar.gz
[apple/xnu.git] / osfmk / kperf / kperf.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
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#include <mach/mach_types.h>
29#include <kern/thread.h>
30#include <kern/machine.h>
31#include <kern/kalloc.h>
32#include <sys/errno.h>
33
34#include <kperf/filter.h>
35#include <kperf/sample.h>
36#include <kperf/kperfbsd.h>
37#include <kperf/pet.h>
38#include <kperf/action.h>
39#include <kperf/kperf.h>
40#include <kperf/timetrigger.h>
41
42/** misc functions **/
43#include <chud/chud_xnu.h> /* XXX: should bust this out */
44
45static struct kperf_sample *intr_samplev = NULL;
46static unsigned intr_samplec = 0;
47static unsigned sampling_status = KPERF_SAMPLING_OFF;
48static unsigned kperf_initted = 0;
49
50
51extern void (*chudxnu_thread_ast_handler)(thread_t);
52
53struct kperf_sample*
54kperf_intr_sample_buffer(void)
55{
56 unsigned ncpu = chudxnu_cpu_number();
57
58 // XXX: assert?
59 if( ncpu >= intr_samplec )
60 return NULL;
61
62 return &intr_samplev[ncpu];
63}
64
65/* setup interrupt sample buffers */
66int
67kperf_init(void)
68{
69 unsigned ncpus = 0;
70
71 if( kperf_initted )
72 return 0;
73
74 /* get number of cpus */
75 ncpus = machine_info.logical_cpu_max;
76
77 /* make the CPU array
78 * FIXME: cache alignment
79 */
80 intr_samplev = kalloc( ncpus * sizeof(*intr_samplev));
81
82 if( intr_samplev == NULL )
83 return ENOMEM;
84
85 /* clear it */
86 bzero( intr_samplev, ncpus * sizeof(*intr_samplev) );
87
88 chudxnu_thread_ast_handler = kperf_thread_ast_handler;
89
90 /* we're done */
91 intr_samplec = ncpus;
92 kperf_initted = 1;
93
94 return 0;
95}
96
97
98/** kext start/stop functions **/
99kern_return_t kperf_start (kmod_info_t * ki, void * d);
100
101kern_return_t
102kperf_start (kmod_info_t * ki, void * d)
103{
104 (void) ki;
105 (void) d;
106
107 /* say hello */
108 printf( "aprof: kext starting\n" );
109
110 /* register modules */
111 // kperf_action_init();
112 kperf_filter_init();
113 kperf_pet_init();
114
115 /* register the sysctls */
116 //kperf_register_profiling();
117
118 return KERN_SUCCESS;
119}
120
121
122/* random misc-ish functions */
123uint32_t
124kperf_get_thread_bits( thread_t thread )
125{
126 return thread->t_chud;
127}
128
129void
130kperf_set_thread_bits( thread_t thread, uint32_t bits )
131{
132 thread->t_chud = bits;
133}
134
135/* mark an AST to fire on a thread */
136void
137kperf_set_thread_ast( thread_t thread )
138{
139 /* FIXME: only call this on current thread from an interrupt
140 * handler for now...
141 */
142 if( thread != current_thread() )
143 panic( "unsafe AST set" );
144
145 act_set_kperf(thread);
146}
147
148unsigned
149kperf_sampling_status(void)
150{
151 return sampling_status;
152}
153
154int
155kperf_sampling_enable(void)
156{
157 /* already running! */
158 if( sampling_status == KPERF_SAMPLING_ON )
159 return 0;
160
161 if ( sampling_status != KPERF_SAMPLING_OFF )
162 panic( "kperf: sampling wasn't off" );
163
164 /* make sure interrupt tables and actions are initted */
165 if( !kperf_initted
166 || (kperf_action_get_count() == 0) )
167 return ECANCELED;
168
169 /* mark as running */
170 sampling_status = KPERF_SAMPLING_ON;
171
172 /* tell timers to enable */
173 kperf_timer_go();
174
175 return 0;
176}
177
178int
179kperf_sampling_disable(void)
180{
181 if( sampling_status != KPERF_SAMPLING_ON )
182 return 0;
183
184 /* mark a shutting down */
185 sampling_status = KPERF_SAMPLING_SHUTDOWN;
186
187 /* tell timers to disable */
188 kperf_timer_stop();
189
190 /* mark as off */
191 sampling_status = KPERF_SAMPLING_OFF;
192
193 return 0;
194}