diff options
Diffstat (limited to 'gmon')
-rw-r--r-- | gmon/gmon.c | 6 | ||||
-rw-r--r-- | gmon/mcount.c | 32 | ||||
-rw-r--r-- | gmon/sys/gmon.h | 2 |
3 files changed, 18 insertions, 22 deletions
diff --git a/gmon/gmon.c b/gmon/gmon.c index 300ca30..10ae215 100644 --- a/gmon/gmon.c +++ b/gmon/gmon.c @@ -82,13 +82,13 @@ __moncontrol (mode) if (mode) { /* start */ - profil((void *) p->kcount, p->kcountsize, p->lowpc, s_scale); + __profil((void *) p->kcount, p->kcountsize, p->lowpc, s_scale); p->state = GMON_PROF_ON; } else { /* stop */ - profil((void *) 0, 0, 0, 0); + __profil(NULL, 0, 0, 0); p->state = GMON_PROF_OFF; } } @@ -113,6 +113,8 @@ __monstartup (lowpc, highpc) p->kcountsize = p->textsize / HISTFRACTION; p->hashfraction = HASHFRACTION; p->log_hashfraction = -1; + /* The following test must be kept in sync with the corresponding + test in mcount.c. */ if ((HASHFRACTION & (HASHFRACTION - 1)) == 0) { /* if HASHFRACTION is a power of two, mcount can use shifting instead of integer division. Precompute shift amount. */ diff --git a/gmon/mcount.c b/gmon/mcount.c index 66da3d0..fe392c0 100644 --- a/gmon/mcount.c +++ b/gmon/mcount.c @@ -42,6 +42,8 @@ static char sccsid[] = "@(#)mcount.c 8.1 (Berkeley) 6/4/93"; and MCOUNT macros. */ #include "machine-gmon.h" +#include <atomicity.h> + /* * mcount is called on entry to each function compiled with the profiling * switch set. _mcount(), which is declared in a machine-dependent way @@ -63,9 +65,6 @@ _MCOUNT_DECL(frompc, selfpc) /* _mcount; may be static, inline, etc */ register struct tostruct *top, *prevtop; register struct gmonparam *p; register long toindex; -#ifdef KERNEL - register int s; -#endif int i; p = &_gmonparam; @@ -73,13 +72,9 @@ _MCOUNT_DECL(frompc, selfpc) /* _mcount; may be static, inline, etc */ * check that we are profiling * and that we aren't recursively invoked. */ - if (p->state != GMON_PROF_ON) - return; -#ifdef KERNEL - MCOUNT_ENTER; -#else - p->state = GMON_PROF_BUSY; -#endif + if (! compare_and_swap (&p->state, GMON_PROF_ON, GMON_PROF_BUSY)) + return; + /* * check that frompcindex is a reasonable pc value. * for example: signal catchers get called from the stack, @@ -89,8 +84,14 @@ _MCOUNT_DECL(frompc, selfpc) /* _mcount; may be static, inline, etc */ if (frompc > p->textsize) goto done; - /* avoid integer divide if possible: */ - if (p->log_hashfraction >= 0) { + /* The following test used to be + if (p->log_hashfraction >= 0) + But we can simplify this if we assume the profiling data + is always initialized by the functions in gmon.c. But + then it is possible to avoid a runtime check and use the + smae `if' as in gmon.c. So keep these tests in sync. */ + if ((HASHFRACTION & (HASHFRACTION - 1)) == 0) { + /* avoid integer divide if possible: */ i = frompc >> p->log_hashfraction; } else { i = frompc / (p->hashfraction * sizeof(*p->froms)); @@ -167,17 +168,10 @@ _MCOUNT_DECL(frompc, selfpc) /* _mcount; may be static, inline, etc */ } done: -#ifdef KERNEL - MCOUNT_EXIT; -#else p->state = GMON_PROF_ON; -#endif return; overflow: p->state = GMON_PROF_ERROR; -#ifdef KERNEL - MCOUNT_EXIT; -#endif return; } diff --git a/gmon/sys/gmon.h b/gmon/sys/gmon.h index 930729e..85d9392 100644 --- a/gmon/sys/gmon.h +++ b/gmon/sys/gmon.h @@ -133,7 +133,7 @@ struct rawarc { * The profiling data structures are housed in this structure. */ struct gmonparam { - int state; + long int state; u_short *kcount; u_long kcountsize; u_short *froms; |