diff options
Diffstat (limited to 'src/common/mutex.c')
-rw-r--r-- | src/common/mutex.c | 256 |
1 files changed, 133 insertions, 123 deletions
diff --git a/src/common/mutex.c b/src/common/mutex.c index 6b4f55119..813bef31b 100644 --- a/src/common/mutex.c +++ b/src/common/mutex.c @@ -15,26 +15,26 @@ #include "../common/timer.h" #include "../common/mutex.h" -struct ramutex{ +struct ramutex { #ifdef WIN32 - CRITICAL_SECTION hMutex; + CRITICAL_SECTION hMutex; #else - pthread_mutex_t hMutex; + pthread_mutex_t hMutex; #endif }; -struct racond{ +struct racond { #ifdef WIN32 - HANDLE events[2]; - ra_align(8) volatile LONG nWaiters; - CRITICAL_SECTION waiters_lock; + HANDLE events[2]; + ra_align(8) volatile LONG nWaiters; + CRITICAL_SECTION waiters_lock; #define EVENT_COND_SIGNAL 0 #define EVENT_COND_BROADCAST 1 #else - pthread_cond_t hCond; + pthread_cond_t hCond; #endif }; @@ -46,68 +46,73 @@ struct racond{ // -ramutex ramutex_create(){ - struct ramutex *m; - - m = (struct ramutex*)aMalloc( sizeof(struct ramutex) ); - if(m == NULL){ - ShowFatalError("ramutex_create: OOM while allocating %u bytes.\n", sizeof(struct ramutex)); - return NULL; - } - +ramutex ramutex_create() +{ + struct ramutex *m; + + m = (struct ramutex *)aMalloc(sizeof(struct ramutex)); + if (m == NULL) { + ShowFatalError("ramutex_create: OOM while allocating %u bytes.\n", sizeof(struct ramutex)); + return NULL; + } + #ifdef WIN32 - InitializeCriticalSection(&m->hMutex); + InitializeCriticalSection(&m->hMutex); #else - pthread_mutex_init(&m->hMutex, NULL); + pthread_mutex_init(&m->hMutex, NULL); #endif - - return m; + + return m; }//end: ramutex_create() -void ramutex_destroy( ramutex m ){ +void ramutex_destroy(ramutex m) +{ #ifdef WIN32 - DeleteCriticalSection(&m->hMutex); + DeleteCriticalSection(&m->hMutex); #else - pthread_mutex_destroy(&m->hMutex); + pthread_mutex_destroy(&m->hMutex); #endif - aFree(m); + aFree(m); }//end: ramutex_destroy() -void ramutex_lock( ramutex m ){ +void ramutex_lock(ramutex m) +{ #ifdef WIN32 - EnterCriticalSection(&m->hMutex); + EnterCriticalSection(&m->hMutex); #else - pthread_mutex_lock(&m->hMutex); + pthread_mutex_lock(&m->hMutex); #endif }//end: ramutex_lock -bool ramutex_trylock( ramutex m ){ +bool ramutex_trylock(ramutex m) +{ #ifdef WIN32 - if(TryEnterCriticalSection(&m->hMutex) == TRUE) - return true; + if (TryEnterCriticalSection(&m->hMutex) == TRUE) + return true; - return false; + return false; #else - if(pthread_mutex_trylock(&m->hMutex) == 0) - return true; - - return false; + if (pthread_mutex_trylock(&m->hMutex) == 0) + return true; + + return false; #endif }//end: ramutex_trylock() -void ramutex_unlock( ramutex m ){ +void ramutex_unlock(ramutex m) +{ #ifdef WIN32 - LeaveCriticalSection(&m->hMutex); + LeaveCriticalSection(&m->hMutex); #else - pthread_mutex_unlock(&m->hMutex); + pthread_mutex_unlock(&m->hMutex); #endif }//end: ramutex_unlock() @@ -116,131 +121,136 @@ void ramutex_unlock( ramutex m ){ /////////////// // Condition Variables -// +// // Implementation: // -racond racond_create(){ - struct racond *c; - - c = (struct racond*)aMalloc( sizeof(struct racond) ); - if(c == NULL){ - ShowFatalError("racond_create: OOM while allocating %u bytes\n", sizeof(struct racond)); - return NULL; - } +racond racond_create() +{ + struct racond *c; + + c = (struct racond *)aMalloc(sizeof(struct racond)); + if (c == NULL) { + ShowFatalError("racond_create: OOM while allocating %u bytes\n", sizeof(struct racond)); + return NULL; + } #ifdef WIN32 - c->nWaiters = 0; - c->events[ EVENT_COND_SIGNAL ] = CreateEvent( NULL, FALSE, FALSE, NULL ); - c->events[ EVENT_COND_BROADCAST ] = CreateEvent( NULL, TRUE, FALSE, NULL ); - InitializeCriticalSection( &c->waiters_lock ); + c->nWaiters = 0; + c->events[ EVENT_COND_SIGNAL ] = CreateEvent(NULL, FALSE, FALSE, NULL); + c->events[ EVENT_COND_BROADCAST ] = CreateEvent(NULL, TRUE, FALSE, NULL); + InitializeCriticalSection(&c->waiters_lock); #else - pthread_cond_init(&c->hCond, NULL); + pthread_cond_init(&c->hCond, NULL); #endif - - return c; + + return c; }//end: racond_create() -void racond_destroy( racond c ){ +void racond_destroy(racond c) +{ #ifdef WIN32 - CloseHandle( c->events[ EVENT_COND_SIGNAL ] ); - CloseHandle( c->events[ EVENT_COND_BROADCAST ] ); - DeleteCriticalSection( &c->waiters_lock ); + CloseHandle(c->events[ EVENT_COND_SIGNAL ]); + CloseHandle(c->events[ EVENT_COND_BROADCAST ]); + DeleteCriticalSection(&c->waiters_lock); #else - pthread_cond_destroy(&c->hCond); + pthread_cond_destroy(&c->hCond); #endif - aFree(c); + aFree(c); }//end: racond_destroy() -void racond_wait( racond c, ramutex m, sysint timeout_ticks){ +void racond_wait(racond c, ramutex m, sysint timeout_ticks) +{ #ifdef WIN32 - register DWORD ms; - int result; - bool is_last = false; + register DWORD ms; + int result; + bool is_last = false; - EnterCriticalSection(&c->waiters_lock); - c->nWaiters++; - LeaveCriticalSection(&c->waiters_lock); + EnterCriticalSection(&c->waiters_lock); + c->nWaiters++; + LeaveCriticalSection(&c->waiters_lock); - if(timeout_ticks < 0) - ms = INFINITE; - else - ms = (timeout_ticks > MAXDWORD) ? (MAXDWORD - 1) : (DWORD)timeout_ticks; - - - // we can release the mutex (m) here, cause win's - // manual reset events maintain state when used with - // SetEvent() - ramutex_unlock(m); + if (timeout_ticks < 0) + ms = INFINITE; + else + ms = (timeout_ticks > MAXDWORD) ? (MAXDWORD - 1) : (DWORD)timeout_ticks; - result = WaitForMultipleObjects(2, c->events, FALSE, ms); - - - EnterCriticalSection(&c->waiters_lock); - c->nWaiters--; - if( (result == WAIT_OBJECT_0 + EVENT_COND_BROADCAST) && (c->nWaiters == 0) ) - is_last = true; // Broadcast called! - LeaveCriticalSection(&c->waiters_lock); - + // we can release the mutex (m) here, cause win's + // manual reset events maintain state when used with + // SetEvent() + ramutex_unlock(m); - // we are the last waiter that has to be notified, or to stop waiting - // so we have to do a manual reset - if(is_last == true) - ResetEvent( c->events[EVENT_COND_BROADCAST] ); + result = WaitForMultipleObjects(2, c->events, FALSE, ms); - ramutex_lock(m); + EnterCriticalSection(&c->waiters_lock); + c->nWaiters--; + if ((result == WAIT_OBJECT_0 + EVENT_COND_BROADCAST) && (c->nWaiters == 0)) + is_last = true; // Broadcast called! + LeaveCriticalSection(&c->waiters_lock); + + + + // we are the last waiter that has to be notified, or to stop waiting + // so we have to do a manual reset + if (is_last == true) + ResetEvent(c->events[EVENT_COND_BROADCAST]); + + + ramutex_lock(m); #else - if(timeout_ticks < 0){ - pthread_cond_wait( &c->hCond, &m->hMutex ); - }else{ - struct timespec wtime; - int64 exact_timeout = gettick() + timeout_ticks; - - wtime.tv_sec = exact_timeout/1000; - wtime.tv_nsec = (exact_timeout%1000)*1000000; - - pthread_cond_timedwait( &c->hCond, &m->hMutex, &wtime); - } + if (timeout_ticks < 0) { + pthread_cond_wait(&c->hCond, &m->hMutex); + } else { + struct timespec wtime; + int64 exact_timeout = gettick() + timeout_ticks; + + wtime.tv_sec = exact_timeout/1000; + wtime.tv_nsec = (exact_timeout%1000)*1000000; + + pthread_cond_timedwait(&c->hCond, &m->hMutex, &wtime); + } #endif }//end: racond_wait() -void racond_signal( racond c ){ +void racond_signal(racond c) +{ #ifdef WIN32 -// bool has_waiters = false; -// EnterCriticalSection(&c->waiters_lock); -// if(c->nWaiters > 0) -// has_waiters = true; -// LeaveCriticalSection(&c->waiters_lock); - -// if(has_waiters == true) - SetEvent( c->events[ EVENT_COND_SIGNAL ] ); + // bool has_waiters = false; + // EnterCriticalSection(&c->waiters_lock); + // if(c->nWaiters > 0) + // has_waiters = true; + // LeaveCriticalSection(&c->waiters_lock); + + // if(has_waiters == true) + SetEvent(c->events[ EVENT_COND_SIGNAL ]); #else - pthread_cond_signal(&c->hCond); + pthread_cond_signal(&c->hCond); #endif }//end: racond_signal() -void racond_broadcast( racond c ){ +void racond_broadcast(racond c) +{ #ifdef WIN32 -// bool has_waiters = false; -// EnterCriticalSection(&c->waiters_lock); -// if(c->nWaiters > 0) -// has_waiters = true; -// LeaveCriticalSection(&c->waiters_lock); - -// if(has_waiters == true) - SetEvent( c->events[ EVENT_COND_BROADCAST ] ); + // bool has_waiters = false; + // EnterCriticalSection(&c->waiters_lock); + // if(c->nWaiters > 0) + // has_waiters = true; + // LeaveCriticalSection(&c->waiters_lock); + + // if(has_waiters == true) + SetEvent(c->events[ EVENT_COND_BROADCAST ]); #else - pthread_cond_broadcast(&c->hCond); + pthread_cond_broadcast(&c->hCond); #endif }//end: racond_broadcast() |