mirror of
https://github.com/corda/corda.git
synced 2025-01-19 11:16:54 +00:00
implement atomicCompareAndSwap on x86_32 for GCC versions prior to 4.1 and for MSVC
This commit is contained in:
parent
e91157a390
commit
15eada93ed
2
makefile
2
makefile
@ -101,7 +101,7 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
|
||||
common-cflags = $(warnings) -fno-rtti -fno-exceptions -fno-omit-frame-pointer \
|
||||
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(native-build) \
|
||||
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
||||
$(gnu-cflags)
|
||||
-DUSE_ATOMIC_OPERATIONS $(gnu-cflags)
|
||||
|
||||
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
|
||||
"-I$(JAVA_HOME)/include/linux" -I$(src) -pthread
|
||||
|
15
src/common.h
15
src/common.h
@ -63,11 +63,6 @@ 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)
|
||||
|
||||
@ -330,16 +325,6 @@ 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 COMPARE_AND_SWAP(p, *p, *p | v)) { }
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void
|
||||
clearBit(uintptr_t* map, unsigned i)
|
||||
{
|
||||
|
11
src/heap.cpp
11
src/heap.cpp
@ -11,6 +11,7 @@
|
||||
#include "heap.h"
|
||||
#include "system.h"
|
||||
#include "common.h"
|
||||
#include "arch.h"
|
||||
|
||||
using namespace vm;
|
||||
|
||||
@ -69,6 +70,16 @@ System* system(Context*);
|
||||
void* tryAllocate(Context* c, unsigned size);
|
||||
void free(Context* c, const void* p, unsigned size);
|
||||
|
||||
#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 atomicCompareAndSwap(p, *p, *p | v)) { }
|
||||
}
|
||||
#endif // USE_ATOMIC_OPERATIONS
|
||||
|
||||
inline void*
|
||||
get(void* o, unsigned offsetInWords)
|
||||
{
|
||||
|
@ -90,6 +90,19 @@ syncInstructionCache(const void* start, unsigned size)
|
||||
__asm__ __volatile__("isync");
|
||||
}
|
||||
|
||||
#ifdef USE_ATOMIC_OPERATIONS
|
||||
inline bool
|
||||
atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_)
|
||||
{
|
||||
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
|
||||
return __sync_bool_compare_and_swap(p, old, new_);
|
||||
#else // not GCC >= 4.1
|
||||
// todo: implement using inline assembly
|
||||
# undef USE_ATOMIC_OPERATIONS
|
||||
#endif // not GCC >= 4.1
|
||||
}
|
||||
#endif // USE_ATOMIC_OPERATIONS
|
||||
|
||||
inline uint64_t
|
||||
dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
|
||||
unsigned argumentCount, unsigned argumentsSize,
|
||||
|
34
src/x86.h
34
src/x86.h
@ -188,6 +188,40 @@ syncInstructionCache(const void*, unsigned)
|
||||
// ignore
|
||||
}
|
||||
|
||||
#ifdef USE_ATOMIC_OPERATIONS
|
||||
inline bool
|
||||
atomicCompareAndSwap(uintptr_t* p, uintptr_t old, uintptr_t new_)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
# ifdef ARCH_x86_32
|
||||
InterlockedCompareExchange(p, new_, old);
|
||||
# elif defined ARCH_x86_64
|
||||
InterlockedCompareExchange64(p, new_, old);
|
||||
# endif // ARCH_x86_64
|
||||
#elif (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)
|
||||
return __sync_bool_compare_and_swap(p, old, new_);
|
||||
#elif defined ARCH_x86_32
|
||||
uint8_t result;
|
||||
|
||||
__asm__ __volatile__("lock; cmpxchgl %2, %0; setz %1"
|
||||
: "=m"(*p), "=q"(result)
|
||||
: "r"(new_), "a"(old), "m"(*p)
|
||||
: "memory");
|
||||
|
||||
return result != 0;
|
||||
#elif defined ARCH_x86_64
|
||||
uint8_t result;
|
||||
|
||||
__asm__ __volatile__("lock; cmpxchg1 %2, %0; setz %1"
|
||||
: "=m"(*p), "=q"(result)
|
||||
: "r"(new_), "a"(old), "m"(*p)
|
||||
: "memory");
|
||||
|
||||
return result != 0;
|
||||
#endif // ARCH_x86_64
|
||||
}
|
||||
#endif // USE_ATOMIC_OPERATIONS
|
||||
|
||||
} // namespace vm
|
||||
|
||||
#endif//X86_H
|
||||
|
Loading…
Reference in New Issue
Block a user