]> git.saurik.com Git - apple/objc4.git/blobdiff - test/synchronized-counter.m
objc4-437.tar.gz
[apple/objc4.git] / test / synchronized-counter.m
diff --git a/test/synchronized-counter.m b/test/synchronized-counter.m
new file mode 100644 (file)
index 0000000..b60c569
--- /dev/null
@@ -0,0 +1,82 @@
+#include "test.h"
+
+#include <stdlib.h>
+#include <pthread.h>
+#include <objc/runtime.h>
+#include <objc/objc-sync.h>
+#include <Foundation/Foundation.h>
+#include <System/pthread_machdep.h>
+
+// synchronized stress test
+// Single locked counter incremented by many threads.
+
+// 64 / 1024*24 test takes about 20s on 4x2.6GHz Mac Pro
+#define THREADS 64
+#define COUNT 1024*24
+
+static id lock;
+static int count;
+
+static void *threadfn(void *arg)
+{
+    int n, d;
+    int depth = 1 + (int)(intptr_t)arg % 4;
+
+    objc_registerThreadWithCollector();
+
+    for (n = 0; n < COUNT; n++) {
+        // Lock
+        for (d = 0; d < depth; d++) {
+            int err = objc_sync_enter(lock);
+            testassert(err == OBJC_SYNC_SUCCESS);
+        }
+        
+        // Increment
+        count++;
+        
+        // Unlock
+        for (d = 0; d < depth; d++) {
+            int err = objc_sync_exit(lock);
+            testassert(err == OBJC_SYNC_SUCCESS);
+        }
+    }
+
+    // Verify lack of objc pthread data (should have used sync fast cache)
+    if (_pthread_has_direct_tsd()) {
+        testassert(! pthread_getspecific(__PTK_FRAMEWORK_OBJC_KEY5));
+    }
+    return NULL;
+}
+
+int main()
+{
+    pthread_t threads[THREADS];
+    int t;
+    int err;
+
+    lock = [[NSObject alloc] init];
+
+    // Verify objc pthread data on this thread (from +initialize)
+    // Worker threads shouldn't have any because of sync fast cache.
+    if (_pthread_has_direct_tsd()) {
+        testassert(pthread_getspecific(__PTK_FRAMEWORK_OBJC_KEY5));
+    }
+
+    // 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 lock: should be available
+    // Verify count: should be THREADS*COUNT
+    err = objc_sync_enter(lock);
+    testassert(err == OBJC_SYNC_SUCCESS);
+    testassert(count == THREADS*COUNT);
+
+    succeed(__FILE__);
+}