#ifdef PROFILER
#include <util.h>
#include <machine.h>
#include <machine/profiler.h>
#ifdef CHECKPOINT_PROFILER
volatile unsigned int checkpoint VISIBLE;
unsigned int max_checkpoint;
profiler_entry_t profiler_entries[MAX_UNIQUE_CHECKPOINTS];
#else
int profiler_num_entries;
long long profiler_dropped_instructions;
profiler_entry_t profiler_entries[MAX_UNIQUE_INSTRUCTIONS];
#endif
bool_t profiler_enabled VISIBLE = true;
#ifdef CHECKPOINT_PROFILER
void
profiler_reset(void)
{
word_t i;
for (i = 0; i < MAX_UNIQUE_CHECKPOINTS; i++) {
profiler_entries[i].pc = 0;
profiler_entries[i].count = 0;
}
checkpoint = 0;
}
void
profiler_list(void)
{
unsigned int samples, i, count;
printf("checkpoint count\n");
samples = 0;
count = 0;
for (i = 0; i <= max_checkpoint; i++) {
if (profiler_entries[i].pc != 0) {
printf("%u %u\n", i, (unsigned int)profiler_entries[i].count);
samples += profiler_entries[i].count;
count++;
}
}
printf("%u checkpoints, %u sample(s)\n", count, samples);
}
void
profiler_record_sample(word_t pc)
{
if (checkpoint > max_checkpoint) {
max_checkpoint = checkpoint;
}
if (!profiler_entries[checkpoint].pc) {
profiler_entries[checkpoint].pc = 1;
}
profiler_entries[checkpoint].count++;
}
#else
void profiler_reset(void)
{
for (word_t i = 0; i < MAX_UNIQUE_INSTRUCTIONS; i++) {
profiler_entries[i].pc = 0;
profiler_entries[i].count = 0;
}
profiler_num_entries = 0;
profiler_dropped_instructions = 0;
}
void profiler_list(void)
{
long long samples;
printf("addr count\n");
samples = 0;
for (word_t i = 0; i < MAX_UNIQUE_INSTRUCTIONS; i++) {
if (profiler_entries[i].pc != 0) {
printf("%x %d\n", (unsigned int)profiler_entries[i].pc,
(int)profiler_entries[i].count);
samples += profiler_entries[i].count;
}
}
printf("\n%d unique address(es), %d sample(s)\n",
(int)profiler_num_entries, (int)samples);
if (profiler_dropped_instructions > 0) {
printf("*** WARNING : %d instructions dropped\n",
(int)profiler_dropped_instructions);
}
}
void profiler_record_sample(word_t pc)
{
const int hashVal = 1024;
word_t hash = (pc >> 2) % MAX_UNIQUE_INSTRUCTIONS;
word_t hash2 = ((pc >> 2) % hashVal) + 1;
if (!profiler_enabled) {
return;
}
while (true) {
if (profiler_entries[hash].pc == pc) {
profiler_entries[hash].count++;
break;
} else if (profiler_entries[hash].pc == 0) {
if (profiler_num_entries < (MAX_UNIQUE_INSTRUCTIONS / 4) * 3) {
profiler_entries[hash].pc = pc;
profiler_entries[hash].count = 1;
profiler_num_entries++;
break;
} else {
profiler_dropped_instructions++;
break;
}
}
hash += hash2;
hash %= MAX_UNIQUE_INSTRUCTIONS;
}
}
#endif
#endif