Beispiel #1
0
extern "C" int pthread_detach(pthread_t thread)
{
  int retval = 0;
  void *return_addr = GET_RETURN_ADDRESS();
  if (!shouldSynchronize(return_addr)) {
    int retval = _real_pthread_detach(thread);
    if (retval == 0) {
      dmtcp::ThreadInfo::markDetached(thread);
    }
    return retval;
  }

  log_entry_t my_entry = create_pthread_detach_entry(my_clone_id,
                                                     pthread_detach_event,
                                                     thread);

  //FIXME: We don't need to log/replay this event.
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY(pthread_detach);
  } else  if (SYNC_IS_RECORD) {
    retval = _real_pthread_detach(thread);
    WRAPPER_LOG_WRITE_ENTRY(pthread_detach);
  }

  if (retval == 0) {
    dmtcp::ThreadInfo::markDetached(thread);
  }
  return retval;
}
Beispiel #2
0
extern "C" int getgrgid_r(gid_t gid, struct group *grp,
                          char *buf, size_t buflen, struct group **result)
{
  WRAPPER_HEADER(int, getgrgid_r, _real_getgrgid_r, gid, grp, buf, buflen, result);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(getgrgid_r);
    if (retval == 0 &&
        GET_FIELD(my_entry, getgrgid_r, ret_result) != NULL) {
      *grp = GET_FIELD(my_entry, getgrgid_r, ret_grp);
      WRAPPER_REPLAY_READ_FROM_READ_LOG(getgrgid_r, buf, buflen);
    }
    *result = GET_FIELD(my_entry, getgrgid_r, ret_result);
    WRAPPER_REPLAY_END(getgrgid_r);
  } else if (SYNC_IS_RECORD) {
    isOptionalEvent = true;
    retval = _real_getgrgid_r(gid, grp, buf, buflen, result);
    isOptionalEvent = false;
    if (retval == 0 && result != NULL) {
      SET_FIELD2(my_entry, getgrgid_r, ret_grp, *grp);
      WRAPPER_LOG_WRITE_INTO_READ_LOG(getgrgid_r, buf, buflen);
    }
    SET_FIELD2(my_entry, getgrgid_r, ret_result, *result);
    WRAPPER_LOG_WRITE_ENTRY(my_entry);
  }
  return retval;
}
Beispiel #3
0
extern "C" int getpwuid_r(uid_t uid, struct passwd *pwd,
                          char *buf, size_t buflen, struct passwd **result)
{
  WRAPPER_HEADER(int, getpwuid_r, _real_getpwuid_r, uid, pwd, buf, buflen, result);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(getpwuid_r);
    if (retval == 0 &&
        GET_FIELD(my_entry, getpwuid_r, ret_result) != NULL) {
      *pwd = GET_FIELD(my_entry, getpwuid_r, ret_pwd);
      WRAPPER_REPLAY_READ_FROM_READ_LOG(getpwuid_r, buf, buflen);
    }
    *result = GET_FIELD(my_entry, getpwuid_r, ret_result);
    WRAPPER_REPLAY_END(getpwuid_r);
  } else if (SYNC_IS_RECORD) {
    isOptionalEvent = true;
    retval = _real_getpwuid_r(uid, pwd, buf, buflen, result);
    isOptionalEvent = false;
    if (retval == 0 && result != NULL) {
      SET_FIELD2(my_entry, getpwuid_r, ret_pwd, *pwd);
      WRAPPER_LOG_WRITE_INTO_READ_LOG(getpwuid_r, buf, buflen);
    }
    SET_FIELD2(my_entry, getpwuid_r, ret_result, *result);
    WRAPPER_LOG_WRITE_ENTRY(my_entry);
  }
  return retval;
}
Beispiel #4
0
extern "C" char *getcwd(char *buf, size_t size)
{
  WRAPPER_HEADER(char *, getcwd, _real_getcwd, buf, size);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START_TYPED(char*, getcwd);
    if (retval != NULL) {
      /* retval will be a pointer to whatever buffer was used. If the
         user provided a NULL buffer, _real_getcwd allocated one on
         RECORD, but the optional event handler allocated it on REPLAY
         before we arrive here. Memory accurate replay allows us to
         depend on 'retval' pointing to the allocated buffer by the
         optional event handler. If the user provided a buffer, retval
         points to it. */
      WRAPPER_REPLAY_READ_FROM_READ_LOG(getcwd, retval, size);
    }
    WRAPPER_REPLAY_END(getcwd);
  } else if (SYNC_IS_RECORD) {
    dmtcp::ThreadInfo::setOptionalEvent();
    retval = _real_getcwd(buf, size);
    dmtcp::ThreadInfo::unsetOptionalEvent();
    if (retval != NULL) {
      /* retval will be a pointer to whatever buffer was used. If the
         user provided a NULL buffer, _real_getcwd will allocate one
         and retval points to it. If the user provided a buffer,
         retval points to it. */
      JASSERT(size > 0).Text("Unimplemented.");
      WRAPPER_LOG_WRITE_INTO_READ_LOG(getcwd, retval, size);
    }
    WRAPPER_LOG_WRITE_ENTRY(getcwd);
  }
  return retval;
}
extern "C" void free(void *ptr)
{
  if (fred_wrappers_initializing) {
    JASSERT(mem_allocated_for_initializing_wrappers);
    JASSERT(ptr == wrapper_init_buf);
    return;
  }
  void *return_addr = GET_RETURN_ADDRESS();
  if ((!shouldSynchronize(return_addr) && !log_all_allocs) ||
      ptr == NULL ||
      jalib::Filesystem::GetProgramName() == "gdb") {
    _real_pthread_mutex_lock(&allocation_lock);
    _real_free(ptr);
    _real_pthread_mutex_unlock(&allocation_lock);
    return;
  }

  log_entry_t my_entry = create_free_entry(my_clone_id, free_event, ptr);
  void *retval = NULL;

  if (SYNC_IS_REPLAY) {
    waitForTurn(&my_entry, &free_turn_check);
    _real_pthread_mutex_lock(&allocation_lock);
    _real_free(ptr);
    _real_pthread_mutex_unlock(&allocation_lock);
    WRAPPER_REPLAY_END(free);
  } else if (SYNC_IS_RECORD) {
    // Not restart; we should be logging.
    _real_pthread_mutex_lock(&allocation_lock);
    _real_free(ptr);
    WRAPPER_LOG_WRITE_ENTRY(my_entry);
    _real_pthread_mutex_unlock(&allocation_lock);
  }
}
Beispiel #6
0
extern "C" int getnameinfo(const struct sockaddr *sa, socklen_t salen,
                           char *host, socklen_t hostlen,
                           char *serv, socklen_t servlen, unsigned int flags)
{
  WRAPPER_HEADER(int, getnameinfo, _real_getnameinfo, sa, salen, host, hostlen,
                 serv, servlen, flags);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(getnameinfo);
    if (retval == 0 && host != NULL) {
      strncpy(host, GET_FIELD(my_entry, getnameinfo, ret_host), hostlen);
    }
    if (retval == 0 && host != NULL) {
      strncpy(serv, GET_FIELD(my_entry, getnameinfo, ret_serv), servlen);
    }
    WRAPPER_REPLAY_END(getnameinfo);
  } else if (SYNC_IS_RECORD) {
    isOptionalEvent = true;
    retval = _real_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
    isOptionalEvent = false;

    if (retval == 0 && host != NULL) {
      strncpy(GET_FIELD(my_entry, getnameinfo, ret_host), host, hostlen);
    }
    if (retval == 0 && host != NULL) {
      strncpy(GET_FIELD(my_entry, getnameinfo, ret_serv), serv, servlen);
    }

    WRAPPER_LOG_WRITE_ENTRY(my_entry);
  }
  return retval;

}
extern "C" void *mremap(void *old_address, size_t old_size,
                        size_t new_size, int flags, ...)
{
  va_list ap;
  va_start( ap, flags );
  void *new_address = va_arg ( ap, void * );
  va_end ( ap );

  MALLOC_FAMILY_WRAPPER_HEADER(mremap, old_address, old_size, new_size, flags,
                               new_address);
  if (SYNC_IS_REPLAY) {
    MALLOC_FAMILY_WRAPPER_REPLAY_START(mremap);
    void *addr = GET_COMMON(my_entry, retval);
    flags |= (MREMAP_MAYMOVE | MREMAP_FIXED);
    retval = _real_mremap (old_address, old_size, new_size, flags, addr);
    JASSERT ( retval == GET_COMMON(my_entry, retval) );
    MALLOC_FAMILY_WRAPPER_REPLAY_END(mremap);
  } else if (SYNC_IS_RECORD) {
    _real_pthread_mutex_lock(&mmap_lock);
    retval = _real_mremap (old_address, old_size, new_size, flags, new_address);
    WRAPPER_LOG_WRITE_ENTRY(my_entry);
    _real_pthread_mutex_unlock(&mmap_lock);
  }
  return retval;
}
Beispiel #8
0
extern "C" int rand()
{
  WRAPPER_HEADER(int, rand, _real_rand);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY(rand);
  } else if (SYNC_IS_RECORD) {
    retval = _real_rand();
    WRAPPER_LOG_WRITE_ENTRY(rand);
  }
  return retval;
}
Beispiel #9
0
extern "C" int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
{
  WRAPPER_HEADER(int, pthread_rwlock_wrlock, _real_pthread_rwlock_wrlock,
                 rwlock);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY(pthread_rwlock_wrlock);
  } else if (SYNC_IS_RECORD) {
    retval = _real_pthread_rwlock_wrlock(rwlock);
    WRAPPER_LOG_WRITE_ENTRY(pthread_rwlock_wrlock);
  }
  return retval;
}
Beispiel #10
0
extern "C" int pthread_cond_destroy(pthread_cond_t *cond)
{
  WRAPPER_HEADER(int, pthread_cond_destroy, _real_pthread_cond_destroy, cond);

  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY(pthread_cond_destroy);
  } else if (SYNC_IS_RECORD) {
    retval = _real_pthread_cond_destroy(cond);
    WRAPPER_LOG_WRITE_ENTRY(pthread_cond_destroy);
  }
  return retval;
}
Beispiel #11
0
extern "C" int pthread_mutex_unlock(pthread_mutex_t *mutex)
{
  WRAPPER_HEADER(int, pthread_mutex_unlock, _real_pthread_mutex_unlock, mutex);
  /* NOTE: Don't call JTRACE (or anything that calls JTRACE) before
    this point. */

  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY(pthread_mutex_unlock);
    if (!my_entry.isRetvalZero()) {
      WRAPPER_REPLAY(pthread_mutex_unlock);
    }
  } else if (SYNC_IS_RECORD) {
    SET_RETVAL_ERRNO(my_entry, pthread_mutex_unlock, 0, 0);
    WRAPPER_LOG_WRITE_ENTRY(pthread_mutex_unlock);
    retval = _real_pthread_mutex_unlock(mutex);
    /* If the call failed, we want to record the return-value and errno into
     * the log entry. We can do it by doing reserve-slot/write-into-slot as we
     * do with other wrappers (such as pthread-create). However, doing so would
     * require us to write the full-entry (including the event-specific part
     * that contains the return value/errno) for each call resulting in
     * three-times the space requirement.
     *
     * In order to save space, we record the entry only once, before performing
     * the syscall and assume it to be successful. If instead, this call fails,
     * we record the failure by unsetting the 'retvalZero' bit and update the
     * entry. We follow up with a new entry, that contains the correct return
     * value.
     *
     * This way, the cost of unsuccessful calls increases by 25%, however, we
     * save 75% on successful calls.
     */
    if (retval != 0) {
      my_entry.unsetRetvalZero();
      WRAPPER_LOG_UPDATE_HEADER(pthread_mutex_unlock);
      WRAPPER_LOG_WRITE_ENTRY(pthread_mutex_unlock);
    }
  }
  return retval;
}
Beispiel #12
0
extern "C" int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
{
  WRAPPER_HEADER(int, pthread_rwlock_unlock, _real_pthread_rwlock_unlock,
                 rwlock);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY(pthread_rwlock_unlock);
    if (!my_entry.isRetvalZero()) {
      WRAPPER_REPLAY(pthread_mutex_unlock);
    }
  } else if (SYNC_IS_RECORD) {
    SET_RETVAL_ERRNO(my_entry, pthread_mutex_unlock, 0, 0);
    WRAPPER_LOG_WRITE_ENTRY(pthread_rwlock_unlock);
    retval = _real_pthread_rwlock_unlock(rwlock);
    if (retval != 0) {
      // See the comments in pthread_mutex_unlock
      my_entry.unsetRetvalZero();
      WRAPPER_LOG_UPDATE_HEADER(pthread_rwlock_unlock);
      WRAPPER_LOG_WRITE_ENTRY(pthread_rwlock_unlock);
    }
  }
  return retval;
}
Beispiel #13
0
extern "C" int pthread_cond_signal(pthread_cond_t *cond)
{
  WRAPPER_HEADER(int, pthread_cond_signal, _real_pthread_cond_signal, cond);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY(pthread_cond_signal);
  } else  if (SYNC_IS_RECORD) {
    dmtcp::ThreadInfo::setOptionalEvent();
    retval = _real_pthread_cond_signal(cond);
    dmtcp::ThreadInfo::unsetOptionalEvent();
    WRAPPER_LOG_WRITE_ENTRY(pthread_cond_signal);
  }
  return retval;
}
Beispiel #14
0
extern "C" int pthread_mutex_trylock(pthread_mutex_t *mutex)
{
  WRAPPER_HEADER(int, pthread_mutex_trylock, _real_pthread_mutex_trylock,
                 mutex);
  /* NOTE: Don't call JTRACE (or anything that calls JTRACE) before
    this point. */
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY(pthread_mutex_trylock);
  } else if (SYNC_IS_RECORD) {
    retval = _real_pthread_mutex_trylock(mutex);
    WRAPPER_LOG_WRITE_ENTRY(pthread_mutex_trylock);
  }
  return retval;
}
Beispiel #15
0
pid_t fork()
{
  WRAPPER_HEADER(pid_t, fork, _real_fork);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_TYPED(pid_t, fork);
  } else if (SYNC_IS_RECORD) {
    dmtcp::ThreadInfo::setOptionalEvent();
    retval = _real_fork();
    if (retval != 0) {
      dmtcp::ThreadInfo::unsetOptionalEvent();
      WRAPPER_LOG_WRITE_ENTRY(fork);
    }
  }
  return retval;
}
Beispiel #16
0
extern "C" int clock_getres(clockid_t clk_id, struct timespec *res)
{
  WRAPPER_HEADER(int, clock_getres, _real_clock_getres, clk_id, res);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(clock_getres);
    if (retval == 0 && res != NULL) {
      *res = GET_FIELD(my_entry, clock_getres, ret_res);
    }
    WRAPPER_REPLAY_END(clock_getres);
  } else if (SYNC_IS_RECORD) {
    retval = _real_clock_getres(clk_id, res);
    if (retval == 0 && res != NULL) {
      SET_FIELD2(my_entry, clock_getres, ret_res, *res);
    }
    WRAPPER_LOG_WRITE_ENTRY(clock_getres);
  }
  return retval;
}
Beispiel #17
0
extern "C" time_t time(time_t *tloc)
{
  WRAPPER_HEADER(time_t, time, _real_time, tloc);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(time);
    if (retval != (time_t) -1 && tloc != NULL) {
      *tloc = GET_FIELD(my_entry, time, ret_tloc);
    }
    WRAPPER_REPLAY_END(time);
  } else if (SYNC_IS_RECORD) {
    retval = _real_time(tloc);
    if (tloc != NULL) {
      SET_FIELD2(my_entry, time, ret_tloc, *tloc);
    }
    WRAPPER_LOG_WRITE_ENTRY(time);
  }
  return retval;
}
Beispiel #18
0
extern "C" int clock_gettime(clockid_t clk_id, struct timespec *tp)
{
  WRAPPER_HEADER(int, clock_gettime, _real_clock_gettime, clk_id, tp);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(clock_gettime);
    if (retval == 0 && tp != NULL) {
      *tp = GET_FIELD(my_entry, clock_gettime, ret_tp);
    }
    WRAPPER_REPLAY_END(clock_gettime);
  } else if (SYNC_IS_RECORD) {
    retval = _real_clock_gettime(clk_id, tp);
    if (retval == 0 && tp != NULL) {
      SET_FIELD2(my_entry, clock_gettime, ret_tp, *tp);
    }
    WRAPPER_LOG_WRITE_ENTRY(clock_gettime);
  }
  return retval;
}
Beispiel #19
0
extern "C" int munmap(void *addr, size_t length)
{
  MALLOC_FAMILY_WRAPPER_HEADER_TYPED(int, munmap, addr, length);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(munmap);
    _real_pthread_mutex_lock(&allocation_lock);
    retval = _real_munmap (addr, length);
    JASSERT (retval == (int)(unsigned long)GET_COMMON(my_entry, retval));
    _real_pthread_mutex_unlock(&allocation_lock);
    WRAPPER_REPLAY_END(munmap);
  } else if (SYNC_IS_RECORD) {
    _real_pthread_mutex_lock(&mmap_lock);
    retval = _real_munmap (addr, length);
    WRAPPER_LOG_WRITE_ENTRY(my_entry);
    _real_pthread_mutex_unlock(&mmap_lock);
  }
  return retval;
}
Beispiel #20
0
/* mmap/mmap64
 * TODO: Remove the PROT_WRITE flag on REPLAY phase if it was not part of
 *       original flags.
 * FIXME: MAP_SHARED areas are restored as MAP_PRIVATE, check for correctness.
 */
extern "C" void *mmap(void *addr, size_t length, int prot, int flags,
                      int fd, off_t offset)
{
  SET_IN_MMAP_WRAPPER();
  MMAP_WRAPPER_HEADER(mmap, addr, length, prot, flags, fd, offset);
  if (SYNC_IS_REPLAY) {
    bool mmap_read_from_readlog = false;
    MMAP_WRAPPER_REPLAY_START(mmap);
    //JWARNING ( addr == NULL ).Text("Unimplemented to have non-null addr.");
    addr = GET_COMMON(my_entry, retval);
    if (retval != MAP_FAILED && fd != -1 &&
        ((flags & MAP_PRIVATE) != 0 || (flags & MAP_SHARED) != 0)) {
      flags &= ~MAP_SHARED;
      flags |= MAP_PRIVATE;
      flags |= MAP_ANONYMOUS;
      fd = -1;
      offset = 0;
      size_t page_size = sysconf(_SC_PAGESIZE);
      size_t page_mask = ~(page_size - 1);
      length = (length + page_size - 1) & page_mask ;
      mmap_read_from_readlog = true;
    }
    flags |= MAP_FIXED;
    retval = _real_mmap (addr, length, prot | PROT_WRITE, flags, fd, offset);
    if (retval != GET_COMMON(my_entry, retval)) sleep(20);
    JASSERT ( retval == GET_COMMON(my_entry, retval) ) (retval)
      (GET_COMMON(my_entry, retval)) (JASSERT_ERRNO);
    if (mmap_read_from_readlog) {
      WRAPPER_REPLAY_READ_FROM_READ_LOG(mmap, retval, length);
    }
    MMAP_WRAPPER_REPLAY_END(mmap);
  } else if (SYNC_IS_RECORD) {
    _real_pthread_mutex_lock(&mmap_lock);
    retval = _real_mmap (addr, length, prot, flags, fd, offset);
    if (retval != MAP_FAILED && fd != -1 &&
        ((flags & MAP_PRIVATE) != 0 || (flags & MAP_SHARED) != 0)) {
      WRAPPER_LOG_WRITE_INTO_READ_LOG(mmap, retval, length);
    }
    WRAPPER_LOG_WRITE_ENTRY(my_entry);
    _real_pthread_mutex_unlock(&mmap_lock);
  }
  UNSET_IN_MMAP_WRAPPER();
  return retval;
}
Beispiel #21
0
extern "C" FILE *fdopen(int fd, const char *mode)
{
  WRAPPER_HEADER(FILE*, fdopen, _real_fdopen, fd, mode);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START_TYPED(FILE*, fdopen);
    if (retval != NULL) {
      *retval = GET_FIELD(my_entry, fdopen, fdopen_retval);
    }
    WRAPPER_REPLAY_END(fdopen);
  } else if (SYNC_IS_RECORD) {
    dmtcp::ThreadInfo::setOptionalEvent();
    retval = _real_fdopen(fd, mode);
    dmtcp::ThreadInfo::unsetOptionalEvent();
    if (retval != NULL) {
      SET_FIELD2(my_entry, fdopen, fdopen_retval, *retval);
    }
    WRAPPER_LOG_WRITE_ENTRY(fdopen);
  }
  return retval;
}
Beispiel #22
0
extern "C" void *mremap(void *old_address, size_t old_size,
    size_t new_size, int flags)
{

  MALLOC_FAMILY_WRAPPER_HEADER(mremap, old_address, old_size, new_size, flags,
			       NULL);
  if (SYNC_IS_REPLAY) {
    MALLOC_FAMILY_WRAPPER_REPLAY_START(mremap);
    void *addr = GET_COMMON(my_entry, retval);
    flags |= MREMAP_MAYMOVE;
    retval = _real_mremap (old_address, old_size, new_size, flags, addr);
    JASSERT ( retval == GET_COMMON(my_entry, retval) );
    MALLOC_FAMILY_WRAPPER_REPLAY_END(mremap);
  } else if (SYNC_IS_RECORD) {
    _real_pthread_mutex_lock(&mmap_lock);
    retval = _real_mremap (old_address, old_size, new_size, flags, 0);
    WRAPPER_LOG_WRITE_ENTRY(my_entry);
    _real_pthread_mutex_unlock(&mmap_lock);
  }
  return retval;
}
Beispiel #23
0
extern "C" int pthread_cond_timedwait(pthread_cond_t *cond,
    pthread_mutex_t *mutex, const struct timespec *abstime)
{
  /* See the comments in pthread_cond_wait() for the explanation of
   * the call to FAKE_BASIC_SYNC_WRAPPER()
   */
  FAKE_BASIC_SYNC_WRAPPER(int, pthread_mutex_unlock, mutex);

  WRAPPER_HEADER(int, pthread_cond_timedwait, _real_pthread_cond_timedwait,
                 cond, mutex, abstime);

  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY(pthread_cond_timedwait);
  } else if (SYNC_IS_RECORD) {
    dmtcp::ThreadInfo::setOptionalEvent();
    retval = _real_pthread_cond_timedwait(cond, mutex, abstime);
    dmtcp::ThreadInfo::unsetOptionalEvent();
    WRAPPER_LOG_WRITE_ENTRY(pthread_cond_timedwait);
  }
  return retval;
}
Beispiel #24
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;
}
Beispiel #25
0
extern "C" struct tm *localtime_r(const time_t *timep, struct tm *result)
{
  WRAPPER_HEADER(struct tm *, localtime_r, _real_localtime_r, timep, result);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START_TYPED(struct tm *, localtime_r);
    if (retval != NULL) {
      *retval = GET_FIELD(my_entry, localtime_r, ret_result);
      if (result != NULL) {
        *result = GET_FIELD(my_entry, localtime_r, ret_result);
      }
    }
    WRAPPER_REPLAY_END(localtime_r);
  } else if (SYNC_IS_RECORD) {
    dmtcp::ThreadInfo::setOptionalEvent();
    retval = _real_localtime_r(timep, result);
    dmtcp::ThreadInfo::unsetOptionalEvent();
    if (retval != NULL) {
      SET_FIELD2(my_entry, localtime_r, ret_result, *retval);
    }
    WRAPPER_LOG_WRITE_ENTRY(localtime_r);
  }
  return retval;
}
Beispiel #26
0
extern "C" int gettimeofday(struct timeval *tv, struct timezone *tz)
{
  WRAPPER_HEADER(int, gettimeofday, _real_gettimeofday, tv, tz);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(gettimeofday);
    if (retval == 0 && tv != NULL) {
      *tv = GET_FIELD(my_entry, gettimeofday, ret_tv);
    }
    if (retval == 0 && tz != NULL) {
      *tz = GET_FIELD(my_entry, gettimeofday, ret_tz);
    }
    WRAPPER_REPLAY_END(gettimeofday);
  } else if (SYNC_IS_RECORD) {
    retval = _real_gettimeofday(tv, tz);
    if (retval == 0 && tv != NULL) {
      SET_FIELD2(my_entry, gettimeofday, ret_tv, *tv);
    }
    if (retval == 0 && tz != NULL) {
      SET_FIELD2(my_entry, gettimeofday, ret_tz, *tz);
    }
    WRAPPER_LOG_WRITE_ENTRY(gettimeofday);
  }
  return retval;
}
Beispiel #27
0
extern "C" int getpeername(int sockfd, struct sockaddr *addr,
                           socklen_t *addrlen)
{
  WRAPPER_EXECUTION_DISABLE_CKPT();
  WRAPPER_HEADER_CKPT_DISABLED(int, getpeername, _real_getpeername,
                               sockfd, addr, addrlen);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(getpeername);
    if (retval != -1) {
      *addr = GET_FIELD(my_entry, getpeername, ret_addr);
      *addrlen = GET_FIELD(my_entry, getpeername, ret_addrlen);
    }
    WRAPPER_REPLAY_END(getpeername);
  } else if (SYNC_IS_RECORD) {
    retval = _real_getpeername(sockfd, addr, addrlen);
    if (retval != -1) {
      SET_FIELD2(my_entry, getpeername, ret_addr, *addr);
      SET_FIELD2(my_entry, getpeername, ret_addrlen, *addrlen);
    }
    WRAPPER_LOG_WRITE_ENTRY(my_entry);
  }
  WRAPPER_EXECUTION_ENABLE_CKPT();
  return retval;
}
Beispiel #28
0
extern "C" int getaddrinfo(const char *node, const char *service,
                           const struct addrinfo *hints, struct addrinfo **res)
{
  struct addrinfo_extended addrinfo_res[ADDRINFO_MAX_RES];
  struct addrinfo *rp;
  int numResults = 0;

  WRAPPER_HEADER(int, getaddrinfo, _real_getaddrinfo, node, service, hints,
                 res);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(getaddrinfo);
    if (retval == 0) {
      *res = GET_FIELD(my_entry, getaddrinfo, ret_res);
      numResults = GET_FIELD(my_entry, getaddrinfo, num_res);

      WRAPPER_REPLAY_READ_FROM_READ_LOG(getaddrinfo, (void*) addrinfo_res,
                                        (numResults *
                                         sizeof (struct addrinfo_extended)));
      for (int i = 0; i < numResults; i++) {
        struct addrinfo_extended *ext_info = &addrinfo_res[i];
        struct addrinfo *_addrinfo = &(addrinfo_res[i]._addrinfo);
        struct sockaddr *_sockaddr = &(addrinfo_res[i]._sockaddr);
        memcpy(ext_info->_addrinfo_p, _addrinfo, sizeof(struct addrinfo));
        memcpy(_addrinfo->ai_addr, _sockaddr, _addrinfo->ai_addrlen);
        if (_addrinfo->ai_canonname != NULL) {
          strncpy(_addrinfo->ai_canonname, ext_info->canonname,
                  sizeof(ext_info->canonname));
        }
      }
    }
    WRAPPER_REPLAY_END(getaddrinfo);
  } else if (SYNC_IS_RECORD) {
    isOptionalEvent = true;
    retval = _real_getaddrinfo(node, service, hints, res);
    isOptionalEvent = false;

    if (retval == 0) {
      SET_FIELD2(my_entry, getaddrinfo, ret_res, *res);
      for (rp = *res; rp != NULL; rp = rp->ai_next) {
        JASSERT(numResults < ADDRINFO_MAX_RES);
        struct addrinfo_extended *ext_info = &addrinfo_res[numResults];
        struct addrinfo *_addrinfo = &(addrinfo_res[numResults]._addrinfo);
        struct sockaddr *_sockaddr = &(addrinfo_res[numResults]._sockaddr);
        ext_info->_addrinfo_p = rp;
        memcpy(_addrinfo, rp, sizeof (struct addrinfo));
        memcpy(_sockaddr, rp->ai_addr, rp->ai_addrlen);
        if (rp->ai_canonname != NULL) {
          strncpy(ext_info->canonname, rp->ai_canonname,
                  sizeof(ext_info->canonname));
        }
        numResults++;
      }
      WRAPPER_LOG_WRITE_INTO_READ_LOG(getaddrinfo, (void*) addrinfo_res,
                                      (numResults *
                                       sizeof (struct addrinfo_extended)));
    }
    SET_FIELD2(my_entry, getaddrinfo, num_res, numResults);

    WRAPPER_LOG_WRITE_ENTRY(my_entry);
  }
  return retval;
}