7 #include <objc/runtime.h>
8 #include <objc/objc-sync.h>
9 #include <Foundation/NSObject.h>
11 // synchronized stress test
12 // 2-D grid of counters and locks.
13 // Each thread increments all counters some number of times.
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
21 // 16 / 4 / 3 / 1024*8 test takes about 30s on 2nd gen iPod touch
27 // 64 / 4 / 3 / 1024*8 test takes about 20s on 4x2.6GHz Mac Pro
34 static id locks[ROWS][COLS];
35 static int counts[ROWS][COLS];
38 static void *threadfn(void *arg)
41 int depth = 1 + (int)(intptr_t)arg % 4;
43 for (n = 0; n < COUNT; n++) {
44 int rrr = rand() % ROWS;
45 int ccc = rand() % COLS;
47 for (rr = 0; rr < ROWS; rr++) {
48 int r = (rrr+rr) % ROWS;
49 for (cc = 0; cc < COLS; cc++) {
50 int c = (ccc+cc) % COLS;
54 // ... in that order to prevent deadlock
55 for (l = 0; l <= c; l++) {
56 for (d = 0; d < depth; d++) {
57 int err = objc_sync_enter(locks[r][l]);
58 testassert(err == OBJC_SYNC_SUCCESS);
62 // Increment count [r][c]
66 // ... in that order to increase contention
67 for (l = 0; l <= c; l++) {
68 for (d = 0; d < depth; d++) {
69 int err = objc_sync_exit(locks[r][l]);
70 testassert(err == OBJC_SYNC_SUCCESS);
82 pthread_t threads[THREADS];
85 for (r = 0; r < ROWS; r++) {
86 for (c = 0; c < COLS; c++) {
87 locks[r][c] = [[NSObject alloc] init];
92 for (t = 0; t < THREADS; t++) {
93 pthread_create(&threads[t], NULL, &threadfn, (void*)(intptr_t)t);
96 // Wait for threads to finish
97 for (t = 0; t < THREADS; t++) {
98 pthread_join(threads[t], NULL);
101 // Verify locks: all should be available
102 // Verify counts: all should be THREADS*COUNT
103 for (r = 0; r < ROWS; r++) {
104 for (c = 0; c < COLS; c++) {
105 int err = objc_sync_enter(locks[r][c]);
106 testassert(err == OBJC_SYNC_SUCCESS);
107 testassert(counts[r][c] == THREADS*COUNT);