1*7c3d14c8STreehugger Robot// RUN: %clangxx_tsan %s -o %t -framework Foundation -std=c++11 2*7c3d14c8STreehugger Robot// RUN: %run %t 2>&1 | FileCheck %s 3*7c3d14c8STreehugger Robot 4*7c3d14c8STreehugger Robot#import <Foundation/Foundation.h> 5*7c3d14c8STreehugger Robot#import <libkern/OSAtomic.h> 6*7c3d14c8STreehugger Robot 7*7c3d14c8STreehugger Robot#include <thread> 8*7c3d14c8STreehugger Robot 9*7c3d14c8STreehugger Robotvolatile int64_t retainCount = 0; 10*7c3d14c8STreehugger Robot 11*7c3d14c8STreehugger Robotlong g = 0; 12*7c3d14c8STreehugger Robot 13*7c3d14c8STreehugger Robotvoid dealloc() { 14*7c3d14c8STreehugger Robot g = 42; 15*7c3d14c8STreehugger Robot} 16*7c3d14c8STreehugger Robot 17*7c3d14c8STreehugger Robotvoid release() { 18*7c3d14c8STreehugger Robot if (OSAtomicAdd64Barrier(-1, &retainCount) == 0) { 19*7c3d14c8STreehugger Robot dealloc(); 20*7c3d14c8STreehugger Robot } 21*7c3d14c8STreehugger Robot} 22*7c3d14c8STreehugger Robot 23*7c3d14c8STreehugger Robotvoid retain() { 24*7c3d14c8STreehugger Robot OSAtomicAdd64Barrier(1, &retainCount); 25*7c3d14c8STreehugger Robot} 26*7c3d14c8STreehugger Robot 27*7c3d14c8STreehugger Robotint main(int argc, const char * argv[]) { 28*7c3d14c8STreehugger Robot fprintf(stderr, "start\n"); 29*7c3d14c8STreehugger Robot retain(); 30*7c3d14c8STreehugger Robot retain(); 31*7c3d14c8STreehugger Robot 32*7c3d14c8STreehugger Robot std::thread t([]{ 33*7c3d14c8STreehugger Robot release(); 34*7c3d14c8STreehugger Robot }); 35*7c3d14c8STreehugger Robot 36*7c3d14c8STreehugger Robot g = 47; 37*7c3d14c8STreehugger Robot 38*7c3d14c8STreehugger Robot release(); 39*7c3d14c8STreehugger Robot t.join(); 40*7c3d14c8STreehugger Robot 41*7c3d14c8STreehugger Robot fprintf(stderr, "end, g = %ld\n", g); 42*7c3d14c8STreehugger Robot 43*7c3d14c8STreehugger Robot return 0; 44*7c3d14c8STreehugger Robot} 45*7c3d14c8STreehugger Robot 46*7c3d14c8STreehugger Robot// CHECK: start 47*7c3d14c8STreehugger Robot// CHECK: end, g = 42 48*7c3d14c8STreehugger Robot// CHECK-NOT: WARNING: ThreadSanitizer 49