//! 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); }
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; }
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; }