1// TEST_CONFIG MEM=mrc 2 3#include "test.h" 4#include <objc/NSObject.h> 5 6static semaphore_t go1; 7static semaphore_t go2; 8static semaphore_t done; 9 10#define VARCOUNT 100000 11static id obj; 12static id vars[VARCOUNT]; 13 14 15void *destroyer(void *arg __unused) 16{ 17 while (1) { 18 semaphore_wait(go1); 19 for (int i = 0; i < VARCOUNT; i++) { 20 objc_destroyWeak(&vars[i]); 21 } 22 semaphore_signal(done); 23 } 24} 25 26 27void *deallocator(void *arg __unused) 28{ 29 while (1) { 30 semaphore_wait(go2); 31 [obj release]; 32 semaphore_signal(done); 33 } 34} 35 36 37void cycle(void) 38{ 39 // rdar://12896779 objc_destroyWeak() versus weak clear in dealloc 40 41 // Clean up from previous cycle - objc_destroyWeak() doesn't set var to nil 42 for (int i = 0; i < VARCOUNT; i++) { 43 vars[i] = nil; 44 } 45 46 obj = [NSObject new]; 47 for (int i = 0; i < VARCOUNT; i++) { 48 objc_storeWeak(&vars[i], obj); 49 } 50 51 // let destroyer start before deallocator runs 52 semaphore_signal(go1); 53 sched_yield(); 54 semaphore_signal(go2); 55 56 semaphore_wait(done); 57 semaphore_wait(done); 58} 59 60 61int main() 62{ 63 semaphore_create(mach_task_self(), &go1, 0, 0); 64 semaphore_create(mach_task_self(), &go2, 0, 0); 65 semaphore_create(mach_task_self(), &done, 0, 0); 66 67 pthread_t th[2]; 68 pthread_create(&th[1], NULL, deallocator, NULL); 69 pthread_create(&th[1], NULL, destroyer, NULL); 70 71 for (int i = 0; i < 100; i++) { 72 cycle(); 73 } 74 75 succeed(__FILE__); 76} 77