mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-05 08:58:30 +00:00
[tsan] Fix the behavior of OSAtomicTestAndClear
The system implementation of OSAtomicTestAndClear returns the original bit, but the TSan interceptor has a bug which always returns zero from the function. This patch fixes this and adds a test. Differential Revision: https://reviews.llvm.org/D23061 llvm-svn: 277461
This commit is contained in:
parent
58f562887b
commit
3a748d6067
@ -119,24 +119,23 @@ OSATOMIC_INTERCEPTORS_CAS(OSAtomicCompareAndSwap32, __tsan_atomic32, a32,
|
||||
OSATOMIC_INTERCEPTORS_CAS(OSAtomicCompareAndSwap64, __tsan_atomic64, a64,
|
||||
int64_t)
|
||||
|
||||
#define OSATOMIC_INTERCEPTOR_BITOP(f, op, m, mo) \
|
||||
#define OSATOMIC_INTERCEPTOR_BITOP(f, op, clear, mo) \
|
||||
TSAN_INTERCEPTOR(bool, f, uint32_t n, volatile void *ptr) { \
|
||||
SCOPED_TSAN_INTERCEPTOR(f, n, ptr); \
|
||||
char *byte_ptr = ((char *)ptr) + (n >> 3); \
|
||||
char bit_index = n & 7; \
|
||||
char mask = m; \
|
||||
char bit = 0x80u >> (n & 7); \
|
||||
char mask = clear ? ~bit : bit; \
|
||||
char orig_byte = op((a8 *)byte_ptr, mask, mo); \
|
||||
return orig_byte & mask; \
|
||||
return orig_byte & bit; \
|
||||
}
|
||||
|
||||
#define OSATOMIC_INTERCEPTORS_BITOP(f, op, m) \
|
||||
OSATOMIC_INTERCEPTOR_BITOP(f, op, m, kMacOrderNonBarrier) \
|
||||
OSATOMIC_INTERCEPTOR_BITOP(f##Barrier, op, m, kMacOrderBarrier)
|
||||
#define OSATOMIC_INTERCEPTORS_BITOP(f, op, clear) \
|
||||
OSATOMIC_INTERCEPTOR_BITOP(f, op, clear, kMacOrderNonBarrier) \
|
||||
OSATOMIC_INTERCEPTOR_BITOP(f##Barrier, op, clear, kMacOrderBarrier)
|
||||
|
||||
OSATOMIC_INTERCEPTORS_BITOP(OSAtomicTestAndSet, __tsan_atomic8_fetch_or,
|
||||
0x80u >> bit_index)
|
||||
OSATOMIC_INTERCEPTORS_BITOP(OSAtomicTestAndSet, __tsan_atomic8_fetch_or, false)
|
||||
OSATOMIC_INTERCEPTORS_BITOP(OSAtomicTestAndClear, __tsan_atomic8_fetch_and,
|
||||
~(0x80u >> bit_index))
|
||||
true)
|
||||
|
||||
TSAN_INTERCEPTOR(void, OSAtomicEnqueue, OSQueueHead *list, void *item,
|
||||
size_t offset) {
|
||||
|
34
compiler-rt/test/tsan/Darwin/osatomics-bitops.mm
Normal file
34
compiler-rt/test/tsan/Darwin/osatomics-bitops.mm
Normal file
@ -0,0 +1,34 @@
|
||||
// RUN: %clangxx_tsan %s -o %t -framework Foundation -std=c++11
|
||||
// RUN: %run %t 2>&1 | FileCheck %s
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <libkern/OSAtomic.h>
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
int value = 1;
|
||||
bool ret = OSAtomicTestAndClear(7, &value);
|
||||
fprintf(stderr, "value = %d, ret = %d\n", value, ret);
|
||||
// CHECK: value = 0, ret = 1
|
||||
|
||||
ret = OSAtomicTestAndSet(4, &value);
|
||||
fprintf(stderr, "value = %d, ret = %d\n", value, ret);
|
||||
// CHECK: value = 8, ret = 0
|
||||
|
||||
ret = OSAtomicTestAndClear(4, &value);
|
||||
fprintf(stderr, "value = %d, ret = %d\n", value, ret);
|
||||
// CHECK: value = 0, ret = 1
|
||||
|
||||
ret = OSAtomicTestAndSet(12, &value);
|
||||
fprintf(stderr, "value = %d, ret = %d\n", value, ret);
|
||||
// CHECK: value = 2048, ret = 0
|
||||
|
||||
ret = OSAtomicTestAndSet(13, &value);
|
||||
fprintf(stderr, "value = %d, ret = %d\n", value, ret);
|
||||
// CHECK: value = 3072, ret = 0
|
||||
|
||||
ret = OSAtomicTestAndClear(12, &value);
|
||||
fprintf(stderr, "value = %d, ret = %d\n", value, ret);
|
||||
// CHECK: value = 1024, ret = 1
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user