Beispiel #1
0
extern "C" int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
  WRAPPER_HEADER(int, pthread_cond_wait, _real_pthread_cond_wait, cond, mutex);
  /*
   * pthread_cond_wait() internally consists of three events:
   *   pthread_mutex_unlock()
   *   block on cond-var cond
   *   pthread_mutex_lock()
   * Ideally we would like to log the pthread_mutex_{lock,unlock} calls, but
   * since libpthread is making internal calls, we are unable to do so.
   *
   * Due to our inablility to force threads to acquire the mutex during REPLAY,
   * on broadcast calls, all threads blocked on condition variable wake up and
   * start to executing inside the critical section without acquiring the
   * mutex. This is * totally undesired and incorrect.
   *
   * The solution is to make threads wait until the thread executing inside the
   * critical section has left the critical section (This is done either by and
   * explicit call to pthread_mutex_unlock() or a call to pthread_cond_wait()
   * which involves unlocking the mutex).
   *
   * In order to do so, we introduce a _fake_ pthread_mutex_unlock() call (The
   * call is fake in the sense that _real_XXX version is never called during
   * record or replay). This extra log event makes sure that the other threads
   * have to wait until the thread in critical section is able to process this
   * event, hence making sure that only one thread is executing in the critical
   * section during REPLAY.
   */
  FAKE_BASIC_SYNC_WRAPPER(int, pthread_mutex_unlock, mutex);

  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY(pthread_cond_wait);
  } else if (SYNC_IS_RECORD) {
    dmtcp::ThreadInfo::setOptionalEvent();
    retval = _real_pthread_cond_wait(cond, mutex);
    dmtcp::ThreadInfo::unsetOptionalEvent();
    WRAPPER_LOG_WRITE_ENTRY(pthread_cond_wait);
  }
  return retval;
}
extern "C" int
pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
  return _real_pthread_cond_wait(cond, mutex);
}