int ExecutionTracker::SimulateCondTimedwait(thrID myself, void * ret_addr, pthread_cond_t * cond, pthread_mutex_t * lock, const struct timespec * time) { glock(); log->SimulateCondTimedwait(myself); checkCondValidity(cond); //unlock bool proceed = BeforeMutexUnlock(myself, ret_addr, lock, IS_COND_WAIT); safe_assert(proceed); safe_assert(Originals::pthread_mutex_unlock(lock) == OPERATION_SUCCESSFUL); AfterMutexUnlock(myself, ret_addr, OPERATION_SUCCESSFUL,lock,IS_COND_WAIT); cond_map[myself] = cond; handleSimulateCondTimedwait(myself, ret_addr, cond, lock); SchedPointInfo tmp(ret_addr, "Simulate Timed Wait (s)", myself, enable_map, IS_YIELD, cond, lock); schedule(&tmp); gunlock(); waitPauseThread(myself); glock(); cond_map[myself] = NULL; gunlock(); //lock proceed = BeforeMutexLock(myself, ret_addr, lock, IS_COND_WAIT); safe_assert(proceed == false); signalThreadReady(myself); glock(); bool was_signalled = was_signalled_map[myself]; if (! was_signalled) { SchedPointInfo tmp(ret_addr, "Simulate Timed Wait (e)", myself, enable_map, IS_NOT_YIELD, cond, lock); schedule(&tmp); was_signalled_map[myself] = true; } gunlock(); pauseThread(myself); SimulateMutexLock(myself, ret_addr, lock, IS_COND_WAIT); if (was_signalled) { log->timedwaitNoTimeout(myself); glock(); gunlock(); return OPERATION_SUCCESSFUL; } else { log->timedwaitTimeout(myself); glock(); gunlock(); return ETIMEDOUT; } }
void ExecutionTracker::myMemoryWrite(thrID myself, void * ret_addr, void * addr) { glock(); log->myMemoryWrite(myself, addr); handleMyMemoryWrite(myself, ret_addr, addr); SchedPointInfo tmp(ret_addr, "Memory Write", myself, enable_map, IS_NOT_YIELD, addr); schedule(&tmp); gunlock(); pauseThread(myself); glock(); gunlock(); }
bool ExecutionTracker::BeforeBarrierWait(thrID myself, void * ret_addr, pthread_barrier_t * barrier) { glock(); log->BeforeBarrierWait(myself); checkBarrierValidity(barrier); int target_count = bt->getBarrierCount(barrier); int threads_on_barrier = bt->getNumberThreadsWaitingOnBarrier(barrier); if (threads_on_barrier + 1 >= target_count) { vector<thrID> my_thr = bt->getThreadsWaitingOnBarrier(barrier); safe_assert(((unsigned) (my_thr.size() + 1)) == (bt->getBarrierCount(barrier))); vector<thrID>::iterator itr; for (itr = my_thr.begin(); itr != my_thr.end(); itr++) { safe_assert(isDisabled((*itr))); enableThread((*itr)); } enableThread(myself); bt->clearThreadsWaitingOnBarrier(barrier); } else { bt->threadWaitingOnBarrier(myself, barrier); disableThread(myself); } SchedPointInfo tmp(ret_addr, "Before Barrier Wait", myself, enable_map, IS_NOT_YIELD, barrier); schedule(&tmp); gunlock(); pauseThread(myself); return false; }
void ExecutionTracker::AfterMutexUnlock(thrID myself, void * ret_addr, int ret_val, pthread_mutex_t * lock, bool isWait) { if (!isWait) { glock(); } /* Lock and unlocks get called when a thread is finishing up */ if (threadIsFinished(myself)) { if (!isWait) { gunlock(); } return; } log->AfterMutexUnlock(myself, isWait); threadHasReleasedLock(myself, lock); handleAfterMutexUnlock(myself, ret_addr, lock, isWait); if (! isWait) { SchedPointInfo tmp(ret_addr, "After Mutex Unlock", myself, enable_map, IS_NOT_YIELD, lock); schedule(&tmp); gunlock(); pauseThread(myself); } }
bool ExecutionTracker::BeforeCondBroadcast(thrID myself, void * ret_addr, pthread_cond_t * cond) { glock(); checkCondValidity(cond); gunlock(); return false; }
bool ExecutionTracker::BeforeMutexLock(thrID myself, void * ret_addr, pthread_mutex_t * lock, bool isWait) { if (! isWait) { glock(); } /* Lock and unlocks get called when a thread is finishing up */ if (threadIsFinished(myself)) { if (! isWait) { gunlock(); } return true; } log->BeforeMutexLock(myself, ret_addr, lock, isWait); determineLockStatus(myself, lock); handleBeforeMutexLock(myself, ret_addr, lock, isWait); if (! isWait) { SchedPointInfo tmp(ret_addr, "Before Mutex Lock", myself, enable_map, IS_NOT_YIELD, lock); schedule(&tmp); gunlock(); pauseThread(myself); } return false; }
widget *new_toplevel_window(gui *_gui, int width, int height, char *title) { struct gui *g = _gui; struct toplevel_window_widget *w; glock(g); w = new_widget(g, TOPLEVEL_WINDOW, sizeof(struct toplevel_window_widget)); w->common.width = width; w->common.height = height; w->x = x_create_window(g->x, width, height, title); w->common.repack = repack; w->common.add_child = add_child; w->common.allocate = allocate; w->common.paint = paint; w->common.button = button; gunlock(g); return w; }
void DjVuDebug::set_debug_file(FILE * file) { GCriticalSectionLock glock(&debug_lock); if (debug_file && (debug_file != stderr)) fclose(debug_file); debug_file = file; }
void ExecutionTracker::SimulateExit(thrID myself, void * ret_addr, void * arg) { glock(); log->SimulateExit(myself); finalizeThread(myself, ret_addr); gunlock(); Originals::pthread_exit(arg); }
int ExecutionTracker::SimulateCondDestroy(thrID myself, void * ret_addr, pthread_cond_t * cond) { glock(); cond_destroy.push_back(cond); int ret_val = Originals::pthread_cond_destroy(cond); gunlock(); return ret_val; }
int ExecutionTracker::SimulateMutexDestroy(thrID myself, void * addr, pthread_mutex_t * lock) { glock(); mutex_destroy.push_back(lock); int ret_val = Originals::pthread_mutex_destroy(lock); gunlock(); return ret_val; }
void ExecutionTracker::ThreadFinish(thrID myself, void * (*start_routine) (void *), void * arg) { glock(); log->ThreadFinish(myself, arg); finalizeThread(myself, reinterpret_cast<void *>(start_routine)); lock_count--; Originals::pthread_mutex_unlock(global_lock); }
void ExecutionTracker::ThreadStart(thrID myself, void * (*start_routine) (void *), void * arg) { glock(); log->ThreadStart(myself, arg); handleThreadStart(myself, start_routine); gunlock(); pauseThread(myself); }
int ExecutionTracker::SimulateSemDestroy(thrID myself, void * ret_addr, sem_t * sem) { glock(); sem_destroy.push_back(sem); int ret_val = Originals::sem_destroy(sem); gunlock(); return ret_val; }
int ExecutionTracker::SimulateBarrierDestroy(thrID myself, void * ret_addr, pthread_barrier_t * barrier) { glock(); barrier_destroy.push_back(barrier); int ret_val = Originals::pthread_barrier_destroy(barrier); gunlock(); return ret_val; }
void ExecutionTracker::thrilleCheckpoint(thrID myself, void * ret_addr) { glock(); printf("Thrille: CHECKPOINT CALLED!\n"); SchedPointInfo tmp(ret_addr, "Thrille Checkpoint", myself, enable_map, IS_NOT_YIELD); schedule(&tmp); gunlock(); pauseThread(myself); return; }
bool ExecutionTracker::BeforeCondWait(thrID myself, void * ret_addr, pthread_cond_t * cond, pthread_mutex_t * lock) { glock(); log->BeforeCondWait(myself); disableThread(myself); gunlock(); return false; }
void ExecutionTracker::thrilleSchedPoint(thrID myself, void * ret_addr) { glock(); log->BeforeSchedPoint(myself); safe_assert(isEnabled(myself)); SchedPointInfo tmp(ret_addr, "Before Generic Schedule Point", myself, enable_map, IS_NOT_YIELD); schedule(&tmp); gunlock(); pauseThread(myself); }
void ExecutionTracker::scheduleThreadWaitingOnCond(thrID target, SignalPointInfo * s) { glock(); safe_assert(s->cond_map[target] == s->cond); log->signalScheduling(target, s); wait_ready_map[target] = false; waitWakeThread(target); gunlock(); waitThreadReady(s->thread, target); }
int ExecutionTracker::SimulateSemWait(thrID myself, void * ret_addr, sem_t * sem) { glock(); safe_assert(checkSemaphoreValue(sem) > 0); log->SimulateSemWait(myself); checkSemValidity(sem); int result = Originals::sem_wait(sem); threadHasPassedSemaphore(myself, sem); gunlock(); return result; }
int ExecutionTracker::SimulateMutexTrylock(thrID myself, void * ret_addr, pthread_mutex_t * lock) { glock(); log->SimulateMutexTrylock(myself); int result = Originals::pthread_mutex_trylock(lock); if (result == OPERATION_SUCCESSFUL) { threadHasAcquiredLock(myself, lock); } gunlock(); return result; }
/* TODO: implement this */ bool ExecutionTracker::BeforeSigwait(thrID myself, void * ret_addr, const sigset_t * set, int * sig) { glock(); disableThread(myself); SchedPointInfo tmp(ret_addr, "Before Sig Wait", myself, enable_map, false); schedule(&tmp); gunlock(); bool sigwait_is_implemented = false; safe_assert(sigwait_is_implemented); return false; }
bool ExecutionTracker::BeforeCondTimedwait(thrID myself, void * ret_addr, pthread_cond_t * cond, pthread_mutex_t * lock, const struct timespec * time) { glock(); log->BeforeCondTimedwait(myself); enableThread(myself); gunlock(); return false; }
bool ExecutionTracker::BeforeBarrierInit(thrID myself, void * ret_addr, pthread_barrier_t * barrier, const pthread_barrierattr_t * battr, unsigned count) { glock(); log->BeforeBarrierInit(myself); bt->initBarrier(barrier, count); barrierIsValid(barrier); gunlock(); return true; }
void ExecutionTracker::pauseThread(thrID target) { glock(); sem_t * pause = sem_map[target]; safe_assert(pause != NULL); log->pauseThread(target); gunlock(); int result; do { result = Originals::sem_wait(pause); } while (result == -1 && errno == EINTR); safe_assert(result == OPERATION_SUCCESSFUL); }
unsigned int ExecutionTracker::SimulateSleep(thrID myself, void * ret_addr, unsigned int time) { glock(); log->mySleep(myself); handleMySleep(myself, ret_addr); SchedPointInfo tmp(ret_addr, "Simulate Sleep", myself, enable_map, IS_YIELD); schedule(&tmp); gunlock(); pauseThread(myself); return OPERATION_SUCCESSFUL; }
void ExecutionTracker::waitPauseThread(thrID target) { glock(); sem_t * pause = wait_sem_map[target]; safe_assert(pause != NULL); log->waitPauseThread(target); gunlock(); int result; do { result = Originals::sem_wait(pause); } while (result == -1 && errno == EINTR); safe_assert(result == 0); }
bool ExecutionTracker::BeforeCreate(thrID myself, thrID child, void * ret_addr, pthread_t * thread, const pthread_attr_t * thread_attr, void *(* routine)(void *), void * arg) { glock(); log->BeforeCreate(myself, child); initializeThreadData(child); gunlock(); return true; }
bool ExecutionTracker::BeforeMutexTrylock(thrID myself, void * ret_addr, pthread_mutex_t * lock) { glock(); log->BeforeMutexTrylock(myself); enableThread(myself); handleBeforeMutexLock(myself, ret_addr, lock, IS_NOT_COND_WAIT); SchedPointInfo tmp(ret_addr, "Before Mutex Try Lock", myself, enable_map, IS_NOT_YIELD, lock); schedule(&tmp); gunlock(); pauseThread(myself); return false; }
int ExecutionTracker::SimulateMutexLock(thrID myself, void * ret_addr, pthread_mutex_t * lock, bool isWait) { if (! isWait) { glock(); } log->SimulateMutexLock(myself, isWait); threadHasAcquiredLock(myself, lock); int result = Originals::pthread_mutex_trylock(lock); if (! isWait) { gunlock(); } return result; }