]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/posix/profil.c
Fri Mar 1 10:09:46 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
[thirdparty/glibc.git] / sysdeps / posix / profil.c
CommitLineData
e9607dbe
RM
1/* Low-level statistical profiling support function. Mostly POSIX.1 version.
2Copyright (C) 1996 Free Software Foundation, Inc.
3This file is part of the GNU C Library.
4
5The GNU C Library is free software; you can redistribute it and/or
6modify it under the terms of the GNU Library General Public License as
7published by the Free Software Foundation; either version 2 of the
8License, or (at your option) any later version.
9
10The GNU C Library is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13Library General Public License for more details.
14
15You should have received a copy of the GNU Library General Public
16License along with the GNU C Library; see the file COPYING.LIB. If
17not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18Cambridge, MA 02139, USA. */
19
20#include <sys/types.h>
21#include <unistd.h>
22#include <errno.h>
23#include <signal.h>
24#include <sys/time.h>
25
26#ifndef SIGPROF
27
28#include_next <profil.c>
29
30#else
31
32static u_short *samples;
33static size_t nsamples;
34static size_t pc_offset;
35static u_int pc_scale;
36
37static inline void
38profil_count (void *pc)
39{
40 size_t i = ((pc - pc_offset - (void *) 0) / 2) * pc_scale / 65536;
41 if (i < nsamples)
42 ++samples[i];
43}
44
45/* Get the machine-dependent definition of `profil_counter', the signal
46 handler for SIGPROF. It calls `profil_count' (above) with the PC of the
47 interrupted code. */
48#include "profil-counter.h"
49
50/* Enable statistical profiling, writing samples of the PC into at most
51 SIZE bytes of SAMPLE_BUFFER; every processor clock tick while profiling
52 is enabled, the system examines the user PC and increments
53 SAMPLE_BUFFER[((PC - OFFSET) / 2) * SCALE / 65536]. If SCALE is zero,
54 disable profiling. Returns zero on success, -1 on error. */
55
56int
57profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
58{
59 static struct sigaction act, oact;
60 static struct itimerval timer, otimer;
61
62 if (sample_buffer == NULL)
63 {
64 /* Disable profiling. */
65 if (samples == NULL)
66 /* Wasn't turned on. */
67 return 0;
68 samples = NULL;
69
70 if (sigaction (SIGPROF, &oact, NULL) < 0)
71 return -1;
72 return setitimer (ITIMER_PROF, &otimer, NULL);
73 }
74
75 samples = sample_buffer;
76 nsamples = size / sizeof *samples;
77 pc_offset = offset;
78 pc_scale = scale;
79
80 act.sa_handler = (sighandler_t) &profil_counter;
81 act.sa_flags = SA_RESTART;
82 sigfillset (&act.sa_mask);
83 if (sigaction (SIGPROF, &act, &oact) < 0)
84 return -1;
85
86 timer.it_value.tv_sec = 0;
87 timer.it_value.tv_usec = 1;
88 timer.it_interval = timer.it_value;
89 return setitimer (ITIMER_PROF, &timer, &otimer);
90}
91
92#endif