//! Sum inData[0:count-1] over all processors into outData.
    void
    globalVectorSum (const Datum inData[], 
		     Datum outData[], 
		     const int count) 
    {
      safeCopy (inData, outData, count);
    }
    /// \brief Exchange data between processors.
    ///
    /// Exchange sencRecvCount elements of sendData with processor
    /// destProc, receiving the result into recvData.  Assume that
    /// sendData and recvData do not alias one another.
    ///
    /// \param sendData [in] Array of value-type elements to send
    /// \param recvData [out] Array of value-type elements to
    ///   receive.  Caller is responsible for making sure that
    ///   recvData does not alias sendData.
    /// \param sendRecvCount [in] Number of elements to send and
    ///   receive in the array
    /// \param destProc [in] The "other" process' rank (to which
    ///   this process is sending data, and from which this process is
    ///   receiving data)
    /// \param tag [in] MPI tag (ignored)
    void 
    swapData (const Datum sendData[], 
	      Datum recvData[], 
	      const int sendRecvCount, 
	      const int destProc, 
	      const int tag)
    {
      if (destProc != rank())
	{
	  std::ostringstream os;
	  os << "Destination rank " << destProc << " is invalid.  The only "
	     << "valid rank for TSQR::TrivialMessenger is 0 (zero).";
	    throw std::invalid_argument (os.str());
	}
      else if (sendRecvCount < 0)
	{
	  std::ostringstream os;
	  os << "sendRecvCount = " << sendRecvCount << " is invalid: "
	     << "only nonnegative values are allowed.";
	  throw std::invalid_argument (os.str());
	}
      else if (sendRecvCount == 0)
	return; // No data to exchange
      else 
	safeCopy (sendData, recvData, sendRecvCount);
    }
Beispiel #3
0
int Scheduler::futexWakeOp(uint32_t pid, uint32_t tid, FutexInfo fi) {
    DEBUG_FUTEX("Scheduler: FUTEX WAKE OP called with pid %u tid %u", pid, tid);
    int *oldVal = 0; //  int oldval = *(int *) uaddr2;
    if(!safeCopy(fi.uaddr2, oldVal)) {
        panic("Futex Wake Op wasn't able to copy the data.");
    }
    // |op |cmp|   oparg   |  cmparg   |
    //   4   4       12          12    <== # of bits
    int op = (fi.val3 & 0xf) >> 28;      // (((op & 0xf) << 28) |
    int cmp = (fi.val3 & 0xf) >> 24;     // ((cmp & 0xf) << 24) |
    int oparg = (fi.val3 & 0xfff) >> 12; // ((oparg & 0xfff) << 12) |
    int cmparg = (fi.val3 & 0xfff);      // (cmparg & 0xfff))
    // Bit-wise ORing the following value into op causes
    // (1 << oparg) to be used as the operand: FUTEX_OP_ARG_SHIFT  8
    if(op & 8) { oparg = 1 << oparg; }
    int *newVal; *newVal = 0; //  *(int *) uaddr2 = oldval op oparg;
    switch (op) { //Op is defined as:
      case 0: // FUTEX_OP_SET        0  /* uaddr2 = oparg; */
          *newVal = oparg;
      case 1: // FUTEX_OP_ADD        1  /* uaddr2 += oparg; */
          *newVal = *(fi.uaddr2) + oparg;
      case 2: // FUTEX_OP_OR         2  /* uaddr2 |= oparg; */
          *newVal = *(fi.uaddr2) | oparg;
      case 3: // FUTEX_OP_ANDN       3  /* uaddr2 &= ~oparg; */
          *newVal = *(fi.uaddr2) & ~oparg;
      case 4: // FUTEX_OP_XOR        4  /* uaddr2 ^= oparg; */
          *newVal = *(fi.uaddr2) ^ oparg;
      default:
          panic("We are missing an op type in sched wake op");
    }
    int waitersToWake = futexWakeNWaiters(false, 0xffffffff, fi.uaddr, fi.val);
    bool cmpResult = false;
    switch (cmp) { // The cmp field is one of the following:
      case 0: //   FUTEX_OP_CMP_EQ     0  /* if (oldval == cmparg) wake */
          cmpResult = (*oldVal == cmparg);
      case 1: //   FUTEX_OP_CMP_NE     1  /* if (oldval != cmparg) wake */
          cmpResult = (*oldVal != cmparg);
      case 2: //   FUTEX_OP_CMP_LT     2  /* if (oldval < cmparg) wake */
          cmpResult = (*oldVal < cmparg);
      case 3: //   FUTEX_OP_CMP_LE     3  /* if (oldval <= cmparg) wake */
          cmpResult = (*oldVal <= cmparg);
      case 4: //   FUTEX_OP_CMP_GT     4  /* if (oldval > cmparg) wake */
          cmpResult = (*oldVal > cmparg);
      case 5: //   FUTEX_OP_CMP_GE     5  /* if (oldval >= cmparg) wake */
          cmpResult = (*oldVal >= cmparg);
      default:
          panic("We are missing a case for cmp");
    }
    int extraWaitersToWake = 0;
    if(cmpResult) { //  if (oldval cmp cmparg)
      //    futex(uaddr2, FUTEX_WAKE, val2, 0, 0, 0);
      extraWaitersToWake = futexWakeNWaiters(false, 0xffffffff, newVal, fi.val2);
    }
    return waitersToWake + extraWaitersToWake;
}
Beispiel #4
0
int Scheduler::futexCmpReque(bool pi_wake, uint32_t pid, uint32_t tid, FutexInfo fi) {
    DEBUG_FUTEX("Scheduler: FUTEX CMP REQUE called with pi %d pid %u tid %u", pi_wake, pid, tid);
    int *curVal = 0;
    if(!safeCopy(fi.uaddr, curVal)) {
        panic("Futex Wait wasn't able to copy the data.");
    }
    if(fi.val3 != *curVal) {
        DEBUG_FUTEX("Cur val didn't match val in futex wait");
        return 0;
    }
    bool extraWaiters = futexTable[fi.uaddr].size() > (uint32_t)fi.val;
    int waitersToWake = 0;
    if(!pi_wake) {
        futexWakeNWaiters(pi_wake, 0xffffffff, fi.uaddr, fi.val);
    }
    int extraWaitersToWake = 0;
    if(extraWaiters) {
        extraWaitersToWake = futexMoveNWaiters(pi_wake, fi.uaddr, fi.uaddr2, fi.val2);
    }
    return waitersToWake + extraWaitersToWake;
}