]> git.saurik.com Git - apple/objc4.git/blob - test/synchronized-grid.m
objc4-532.2.tar.gz
[apple/objc4.git] / test / synchronized-grid.m
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
34 static id locks[ROWS][COLS];
35 static int counts[ROWS][COLS];
36
37
38 static 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
82 int 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 }