forked from freebsd/freebsd-src
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Import libcxxrt master fd484be8d1e94a1fcf6bc5c67e5c07b65ada19b6
Interesting fixes: 47661d0 Match libc++abi/libsupc++ when demangling array types e44a05c Fix unitialized variable in __cxa_demangle_gnu3 after #6 (#8) 5088b05 Remove some code duplication. fd484be Atomics cleanup (freebsd#11)
- Loading branch information
1 parent
3f8a54b
commit 672085f
Showing
8 changed files
with
489 additions
and
161 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,102 @@ | ||
|
||
#ifndef __has_builtin | ||
#define __has_builtin(x) 0 | ||
# define __has_builtin(x) 0 | ||
#endif | ||
#ifndef __has_feature | ||
#define __has_feature(x) 0 | ||
# define __has_feature(x) 0 | ||
#endif | ||
#ifndef __has_extension | ||
# define __has_extension(x) 0 | ||
#endif | ||
|
||
#if !__has_extension(c_atomic) | ||
# define _Atomic(T) T | ||
#endif | ||
/** | ||
* Swap macro that enforces a happens-before relationship with a corresponding | ||
* ATOMIC_LOAD. | ||
*/ | ||
#if __has_builtin(__c11_atomic_exchange) | ||
#define ATOMIC_SWAP(addr, val)\ | ||
__c11_atomic_exchange(reinterpret_cast<_Atomic(__typeof__(val))*>(addr), val, __ATOMIC_ACQ_REL) | ||
#elif __has_builtin(__sync_swap) | ||
#define ATOMIC_SWAP(addr, val)\ | ||
__sync_swap(addr, val) | ||
# define ATOMIC_BUILTIN(name) __c11_atomic_##name | ||
#else | ||
#define ATOMIC_SWAP(addr, val)\ | ||
__sync_lock_test_and_set(addr, val) | ||
# define ATOMIC_BUILTIN(name) __atomic_##name##_n | ||
#endif | ||
|
||
#if __has_builtin(__c11_atomic_load) | ||
#define ATOMIC_LOAD(addr)\ | ||
__c11_atomic_load(reinterpret_cast<_Atomic(__typeof__(*addr))*>(addr), __ATOMIC_ACQUIRE) | ||
namespace | ||
{ | ||
/** | ||
* C++11 memory orders. We only need a subset of them. | ||
*/ | ||
enum memory_order | ||
{ | ||
/** | ||
* Acquire order. | ||
*/ | ||
acquire = __ATOMIC_ACQUIRE, | ||
|
||
/** | ||
* Release order. | ||
*/ | ||
release = __ATOMIC_RELEASE, | ||
|
||
/** | ||
* Sequentially consistent memory ordering. | ||
*/ | ||
seqcst = __ATOMIC_SEQ_CST | ||
}; | ||
|
||
/** | ||
* Atomic, implements a subset of `std::atomic`. | ||
*/ | ||
template<typename T> | ||
class atomic | ||
{ | ||
/** | ||
* The underlying value. Use C11 atomic qualification if available. | ||
*/ | ||
_Atomic(T) val; | ||
|
||
public: | ||
/** | ||
* Constructor, takes a value. | ||
*/ | ||
atomic(T init) : val(init) {} | ||
|
||
/** | ||
* Atomically load with the specified memory order. | ||
*/ | ||
T load(memory_order order = memory_order::seqcst) | ||
{ | ||
return ATOMIC_BUILTIN(load)(&val, order); | ||
} | ||
|
||
/** | ||
* Atomically store with the specified memory order. | ||
*/ | ||
void store(T v, memory_order order = memory_order::seqcst) | ||
{ | ||
return ATOMIC_BUILTIN(store)(&val, v, order); | ||
} | ||
|
||
/** | ||
* Atomically exchange with the specified memory order. | ||
*/ | ||
T exchange(T v, memory_order order = memory_order::seqcst) | ||
{ | ||
return ATOMIC_BUILTIN(exchange)(&val, v, order); | ||
} | ||
|
||
/** | ||
* Atomically exchange with the specified memory order. | ||
*/ | ||
bool compare_exchange(T & expected, | ||
T desired, | ||
memory_order order = memory_order::seqcst) | ||
{ | ||
#if __has_builtin(__c11_atomic_compare_exchange_strong) | ||
return __c11_atomic_compare_exchange_strong( | ||
&val, &expected, desired, order, order); | ||
#else | ||
#define ATOMIC_LOAD(addr)\ | ||
(__sync_synchronize(), *addr) | ||
return __atomic_compare_exchange_n( | ||
&val, &expected, desired, true, order, order); | ||
#endif | ||
|
||
} | ||
}; | ||
} // namespace | ||
#undef ATOMIC_BUILTIN |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.