diff options
Diffstat (limited to 'src/common/mutex.c')
-rw-r--r-- | src/common/mutex.c | 256 |
1 files changed, 123 insertions, 133 deletions
diff --git a/src/common/mutex.c b/src/common/mutex.c index 813bef31b..6b4f55119 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,73 +46,68 @@ 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() @@ -121,136 +116,131 @@ 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; + 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); + 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); + - result = WaitForMultipleObjects(2, c->events, FALSE, ms); + // 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] ); - 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); + 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() |