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); } }
void userSynchronizedEventBegin() { log_entry_t my_entry = create_user_entry(my_clone_id, user_event); if (SYNC_IS_REPLAY) { waitForTurn(&my_entry, user_turn_check); getNextLogEntry(); } else if (SYNC_IS_RECORD) { addNextLogEntry(my_entry); } }
extern "C" void pthread_exit(void *value_ptr) { WRAPPER_HEADER_NO_RETURN(pthread_exit, _real_pthread_exit, value_ptr); if (SYNC_IS_REPLAY) { waitForTurn(&my_entry, &pthread_exit_turn_check); getNextLogEntry(); _real_pthread_exit(value_ptr); } else if (SYNC_IS_RECORD) { // Not restart; we should be logging. addNextLogEntry(my_entry); _real_pthread_exit(value_ptr); } while(1); // to suppress compiler warning about 'noreturn' function returning }
extern "C" int pthread_kill(pthread_t thread, int sig) { WRAPPER_HEADER(int, pthread_kill, _real_pthread_kill, thread, sig); if (__builtin_expect(signal_thread_alive == 0, 0)) { // Start the thread who will send signals (only on replay, but we need to // start it here so record has same behavior). signal_thread_alive = 1; createSignalThread(); } if (SYNC_IS_REPLAY) { waitForTurn(&my_entry, &pthread_kill_turn_check); getNextLogEntry(); // TODO: Do something better than always returning success. retval = 0;//_real_pthread_kill(thread, sig); } else if (SYNC_IS_RECORD) { // Not restart; we should be logging. addNextLogEntry(my_entry); retval = _real_pthread_kill(thread, sig); } return retval; }