summaryrefslogtreecommitdiff
path: root/gmon
diff options
context:
space:
mode:
Diffstat (limited to 'gmon')
-rw-r--r--gmon/gmon.c6
-rw-r--r--gmon/mcount.c32
-rw-r--r--gmon/sys/gmon.h2
3 files changed, 18 insertions, 22 deletions
diff --git a/gmon/gmon.c b/gmon/gmon.c
index 300ca30a09..10ae215c80 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 66da3d054b..fe392c0949 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 930729e7fc..85d9392d8e 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;