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