lwp_t* tkn_curlwp(void) { ID tskid = tk_get_tid(); lwp_t* re = get_lwp(tskid); return re; }
/* * This function is called by so_break(). * * The following pre-condition is always satisfied. * tskid != TSK_ALL */ static int do_sys_break_task(ID tskid) { int cnt = 0; if( get_lwp(tskid)->is_waiting != 0 ) { tk_dis_wai(tskid, TTW_FLG | TTW_CAL | TTW_RDV ); cnt = 1; } return cnt; }
rawTime64 pd_thread::getRawCpuTime_hw() { #ifdef USES_PMAPI // Hardware method, using the PMAPI int ret; static bool need_init = true; if(need_init) { pm_info_t pinfo; #ifdef PMAPI_GROUPS pm_groups_info_t pginfo; ret = pm_init(PM_VERIFIED | PM_CAVEAT | PM_GET_GROUPS, &pinfo, &pginfo); #else ret = pm_init(PM_VERIFIED | PM_CAVEAT, &pinfo); #endif // We ignore the return, but pm_init must be called to initialize the // library if (ret) pm_error("PARADYNos_init: pm_init", ret); need_init = false; } int lwp_to_use; tid_t indexPtr = 0; struct thrdsinfo thrd_buf; if (get_lwp() > 0) lwp_to_use = get_lwp(); else { /* If we need to get the data for the entire process (ie. get_lwp() == 0) then we need to the pm_get_data_group function requires any lwp in the group, so we'll grab the lwp of any active thread in the process */ if(getthrds(pd_proc->getPid(), &thrd_buf, sizeof(struct thrdsinfo), &indexPtr, 1) == 0) { // perhaps the process ended return -1; } lwp_to_use = thrd_buf.ti_tid; } // PM counters are only valid when the process is paused. bool needToCont = !(pd_proc->isStopped()); if(needToCont) { // process running if (!pd_proc->pauseProc()) { return -1; // pause failed, so returning failure } } pm_data_t data; if(get_lwp() > 0) ret = pm_get_data_thread(pd_proc->getPid(), lwp_to_use, &data); else { // lwp == 0, means get data for the entire process (ie. all lwps) ret = pm_get_data_group(pd_proc->getPid(), lwp_to_use, &data); while(ret) { // if failed, could have been because the lwp (retrieved via // getthrds) was in process of being deleted. //cerr << " prev lwp_to_use " << lwp_to_use << " failed\n"; if(getthrds(pd_proc->getPid(), &thrd_buf, sizeof(struct thrdsinfo), &indexPtr, 1) == 0) { // couldn't get a valid lwp, go to standard error handling ret = 1; break; } lwp_to_use = thrd_buf.ti_tid; //cerr << " next lwp_to_use is " << lwp_to_use << "\n"; ret = pm_get_data_group(pd_proc->getPid(), lwp_to_use, &data); } } if (ret) { if(!pd_proc->hasExited()) { pm_error("dyn_lwp::getRawCpuTime_hw: pm_get_data_thread", ret); fprintf(stderr, "Attempted pm_get_data(%d, %d, %d)\n", pd_proc->getPid(), get_lwp(), lwp_to_use); } return -1; } rawTime64 result = data.accu[get_hwctr_binding(PM_CYC_EVENT)]; // Continue the process if(needToCont) { pd_proc->continueProc(); } //if(pos_junk != 101) // ct_record(pos_junk, result, hw_previous_, get_lwp(), lwp_to_use); if(result < hw_previous_) { cerr << "rollback in dyn_lwp::getRawCpuTime_hw, lwp_to_use: " << lwp_to_use << ", lwp: " << get_lwp() << ", result: " << result << ", previous result: " << hw_previous_ << "\n"; result = hw_previous_; } else hw_previous_ = result; return result; #else return 0; #endif }
irpcLaunchState_t rpcLWP::runPendingIRPC() { // CHECK FOR SYSTEM CALL STATUS assert(pendingRPC_); // We passed the system call check, so the lwp is in a state // where it is possible to run iRPCs. struct dyn_saved_regs *theSavedRegs = NULL; // Some platforms save daemon-side, some save process-side (on the stack) // Should unify this. theSavedRegs = new dyn_saved_regs; Frame frame = lwp_->getActiveFrame(); inferiorrpc_printf("%s[%d]: original PC at start of iRPC is 0x%lx\n", FILE__, __LINE__, frame.getPC()); bool saveFP = pendingRPC_->rpc->saveFPState; bool status = lwp_->getRegisters(theSavedRegs, saveFP); if(status != true) { // Can happen if we're in a syscall, which is caught above return irpcError; } // RPC is actually going to be running runningRPC_ = pendingRPC_; pendingRPC_ = NULL; mgr_->addRunningRPC(runningRPC_); // Build the in progress struct runningRPC_->savedRegs = theSavedRegs; runningRPC_->rpcthr = NULL; runningRPC_->rpclwp = this; runningRPC_->rpcStartAddr = mgr_->createRPCImage(runningRPC_->rpc->action, // AST tree runningRPC_->rpc->noCost, (runningRPC_->rpc->callbackFunc != NULL), // Callback? runningRPC_->rpcCompletionAddr, // Fills in runningRPC_->rpcResultAddr, runningRPC_->rpcContPostResultAddr, runningRPC_->resultRegister, runningRPC_->rpc->lowmem, NULL, lwp_); // Where to allocate if (!runningRPC_->rpcStartAddr) { cerr << "launchRPC failed, couldn't create image" << endl; return irpcError; } /* Why we don't just pass runningRPC_ into createRPCImage()... */ mgr_->proc()->addCodeRange( runningRPC_ ); #if !defined(i386_unknown_nt4_0) \ && !defined(mips_unknown_ce2_11) // Actually, only need this if a restoreRegisters won't reset // the PC back to the original value Frame curFrame = lwp_->getActiveFrame(); runningRPC_->origPC = curFrame.getPC(); #endif // Launch this sucker. Change the PC, and the caller will set running #if ! defined( ia64_unknown_linux2_4 ) if (!lwp_->changePC(runningRPC_->rpcStartAddr, NULL)) { #else /* Syscalls can actually rewind the PC by 0x10, so we need a bundle _before_ the new PC to check for this. */ if (!lwp_->changePC(runningRPC_->rpcStartAddr + 0x10, NULL)) { #endif cerr << "launchRPC failed: couldn't set PC" << endl; return irpcError; } #if defined(i386_unknown_linux2_0) \ || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ // handle system call interruption: // if we interupted a system call, this clears the state that // would cause the OS to restart the call when we run the rpc. // if we did not, this is a no-op. // after the rpc, an interrupted system call will // be restarted when we restore the original // registers (restore undoes clearOPC) // note that executingSystemCall is always false on this platform. if (!lwp_->clearOPC()) { cerr << "launchRPC failed because clearOPC() failed" << endl; return irpcError; } #endif if (mgr_->proc()->IndependentLwpControl()) { signal_printf("%s[%d]: Continuing lwp %d\n", FILE__, __LINE__, lwp_->get_lwp_id()); lwp_->continueLWP(); } return irpcStarted; } bool rpcLWP::deleteLWPIRPC(unsigned id) { // Can remove a queued or pending lwp IRPC bool removed = false; if (pendingRPC_ && pendingRPC_->rpc->id == id) { // we don't want to do as we normally do when a exit trap occurs, // that is to run the rpc, which gets triggered by this callback get_lwp()->clearSyscallExitTrap(); delete pendingRPC_->rpc; delete pendingRPC_; pendingRPC_ = NULL; // Should probably also remove a system call trap // if one exists return true; } pdvector<inferiorRPCtoDo *> newPostedRPCs; for (unsigned i = 0; i < postedRPCs_.size(); i++) { if (postedRPCs_[i]->id == id) { removed = true; } else { newPostedRPCs.push_back(postedRPCs_[i]); } } postedRPCs_ = newPostedRPCs; return removed; }