From 5f5cc57d125e0b99f48f018821884ad0bdb65507 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 19 Nov 2009 19:32:54 -0700 Subject: [PATCH] only use atomic operations if the compiler supports them --- src/common.h | 9 ++++++++- src/heap.cpp | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/common.h b/src/common.h index 535e231b6c..459cd0dcef 100644 --- a/src/common.h +++ b/src/common.h @@ -63,6 +63,11 @@ typedef uint64_t uintptr_t; # include "stdint.h" +# if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1) +# define USE_ATOMIC_OPERATIONS +# define COMPARE_AND_SWAP __sync_bool_compare_and_swap +# endif + # define LIKELY(v) __builtin_expect((v) != 0, true) # define UNLIKELY(v) __builtin_expect((v) != 0, false) @@ -325,13 +330,15 @@ markBit(uintptr_t* map, unsigned i) map[wordOf(i)] |= static_cast(1) << bitOf(i); } +#ifdef USE_ATOMIC_OPERATIONS inline void markBitAtomic(uintptr_t* map, unsigned i) { uintptr_t* p = map + wordOf(i); uintptr_t v = static_cast(1) << bitOf(i); - while (not __sync_bool_compare_and_swap(p, *p, *p | v)) { } + while (not COMPARE_AND_SWAP(p, *p, *p | v)) { } } +#endif inline void clearBit(uintptr_t* map, unsigned i) diff --git a/src/heap.cpp b/src/heap.cpp index 11c3c4ceda..b2bc515814 100644 --- a/src/heap.cpp +++ b/src/heap.cpp @@ -303,12 +303,14 @@ class Segment { if (child) child->set(p, v); } +#ifdef USE_ATOMIC_OPERATIONS void markAtomic(void* p) { assert(segment->context, bitsPerRecord == 1); markBitAtomic(data, indexOf(p)); assert(segment->context, getBit(data, indexOf(p))); if (child) child->markAtomic(p); } +#endif unsigned get(void* p) { return getBits(data, bitsPerRecord, indexOf(p)); @@ -1816,6 +1818,10 @@ class MyHeap: public Heap { virtual void mark(void* p, unsigned offset, unsigned count) { if (needsMark(p)) { +#ifndef USE_ATOMIC_OPERATIONS + ACQUIRE(c.lock); +#endif + if (c.client->isFixed(p)) { Fixie* f = fixie(p); assert(&c, offset == 0 or f->hasMask); @@ -1830,7 +1836,11 @@ class MyHeap: public Heap { } dirty = true; +#ifdef USE_ATOMIC_OPERATIONS markBitAtomic(f->mask(), offset + i); +#else + markBit(f->mask(), offset + i); +#endif assert(&c, getBit(f->mask(), offset + i)); } } @@ -1848,7 +1858,11 @@ class MyHeap: public Heap { for (unsigned i = 0; i < count; ++i) { void** target = static_cast(p) + offset + i; if (targetNeedsMark(mask(*target))) { +#ifdef USE_ATOMIC_OPERATIONS map->markAtomic(target); +#else + map->set(target); +#endif } } }