mirror of
https://github.com/darlinghq/darling-objc4.git
synced 2024-11-23 04:09:46 +00:00
115 lines
2.9 KiB
Mathematica
115 lines
2.9 KiB
Mathematica
|
// TEST_CONFIG
|
||
|
|
||
|
#include "test.h"
|
||
|
|
||
|
#include <Foundation/NSObject.h>
|
||
|
#include <mach/mach.h>
|
||
|
#include <pthread.h>
|
||
|
#include <sys/time.h>
|
||
|
#include <objc/runtime.h>
|
||
|
#include <objc/objc-sync.h>
|
||
|
|
||
|
// Basic @synchronized tests.
|
||
|
|
||
|
|
||
|
#define WAIT_SEC 3
|
||
|
|
||
|
static id obj;
|
||
|
static semaphore_t go;
|
||
|
static semaphore_t stop;
|
||
|
|
||
|
void *thread(void *arg __unused)
|
||
|
{
|
||
|
int err;
|
||
|
BOOL locked;
|
||
|
|
||
|
// non-blocking sync_enter
|
||
|
err = objc_sync_enter(obj);
|
||
|
testassert(err == OBJC_SYNC_SUCCESS);
|
||
|
|
||
|
// recursive try_sync_enter
|
||
|
locked = objc_sync_try_enter(obj);
|
||
|
testassert(locked);
|
||
|
err = objc_sync_exit(obj);
|
||
|
testassert(err == OBJC_SYNC_SUCCESS);
|
||
|
|
||
|
semaphore_signal(go);
|
||
|
// main thread: sync_exit of object locked on some other thread
|
||
|
semaphore_wait(stop);
|
||
|
|
||
|
err = objc_sync_exit(obj);
|
||
|
testassert(err == OBJC_SYNC_SUCCESS);
|
||
|
err = objc_sync_enter(obj);
|
||
|
testassert(err == OBJC_SYNC_SUCCESS);
|
||
|
|
||
|
semaphore_signal(go);
|
||
|
// main thread: blocking sync_enter
|
||
|
testassert(WAIT_SEC/3*3 == WAIT_SEC);
|
||
|
sleep(WAIT_SEC/3);
|
||
|
// recursive enter while someone waits
|
||
|
err = objc_sync_enter(obj);
|
||
|
testassert(err == OBJC_SYNC_SUCCESS);
|
||
|
sleep(WAIT_SEC/3);
|
||
|
// recursive exit while someone waits
|
||
|
err = objc_sync_exit(obj);
|
||
|
testassert(err == OBJC_SYNC_SUCCESS);
|
||
|
sleep(WAIT_SEC/3);
|
||
|
// sync_exit while someone waits
|
||
|
err = objc_sync_exit(obj);
|
||
|
testassert(err == OBJC_SYNC_SUCCESS);
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
int main()
|
||
|
{
|
||
|
pthread_t th;
|
||
|
int err;
|
||
|
struct timeval start, end;
|
||
|
BOOL locked;
|
||
|
|
||
|
obj = [[NSObject alloc] init];
|
||
|
|
||
|
// sync_exit of never-locked object
|
||
|
err = objc_sync_exit(obj);
|
||
|
testassert(err == OBJC_SYNC_NOT_OWNING_THREAD_ERROR);
|
||
|
|
||
|
semaphore_create(mach_task_self(), &go, 0, 0);
|
||
|
semaphore_create(mach_task_self(), &stop, 0, 0);
|
||
|
pthread_create(&th, NULL, &thread, NULL);
|
||
|
semaphore_wait(go);
|
||
|
|
||
|
// sync_exit of object locked on some other thread
|
||
|
err = objc_sync_exit(obj);
|
||
|
testassert(err == OBJC_SYNC_NOT_OWNING_THREAD_ERROR);
|
||
|
|
||
|
semaphore_signal(stop);
|
||
|
semaphore_wait(go);
|
||
|
|
||
|
// contended try_sync_enter
|
||
|
locked = objc_sync_try_enter(obj);
|
||
|
testassert(!locked);
|
||
|
|
||
|
// blocking sync_enter
|
||
|
gettimeofday(&start, NULL);
|
||
|
err = objc_sync_enter(obj);
|
||
|
gettimeofday(&end, NULL);
|
||
|
testassert(err == OBJC_SYNC_SUCCESS);
|
||
|
// should have waited more than WAIT_SEC but less than WAIT_SEC+1
|
||
|
// fixme hack: sleep(1) is ending 500 usec too early on x86_64 buildbot
|
||
|
// (rdar://6456975)
|
||
|
testassert(end.tv_sec*1000000LL+end.tv_usec >=
|
||
|
start.tv_sec*1000000LL+start.tv_usec + WAIT_SEC*1000000LL
|
||
|
- 3*500 /*hack*/);
|
||
|
testassert(end.tv_sec*1000000LL+end.tv_usec <
|
||
|
start.tv_sec*1000000LL+start.tv_usec + (1+WAIT_SEC)*1000000LL);
|
||
|
|
||
|
err = objc_sync_exit(obj);
|
||
|
testassert(err == OBJC_SYNC_SUCCESS);
|
||
|
|
||
|
err = objc_sync_exit(obj);
|
||
|
testassert(err == OBJC_SYNC_NOT_OWNING_THREAD_ERROR);
|
||
|
|
||
|
succeed(__FILE__);
|
||
|
}
|