diff options
author | davidxu <davidxu@FreeBSD.org> | 2005-05-06 07:37:01 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2005-05-06 07:37:01 +0000 |
commit | 42ce29d66bd2407a5f5b3ec0d6fafec55fdf18a8 (patch) | |
tree | 8789a630d24784bf05ab9999d13d859e0efbdc30 /lib/libc/gmon | |
parent | e513415af91332f009d9733c7156e1a4a60c244f (diff) | |
download | FreeBSD-src-42ce29d66bd2407a5f5b3ec0d6fafec55fdf18a8.zip FreeBSD-src-42ce29d66bd2407a5f5b3ec0d6fafec55fdf18a8.tar.gz |
Fix race by using atomic operation, with this change, both libpthread
and libthr now can run profiling on SMP.
Diffstat (limited to 'lib/libc/gmon')
-rw-r--r-- | lib/libc/gmon/mcount.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/lib/libc/gmon/mcount.c b/lib/libc/gmon/mcount.c index d4faba2..b3b561c 100644 --- a/lib/libc/gmon/mcount.c +++ b/lib/libc/gmon/mcount.c @@ -49,6 +49,7 @@ void btrap(void); void eintr(void); void user(void); #endif +#include <machine/atomic.h> /* * mcount is called on entry to each function compiled with the profiling @@ -92,7 +93,8 @@ _MCOUNT_DECL(uintfptr_t frompc, uintfptr_t selfpc) #ifdef _KERNEL MCOUNT_ENTER(s); #else - p->state = GMON_PROF_BUSY; + if (!atomic_cmpset_acq_int(&p->state, GMON_PROF_ON, GMON_PROF_BUSY)) + return; #endif frompci = frompc - p->lowpc; @@ -260,11 +262,11 @@ done: #ifdef _KERNEL MCOUNT_EXIT(s); #else - p->state = GMON_PROF_ON; + atomic_store_rel_int(&p->state, GMON_PROF_ON); #endif return; overflow: - p->state = GMON_PROF_ERROR; + atomic_store_rel_int(&p->state, GMON_PROF_ERROR); #ifdef _KERNEL MCOUNT_EXIT(s); #endif |