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); } }
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; }
extern "C" int pthread_join (pthread_t thread, void **value_ptr) { /* Reap Existing Threads */ //dmtcp::ThreadInfo::reapThreads(); /* We change things up a bit here. Since we don't allow the user's pthread_join() to have an effect, we don't call the mtcp "delete_thread_on_pthread_join()" function here unless we decide not to synchronize this call to pthread_join(). We DO need to call it from the thread reaper reapThread(), however, which is in pthreadwrappers.cpp. */ //if (!dmtcp::ThreadInfo::isUserJoinable(thread)) { //return EINVAL; //} void *return_addr = GET_RETURN_ADDRESS(); if (!shouldSynchronize(return_addr)) { int retval = _real_pthread_join(thread, value_ptr); if (retval == 0) { dmtcp::ThreadInfo::reapThread(thread); } return retval; } int retval = 0; log_entry_t my_entry = create_pthread_join_entry(my_clone_id, pthread_join_event, thread, value_ptr); if (SYNC_IS_REPLAY) { WRAPPER_REPLAY_START(pthread_join); int saved_retval = (long) RETVAL(my_entry, pthread_join); WRAPPER_REPLAY_END(pthread_join); retval = _real_pthread_join(thread, value_ptr); JASSERT(retval == saved_retval); if (value_ptr != NULL) { JASSERT(*value_ptr == GET_FIELD(my_entry, pthread_join, ret_value_ptr)); } } else if (SYNC_IS_RECORD) { WRAPPER_LOG_RESERVE_SLOT(pthread_join); retval = _real_pthread_join(thread, value_ptr); if (value_ptr != NULL) { SET_FIELD2(my_entry, pthread_join, ret_value_ptr, *value_ptr); } WRAPPER_LOG_UPDATE_ENTRY(pthread_join); } return retval; }