mirror of
https://github.com/adtools/clib2.git
synced 2025-12-08 14:59:05 +00:00
Removed compiler warnings
git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14979 87f5fb63-7c3d-0410-a384-fd976d0f7a62
This commit is contained in:
@ -3,21 +3,24 @@
|
|||||||
#include <proto/exec.h>
|
#include <proto/exec.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
||||||
|
void __mcount(uint32 frompc, uint32 selfpc);
|
||||||
|
|
||||||
void
|
void
|
||||||
__mcount(uint32 frompc, uint32 selfpc)
|
__mcount(uint32 frompc, uint32 selfpc)
|
||||||
{
|
{
|
||||||
uint16 *frompcindex;
|
uint16 *frompcindex;
|
||||||
struct tostruct *top, *prevtop;
|
struct tostruct *top, *prevtop;
|
||||||
struct gmonparam *p;
|
struct gmonparam *p;
|
||||||
|
|
||||||
int32 toindex;
|
int32 toindex;
|
||||||
|
|
||||||
p = &_gmonparam;
|
p = &_gmonparam;
|
||||||
|
|
||||||
if (p->state != kGmonProfOn) return;
|
if (p->state != kGmonProfOn) return;
|
||||||
|
|
||||||
p->state = kGmonProfBusy;
|
p->state = kGmonProfBusy;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the PC is inside our text segment.
|
* Check if the PC is inside our text segment.
|
||||||
* Really should be...
|
* Really should be...
|
||||||
@ -29,18 +32,18 @@ __mcount(uint32 frompc, uint32 selfpc)
|
|||||||
#if (HASHFRACTION & (HASHFRACTION-1)) == 0
|
#if (HASHFRACTION & (HASHFRACTION-1)) == 0
|
||||||
if (p->hashfraction == HASHFRACTION)
|
if (p->hashfraction == HASHFRACTION)
|
||||||
{
|
{
|
||||||
frompcindex = &p->froms[(size_t)(frompc / (HASHFRACTION *
|
frompcindex = &p->froms[(size_t)(frompc / (HASHFRACTION *
|
||||||
sizeof(*p->froms)))];
|
sizeof(*p->froms)))];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
frompcindex = &p->froms[(size_t)(frompc / (p->hashfraction *
|
frompcindex = &p->froms[(size_t)(frompc / (p->hashfraction *
|
||||||
sizeof(*p->froms)))];
|
sizeof(*p->froms)))];
|
||||||
}
|
}
|
||||||
|
|
||||||
toindex = *frompcindex;
|
toindex = *frompcindex;
|
||||||
|
|
||||||
if (toindex == 0)
|
if (toindex == 0)
|
||||||
{
|
{
|
||||||
/* first time down this arc */
|
/* first time down this arc */
|
||||||
@ -48,7 +51,7 @@ __mcount(uint32 frompc, uint32 selfpc)
|
|||||||
if (toindex >= p->tolimit)
|
if (toindex >= p->tolimit)
|
||||||
/* Ouch! Overflow */
|
/* Ouch! Overflow */
|
||||||
goto overflow;
|
goto overflow;
|
||||||
|
|
||||||
*frompcindex = (uint16)toindex;
|
*frompcindex = (uint16)toindex;
|
||||||
top = &p->tos[toindex];
|
top = &p->tos[toindex];
|
||||||
top->selfpc = selfpc;
|
top->selfpc = selfpc;
|
||||||
@ -56,7 +59,7 @@ __mcount(uint32 frompc, uint32 selfpc)
|
|||||||
top->link = 0;
|
top->link = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
top = &p->tos[toindex];
|
top = &p->tos[toindex];
|
||||||
if (top->selfpc == selfpc)
|
if (top->selfpc == selfpc)
|
||||||
{
|
{
|
||||||
@ -64,15 +67,15 @@ __mcount(uint32 frompc, uint32 selfpc)
|
|||||||
top->count++;
|
top->count++;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (top->link == 0)
|
if (top->link == 0)
|
||||||
{
|
{
|
||||||
toindex = ++p->tos[0].link;
|
toindex = ++p->tos[0].link;
|
||||||
if (toindex >= p->tolimit)
|
if (toindex >= p->tolimit)
|
||||||
goto overflow;
|
goto overflow;
|
||||||
|
|
||||||
top = &p->tos[toindex];
|
top = &p->tos[toindex];
|
||||||
top->selfpc = selfpc;
|
top->selfpc = selfpc;
|
||||||
top->count = 1;
|
top->count = 1;
|
||||||
@ -92,11 +95,11 @@ __mcount(uint32 frompc, uint32 selfpc)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
p->state = kGmonProfOn;
|
p->state = kGmonProfOn;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
overflow:
|
overflow:
|
||||||
p->state = kGmonProfError;
|
p->state = kGmonProfError;
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -12,7 +12,11 @@
|
|||||||
#undef DebugPrintF
|
#undef DebugPrintF
|
||||||
#define dprintf(format, args...)((struct ExecIFace *)((*(struct ExecBase **)4)->MainInterface))->DebugPrintF("[%s] " format, __PRETTY_FUNCTION__ , ## args)
|
#define dprintf(format, args...)((struct ExecIFace *)((*(struct ExecBase **)4)->MainInterface))->DebugPrintF("[%s] " format, __PRETTY_FUNCTION__ , ## args)
|
||||||
|
|
||||||
struct gmonparam _gmonparam = {kGmonProfOn};
|
struct gmonparam _gmonparam =
|
||||||
|
{
|
||||||
|
state: kGmonProfOn
|
||||||
|
};
|
||||||
|
|
||||||
static unsigned int s_scale;
|
static unsigned int s_scale;
|
||||||
|
|
||||||
void moncontrol(int);
|
void moncontrol(int);
|
||||||
@ -20,7 +24,7 @@ void monstartup(uint32, uint32);
|
|||||||
void moncleanup(void);
|
void moncleanup(void);
|
||||||
void mongetpcs(uint32* lowpc, uint32 *highpc);
|
void mongetpcs(uint32* lowpc, uint32 *highpc);
|
||||||
|
|
||||||
extern int profil(uint16 *buffer, uint32 bufSize,
|
extern int profil(uint16 *buffer, uint32 bufSize,
|
||||||
uint32 offset, uint32 scale);
|
uint32 offset, uint32 scale);
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -31,7 +35,7 @@ monstartup(uint32 low_pc, uint32 high_pc)
|
|||||||
struct gmonparam *p = &_gmonparam;
|
struct gmonparam *p = &_gmonparam;
|
||||||
dprintf("in monstartup)\n");
|
dprintf("in monstartup)\n");
|
||||||
/*
|
/*
|
||||||
* If we don't get proper lowpc and highpc, then
|
* If we don't get proper lowpc and highpc, then
|
||||||
* we'll try to get them from the elf handle.
|
* we'll try to get them from the elf handle.
|
||||||
*/
|
*/
|
||||||
if (low_pc == 0 && high_pc == 0)
|
if (low_pc == 0 && high_pc == 0)
|
||||||
@ -43,44 +47,44 @@ monstartup(uint32 low_pc, uint32 high_pc)
|
|||||||
lowpc = low_pc;
|
lowpc = low_pc;
|
||||||
highpc = high_pc;
|
highpc = high_pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Round lowpc and highpc to multiples of the density
|
* Round lowpc and highpc to multiples of the density
|
||||||
* to prevent using floating point scaling
|
* to prevent using floating point scaling
|
||||||
*/
|
*/
|
||||||
p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
|
p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
|
||||||
p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
|
p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
|
||||||
|
|
||||||
/* Size of the text segment */
|
/* Size of the text segment */
|
||||||
p->textsize = p->highpc - p->lowpc;
|
p->textsize = p->highpc - p->lowpc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Size of the histogram. Due to the nature of PowerPC code,
|
* Size of the histogram. Due to the nature of PowerPC code,
|
||||||
* we can safely use a histogram fraction of at least 4, since
|
* we can safely use a histogram fraction of at least 4, since
|
||||||
* every instruction is exactly one word wide and always aligned.
|
* every instruction is exactly one word wide and always aligned.
|
||||||
*/
|
*/
|
||||||
p->kcountsize = p->textsize / HISTFRACTION;
|
p->kcountsize = p->textsize / HISTFRACTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The hash table size
|
* The hash table size
|
||||||
*/
|
*/
|
||||||
p->hashfraction = HASHFRACTION;
|
p->hashfraction = HASHFRACTION;
|
||||||
p->fromssize = p->textsize / p->hashfraction;
|
p->fromssize = p->textsize / p->hashfraction;
|
||||||
|
|
||||||
p->tolimit = p->textsize * ARCDENSITY / 100;
|
p->tolimit = p->textsize * ARCDENSITY / 100;
|
||||||
if (p->tolimit < MINARCS)
|
if (p->tolimit < MINARCS)
|
||||||
p->tolimit = MINARCS;
|
p->tolimit = MINARCS;
|
||||||
else if (p->tolimit > MAXARCS)
|
else if (p->tolimit > MAXARCS)
|
||||||
p->tolimit = MAXARCS;
|
p->tolimit = MAXARCS;
|
||||||
|
|
||||||
p->tossize = p->tolimit * sizeof(struct tostruct);
|
p->tossize = p->tolimit * sizeof(struct tostruct);
|
||||||
|
|
||||||
dprintf("lowpc = %p, highpc = %p\n", lowpc, highpc);
|
dprintf("lowpc = %p, highpc = %p\n", lowpc, highpc);
|
||||||
dprintf("textsize = %d\n", p->textsize);
|
dprintf("textsize = %d\n", p->textsize);
|
||||||
dprintf("kcountsize = %d\n", p->kcountsize);
|
dprintf("kcountsize = %d\n", p->kcountsize);
|
||||||
dprintf("fromssize = %d\n", p->fromssize);
|
dprintf("fromssize = %d\n", p->fromssize);
|
||||||
dprintf("tolimit = %d, tossize = %d\n", p->tolimit, p->tossize);
|
dprintf("tolimit = %d, tossize = %d\n", p->tolimit, p->tossize);
|
||||||
|
|
||||||
cp = (uint8*)AllocMem(p->kcountsize + p->fromssize + p->tossize,
|
cp = (uint8*)AllocMem(p->kcountsize + p->fromssize + p->tossize,
|
||||||
MEMF_CLEAR);
|
MEMF_CLEAR);
|
||||||
if (!cp)
|
if (!cp)
|
||||||
@ -88,26 +92,26 @@ monstartup(uint32 low_pc, uint32 high_pc)
|
|||||||
p->state = kGmonProfError;
|
p->state = kGmonProfError;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->memory = cp;
|
p->memory = cp;
|
||||||
p->tos = (struct tostruct *)cp;
|
p->tos = (struct tostruct *)cp;
|
||||||
cp += p->tossize;
|
cp += p->tossize;
|
||||||
|
|
||||||
p->kcount = (uint16 *)cp;
|
p->kcount = (uint16 *)cp;
|
||||||
cp += p->kcountsize;
|
cp += p->kcountsize;
|
||||||
|
|
||||||
p->froms = (uint16 *)cp;
|
p->froms = (uint16 *)cp;
|
||||||
|
|
||||||
p->tos[0].link = 0;
|
p->tos[0].link = 0;
|
||||||
|
|
||||||
/* Verify granularity for sampling */
|
/* Verify granularity for sampling */
|
||||||
if (p->kcountsize < p->textsize)
|
if (p->kcountsize < p->textsize)
|
||||||
/* FIXME Avoid floating point */
|
/* FIXME Avoid floating point */
|
||||||
s_scale = ((float)p->kcountsize / p->textsize) * SCALE_1_TO_1;
|
s_scale = ((float)p->kcountsize / p->textsize) * SCALE_1_TO_1;
|
||||||
else
|
else
|
||||||
s_scale = SCALE_1_TO_1;
|
s_scale = SCALE_1_TO_1;
|
||||||
|
|
||||||
s_scale >>= 1;
|
s_scale >>= 1;
|
||||||
dprintf("Enabling monitor\n");
|
dprintf("Enabling monitor\n");
|
||||||
moncontrol(1);
|
moncontrol(1);
|
||||||
}
|
}
|
||||||
@ -116,7 +120,7 @@ void
|
|||||||
moncontrol(int mode)
|
moncontrol(int mode)
|
||||||
{
|
{
|
||||||
struct gmonparam *p = &_gmonparam;
|
struct gmonparam *p = &_gmonparam;
|
||||||
|
|
||||||
if (mode)
|
if (mode)
|
||||||
{
|
{
|
||||||
/* Start profiling. */
|
/* Start profiling. */
|
||||||
@ -145,7 +149,7 @@ moncleanup(void)
|
|||||||
struct gmonhdr gmonhdr, *hdr;
|
struct gmonhdr gmonhdr, *hdr;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
FILE *log;
|
FILE *log;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
moncontrol(0);
|
moncontrol(0);
|
||||||
|
|
||||||
@ -153,35 +157,35 @@ moncleanup(void)
|
|||||||
{
|
{
|
||||||
fprintf(stderr, "WARNING: Overflow during profiling\n");
|
fprintf(stderr, "WARNING: Overflow during profiling\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = Open("gmon.out", MODE_NEWFILE);
|
fd = Open("gmon.out", MODE_NEWFILE);
|
||||||
if (!fd)
|
if (!fd)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "ERROR: could not open gmon.out\n");
|
fprintf(stderr, "ERROR: could not open gmon.out\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr = (struct gmonhdr *)&gmonhdr;
|
hdr = (struct gmonhdr *)&gmonhdr;
|
||||||
|
|
||||||
hdr->lpc = 0; //p->lowpc;
|
hdr->lpc = 0; //p->lowpc;
|
||||||
hdr->hpc = p->highpc - p->lowpc;
|
hdr->hpc = p->highpc - p->lowpc;
|
||||||
hdr->ncnt = (int)p->kcountsize + sizeof(gmonhdr);
|
hdr->ncnt = (int)p->kcountsize + sizeof(gmonhdr);
|
||||||
hdr->version = GMONVERSION;
|
hdr->version = GMONVERSION;
|
||||||
hdr->profrate = 100; //FIXME:!!
|
hdr->profrate = 100; //FIXME:!!
|
||||||
|
|
||||||
Write(fd, hdr, sizeof(*hdr));
|
Write(fd, hdr, sizeof(*hdr));
|
||||||
Write(fd, p->kcount, p->kcountsize);
|
Write(fd, p->kcount, p->kcountsize);
|
||||||
|
|
||||||
endfrom = p->fromssize / sizeof(*p->froms);
|
endfrom = p->fromssize / sizeof(*p->froms);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
log = fopen("gmon.log", "w");
|
log = fopen("gmon.log", "w");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (fromindex = 0; fromindex < endfrom; fromindex++)
|
for (fromindex = 0; fromindex < endfrom; fromindex++)
|
||||||
{
|
{
|
||||||
if (p->froms[fromindex] == 0) continue;
|
if (p->froms[fromindex] == 0) continue;
|
||||||
|
|
||||||
frompc = 0; /* FIXME: was p->lowpc; needs to be 0 and assumes
|
frompc = 0; /* FIXME: was p->lowpc; needs to be 0 and assumes
|
||||||
-Ttext=0 on compile. Better idea? */
|
-Ttext=0 on compile. Better idea? */
|
||||||
frompc += fromindex * p->hashfraction * sizeof (*p->froms);
|
frompc += fromindex * p->hashfraction * sizeof (*p->froms);
|
||||||
@ -189,10 +193,10 @@ moncleanup(void)
|
|||||||
toindex = p->tos[toindex].link)
|
toindex = p->tos[toindex].link)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (log) fprintf(log, "%p called from %p: %d times\n", frompc,
|
if (log) fprintf(log, "%p called from %p: %d times\n", frompc,
|
||||||
p->tos[toindex].selfpc,
|
p->tos[toindex].selfpc,
|
||||||
p->tos[toindex].count);
|
p->tos[toindex].count);
|
||||||
#endif
|
#endif
|
||||||
rawarc.raw_frompc = frompc;
|
rawarc.raw_frompc = frompc;
|
||||||
rawarc.raw_selfpc = p->tos[toindex].selfpc;
|
rawarc.raw_selfpc = p->tos[toindex].selfpc;
|
||||||
rawarc.raw_count = p->tos[toindex].count;
|
rawarc.raw_count = p->tos[toindex].count;
|
||||||
@ -202,9 +206,9 @@ moncleanup(void)
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (log) fclose(log);
|
if (log) fclose(log);
|
||||||
#endif
|
#endif
|
||||||
Close(fd);
|
Close(fd);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -218,31 +222,31 @@ mongetpcs(uint32* lowpc, uint32 *highpc)
|
|||||||
uint32 i;
|
uint32 i;
|
||||||
Elf32_Shdr *shdr;
|
Elf32_Shdr *shdr;
|
||||||
uint32 numSections;
|
uint32 numSections;
|
||||||
|
|
||||||
*lowpc = 0;
|
*lowpc = 0;
|
||||||
*highpc = 0;
|
*highpc = 0;
|
||||||
|
|
||||||
ElfBase = OpenLibrary("elf.library", 0L);
|
ElfBase = OpenLibrary("elf.library", 0L);
|
||||||
if (!ElfBase) goto out;
|
if (!ElfBase) goto out;
|
||||||
|
|
||||||
IElf = (struct ElfIFace *)GetInterface(ElfBase, "main", 1, NULL);
|
IElf = (struct ElfIFace *)GetInterface(ElfBase, "main", 1, NULL);
|
||||||
if (!IElf) goto out;
|
if (!IElf) goto out;
|
||||||
|
|
||||||
self = (struct Process *)FindTask(0);
|
self = (struct Process *)FindTask(0);
|
||||||
seglist = GetProcSegList(self);
|
seglist = GetProcSegList(self);
|
||||||
|
|
||||||
GetSegListInfoTags(seglist,
|
GetSegListInfoTags(seglist,
|
||||||
GSLI_ElfHandle, &elfHandle,
|
GSLI_ElfHandle, &elfHandle,
|
||||||
TAG_DONE);
|
TAG_DONE);
|
||||||
|
|
||||||
elfHandle = OpenElfTags(
|
elfHandle = OpenElfTags(
|
||||||
OET_ElfHandle, elfHandle,
|
OET_ElfHandle, elfHandle,
|
||||||
TAG_DONE);
|
TAG_DONE);
|
||||||
|
|
||||||
if (!elfHandle) goto out;
|
if (!elfHandle) goto out;
|
||||||
|
|
||||||
GetElfAttrsTags(elfHandle, EAT_NumSections, &numSections, TAG_DONE);
|
GetElfAttrsTags(elfHandle, EAT_NumSections, &numSections, TAG_DONE);
|
||||||
|
|
||||||
for (i = 0; i < numSections; i++)
|
for (i = 0; i < numSections; i++)
|
||||||
{
|
{
|
||||||
shdr = GetSectionHeaderTags(elfHandle,
|
shdr = GetSectionHeaderTags(elfHandle,
|
||||||
@ -269,6 +273,9 @@ out:
|
|||||||
|
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
|
||||||
|
int __profiler_init(void) __attribute__((constructor));
|
||||||
|
void __profiler_exit(void) __attribute__((destructor));
|
||||||
|
|
||||||
int __profiler_init(void)
|
int __profiler_init(void)
|
||||||
{
|
{
|
||||||
monstartup(0,0);
|
monstartup(0,0);
|
||||||
@ -278,4 +285,4 @@ int __profiler_init(void)
|
|||||||
void __profiler_exit(void)
|
void __profiler_exit(void)
|
||||||
{
|
{
|
||||||
moncleanup();
|
moncleanup();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ _mcount:
|
|||||||
mflr r4
|
mflr r4
|
||||||
stw r4,48(r1)
|
stw r4,48(r1)
|
||||||
lwz r3,68(r1)
|
lwz r3,68(r1)
|
||||||
|
|
||||||
bl __mcount
|
bl __mcount
|
||||||
lwz r3,68(r1)
|
lwz r3,68(r1)
|
||||||
mtlr r3
|
mtlr r3
|
||||||
@ -32,4 +32,5 @@ _mcount:
|
|||||||
addi r1,r1,64
|
addi r1,r1,64
|
||||||
bctr
|
bctr
|
||||||
_mcount_end:
|
_mcount_end:
|
||||||
.size _mcount,_mcount_end-_mcount
|
.size _mcount,_mcount_end-_mcount
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
#include <proto/exec.h>
|
#include <proto/exec.h>
|
||||||
#include <proto/performancemonitor.h>
|
|
||||||
#include <exec/interrupts.h>
|
#include <exec/interrupts.h>
|
||||||
|
#include <interfaces/performancemonitor.h>
|
||||||
|
#include <resources/performancemonitor.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
static struct PerformanceMonitorIFace *IPM;
|
|
||||||
static struct Interrupt CounterInt;
|
static struct Interrupt CounterInt;
|
||||||
|
static struct PerformanceMonitorIFace *IPM;
|
||||||
#undef DebugPrintF
|
|
||||||
#define dprintf(format, args...)((struct ExecIFace *)((*(struct ExecBase **)4)->MainInterface))->DebugPrintF("[%s] " format, __PRETTY_FUNCTION__ , ## args)
|
|
||||||
|
|
||||||
static struct IntData
|
static struct IntData
|
||||||
{
|
{
|
||||||
@ -18,77 +17,83 @@ static struct IntData
|
|||||||
uint32 CounterStart;
|
uint32 CounterStart;
|
||||||
} ProfileData;
|
} ProfileData;
|
||||||
|
|
||||||
|
uint32 GetCounterStart(void);
|
||||||
|
uint32 CounterIntFn(struct ExceptionContext *, struct ExecBase *, struct IntData *);
|
||||||
|
|
||||||
uint32
|
|
||||||
|
uint32
|
||||||
GetCounterStart(void)
|
GetCounterStart(void)
|
||||||
{
|
{
|
||||||
uint64 fsb;
|
uint64 fsb;
|
||||||
double bit0time;
|
double bit0time;
|
||||||
uint32 count;
|
uint32 count;
|
||||||
|
|
||||||
GetCPUInfoTags(
|
GetCPUInfoTags(
|
||||||
GCIT_FrontsideSpeed, &fsb,
|
GCIT_FrontsideSpeed, &fsb,
|
||||||
TAG_DONE);
|
TAG_DONE);
|
||||||
|
|
||||||
/* Timebase ticks at 1/4 of FSB */
|
/* Timebase ticks at 1/4 of FSB */
|
||||||
bit0time = 8.0 / (double)fsb;
|
bit0time = 8.0 / (double)fsb;
|
||||||
count = (uint32)(0.01 / bit0time);
|
count = (uint32)(0.01 / bit0time);
|
||||||
|
|
||||||
return 0x80000000 - count;
|
return 0x80000000 - count;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
CounterIntFn(struct ExceptionContext *ctx, struct ExecBase *ExecBase,
|
CounterIntFn(struct ExceptionContext *ctx, struct ExecBase *ExecBase,
|
||||||
struct IntData *ProfileData)
|
struct IntData *ProfileData)
|
||||||
{
|
{
|
||||||
uint32 sia = (uint32)ProfileData->IPM->GetSampledAddress();
|
uint32 sia = (uint32)ProfileData->IPM->GetSampledAddress();
|
||||||
dprintf(".\n");
|
|
||||||
|
/* Silence compiler */
|
||||||
|
(void)ExecBase;
|
||||||
|
(void)ctx;
|
||||||
|
|
||||||
sia = ((sia - ProfileData->Offset) * ProfileData->Scale) >> 16;
|
sia = ((sia - ProfileData->Offset) * ProfileData->Scale) >> 16;
|
||||||
|
|
||||||
if (sia <= (ProfileData->BufferSize>>1))
|
if (sia <= (ProfileData->BufferSize>>1))
|
||||||
{
|
{
|
||||||
//if (ProfileData->Buffer[sia] != 0xffff)
|
//if (ProfileData->Buffer[sia] != 0xffff)
|
||||||
ProfileData->Buffer[sia]++;
|
ProfileData->Buffer[sia]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPM->CounterControl(1, ProfileData->CounterStart, PMCI_Transition);
|
IPM->CounterControl(1, ProfileData->CounterStart, PMCI_Transition);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
profil(uint16 *buffer, uint32 bufSize, uint32 offset, uint32 scale)
|
profil(unsigned short *buffer, size_t bufSize, size_t offset, unsigned int scale)
|
||||||
{
|
{
|
||||||
APTR Stack;
|
APTR Stack;
|
||||||
|
|
||||||
if (buffer == 0)
|
if (buffer == 0)
|
||||||
{
|
{
|
||||||
Stack = SuperState();
|
Stack = SuperState();
|
||||||
IPM->EventControlTags(
|
IPM->EventControlTags(
|
||||||
PMECT_Disable, PMEC_MasterInterrupt,
|
PMECT_Disable, PMEC_MasterInterrupt,
|
||||||
TAG_DONE);
|
TAG_DONE);
|
||||||
|
|
||||||
IPM->SetInterruptVector(1, 0);
|
IPM->SetInterruptVector(1, 0);
|
||||||
|
|
||||||
IPM->Unmark(0);
|
IPM->Unmark(0);
|
||||||
IPM->Release();
|
IPM->Release();
|
||||||
if (Stack) UserState(Stack);
|
if (Stack) UserState(Stack);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPM = (struct PerformanceMonitorIFace *)
|
IPM = (struct PerformanceMonitorIFace *)
|
||||||
OpenResource("performancemonitor.resource");
|
OpenResource("performancemonitor.resource");
|
||||||
|
|
||||||
if (!IPM || IPM->Obtain() != 1)
|
if (!IPM || IPM->Obtain() != 1)
|
||||||
{
|
{
|
||||||
dprintf("No performance monitor\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack = SuperState();
|
Stack = SuperState();
|
||||||
|
|
||||||
/* Init IntData */
|
/* Init IntData */
|
||||||
ProfileData.IPM = IPM;
|
ProfileData.IPM = IPM;
|
||||||
ProfileData.Buffer = buffer;
|
ProfileData.Buffer = buffer;
|
||||||
@ -96,27 +101,27 @@ profil(uint16 *buffer, uint32 bufSize, uint32 offset, uint32 scale)
|
|||||||
ProfileData.Offset = offset;
|
ProfileData.Offset = offset;
|
||||||
ProfileData.Scale = scale;
|
ProfileData.Scale = scale;
|
||||||
ProfileData.CounterStart = GetCounterStart();
|
ProfileData.CounterStart = GetCounterStart();
|
||||||
|
|
||||||
/* Set interrupt vector */
|
/* Set interrupt vector */
|
||||||
CounterInt.is_Code = (void (*)())CounterIntFn;
|
CounterInt.is_Code = (void (*)())CounterIntFn;
|
||||||
CounterInt.is_Data = &ProfileData;
|
CounterInt.is_Data = &ProfileData;
|
||||||
IPM->SetInterruptVector(1, &CounterInt);
|
IPM->SetInterruptVector(1, &CounterInt);
|
||||||
|
|
||||||
/* Prepare Performance Monitor */
|
/* Prepare Performance Monitor */
|
||||||
IPM->MonitorControlTags(
|
IPM->MonitorControlTags(
|
||||||
PMMCT_FreezeCounters, PMMC_Unmarked,
|
PMMCT_FreezeCounters, PMMC_Unmarked,
|
||||||
PMMCT_RTCBitSelect, PMMC_BIT0,
|
PMMCT_RTCBitSelect, PMMC_BIT0,
|
||||||
TAG_DONE);
|
TAG_DONE);
|
||||||
IPM->CounterControl(1, ProfileData.CounterStart, PMCI_Transition);
|
IPM->CounterControl(1, ProfileData.CounterStart, PMCI_Transition);
|
||||||
|
|
||||||
IPM->EventControlTags(
|
IPM->EventControlTags(
|
||||||
PMECT_Enable, 1,
|
PMECT_Enable, 1,
|
||||||
PMECT_Enable, PMEC_MasterInterrupt,
|
PMECT_Enable, PMEC_MasterInterrupt,
|
||||||
TAG_DONE);
|
TAG_DONE);
|
||||||
|
|
||||||
IPM->Mark(0);
|
IPM->Mark(0);
|
||||||
|
|
||||||
if (Stack) UserState(Stack);
|
if (Stack) UserState(Stack);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user