Skip to content

Commit

Permalink
[builtins] Use Interlocked* intrinsics for atomics on MSVC
Browse files Browse the repository at this point in the history
Tested on MSVC 2013, 2015 and 2017 targeting X86, X64 and ARM.

This fixes building emutls.c for Windows for ARM (both with clang
which don't need these atomics fallbacks at all, but just failed
due to the immintrin.h include before, and with MSVC).

Differential Revision: https://reviews.llvm.org/D36071

llvm-svn: 309974
  • Loading branch information
mstorsjo committed Aug 3, 2017
1 parent 3eaab96 commit becd2ef
Showing 1 changed file with 6 additions and 8 deletions.
14 changes: 6 additions & 8 deletions compiler-rt/lib/builtins/emutls.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ static __inline emutls_address_array* emutls_getspecific() {
#include <malloc.h>
#include <stdio.h>
#include <assert.h>
#include <immintrin.h>

static LPCRITICAL_SECTION emutls_mutex;
static DWORD emutls_tls_index = TLS_OUT_OF_INDEXES;
Expand Down Expand Up @@ -203,25 +202,24 @@ static __inline emutls_address_array* emutls_getspecific() {
/* Provide atomic load/store functions for emutls_get_index if built with MSVC.
*/
#if !defined(__ATOMIC_RELEASE)
#include <intrin.h>

enum { __ATOMIC_ACQUIRE = 2, __ATOMIC_RELEASE = 3 };

static __inline uintptr_t __atomic_load_n(void *ptr, unsigned type) {
assert(type == __ATOMIC_ACQUIRE);
// These return the previous value - but since we do an OR with 0,
// it's equivalent to a plain load.
#ifdef _WIN64
return (uintptr_t) _load_be_u64(ptr);
return InterlockedOr64(ptr, 0);
#else
return (uintptr_t) _load_be_u32(ptr);
return InterlockedOr(ptr, 0);
#endif
}

static __inline void __atomic_store_n(void *ptr, uintptr_t val, unsigned type) {
assert(type == __ATOMIC_RELEASE);
#ifdef _WIN64
_store_be_u64(ptr, val);
#else
_store_be_u32(ptr, val);
#endif
InterlockedExchangePointer((void *volatile *)ptr, (void *)val);
}

#endif
Expand Down

0 comments on commit becd2ef

Please sign in to comment.