linux-lts-quantal-3.5.0/kernel/replay.c
/* Called on enter of do_exit() in kernel/exit.c 
 *
 * recplay_exit_start is called on enter of do_exit in kernel/exit.c
 * It records the global vector clock value and frees the record log.
 * 
 * No locks are held on entry or exit.
 * */
Called on enter of do_exit() in kernel/exit.c
recplay_exit_start is called on enter of do_exit in kernel/exit.c
It records the global vector clock value and frees the record log.

No locks are held on entry or exit.
Called on enter of do_exit () in kernel / exit . c recplay_exit_start is called on enter of do_exit in kernel / exit . c It records the global vector clock value and frees the record log . No locks are held on entry or exit .
void 
recplay_exit_start(void)
{
	struct record_thread* prt = current->record_thrd;
	if (prt) {
		MPRINT ("Record thread %d starting to exit\n", current->pid);
#ifndef USE_DEBUG_LOG
		flush_user_log (prt);
#endif
		write_user_log (prt); 
#ifdef USE_EXTRA_DEBUG_LOG
		write_user_extra_log (prt);
#endif
		MPRINT ("Pid %d -- Deallocate the user log", current->pid);
		deallocate_user_log (prt); 
	} else if (current->replay_thrd) {
		MPRINT ("Replay thread %d starting to exit, recpid %d\n", current->pid, current->replay_thrd->rp_record_thread->rp_record_pid);
		if (is_pin_attached() && current->replay_thrd->rp_pin_restart_syscall) {
			MPRINT ("Pid %d, since this was a restart syscall, need to wait for exit, %d\n", current->pid, current->replay_thrd->rp_pin_restart_syscall);
			BUG_ON (!current->replay_thrd->rp_saved_psr);
			if (current->replay_thrd->rp_pin_restart_syscall == REPLAY_PIN_TRAP_STATUS_ENTER) {
				u_long wait_clock;
				struct replay_thread* prept = current->replay_thrd;
				BUG_ON(!prept->rp_saved_psr);
				BUG_ON(!prept->rp_start_clock_save);
				MPRINT ("Pid %d -- need to consume start clock first", current->pid);
				wait_clock = prept->rp_start_clock_save;
				MPRINT ("Pid %d, recplay start, wait for clock value %lu from saved syscall entry\n", current->pid, wait_clock);
				get_next_clock(prept, prept->rp_group, wait_clock);
				prept->rp_pin_restart_syscall = REPLAY_PIN_TRAP_STATUS_EXIT;
			}
			MPRINT ("Pid %d, recplay start, wait for clock value %lu from saved syscall exit\n", current->pid, current->replay_thrd->rp_stop_clock_save);
			get_next_clock(current->replay_thrd, current->replay_thrd->rp_group, current->replay_thrd->rp_stop_clock_save);
			current->replay_thrd->rp_pin_restart_syscall = REPLAY_PIN_TRAP_STATUS_NONE;
			MPRINT ("Pid %d - thread exiting because of Pin\n", current->pid);
			current->replay_thrd->rp_replay_exit = 1;
		}
	}
}
void recplay_exit_start ( void ) { struct record_thread * prt = current -> record_thrd ; if ( prt ) { MPRINT ( " \n " , current -> pid ) ; #ifndef USE_DEBUG_LOG flush_user_log ( prt ) ; #endif write_user_log ( prt ) ; #ifdef USE_EXTRA_DEBUG_LOG write_user_extra_log ( prt ) ; #endif MPRINT ( " " , current -> pid ) ; deallocate_user_log ( prt ) ; } else if ( current -> replay_thrd ) { MPRINT ( " \n " , current -> pid , current -> replay_thrd -> rp_record_thread -> rp_record_pid ) ; if ( is_pin_attached ( ) && current -> replay_thrd -> rp_pin_restart_syscall ) { MPRINT ( " \n " , current -> pid , current -> replay_thrd -> rp_pin_restart_syscall ) ; BUG_ON ( ! current -> replay_thrd -> rp_saved_psr ) ; if ( current -> replay_thrd -> rp_pin_restart_syscall == REPLAY_PIN_TRAP_STATUS_ENTER ) { u_long wait_clock ; struct replay_thread * prept = current -> replay_thrd ; BUG_ON ( ! prept -> rp_saved_psr ) ; BUG_ON ( ! prept -> rp_start_clock_save ) ; MPRINT ( " " , current -> pid ) ; wait_clock = prept -> rp_start_clock_save ; MPRINT ( " \n " , current -> pid , wait_clock ) ; get_next_clock ( prept , prept -> rp_group , wait_clock ) ; prept -> rp_pin_restart_syscall = REPLAY_PIN_TRAP_STATUS_EXIT ; } MPRINT ( " \n " , current -> pid , current -> replay_thrd -> rp_stop_clock_save ) ; get_next_clock ( current -> replay_thrd , current -> replay_thrd -> rp_group , current -> replay_thrd -> rp_stop_clock_save ) ; current -> replay_thrd -> rp_pin_restart_syscall = REPLAY_PIN_TRAP_STATUS_NONE ; MPRINT ( " \n " , current -> pid ) ; current -> replay_thrd -> rp_replay_exit = 1 ; } } }
Called on enter of do_exit() in kernel/exit.c
 recplay_exit_start is called on enter of do_exit in kernel/exit.c
 It records the global vector clock value and frees the record log.
Called on enter of do_exit () in kernel / exit . c recplay_exit_start is called on enter of do_exit in kernel / exit . c It records the global vector clock value and frees the record log .
// Write this out before we destroy the mm // For multi-threaded programs, we need to reuse the memory // When exiting threads with Pin attached, we need to make sure we exit the threads // in the correct order, while making sure Pin doesn't deadlock // since Pin is forcing an exit, we need to consume the last clock value in // this thread // So we don't have abnormal termination, since Pin told us to exit