Initial source commit
This commit is contained in:
commit
f1384c11ee
335 changed files with 52715 additions and 0 deletions
192
minorGems/system/linux/BinarySemaphoreLinux.cpp
Normal file
192
minorGems/system/linux/BinarySemaphoreLinux.cpp
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Modification History
|
||||
*
|
||||
* 2001-January-11 Jason Rohrer
|
||||
* Created.
|
||||
*
|
||||
* 2003-August-26 Jason Rohrer
|
||||
* Added support for timeouts on wait.
|
||||
*
|
||||
* 2006-February-28 Jason Rohrer
|
||||
* Fixed bug in sub-second timeout computation.
|
||||
*/
|
||||
|
||||
#include "minorGems/system/BinarySemaphore.h"
|
||||
#include "minorGems/system/Time.h"
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
/**
|
||||
* Linux-specific implementation of the BinarySemaphore class member functions.
|
||||
*
|
||||
* May also be compatible with other POSIX-like systems.
|
||||
*
|
||||
* To compile:
|
||||
* g++ -lpthread
|
||||
*/
|
||||
|
||||
/**
|
||||
* Native object pointer A is the condition variable.
|
||||
* Pointer B is the mutex that must go along with it.
|
||||
*/
|
||||
|
||||
|
||||
BinarySemaphore::BinarySemaphore() :
|
||||
mSemaphoreValue( 0 ) {
|
||||
|
||||
// allocate a condition variable structure on the heap
|
||||
mNativeObjectPointerA = (void *)( new pthread_cond_t[1] );
|
||||
|
||||
// get a pointer to the cond
|
||||
pthread_cond_t *condPointer =
|
||||
(pthread_cond_t *)mNativeObjectPointerA;
|
||||
|
||||
// init the cond
|
||||
pthread_cond_init( &( condPointer[0] ), NULL );
|
||||
|
||||
|
||||
// allocate a mutex structure on the heap
|
||||
mNativeObjectPointerB = (void *)( new pthread_mutex_t[1] );
|
||||
|
||||
// get a pointer to the mutex
|
||||
pthread_mutex_t *mutexPointer =
|
||||
(pthread_mutex_t *)mNativeObjectPointerB;
|
||||
|
||||
// init the mutex
|
||||
pthread_mutex_init( &( mutexPointer[0] ), NULL );
|
||||
|
||||
}
|
||||
|
||||
BinarySemaphore::~BinarySemaphore() {
|
||||
|
||||
// get a pointer to the cond
|
||||
pthread_cond_t *condPointer =
|
||||
(pthread_cond_t *)mNativeObjectPointerA;
|
||||
|
||||
// destroy the cond
|
||||
pthread_cond_destroy( &( condPointer[0] ) );
|
||||
|
||||
// de-allocate the cond structure from the heap
|
||||
delete [] condPointer;
|
||||
|
||||
|
||||
// get a pointer to the mutex
|
||||
pthread_mutex_t *mutexPointer =
|
||||
(pthread_mutex_t *)mNativeObjectPointerB;
|
||||
|
||||
// destroy the mutex
|
||||
pthread_mutex_destroy( &( mutexPointer[0] ) );
|
||||
|
||||
// de-allocate the mutex structure from the heap
|
||||
delete [] mutexPointer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int BinarySemaphore::wait( int inTimeoutInMilliseconds ) {
|
||||
|
||||
int returnValue = 1;
|
||||
|
||||
// get a pointer to the cond
|
||||
pthread_cond_t *condPointer =
|
||||
(pthread_cond_t *)mNativeObjectPointerA;
|
||||
|
||||
// get a pointer to the mutex
|
||||
pthread_mutex_t *mutexPointer =
|
||||
(pthread_mutex_t *)mNativeObjectPointerB;
|
||||
|
||||
|
||||
// lock the mutex
|
||||
pthread_mutex_lock( &( mutexPointer[0] ) );
|
||||
|
||||
if( mSemaphoreValue == 0 ) {
|
||||
// wait on condition variable, which automatically unlocks
|
||||
// the passed-in mutex
|
||||
|
||||
if( inTimeoutInMilliseconds == -1 ) {
|
||||
// no timeout
|
||||
pthread_cond_wait( &( condPointer[0] ), &( mutexPointer[0] ) );
|
||||
}
|
||||
else {
|
||||
// use timeout version
|
||||
|
||||
unsigned long nsecPerSecond = 1000000000;
|
||||
unsigned long nsecPerMillisecond = 1000000;
|
||||
|
||||
|
||||
unsigned long currentSec;
|
||||
unsigned long currentMS;
|
||||
|
||||
Time::getCurrentTime( ¤tSec, ¤tMS );
|
||||
|
||||
unsigned long currentNS = currentMS * nsecPerMillisecond;
|
||||
|
||||
|
||||
long timeoutSec = inTimeoutInMilliseconds / 1000;
|
||||
long extraMS = inTimeoutInMilliseconds % 1000;
|
||||
|
||||
long extraNS = extraMS * nsecPerMillisecond;
|
||||
|
||||
|
||||
|
||||
unsigned long absTimeoutSec = currentSec + timeoutSec;
|
||||
unsigned long absTimeoutNsec = currentNS + extraNS;
|
||||
|
||||
// check for nsec overflow
|
||||
if( absTimeoutNsec > nsecPerSecond ) {
|
||||
absTimeoutSec += 1;
|
||||
absTimeoutNsec -= nsecPerSecond;
|
||||
}
|
||||
|
||||
struct timespec abstime;
|
||||
abstime.tv_sec = absTimeoutSec;
|
||||
abstime.tv_nsec = absTimeoutNsec;
|
||||
|
||||
int result = pthread_cond_timedwait( &( condPointer[0] ),
|
||||
&( mutexPointer[0] ),
|
||||
&abstime );
|
||||
|
||||
if( result != 0 ) {
|
||||
// timed out
|
||||
returnValue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// mutex is apparently re-locked when we return from cond_wait
|
||||
|
||||
}
|
||||
|
||||
// decrement the semaphore value
|
||||
mSemaphoreValue = 0;
|
||||
|
||||
// unlock the mutex again
|
||||
pthread_mutex_unlock( &( mutexPointer[0] ) );
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BinarySemaphore::signal() {
|
||||
|
||||
// get a pointer to the cond
|
||||
pthread_cond_t *condPointer =
|
||||
(pthread_cond_t *)mNativeObjectPointerA;
|
||||
|
||||
// get a pointer to the mutex
|
||||
pthread_mutex_t *mutexPointer =
|
||||
(pthread_mutex_t *)mNativeObjectPointerB;
|
||||
|
||||
|
||||
// lock the mutex
|
||||
pthread_mutex_lock( &( mutexPointer[0] ) );
|
||||
|
||||
// increment the semaphore value
|
||||
mSemaphoreValue = 1;
|
||||
|
||||
pthread_cond_signal( &( condPointer[0] ) );
|
||||
|
||||
|
||||
// unlock the mutex
|
||||
pthread_mutex_unlock( &( mutexPointer[0] ) );
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue