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 11// synchronized stress test 12// 2-D grid of counters and locks. 13// Each thread increments all counters some number of times. 14// To increment: 15// * thread picks a target [row][col] 16// * thread locks all locks [row][0] to [row][col], possibly recursively 17// * thread increments counter [row][col] 18// * thread unlocks all of the locks 19 20#if defined(__arm__) 21// 16 / 4 / 3 / 1024*8 test takes about 30s on 2nd gen iPod touch 22#define THREADS 16 23#define ROWS 4 24#define COLS 3 25#define COUNT 1024*8 26#else 27// 64 / 4 / 3 / 1024*8 test takes about 20s on 4x2.6GHz Mac Pro 28#define THREADS 64 29#define ROWS 4 30#define COLS 3 31#define COUNT 1024*8 32#endif 33 34static id locks[ROWS][COLS]; 35static int counts[ROWS][COLS]; 36 37 38static void *threadfn(void *arg) 39{ 40 int n, d; 41 int depth = 1 + (int)(intptr_t)arg % 4; 42 43 objc_registerThreadWithCollector(); 44 45 for (n = 0; n < COUNT; n++) { 46 int rrr = rand() % ROWS; 47 int ccc = rand() % COLS; 48 int rr, cc; 49 for (rr = 0; rr < ROWS; rr++) { 50 int r = (rrr+rr) % ROWS; 51 for (cc = 0; cc < COLS; cc++) { 52 int c = (ccc+cc) % COLS; 53 int l; 54 55 // Lock [r][0..c] 56 // ... in that order to prevent deadlock 57 for (l = 0; l <= c; l++) { 58 for (d = 0; d < depth; d++) { 59 int err = objc_sync_enter(locks[r][l]); 60 testassert(err == OBJC_SYNC_SUCCESS); 61 } 62 } 63 64 // Increment count [r][c] 65 counts[r][c]++; 66 67 // Unlock [r][0..c] 68 // ... in that order to increase contention 69 for (l = 0; l <= c; l++) { 70 for (d = 0; d < depth; d++) { 71 int err = objc_sync_exit(locks[r][l]); 72 testassert(err == OBJC_SYNC_SUCCESS); 73 } 74 } 75 } 76 } 77 } 78 79 return NULL; 80} 81 82int main() 83{ 84 pthread_t threads[THREADS]; 85 int r, c, t; 86 87 for (r = 0; r < ROWS; r++) { 88 for (c = 0; c < COLS; c++) { 89 locks[r][c] = [[NSObject alloc] init]; 90 } 91 } 92 93 // Start the threads 94 for (t = 0; t < THREADS; t++) { 95 pthread_create(&threads[t], NULL, &threadfn, (void*)(intptr_t)t); 96 } 97 98 // Wait for threads to finish 99 for (t = 0; t < THREADS; t++) { 100 pthread_join(threads[t], NULL); 101 } 102 103 // Verify locks: all should be available 104 // Verify counts: all should be THREADS*COUNT 105 for (r = 0; r < ROWS; r++) { 106 for (c = 0; c < COLS; c++) { 107 int err = objc_sync_enter(locks[r][c]); 108 testassert(err == OBJC_SYNC_SUCCESS); 109 testassert(counts[r][c] == THREADS*COUNT); 110 } 111 } 112 113 succeed(__FILE__); 114} 115