Source to osfmk/kern/profile.h
/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
* are subject to the Apple Public Source License Version 1.1 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
*
* This Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* @OSF_COPYRIGHT@
*/
/*
* Mach Operating System
* Copyright (c) 1991,1990,1989 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or [email protected]
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
*/
#ifndef _KERN_PROFILE_H
#define _KERN_PROFILE_H
#include <mach/boolean.h>
#include <vm/vm_kern.h>
#define NB_PROF_BUFFER 4 /* number of buffers servicing a */
#define SIZE_PROF_BUFFER 200 /* size of a profil buffer (in natural_t) */
/* -> at most 1 packet every 2 secs */
/* profiled thread */
struct prof_data {
struct ipc_port *prof_port; /* where to send a full buffer */
struct buffer {
queue_chain_t p_list;
natural_t *p_zone; /* points to the actual storage area */
int p_index; /* next slot to be filled */
int p_dropped; /* # dropped samples when full */
boolean_t p_full; /* is the current buffer full ? */
struct prof_data *p_prof; /* base to get prof_port */
char p_wakeme; /* do wakeup when sent */
} prof_area[NB_PROF_BUFFER];
int prof_index; /* index of the buffer structure */
/* currently in use */
};
typedef struct prof_data *prof_data_t;
#define NULLPROFDATA ((prof_data_t) 0)
typedef struct buffer *buffer_t;
#define NULLPBUF ((buffer_t) 0)
/* Macros */
#define set_pbuf_nb(pbuf, nb) \
(((nb) >= 0 && (nb) < NB_PROF_BUFFER) \
? (pbuf)->prof_index = (nb), 1 \
: 0)
#define get_pbuf_nb(pbuf) \
(pbuf)->prof_index
extern vm_map_t kernel_map;
/* MACRO set_pbuf_value
**
** enters the value 'val' in the buffer 'pbuf' and returns the following
** indications: 0: means that a fatal error occured: the buffer was full
** (it hasn't been sent yet)
** 1: means that a value has been inserted successfully
** 2: means that we'v just entered the last value causing
** the current buffer to be full.(must switch to
** another buffer and signal the sender to send it)
*/
#if MACH_PROF
#define set_pbuf_value(pbuf, val) \
{ \
register buffer_t a = &((pbuf)->prof_area[(pbuf)->prof_index]); \
register int i ;\
register boolean_t f = a->p_full; \
\
if (f == TRUE ) {\
a->p_dropped++; \
*(val) = 0L; \
} else { \
i = a->p_index++; \
a->p_zone[i] = *(val); \
if (i == SIZE_PROF_BUFFER-1) { \
a->p_full = TRUE; \
*(val) = 2; \
} \
else \
*(val) = 1; \
} \
}
#define reset_pbuf_area(pbuf) \
{ \
int i; \
(pbuf)->prof_index = ((pbuf)->prof_index + 1) % NB_PROF_BUFFER; \
i = (pbuf)->prof_index; \
(pbuf)->prof_area[i].p_index = 0; \
(pbuf)->prof_area[i].p_dropped = 0; \
}
#endif /* MACH_PROF */
/*
** Global variable: the head of the queue of buffers to send
** It is a queue with locks (uses macros from queue.h) and it
** is shared by hardclock() and the sender_thread()
*/
mpqueue_head_t prof_queue;
extern void profile(
natural_t pc, /* program counter */
prof_data_t pbuf); /* trace/prof data area */
#if MACH_PROF
#define task_prof_init(task) \
task->task_profiled = FALSE; \
task->profil_buffer = NULLPROFDATA;
#define act_prof_init(thr_act, task) \
thr_act->act_profiled = task->task_profiled; \
thr_act->profil_buffer = task->profil_buffer;
#define task_prof_deallocate(task) \
if (task->profil_buffer) \
task_sample(task, MACH_PORT_NULL); \
#define act_prof_deallocate(thr_act) \
if (thr_act->act_profiled_own && thr_act->profil_buffer) \
thread_sample(thr_act, MACH_PORT_NULL); \
extern kern_return_t thread_sample(thread_act_t, ipc_port_t);
extern kern_return_t task_sample(task_t, ipc_port_t);
#else /* !MACH_PROT */
#define task_prof_init(task)
#define act_prof_init(thr_act, task)
#define task_prof_deallocate(task)
#define act_prof_deallocate(thr_act)
#endif /* !MACH_PROF */
#endif /* _KERN_PROFILE_H */