1 // Test that mach_vm_[de]allocate resets shadow memory status.
3 // RUN: %clang_tsan %s -o %t
4 // RUN: %run %t 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer'
6 // <mach/mach_vm.h> is not provided by the simulator SDK.
10 #include <mach/mach_vm.h>
17 const mach_vm_size_t alloc_size
= sizeof(int);
18 static int *global_ptr
;
21 mach_vm_address_t addr
;
23 mach_vm_allocate(mach_task_self(), &addr
, alloc_size
, VM_FLAGS_ANYWHERE
);
24 assert(kr
== KERN_SUCCESS
);
28 static void alloc_fixed(int *ptr
) {
29 mach_vm_address_t addr
= (mach_vm_address_t
)ptr
;
30 // Re-allocation via VM_FLAGS_FIXED sporadically fails.
32 mach_vm_allocate(mach_task_self(), &addr
, alloc_size
, VM_FLAGS_FIXED
);
33 if (kr
!= KERN_SUCCESS
)
37 static void dealloc(int *ptr
) {
39 mach_vm_deallocate(mach_task_self(), (mach_vm_address_t
)ptr
, alloc_size
);
40 assert(kr
== KERN_SUCCESS
);
43 static void *Thread(void *arg
) {
44 *global_ptr
= 7; // Assignment 1
46 // We want to test that TSan does not report a race between the two
47 // assignments to *global_ptr when the underlying memory is re-allocated
48 // between assignments. The calls to the API itself are racy though, so ignore
50 AnnotateIgnoreWritesBegin(__FILE__
, __LINE__
);
52 alloc_fixed(global_ptr
);
53 AnnotateIgnoreWritesEnd(__FILE__
, __LINE__
);
55 barrier_wait(&barrier
);
59 static bool try_realloc_on_same_address() {
60 barrier_init(&barrier
, 2);
63 pthread_create(&t
, NULL
, Thread
, NULL
);
65 barrier_wait(&barrier
);
67 *global_ptr
= 8; // Assignment 2
69 pthread_join(t
, NULL
);
72 return global_ptr
!= NULL
;
75 int main(int argc
, const char *argv
[]) {
77 for (int i
= 0; i
< 10; i
++) {
78 success
= try_realloc_on_same_address();
83 fprintf(stderr
, "Unable to set up testing condition; silently pass test\n");