Ejemplo n.º 1
0
lwp_t*
tkn_curlwp(void)
{
	ID tskid = tk_get_tid();

	lwp_t* re = get_lwp(tskid);

	return re;
}
Ejemplo n.º 2
0
/*
 * 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;
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
0
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;
}