bool rdEventLocal::wait(rdMutex& mutex, time_t timeout) { if (!signaled) { struct timespec abs_ts; #ifdef PTHREAD_GET_EXPIRATION_NP struct timespec rel_ts; rel_ts.tv_sec = timeout/1000; rel_ts.tv_nsec = timeout%1000*1000000; pthread_get_expiration_np(&rel_ts, &abs_ts); #else struct timeval cur_tv; gettimeofday(&cur_tv, NULL); abs_ts.tv_sec = cur_tv.tv_sec + timeout/1000; abs_ts.tv_nsec = cur_tv.tv_usec*1000 + timeout%1000*1000000; if (abs_ts.tv_nsec > 1000000000) { abs_ts.tv_nsec -= 1000000000; abs_ts.tv_sec += 1; } #endif do { int rc = pthread_cond_timedwait(&cond, &mutex._mutex, &abs_ts); if (rc != 0) { return false; } } while (!signaled); } return true; }
bool SemaphoreImpl::waitImpl(long milliseconds) { int rc = 0; struct timespec abstime; #if defined(__VMS) struct timespec delta; delta.tv_sec = milliseconds / 1000; delta.tv_nsec = (milliseconds % 1000)*1000000; pthread_get_expiration_np(&delta, &abstime); #elif defined(POCO_HAVE_MONOTONIC_PTHREAD_COND_TIMEDWAIT) clock_gettime(CLOCK_MONOTONIC, &abstime); abstime.tv_sec += milliseconds / 1000; abstime.tv_nsec += (milliseconds % 1000)*1000000; if (abstime.tv_nsec >= 1000000000) { abstime.tv_nsec -= 1000000000; abstime.tv_sec++; } #elif (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) clock_gettime(CLOCK_REALTIME, &abstime); abstime.tv_sec += milliseconds / 1000; abstime.tv_nsec += (milliseconds % 1000)*1000000; if (abstime.tv_nsec >= 1000000000) { abstime.tv_nsec -= 1000000000; abstime.tv_sec++; } #else struct timeval tv; gettimeofday(&tv, NULL); abstime.tv_sec = tv.tv_sec + milliseconds / 1000; abstime.tv_nsec = tv.tv_usec*1000 + (milliseconds % 1000)*1000000; if (abstime.tv_nsec >= 1000000000) { abstime.tv_nsec -= 1000000000; abstime.tv_sec++; } #endif if (pthread_mutex_lock(&_mutex) != 0) throw SystemException("wait for semaphore failed (lock)"); while (_n < 1) { if ((rc = pthread_cond_timedwait(&_cond, &_mutex, &abstime))) { if (rc == ETIMEDOUT) break; pthread_mutex_unlock(&_mutex); throw SystemException("cannot wait for semaphore"); } } if (rc == 0) --_n; pthread_mutex_unlock(&_mutex); return rc == 0; }
void IntervalTimerDriver (pthread_addr_t argument) { pthread_t self = pthread_self (); struct timespec expirationTime, expirationInterval; int result; pthread_cleanup_push ((pthread_cleanuproutine_t)pthread_detach, (void*)self); WaitUntilInitializationComplete (); EmbCommAreaPtr->clockTime = -1; begin_MUTEX_LOCKED (clockLock); while (TRUE) { if (EmbCommAreaPtr->clockTime >= 0) { expirationInterval.tv_sec = 0; expirationInterval.tv_nsec = 1000 * EmbCommAreaPtr->clockTime; while (expirationInterval.tv_nsec >= OneSecond) { expirationInterval.tv_sec++; expirationInterval.tv_nsec -= OneSecond; } if (pthread_get_expiration_np (&expirationInterval, &expirationTime) < 0) vpunt (NULL, "Unable to compute interval timer expiration time"); result = pthread_cond_timedwait (&EmbCommAreaPtr->clockSignal, &EmbCommAreaPtr->clockLock, &expirationTime); } else /* Wait indefinitely for someone to program the interval timer */ result = pthread_cond_wait (&EmbCommAreaPtr->clockSignal, &EmbCommAreaPtr->clockLock); if (result == ETIMEDOUT) { EmbSendSignal (EmbCommAreaPtr->clock_signal); EmbCommAreaPtr->clockTime = -1; } } end_MUTEX_LOCKED (clockLock); pthread_cleanup_pop (TRUE); }
bool EventImpl::waitImpl(long milliseconds) { int rc = 0; struct timespec abstime; #if defined(__VMS) struct timespec delta; delta.tv_sec = milliseconds / 1000; delta.tv_nsec = (milliseconds % 1000)*1000000; pthread_get_expiration_np(&delta, &abstime); #elif defined(PIL_VXWORKS) clock_gettime(CLOCK_REALTIME, &abstime); abstime.tv_sec += milliseconds / 1000; abstime.tv_nsec += (milliseconds % 1000)*1000000; if (abstime.tv_nsec >= 1000000000) { abstime.tv_nsec -= 1000000000; abstime.tv_sec++; } #else struct timeval tv; gettimeofday(&tv, NULL); abstime.tv_sec = tv.tv_sec + milliseconds / 1000; abstime.tv_nsec = tv.tv_usec*1000 + (milliseconds % 1000)*1000000; if (abstime.tv_nsec >= 1000000000) { abstime.tv_nsec -= 1000000000; abstime.tv_sec++; } #endif if (pthread_mutex_lock(&_mutex) != 0) throw SystemException("wait for event failed (lock)"); while (!_state) { if ((rc = pthread_cond_timedwait(&_cond, &_mutex, &abstime))) { if (rc == ETIMEDOUT) break; pthread_mutex_unlock(&_mutex); throw SystemException("cannot wait for event"); } } if (rc == 0 && _auto) _state = false; pthread_mutex_unlock(&_mutex); return rc == 0; }
timespec *getTimeout(struct timespec *spec, timeout_t timer) { static struct timespec myspec; if(spec == NULL) spec = &myspec; #ifdef PTHREAD_GET_EXPIRATION_NP struct timespec offset; offset.tv_sec = timer / 1000; offset.tv_nsec = (timer % 1000) * 1000000; pthread_get_expiration_np(&offset, spec); #else struct timeval current; SysTime::getTimeOfDay(¤t); spec->tv_sec = current.tv_sec + ((timer + current.tv_usec / 1000) / 1000); spec->tv_nsec = ((current.tv_usec / 1000 + timer) % 1000) * 1000000; #endif return spec; }
bool CSemaphoreImpl::waitImpl(long milliseconds) { int rc = 0; struct timespec abstime; #if defined(__VMS) struct timespec delta; delta.tv_sec = milliseconds / 1000; delta.tv_nsec = (milliseconds % 1000)*1000000; pthread_get_expiration_np(&delta, &abstime); #else struct timeval tv; gettimeofday(&tv, NULL); abstime.tv_sec = tv.tv_sec + milliseconds / 1000; abstime.tv_nsec = tv.tv_usec*1000 + (milliseconds % 1000)*1000000; if (abstime.tv_nsec >= 1000000000) { abstime.tv_nsec -= 1000000000; abstime.tv_sec++; } #endif if (pthread_mutex_lock(&_mutex) != 0) throw CSystemException("wait for semaphore failed (lock)"); while (_n < 1) { if ((rc = pthread_cond_timedwait(&_cond, &_mutex, &abstime))) { if (rc == ETIMEDOUT) break; pthread_mutex_unlock(&_mutex); throw CSystemException("cannot wait for semaphore"); } } if (rc == 0) --_n; pthread_mutex_unlock(&_mutex); return rc == 0; }
bool EventSemaphoreImpl::waitImpl(long milliseconds) { int rc = 0; struct timespec abstime; #if defined(__VMS) struct timespec delta; delta.tv_sec = milliseconds / 1000; delta.tv_nsec = (milliseconds % 1000)*1000000; pthread_get_expiration_np(&delta, &abstime); #else struct timeval tv; gettimeofday(&tv, NULL); abstime.tv_sec = tv.tv_sec + milliseconds / 1000; abstime.tv_nsec = tv.tv_usec*1000 + (milliseconds % 1000)*1000000; if (abstime.tv_nsec >= 1000000000) { abstime.tv_nsec -= 1000000000; abstime.tv_sec++; } #endif if (pthread_mutex_lock(&_mutex) != 0) NIT_THROW_FMT(EX_SYSTEM, "wait for event failed (lock)"); while (!_state) { if ((rc = pthread_cond_timedwait(&_cond, &_mutex, &abstime))) { if (rc == ETIMEDOUT) break; pthread_mutex_unlock(&_mutex); NIT_THROW_FMT(EX_SYSTEM, "cannot wait for event"); } } if (rc == 0 && _auto) _state = false; pthread_mutex_unlock(&_mutex); return rc == 0; }
int Event::Lock (unsigned int nTime) { int nResult = 0; #ifdef __POSIX__ if (nTime == INFINITE) { nResult = Lock (); } else { // See if we can check the state. pthread_mutex_lock (&m_syncAdminLock); // We are not busy Setting the flag, so we can check it. if (m_blCondition == false) { struct timespec structTime; #ifdef __LINUX__ struct timeval structDelta; gettimeofday(&structDelta, NULL); structTime.tv_sec = structDelta.tv_sec + nTime; structTime.tv_nsec = 0; #endif #ifdef __DEC__ struct timespec structDelta; // Convert the given time to a delta time. structDelta.tv_sec = nTime; structDelta.tv_nsec = 0; pthread_get_expiration_np (&structDelta, &structTime); #endif do { // Oops it seems that we are not allowed to pass. nResult = pthread_cond_timedwait (&m_syncCondition, &m_syncAdminLock, &structTime); if (nResult != 0) { // Something went wrong, so assume... TRACE_L5 ("Timed out waiting for event <%d>!", nResult); } // For some reason the documentation says that we have to double check on // the condition variable to see if we are allowed to fall through, so we // do (Guide to DEC threads, March 1996 ,page pthread-56, paragraph 4) } while ( (m_blCondition == false) && (nResult == 0) ); } // Seems that the event is triggered, lets continue. but // do not forget to give back the flag.. pthread_mutex_unlock (&m_syncAdminLock); } #endif #ifdef __WIN32__ nResult = ::WaitForSingleObjectEx (m_syncEvent, nTime, FALSE); if (nResult == WAIT_OBJECT_0) { nResult = OK; } #endif return (nResult); }
int BinairySemaphore::Lock (unsigned int nTime) { int nResult = 0; #ifdef __POSIX__ if (nTime == INFINITE) { nResult = Lock (); } else { // See if we can check the state. pthread_mutex_lock (&m_syncAdminLock); // We are not busy Setting the flag, so we can check it. if (m_blLocked != false) { struct timespec structTime; #ifdef __LINUX__ struct timeval structDelta; gettimeofday(&structDelta, NULL); structTime.tv_sec = structDelta.tv_sec + nTime; structTime.tv_nsec = 0; #endif #ifdef __DEC__ struct timespec structDelta; // Convert the given time to a delta time. structDelta.tv_sec = nTime; structDelta.tv_nsec = 0; pthread_get_expiration_np (&structDelta, &structTime); #endif do { // Oops it seems that we are not allowed to pass. nResult = pthread_cond_timedwait (&m_syncCondition, &m_syncAdminLock, &structTime); if (nResult == ETIMEDOUT) { // Something went wrong, so assume... TRACE_L5 ("Timed out waiting for event <%d>.", nTime); } else if (nResult != 0) { // Something went wrong, so assume... TRACE_L5 ("Waiting on semaphore failed. Error code <%d>", nResult); } // For some reason the documentation says that we have to double check on // the condition variable to see if we are allowed to fall through, so we // do (Guide to DEC threads, March 1996 ,page pthread-56, paragraph 4) } while ( (m_blLocked == true) && (nResult == 0) ); } // Seems like we have the token, So the object is locked now. m_blLocked = true; // Done with the internals of the binairy semphore, everyone can access it again. pthread_mutex_unlock (&m_syncAdminLock); } #endif #ifdef __WIN32__ nResult = ::WaitForSingleObjectEx (m_syncMutex, nTime, FALSE); if (nResult == WAIT_OBJECT_0) { nResult = OK; } #endif // Timed out or did we get the token ? return (nResult); }
void *Consume (void *arg) /* Consumer thread function. */ { msg_block_t *pmb; statistics_t * ps; int my_number, tstatus; struct timespec timeout, delta; delta.tv_sec = 2; delta.tv_nsec = 0; /* Create thread-specific storage key */ tstatus = pthread_once (&once_control, once_init_function); if (tstatus != 0) err_abort (tstatus, "One time init failed"); pmb = (msg_block_t *)arg; /* Allocate storage for thread-specific statistics */ ps = calloc (sizeof(statistics_t), 1); if (ps == NULL) errno_abort ("Cannot allocate memory"); tstatus = pthread_setspecific (ts_key, ps); if (tstatus != 0) err_abort (tstatus, "Error setting ts storage"); ps->pmblock = pmb; /* Give this thread a unique number */ /* Note that the mutex is "overloaded" to protect data */ /* outside the message block structure */ tstatus = pthread_mutex_lock (&pmb->nGuard); if (tstatus != 0) err_abort (tstatus, "Lock error"); ps->th_number = thread_number++; tstatus = pthread_mutex_unlock (&pmb->nGuard); if (tstatus != 0) err_abort (tstatus, "Unlock error"); /* Consume the NEXT message when prompted by the user */ while (!pmb->fStop) { /* This is the only thread accessing stdin, stdout */ tstatus = pthread_mutex_lock (&pmb->nGuard); if (tstatus != 0) err_abort (tstatus, "Lock error"); /* Get the next message. Use a timed wait so as to be able */ /* to sample the stop flag peridically. */ do { pthread_get_expiration_np (&delta, &timeout); tstatus = pthread_cond_timedwait (&pmb->mReady, &pmb->nGuard, &timeout); if (tstatus != 0 && tstatus != ETIMEDOUT) err_abort (tstatus, "CV wait error"); } while (!pmb->f_ready && !pmb->fStop); if (!pmb->fStop) { /* printf ("Message received\n"); */ accumulate_statistics (); pmb->f_consumed = 1; pmb->f_ready = 0; } tstatus = pthread_cond_signal (&pmb->mconsumed); if (tstatus != 0) err_abort (tstatus, "Signal error"); tstatus = pthread_mutex_unlock (&pmb->nGuard); if (tstatus != 0) err_abort (tstatus, "Unlock error"); } /* Shutdown. Report the statistics */ tstatus = pthread_mutex_lock (&pmb->nGuard); if (tstatus != 0) err_abort (tstatus, "Lock error"); report_statistics (); tstatus = pthread_mutex_unlock (&pmb->nGuard); if (tstatus != 0) err_abort (tstatus, "Unlock error"); /* Terminate the consumer thread. The destructor will */ /* free the memory allocated for the statistics */ return NULL; }