You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

246 lines
3.8 KiB

#include "threads.h"
#if defined(__OS2__) || defined(__WINDOWS__) || defined(WIN32) || defined(WIN64) || defined(_MSC_VER)
int simple_threads_cond_wait(THREAD h, HANDLE m, long milisec) {
if (milisec < 0)
return WaitForSingleObject(h, INFINITE);
return WaitForSingleObject(h, milisec);
}
int WINAPI simple_threads_create_thread(THREAD* h, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter) {
HANDLE hn = CreateThread(NULL, 0, lpStartAddress, lpParameter, 0, NULL);
if (hn == 0)
return -1;
*h = hn;
return 0;
}
void* simple_threads_release_thread(THREAD t) {
void* result = simple_threads_join_thread(t);
CloseHandle(t);
return result;
}
void* simple_threads_join_thread(THREAD t) {
WaitForSingleObject(t, INFINITE);
return NULL; // TODO: also get thread exit status
}
#else
int simple_threads_cond_wait(pthread_cond_t * h, pthread_mutex_t *m, long milisec) {
struct timespec waittime;
struct timeval curtime;
int retcode;
if (milisec < 0) {
return pthread_cond_wait(h, m);
}
/*
* We calculate the delay time (representing the desired frame
* rate). This delay time is in *nanoseconds*.
* We will wait 0.5 seconds which gives a practical minimum
* framerate of 2 which is desired for the motion_loop to
* function.
*/
gettimeofday(&curtime, NULL);
curtime.tv_usec += milisec * 1000;
if (curtime.tv_usec > 1000000) {
curtime.tv_usec -= 1000000;
curtime.tv_sec++;
}
waittime.tv_sec = curtime.tv_sec;
waittime.tv_nsec = 1000L * curtime.tv_usec;
do {
retcode = pthread_cond_timedwait(h, m, &waittime);
} while (retcode == EINTR);
return retcode;
}
int simple_threads_create_thread(THREAD* t, void *(*start_routine)(void*), void *arg) {
pthread_attr_init(&(t->attr));
//pthread_attr_setdetachstate(&(t->attr), PTHREAD_CREATE_DETACHED);
return pthread_create(&(t->thread), &(t->attr), start_routine, arg);
}
void* simple_threads_release_thread(THREAD t) {
void* result = simple_threads_join_thread(t);
pthread_attr_destroy(&(t.attr));
return result;
}
void* simple_threads_join_thread(THREAD t) {
void* result;
pthread_join(t.thread, &result);
return result;
}
#endif
Mutex::Mutex() {
MUTEX_INIT(mutex);
owner = THREAD_NONE;
counter = 0;
recursive = false;
}
Mutex::~Mutex() {
MUTEX_DESTROY(mutex);
}
void Mutex::acquire() {
if (!recursive) {
MUTEX_LOCK(mutex);
} else {
THREAD_IDENTIFIER tid = THREAD_GET_IDENTIFIER();
if (!THREAD_EQUALS(tid, owner)) {
MUTEX_LOCK(mutex);
owner = tid;
counter = 0;
}
counter++;
}
}
void Mutex::release() {
if (!recursive) {
MUTEX_UNLOCK(mutex);
} else {
THREAD_IDENTIFIER tid = THREAD_GET_IDENTIFIER();
if (THREAD_EQUALS(tid, owner)) {
counter--;
if (counter < 1) {
owner = THREAD_NONE;
MUTEX_UNLOCK(mutex);
}
}
}
}
RecursiveMutex::RecursiveMutex() : Mutex() {
recursive = true;
}
RecursiveMutex::~RecursiveMutex() {
}
Lock::Lock(Mutex& mutex) : mutex(mutex), locked(false)
{
lock();
}
Lock::Lock(Synchronized& mutex) : mutex(mutex.object_mutex), locked(false) {
lock();
}
Lock::~Lock()
{
unlock();
}
Lock::operator bool () const
{
return locked;
}
void Lock::lock() {
if (!locked) {
mutex.acquire();
locked = true;
}
}
void Lock::unlock() {
if (locked) {
locked = false;
mutex.release();
}
}
Signal::Signal() {
CONDITION_INIT(condition);
MUTEX_INIT(mutex);
}
Signal::~Signal() {
CONDITION_DESTROY(condition);
MUTEX_DESTROY(mutex);
}
void Signal::wait(long timeout) {
MUTEX_LOCK(mutex);
if (timeout > 0) {
CONDITION_TIMEDWAIT(condition, mutex, timeout);
} else {
CONDITION_WAIT(condition, mutex);
}
MUTEX_UNLOCK(mutex);
}
void Signal::notify() {
MUTEX_LOCK(mutex);
CONDITION_SIGNAL(condition);
MUTEX_UNLOCK(mutex);
}
Synchronized::Synchronized() {
}
Synchronized::~Synchronized() {
}