]> git.saurik.com Git - apple/objc4.git/blob - test/synchronized.m
objc4-680.tar.gz
[apple/objc4.git] / test / synchronized.m
1 // TEST_CONFIG
2
3 #include "test.h"
4
5 #include <Foundation/NSObject.h>
6 #include <mach/mach.h>
7 #include <pthread.h>
8 #include <sys/time.h>
9 #include <objc/runtime.h>
10 #include <objc/objc-sync.h>
11
12 // Basic @synchronized tests.
13
14
15 #define WAIT_SEC 3
16
17 static id obj;
18 static semaphore_t go;
19 static semaphore_t stop;
20
21 void *thread(void *arg __unused)
22 {
23 int err;
24
25 objc_registerThreadWithCollector();
26
27 // non-blocking sync_enter
28 err = objc_sync_enter(obj);
29 testassert(err == OBJC_SYNC_SUCCESS);
30
31 semaphore_signal(go);
32 // main thread: sync_exit of object locked on some other thread
33 semaphore_wait(stop);
34
35 err = objc_sync_exit(obj);
36 testassert(err == OBJC_SYNC_SUCCESS);
37 err = objc_sync_enter(obj);
38 testassert(err == OBJC_SYNC_SUCCESS);
39
40 semaphore_signal(go);
41 // main thread: blocking sync_enter
42 testassert(WAIT_SEC/3*3 == WAIT_SEC);
43 sleep(WAIT_SEC/3);
44 // recursive enter while someone waits
45 err = objc_sync_enter(obj);
46 testassert(err == OBJC_SYNC_SUCCESS);
47 sleep(WAIT_SEC/3);
48 // recursive exit while someone waits
49 err = objc_sync_exit(obj);
50 testassert(err == OBJC_SYNC_SUCCESS);
51 sleep(WAIT_SEC/3);
52 // sync_exit while someone waits
53 err = objc_sync_exit(obj);
54 testassert(err == OBJC_SYNC_SUCCESS);
55
56 return NULL;
57 }
58
59 int main()
60 {
61 pthread_t th;
62 int err;
63 struct timeval start, end;
64
65 obj = [[NSObject alloc] init];
66
67 // sync_exit of never-locked object
68 err = objc_sync_exit(obj);
69 testassert(err == OBJC_SYNC_NOT_OWNING_THREAD_ERROR);
70
71 semaphore_create(mach_task_self(), &go, 0, 0);
72 semaphore_create(mach_task_self(), &stop, 0, 0);
73 pthread_create(&th, NULL, &thread, NULL);
74 semaphore_wait(go);
75
76 // sync_exit of object locked on some other thread
77 err = objc_sync_exit(obj);
78 testassert(err == OBJC_SYNC_NOT_OWNING_THREAD_ERROR);
79
80 semaphore_signal(stop);
81 semaphore_wait(go);
82
83 // blocking sync_enter
84 gettimeofday(&start, NULL);
85 err = objc_sync_enter(obj);
86 gettimeofday(&end, NULL);
87 testassert(err == OBJC_SYNC_SUCCESS);
88 // should have waited more than WAIT_SEC but less than WAIT_SEC+1
89 // fixme hack: sleep(1) is ending 500 usec too early on x86_64 buildbot
90 // (rdar://6456975)
91 testassert(end.tv_sec*1000000LL+end.tv_usec >=
92 start.tv_sec*1000000LL+start.tv_usec + WAIT_SEC*1000000LL
93 - 3*500 /*hack*/);
94 testassert(end.tv_sec*1000000LL+end.tv_usec <
95 start.tv_sec*1000000LL+start.tv_usec + (1+WAIT_SEC)*1000000LL);
96
97 err = objc_sync_exit(obj);
98 testassert(err == OBJC_SYNC_SUCCESS);
99
100 err = objc_sync_exit(obj);
101 testassert(err == OBJC_SYNC_NOT_OWNING_THREAD_ERROR);
102
103 succeed(__FILE__);
104 }