X-Git-Url: https://git.saurik.com/apple/objc4.git/blobdiff_plain/7c0e6487d7b67b6bf6c632300ee4b74e8950b051..7af964d1562d70f51a8e9aca24215ac3d83d0624:/test/synchronized-grid.m diff --git a/test/synchronized-grid.m b/test/synchronized-grid.m new file mode 100644 index 0000000..3988306 --- /dev/null +++ b/test/synchronized-grid.m @@ -0,0 +1,104 @@ +#include "test.h" + +#include +#include +#include +#include +#include + +// synchronized stress test +// 2-D grid of counters and locks. +// Each thread increments all counters some number of times. +// To increment: +// * thread picks a target [row][col] +// * thread locks all locks [row][0] to [row][col], possibly recursively +// * thread increments counter [row][col] +// * thread unlocks all of the locks + +// 64 / 4 / 3 / 1024*8 test takes about 20s on 4x2.6GHz Mac Pro +#define THREADS 64 +#define ROWS 4 +#define COLS 3 +#define COUNT 1024*8 + +static id locks[ROWS][COLS]; +static int counts[ROWS][COLS]; + + +static void *threadfn(void *arg) +{ + int n, d; + int depth = 1 + (int)(intptr_t)arg % 4; + + objc_registerThreadWithCollector(); + + for (n = 0; n < COUNT; n++) { + int rrr = rand() % ROWS; + int ccc = rand() % COLS; + int rr, cc; + for (rr = 0; rr < ROWS; rr++) { + int r = (rrr+rr) % ROWS; + for (cc = 0; cc < COLS; cc++) { + int c = (ccc+cc) % COLS; + int l; + + // Lock [r][0..c] + // ... in that order to prevent deadlock + for (l = 0; l <= c; l++) { + for (d = 0; d < depth; d++) { + int err = objc_sync_enter(locks[r][l]); + testassert(err == OBJC_SYNC_SUCCESS); + } + } + + // Increment count [r][c] + counts[r][c]++; + + // Unlock [r][0..c] + // ... in that order to increase contention + for (l = 0; l <= c; l++) { + for (d = 0; d < depth; d++) { + int err = objc_sync_exit(locks[r][l]); + testassert(err == OBJC_SYNC_SUCCESS); + } + } + } + } + } + + return NULL; +} + +int main() +{ + pthread_t threads[THREADS]; + int r, c, t; + + for (r = 0; r < ROWS; r++) { + for (c = 0; c < COLS; c++) { + locks[r][c] = [[NSObject alloc] init]; + } + } + + // Start the threads + for (t = 0; t < THREADS; t++) { + pthread_create(&threads[t], NULL, &threadfn, (void*)(intptr_t)t); + } + + // Wait for threads to finish + for (t = 0; t < THREADS; t++) { + pthread_join(threads[t], NULL); + } + + // Verify locks: all should be available + // Verify counts: all should be THREADS*COUNT + for (r = 0; r < ROWS; r++) { + for (c = 0; c < COLS; c++) { + int err = objc_sync_enter(locks[r][c]); + testassert(err == OBJC_SYNC_SUCCESS); + testassert(counts[r][c] == THREADS*COUNT); + } + } + + succeed(__FILE__); +}