about summary refs log tree commit diff
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;