vpr::CondVarPosix Class Reference

Condition variable wrapper for POSIX-compliant systems using pthreads condition variables for the implementation. More...

#include <vpr/Sync/CondVar.h>

Collaboration diagram for vpr::CondVarPosix:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 CondVarPosix (MutexPosix *mutex=NULL)
 Constructor for vpr::CondVarPosix class.
 ~CondVarPosix ()
 Destructor for vpr::CondVarPosix class.
vpr::ReturnStatus wait (vpr::Interval timeToWait=vpr::Interval::NoTimeout)
 Blocks on a condition.
vpr::ReturnStatus signal ()
 Signals a thread waiting on this condition variable.
vpr::ReturnStatus broadcast ()
 Signals all waiting threads.
vpr::ReturnStatus acquire ()
 Acquires a lock on the mutex variable associated with this condition variable.
vpr::ReturnStatus tryAcquire ()
 Try to acquire a lock on the mutex variable associated with this condition variable.
vpr::ReturnStatus release ()
 Releases the lock on the mutex variable associated with this condition variable.
void setMutex (vpr::MutexPosix *mutex)
 Changes the condition variable mutex to be the specifiec mutex variable.
int test ()
 Tests the mutex to see if it is held.
void dump () const
 Prints out information about the condition variable to stderr.

Detailed Description

Condition variable wrapper for POSIX-compliant systems using pthreads condition variables for the implementation.

This is typedef'd to vpr::CondVar.

Examples:

Example of using a vpr::CondVar.

Definition at line 68 of file CondVarPosix.h.


Constructor & Destructor Documentation

vpr::CondVarPosix::CondVarPosix ( MutexPosix mutex = NULL  )  [inline]

Constructor for vpr::CondVarPosix class.

Postcondition:
The condition variable is intialized, and the mutex variable associated with it is defined. These two steps must be done before any other member functions can use them.
Parameters:
mutex Pointer to a vpr::MutexPosix variable that is used in association with this condition variable in this class (optional).

Definition at line 82 of file CondVarPosix.h.

00083    {
00084       // Initialize the condition variable.
00085       pthread_cond_init(&mCondVar, NULL);
00086 
00087       // If the caller did not specify a mutex variable to use with
00088       // the condition variable, use mDefaultMutex.
00089       if ( mutex == NULL )
00090       {
00091          mutex = &mDefaultMutex;
00092       }
00093 
00094       mCondMutex = mutex;
00095    }

vpr::CondVarPosix::~CondVarPosix (  )  [inline]

Destructor for vpr::CondVarPosix class.

Postcondition:
The condition variable is destroyed.

Definition at line 102 of file CondVarPosix.h.

00103    {
00104       pthread_cond_destroy(&mCondVar);
00105    }


Member Function Documentation

vpr::ReturnStatus vpr::CondVarPosix::wait ( vpr::Interval  timeToWait = vpr::Interval::NoTimeout  ) 

Blocks on a condition.

Precondition:
The mutex variable associated with this condition variable must be locked.
Postcondition:
The condition variable is locked. If it was previously locked, the caller blocks until signaled.
Returns:
vpr::ReturnStatus::Succeed is returned after blocking.

vpr::ReturnStatus::Fail is returned if an error occurred when trying to wait on the condition variable.

Examples:
Example of using a vpr::CondVar.

Definition at line 55 of file CondVarPosix.cpp.

References vpr::ReturnStatus::Fail, vpr::MutexPosix::mMutex, vpr::Interval::NoTimeout, vpr::Interval::sec(), vpr::ReturnStatus::setCode(), vpr::ReturnStatus::Succeed, vpr::MutexPosix::test(), vpr::ReturnStatus::Timeout, vpr::Interval::usec(), vprASSERT, vprDBG_ALL(), vprDBG_CRITICAL_LVL, vprDEBUG, and vprDEBUG_FLUSH.

Referenced by vpr::ThreadPosix::start().

00056 {
00057    // ASSERT:  We have been locked
00058    vpr::ReturnStatus status;
00059 
00060    // If not locked ...
00061    if ( mCondMutex->test() == 0 )
00062    {
00063       std::cerr << "[vpr::CondVarPosix::wait()] INCORRECT USAGE: Mutex was not "
00064                 << "locked when wait invoked!!!\n";
00065 
00066       status.setCode(vpr::ReturnStatus::Fail);
00067    }
00068    else
00069    {
00070       // The mutex variable must be locked when passed to
00071       // pthread_cond_wait().
00072       if ( vpr::Interval::NoTimeout == timeToWait )
00073       {
00074          int retcode = pthread_cond_wait(&mCondVar, &(mCondMutex->mMutex));
00075          if ( retcode != 0 )
00076          {
00077 #ifdef HAVE_STRERROR_R
00078             char error_str[255];
00079             strerror_r(retcode, error_str, 254);
00080 #else
00081             char* error_str = strerror(retcode);
00082 #endif
00083             vprDEBUG(vprDBG_ALL,vprDBG_CRITICAL_LVL)
00084                << "[vpr::CondVarPosix::wait()] Unexpected error: "
00085                << error_str << std::endl << vprDEBUG_FLUSH;
00086             status.setCode(vpr::ReturnStatus::Fail);
00087          }
00088       }
00089       else
00090       {
00091          struct timeval  now;                // The current time
00092          struct timespec abs_timeout;        // The absolute time of the timeout
00093 
00094          const vpr::Uint64 UsecsPerSec(1000000);
00095 
00096          // Calculate the absolute time for wait timeout
00097          gettimeofday(&now, NULL);
00098 
00099          // - Calculate the amount of usecs left as fractional seconds from
00100          //   wait time
00101          // - Calcualte the absolute time number of usecs
00102          // - If greater then a second then addon on those seconds to abs
00103          //   seconds
00104          // - Add on the waiting secons and the current time in seconds
00105          vpr::Uint64 abs_secs(0);
00106          const vpr::Uint64 left_over_usecs = timeToWait.usec() % UsecsPerSec;
00107          vpr::Uint64 abs_usecs = now.tv_usec + left_over_usecs;
00108          if(abs_usecs > UsecsPerSec)    // Have extra seconds
00109          {
00110             abs_secs = abs_usecs / UsecsPerSec;    // Get the number of seconds
00111             abs_usecs = abs_usecs % UsecsPerSec;
00112          }
00113          abs_secs += (now.tv_sec + timeToWait.sec());
00114 
00115          abs_timeout.tv_sec = abs_secs;
00116          abs_timeout.tv_nsec = 1000 * (abs_usecs);
00117          vprASSERT(abs_timeout.tv_nsec < vpr::Int64(UsecsPerSec * 1000) &&
00118                    "Nano seconds out of range (greater then one second).");
00119 
00120          int retcode = pthread_cond_timedwait(&mCondVar, &(mCondMutex->mMutex),
00121                                               &abs_timeout);
00122 
00123          if(0 == retcode)
00124          {
00125             status.setCode(vpr::ReturnStatus::Succeed);
00126          }
00127          else if(ETIMEDOUT == retcode)
00128          {
00129             status.setCode(vpr::ReturnStatus::Timeout);
00130          }
00131          else if(EINVAL == retcode)
00132          {
00133             status.setCode(vpr::ReturnStatus::Fail);
00134             vprDEBUG(vprDBG_ALL,vprDBG_CRITICAL_LVL)
00135                << "[vpr::CondVarPosix::wait()] Invalid value.\n"
00136                << vprDEBUG_FLUSH;
00137          }
00138          else
00139          {
00140 #ifdef HAVE_STRERROR_R
00141             char error_str[255];
00142             strerror_r(retcode, error_str, 254);
00143 #else
00144             char* error_str = strerror(retcode);
00145 #endif
00146             vprDEBUG(vprDBG_ALL,vprDBG_CRITICAL_LVL)
00147                << "[vpr::CondVarPosix::wait()] Unexpected error: "
00148                << error_str << std::endl << vprDEBUG_FLUSH;
00149             status.setCode(vpr::ReturnStatus::Fail);
00150          }
00151       }
00152    }
00153 
00154    return status;
00155 }

vpr::ReturnStatus vpr::CondVarPosix::signal (  )  [inline]

Signals a thread waiting on this condition variable.

Precondition:
The condition variable must be locked.
Postcondition:
The condition variable is unlocked, and a signal is sent to a thread waiting on it.
Returns:
vpr::ReturnStatus::Succeed is returned if the signal is sent successfully.

vpr::ReturnStatus::Fail is returned if the signalling failed.

Examples:
Example of using a vpr::CondVar.

Definition at line 132 of file CondVarPosix.h.

References vpr::ReturnStatus::Fail, and vpr::ReturnStatus::Succeed.

Referenced by vpr::ThreadPosix::startThread().

00133    {
00134       // ASSERT:  We have been locked
00135       if ( pthread_cond_signal(&mCondVar) == 0 )
00136       {
00137          return vpr::ReturnStatus(vpr::ReturnStatus::Succeed);
00138       }
00139       else
00140       {
00141          return vpr::ReturnStatus(vpr::ReturnStatus::Fail);
00142       }
00143    }

vpr::ReturnStatus vpr::CondVarPosix::broadcast (  )  [inline]

Signals all waiting threads.

Precondition:
The mutex variable associated with this condition variable should be locked.
Postcondition:
The condition variable is unlocked, and all waiting threads are signaled of this event.
Returns:
vpr::ReturnStatus::Succeed is returned if a signal was broadcast to all waiting threads successfully.

vpr::ReturnStatus::Fail is returned to indicate an error with the signal broadcast.

Definition at line 158 of file CondVarPosix.h.

References vpr::ReturnStatus::Fail, vpr::ReturnStatus::Succeed, and vpr::MutexPosix::test().

00159    {
00160       // ASSERT:  We have been locked
00161 
00162       // If not locked ...
00163       if ( mCondMutex->test() == 0 )
00164       {
00165          std::cerr << "vpr::CondVarPosix::broadcast: Mutex was not locked when "
00166                    << "broadcast called!!!\n";
00167       }
00168 
00169       if ( pthread_cond_broadcast(&mCondVar) == 0 )
00170       {
00171          return vpr::ReturnStatus(vpr::ReturnStatus::Succeed);
00172       }
00173       else
00174       {
00175          return vpr::ReturnStatus(vpr::ReturnStatus::Fail);
00176       }
00177    }

vpr::ReturnStatus vpr::CondVarPosix::acquire (  )  [inline]

Acquires a lock on the mutex variable associated with this condition variable.

Postcondition:
A lock is acquired on the mutex variable associated with the condition variable. If a lock is acquired, the caller controls the mutex variable. If it was previously locked, the caller blocks until it is unlocked.
Returns:
vpr::ReturnStatus::Succeed is returned if the lock was acquired successfully.

vpr::ReturnStatus::Fail is returned otherwise.

Examples:
Example of using a vpr::CondVar.

Definition at line 192 of file CondVarPosix.h.

References vpr::MutexPosix::acquire().

Referenced by vpr::ThreadPosix::start(), and vpr::ThreadPosix::startThread().

00193    {
00194       return mCondMutex->acquire();
00195    }

vpr::ReturnStatus vpr::CondVarPosix::tryAcquire (  )  [inline]

Try to acquire a lock on the mutex variable associated with this condition variable.

Postcondition:
If the mutex variable is not already locked, the caller obtains a lock on it. If it is already locked, the routine returns immediately to the caller.
Returns:
vpr::ReturnStatus::Succeed is returned if the lock was acquired successfully.

vpr::ReturnStatus::Fail is returned if the lock could not be acquired.

Definition at line 210 of file CondVarPosix.h.

References vpr::MutexPosix::tryAcquire().

00211    {
00212       return mCondMutex->tryAcquire();
00213    }

vpr::ReturnStatus vpr::CondVarPosix::release (  )  [inline]

Releases the lock on the mutex variable associated with this condition variable.

Postcondition:
The lock held by the caller on the mutex variable is released.
Examples:
Example of using a vpr::CondVar.

Definition at line 221 of file CondVarPosix.h.

References vpr::MutexPosix::release().

Referenced by vpr::ThreadPosix::start(), and vpr::ThreadPosix::startThread().

00222    {
00223       return mCondMutex->release();
00224    }

void vpr::CondVarPosix::setMutex ( vpr::MutexPosix mutex  )  [inline]

Changes the condition variable mutex to be the specifiec mutex variable.

Precondition:
The specified mutex variable must be initialized.
Postcondition:
The condition variable associated with the mutex variable is reset to the specified variable.
Parameters:
mutex Pointer to a vpr::MutexPosix variable that is used in association with the condition variable in this class.
Note:
NEVER call except to initialize explicitly.

Definition at line 239 of file CondVarPosix.h.

References vpr::MutexPosix::release().

00240    {
00241       // NOT exactly correct, but just make sure not to leave it locked
00242       mutex->release();
00243       mCondMutex = mutex;
00244    }

int vpr::CondVarPosix::test (  )  [inline]

Tests the mutex to see if it is held.

Definition at line 247 of file CondVarPosix.h.

References vpr::MutexPosix::test().

00248    {
00249       return mCondMutex->test();
00250    }

void vpr::CondVarPosix::dump (  )  const [inline]

Prints out information about the condition variable to stderr.

Postcondition:
All important data and debugging information related to the condition variable and its mutex are dumped to stderr.

Definition at line 258 of file CondVarPosix.h.

00259    {
00260       std::cerr << "------------- vpr::CondVarPosix::Dump ---------\n"
00261                 << "Not Implemented yet.\n";
00262    }


The documentation for this class was generated from the following files:
Generated on Thu Jan 4 10:55:36 2007 for VR Juggler Portable Runtime by  doxygen 1.5.1