mirror of
https://github.com/corda/corda.git
synced 2025-02-10 12:51:37 +00:00
only use atomic operations if the compiler supports them
This commit is contained in:
parent
07f40a07e1
commit
5f5cc57d12
@ -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<uintptr_t>(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<uintptr_t>(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)
|
||||
|
14
src/heap.cpp
14
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<void**>(p) + offset + i;
|
||||
if (targetNeedsMark(mask(*target))) {
|
||||
#ifdef USE_ATOMIC_OPERATIONS
|
||||
map->markAtomic(target);
|
||||
#else
|
||||
map->set(target);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user