profile.h revision 114349
1250661Sdavidcs/* 2250661Sdavidcs * Copyright (c) 1992, 1993 3250661Sdavidcs * The Regents of the University of California. All rights reserved. 4250661Sdavidcs * 5250661Sdavidcs * Redistribution and use in source and binary forms, with or without 6250661Sdavidcs * modification, are permitted provided that the following conditions 7250661Sdavidcs * are met: 8250661Sdavidcs * 1. Redistributions of source code must retain the above copyright 9250661Sdavidcs * notice, this list of conditions and the following disclaimer. 10250661Sdavidcs * 2. Redistributions in binary form must reproduce the above copyright 11250661Sdavidcs * notice, this list of conditions and the following disclaimer in the 12250661Sdavidcs * documentation and/or other materials provided with the distribution. 13250661Sdavidcs * 3. All advertising materials mentioning features or use of this software 14250661Sdavidcs * must display the following acknowledgement: 15250661Sdavidcs * This product includes software developed by the University of 16250661Sdavidcs * California, Berkeley and its contributors. 17250661Sdavidcs * 4. Neither the name of the University nor the names of its contributors 18250661Sdavidcs * may be used to endorse or promote products derived from this software 19250661Sdavidcs * without specific prior written permission. 20250661Sdavidcs * 21250661Sdavidcs * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22250661Sdavidcs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23250661Sdavidcs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24250661Sdavidcs * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25250661Sdavidcs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26250661Sdavidcs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27250661Sdavidcs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28250661Sdavidcs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29250661Sdavidcs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30250661Sdavidcs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31250661Sdavidcs * SUCH DAMAGE. 32250661Sdavidcs * 33250661Sdavidcs * @(#)profile.h 8.1 (Berkeley) 6/11/93 34250661Sdavidcs * $FreeBSD: head/sys/amd64/include/profile.h 114349 2003-05-01 01:05:25Z peter $ 35250661Sdavidcs */ 36250661Sdavidcs 37250661Sdavidcs#ifndef _MACHINE_PROFILE_H_ 38250661Sdavidcs#define _MACHINE_PROFILE_H_ 39250661Sdavidcs 40250661Sdavidcs#ifdef _KERNEL 41250661Sdavidcs 42250661Sdavidcs/* 43250661Sdavidcs * Config generates something to tell the compiler to align functions on 16 44250661Sdavidcs * byte boundaries. A strict alignment is good for keeping the tables small. 45250661Sdavidcs */ 46250661Sdavidcs#define FUNCTION_ALIGNMENT 16 47250661Sdavidcs 48250661Sdavidcs/* 49250661Sdavidcs * The kernel uses assembler stubs instead of unportable inlines. 50250661Sdavidcs * This is mainly to save a little time when profiling is not enabled, 51250661Sdavidcs * which is the usual case for the kernel. 52250661Sdavidcs */ 53250661Sdavidcs#define _MCOUNT_DECL void mcount 54250661Sdavidcs#define MCOUNT 55250661Sdavidcs 56250661Sdavidcs#ifdef GUPROF 57250661Sdavidcs#define CALIB_SCALE 1000 58250661Sdavidcs#define KCOUNT(p,index) ((p)->kcount[(index) \ 59250661Sdavidcs / (HISTFRACTION * sizeof(HISTCOUNTER))]) 60250661Sdavidcs#define MCOUNT_DECL(s) 61250661Sdavidcs#define MCOUNT_ENTER(s) 62250661Sdavidcs#define MCOUNT_EXIT(s) 63250661Sdavidcs#define PC_TO_I(p, pc) ((uintfptr_t)(pc) - (uintfptr_t)(p)->lowpc) 64250661Sdavidcs#else 65250661Sdavidcs#define MCOUNT_DECL(s) u_long s; 66250661Sdavidcs#ifdef SMP 67250661Sdavidcsextern int mcount_lock; 68250661Sdavidcs#define MCOUNT_ENTER(s) { s = read_rflags(); disable_intr(); \ 69250661Sdavidcs while (!atomic_cmpset_acq_int(&mcount_lock, 0, 1)) \ 70250661Sdavidcs /* nothing */ ; } 71250661Sdavidcs#define MCOUNT_EXIT(s) { atomic_store_rel_int(&mcount_lock, 0); \ 72250661Sdavidcs write_rflags(s); } 73250661Sdavidcs#else 74250661Sdavidcs#define MCOUNT_ENTER(s) { s = read_rflags(); disable_intr(); } 75250661Sdavidcs#define MCOUNT_EXIT(s) (write_rflags(s)) 76250661Sdavidcs#endif 77250661Sdavidcs#endif /* GUPROF */ 78250661Sdavidcs 79250661Sdavidcs#else /* !_KERNEL */ 80250661Sdavidcs 81250661Sdavidcs#define FUNCTION_ALIGNMENT 4 82250661Sdavidcs 83250661Sdavidcs#define _MCOUNT_DECL static __inline void _mcount 84250661Sdavidcs 85250661Sdavidcs#ifdef __GNUC__ 86250661Sdavidcs#define MCOUNT \ 87250661Sdavidcsvoid \ 88250661Sdavidcsmcount() \ 89250661Sdavidcs{ \ 90250661Sdavidcs uintfptr_t selfpc, frompc; \ 91250661Sdavidcs /* \ 92250661Sdavidcs * Find the return address for mcount, \ 93250661Sdavidcs * and the return address for mcount's caller. \ 94250661Sdavidcs * \ 95250661Sdavidcs * selfpc = pc pushed by call to mcount \ 96250661Sdavidcs */ \ 97250661Sdavidcs asm("movq 8(%%rbp),%0" : "=r" (selfpc)); \ 98250661Sdavidcs /* \ 99250661Sdavidcs * frompc = pc pushed by call to mcount's caller. \ 100250661Sdavidcs * The caller's stack frame has already been built, so %ebp is \ 101250661Sdavidcs * the caller's frame pointer. The caller's raddr is in the \ 102250661Sdavidcs * caller's frame following the caller's caller's frame pointer.\ 103250661Sdavidcs */ \ 104250661Sdavidcs asm("movq (%%rbp),%0" : "=r" (frompc)); \ 105250661Sdavidcs frompc = ((uintfptr_t *)frompc)[1]; \ 106250661Sdavidcs _mcount(frompc, selfpc); \ 107250661Sdavidcs} 108250661Sdavidcs#else /* __GNUC__ */ 109250661Sdavidcs#define MCOUNT \ 110250661Sdavidcsvoid \ 111250661Sdavidcsmcount() \ 112250661Sdavidcs{ \ 113250661Sdavidcs} 114250661Sdavidcs#endif /* __GNUC__ */ 115250661Sdavidcs 116250661Sdavidcstypedef unsigned long uintfptr_t; 117250661Sdavidcs 118250661Sdavidcs#endif /* _KERNEL */ 119250661Sdavidcs 120250661Sdavidcs/* 121250661Sdavidcs * An unsigned integral type that can hold non-negative difference between 122250661Sdavidcs * function pointers. 123250661Sdavidcs */ 124250661Sdavidcstypedef u_int fptrdiff_t; 125250661Sdavidcs 126250661Sdavidcs#ifdef _KERNEL 127250661Sdavidcs 128250661Sdavidcsvoid mcount(uintfptr_t frompc, uintfptr_t selfpc); 129250661Sdavidcsvoid kmupetext(uintfptr_t nhighpc); 130250661Sdavidcs 131250661Sdavidcs#ifdef GUPROF 132250661Sdavidcsstruct gmonparam; 133250661Sdavidcs 134250661Sdavidcsvoid nullfunc_loop_profiled(void); 135250661Sdavidcsvoid nullfunc_profiled(void); 136250661Sdavidcsvoid startguprof(struct gmonparam *p); 137250661Sdavidcsvoid stopguprof(struct gmonparam *p); 138250661Sdavidcs#else 139250661Sdavidcs#define startguprof(p) 140250661Sdavidcs#define stopguprof(p) 141250661Sdavidcs#endif /* GUPROF */ 142250661Sdavidcs 143250661Sdavidcs#else /* !_KERNEL */ 144250661Sdavidcs 145250661Sdavidcs#include <sys/cdefs.h> 146250661Sdavidcs 147250661Sdavidcs__BEGIN_DECLS 148250661Sdavidcs#ifdef __GNUC__ 149250661Sdavidcsvoid mcount(void) __asm(".mcount"); 150250661Sdavidcs#endif 151250661Sdavidcsstatic void _mcount(uintfptr_t frompc, uintfptr_t selfpc); 152250661Sdavidcs__END_DECLS 153250661Sdavidcs 154250661Sdavidcs#endif /* _KERNEL */ 155250661Sdavidcs 156250661Sdavidcs#ifdef GUPROF 157250661Sdavidcs/* XXX doesn't quite work outside kernel yet. */ 158250661Sdavidcsextern int cputime_bias; 159250661Sdavidcs 160250661Sdavidcs__BEGIN_DECLS 161250661Sdavidcsint cputime(void); 162250661Sdavidcsvoid empty_loop(void); 163250661Sdavidcsvoid mexitcount(uintfptr_t selfpc); 164250661Sdavidcsvoid nullfunc(void); 165250661Sdavidcsvoid nullfunc_loop(void); 166250661Sdavidcs__END_DECLS 167250661Sdavidcs#endif 168250661Sdavidcs 169250661Sdavidcs#endif /* !_MACHINE_PROFILE_H_ */ 170250661Sdavidcs