fdwalk should return 0 on an empty directory
[kopensolaris-gnu/glibc.git] / gmon / mcount.c
index 4d3097f..5a4a249 100644 (file)
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
 #if !defined(lint) && !defined(KERNEL) && defined(LIBC_SCCS)
 static char sccsid[] = "@(#)mcount.c   8.1 (Berkeley) 6/4/93";
 #endif
-       int i;
 
+#include <unistd.h>
 #include <sys/param.h>
 #include <sys/gmon.h>
 
 /* This file provides the machine-dependent definitions of the _MCOUNT_DECL
    and MCOUNT macros.  */
-#include "machine-gmon.h"
+#include <machine-gmon.h>
+
+#include <atomic.h>
 
 /*
  * mcount is called on entry to each function compiled with the profiling
@@ -59,15 +57,11 @@ static char sccsid[] = "@(#)mcount.c        8.1 (Berkeley) 6/4/93";
  * perform this optimization.
  */
 _MCOUNT_DECL(frompc, selfpc)   /* _mcount; may be static, inline, etc */
-       register u_long frompc, selfpc;
 {
-       register u_short *frompcindex;
+       register ARCINDEX *frompcindex;
        register struct tostruct *top, *prevtop;
        register struct gmonparam *p;
-       register long toindex;
-#ifdef KERNEL
-       register int s;
-#endif
+       register ARCINDEX toindex;
        int i;
 
        p = &_gmonparam;
@@ -75,13 +69,10 @@ _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 (catomic_compare_and_exchange_bool_acq (&p->state, GMON_PROF_BUSY,
+                                                  GMON_PROF_ON))
+         return;
+
        /*
         * check that frompcindex is a reasonable pc value.
         * for example: signal catchers get called from the stack,
@@ -91,8 +82,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));
@@ -169,17 +166,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;
 }