18#define GMON_PROF_BUSY 1
19#define GMON_PROF_ERROR 2
20#define GMON_PROF_OFF 3
22#define GMONVERSION 0x00051879
25#include <timer_alarm.h>
53 unsigned int textsize;
54 unsigned int hashfraction;
60 unsigned int *samples;
74#define SAMPLE_FREQ 1000
82__attribute__((__no_instrument_function__, __no_profile_instrument_function__))
83static uint64_t timer_handler(
int id, uint64_t scheduled_time, uint64_t actual_time,
void *arg,
void *pc_value)
87 unsigned int frompc = current_gp->pc;
89 if (current_gp->state == GMON_PROF_ON) {
91 if (frompc >= current_gp->lowpc && frompc <= current_gp->highpc) {
92 int e = (frompc - current_gp->lowpc) / current_gp->hashfraction;
93 current_gp->samples[e]++;
98 current_gp->timerId = iSetTimerAlarm(USec2TimerBusClock(SAMPLE_FREQ), &timer_handler, arg);
109__attribute__((__no_instrument_function__, __no_profile_instrument_function__))
112 memset(&gp,
'\0',
sizeof(gp));
113 gp.state = GMON_PROF_ON;
114 gp.lowpc = (
unsigned int)&_ftext;
115 gp.highpc = (
unsigned int)&_etext;
116 gp.textsize = gp.highpc - gp.lowpc;
117 gp.hashfraction = HISTFRACTION;
119 gp.narcs = (gp.textsize + gp.hashfraction - 1) / gp.hashfraction;
120 gp.arcs = (
struct rawarc *)malloc(
sizeof(
struct rawarc) * gp.narcs);
121 if (gp.arcs == NULL) {
122 gp.state = GMON_PROF_ERROR;
126 gp.nsamples = (gp.textsize + gp.hashfraction - 1) / gp.hashfraction;
127 gp.samples = (
unsigned int *)malloc(
sizeof(
unsigned int) * gp.nsamples);
128 if (gp.samples == NULL) {
131 gp.state = GMON_PROF_ERROR;
135 memset((
void *)gp.arcs,
'\0', gp.narcs * (
sizeof(
struct rawarc)));
136 memset((
void *)gp.samples,
'\0', gp.nsamples * (
sizeof(
unsigned int)));
139 gp.state = GMON_PROF_ON;
140 gp.timerId = SetTimerAlarm(USec2TimerBusClock(SAMPLE_FREQ), &timer_handler, &gp);
141 if (gp.timerId < 0) {
146 gp.state = GMON_PROF_ERROR;
151__attribute__((__no_instrument_function__, __no_profile_instrument_function__))
152void gprof_start(
void)
155 if (gp.state == GMON_PROF_ON) {
161__attribute__((__no_instrument_function__, __no_profile_instrument_function__))
162void gprof_stop(
const char *filename,
int should_dump)
168 if (gp.state != GMON_PROF_ON) {
174 gp.state = GMON_PROF_OFF;
176 ReleaseTimerAlarm(gp.timerId);
179 fp = fopen(filename,
"wb");
182 hdr.ncnt =
sizeof(hdr) + (
sizeof(
unsigned int) * gp.nsamples);
183 hdr.version = GMONVERSION;
184 hdr.profrate = SAMPLE_FREQ;
188 fwrite(&hdr, 1,
sizeof(hdr), fp);
189 fwrite(gp.samples, gp.nsamples,
sizeof(
unsigned int), fp);
191 for (i = 0; i < gp.narcs; i++) {
192 if (gp.arcs[i].count > 0) {
193 fwrite(gp.arcs + i,
sizeof(
struct rawarc), 1, fp);
209__attribute__((__no_instrument_function__, __no_profile_instrument_function__))
210void __gprof_cleanup()
212 gprof_stop(
"gmon.out", 1);
224__attribute__((__no_instrument_function__, __no_profile_instrument_function__))
225void __mcount(
unsigned int frompc,
unsigned int selfpc)
230 if (gp.state != GMON_PROF_ON) {
235 frompc = frompc & 0x0FFFFFFF;
236 selfpc = selfpc & 0x0FFFFFFF;
239 if (frompc >= gp.lowpc && frompc <= gp.highpc) {
241 e = (frompc - gp.lowpc) / gp.hashfraction;
243 arc->frompc = frompc;
244 arc->selfpc = selfpc;