1// TEST_CONFIG 2 3#include "test.h" 4 5#include <stdlib.h> 6#include <pthread.h> 7#include <objc/runtime.h> 8#include <objc/objc-sync.h> 9#include <Foundation/NSObject.h> 10#include <System/pthread_machdep.h> 11 12// synchronized stress test 13// Single locked counter incremented by many threads. 14 15#if defined(__arm__) 16#define THREADS 16 17#define COUNT 1024*24 18#else 19// 64 / 1024*24 test takes about 20s on 4x2.6GHz Mac Pro 20#define THREADS 64 21#define COUNT 1024*24 22#endif 23 24static id lock; 25static int count; 26 27static void *threadfn(void *arg) 28{ 29 int n, d; 30 int depth = 1 + (int)(intptr_t)arg % 4; 31 32 objc_registerThreadWithCollector(); 33 34 for (n = 0; n < COUNT; n++) { 35 // Lock 36 for (d = 0; d < depth; d++) { 37 int err = objc_sync_enter(lock); 38 testassert(err == OBJC_SYNC_SUCCESS); 39 } 40 41 // Increment 42 count++; 43 44 // Unlock 45 for (d = 0; d < depth; d++) { 46 int err = objc_sync_exit(lock); 47 testassert(err == OBJC_SYNC_SUCCESS); 48 } 49 } 50 51 // Verify lack of objc pthread data (should have used sync fast cache) 52#ifdef __PTK_FRAMEWORK_OBJC_KEY5 53 testassert(! pthread_getspecific(__PTK_FRAMEWORK_OBJC_KEY5)); 54#endif 55 56 return NULL; 57} 58 59int main() 60{ 61 pthread_t threads[THREADS]; 62 int t; 63 int err; 64 65 lock = [[NSObject alloc] init]; 66 67 // Verify objc pthread data on this thread (from +initialize) 68 // Worker threads shouldn't have any because of sync fast cache. 69#ifdef __PTK_FRAMEWORK_OBJC_KEY5 70 testassert(pthread_getspecific(__PTK_FRAMEWORK_OBJC_KEY5)); 71#endif 72 73 // Start the threads 74 for (t = 0; t < THREADS; t++) { 75 pthread_create(&threads[t], NULL, &threadfn, (void*)(intptr_t)t); 76 } 77 78 // Wait for threads to finish 79 for (t = 0; t < THREADS; t++) { 80 pthread_join(threads[t], NULL); 81 } 82 83 // Verify lock: should be available 84 // Verify count: should be THREADS*COUNT 85 err = objc_sync_enter(lock); 86 testassert(err == OBJC_SYNC_SUCCESS); 87 testassert(count == THREADS*COUNT); 88 89 succeed(__FILE__); 90} 91