//Make sure data is up-to-date with latest cache version before reading void CoherencyManager::checkRead(TreeDescriptor treeIdx, int nid) { int ownerIdx; bool isOwner; bool isWarm; bool isDirty; int timestamp; int sendNid, sendTreeIdx; if(!chanFactory.isCommunicationEnabled()) return; dataManager->getCoherencyInfo(treeIdx, nid, isOwner, ownerIdx, isWarm, isDirty, timestamp); if(isOwner || ownerIdx == -1 || isWarm || !isDirty) return; ChannelAddress *addr = chanFactory.getAddress(ownerIdx); //Request whole data set sendNid = channel->fromNative(nid); sendTreeIdx = channel->fromNative(treeIdx.getShot()); char *name = treeIdx.getName(); char nameLen = strlen(name); char *sendInfo = new char[2*sizeof(int)+1+nameLen]; ((int *)sendInfo)[0] = sendNid; ((int *)sendInfo)[1] = sendTreeIdx; sendInfo[2*sizeof(int)] = nameLen; memcpy(&sendInfo[2*sizeof(int)+1], name, nameLen); Event *dataEvent = dataManager->getDataEvent(treeIdx, nid); channel->sendMessage(addr, (char *)sendInfo, 2*sizeof(int)+1+nameLen, REQUEST_DATA_TYPE); dataEvent->wait(); delete [] sendInfo; }
void CoherencyManager::handleOwnershipWarmMessage(TreeDescriptor treeIdx, int nid, ChannelAddress *senderAddr, int senderIdx) { int ownerIdx; bool isOwner; bool isWarm; bool isDirty; int timestamp; #ifdef DEBUG printf("WARM OWNERSHIP message. nid: %d\n", nid); #endif dataManager->getCoherencyInfo(treeIdx, nid, isOwner, ownerIdx, isWarm, isDirty, timestamp); if(!isOwner) return; dataManager->addWarm(treeIdx, nid, senderIdx); int serializedSize = dataManager->getSerializedSize(treeIdx, nid); char *name = treeIdx.getName(); char nameLen = strlen(name); char *serialized = new char[2*sizeof(int)+1+nameLen+serializedSize]; *(unsigned int *)serialized = channel->fromNative(nid); ((int *)serialized)[1] = channel->fromNative(treeIdx.getShot()); serialized[2*sizeof(int)] = nameLen; memcpy(&serialized[2*sizeof(int) + 1], name, nameLen); dataManager->getSerialized(treeIdx, nid, &serialized[2*sizeof(int)+1+nameLen]); ChannelAddress *retAddr = chanFactory.getAddress(senderIdx); channel->sendMessage(retAddr, serialized, serializedSize+2*sizeof(int)+1+nameLen, DATA_TYPE); delete[] serialized; }
void CoherencyManager::handleOwnershipMsg(TreeDescriptor treeIdx, int nid, int timestamp, char ownerIdx, ChannelAddress *addr, int senderIdx) { int prevOwnerIdx; bool isOwner; bool isWarm; bool isDirty; int prevTimestamp; dataManager->getCoherencyInfo(treeIdx, nid, isOwner, prevOwnerIdx, isWarm, isDirty, prevTimestamp); #ifdef DEBUG printf("OWNERSHIP message. nid: %d, timestamp: %d ownerIdx: %d\n", nid, timestamp, ownerIdx); #endif /* TEMPORANEO if((timestamp < prevTimestamp )|| //It is an outdated message ((timestamp == prevTimestamp) && ownerIdx < prevOwnerIdx)) //It is a concurrent write, but the sender has lowe priority { #ifdef DEBUG printf("Outdated ownership message\n"); #endif return; } */ dataManager->setOwner(treeIdx, nid, ownerIdx, timestamp); if(isWarm) { int msgNid = channel->fromNative(nid); int msgTreeIdx = channel->fromNative(treeIdx.getShot()); char *msgTreeName = treeIdx.getName(); char msgTreeNameLen = strlen(msgTreeName); char *msgInfo = new char[2*sizeof(int)+1+msgTreeNameLen]; // msgInfo[0] = nid; // msgInfo[1] = treeIdx; ((int *)msgInfo)[0] = msgNid; ((int *)msgInfo)[1] = msgTreeIdx; msgInfo[2*sizeof(int)] = msgTreeNameLen; memcpy(&msgInfo[2*sizeof(int)+1], msgTreeName, msgTreeNameLen); ChannelAddress *retAddr = chanFactory.getAddress(senderIdx); channel->sendMessage(retAddr, (char *)msgInfo, 2*sizeof(int)+1+msgTreeNameLen, OWNERSHIP_WARM_ACK_TYPE); delete[] msgInfo; } else dataManager->setDirty(treeIdx, nid, true); }
//Manages request for data: read the whole data slot set and send it. //The returned message contains the data slots. void CoherencyManager::handleRequestDataMsg(TreeDescriptor treeIdx, int nid, ChannelAddress *senderAddr, int senderIdx) { int serializedSize; #ifdef DEBUG printf("DATA REQUEST message. nid: %d\n", nid); #endif serializedSize = dataManager->getSerializedSize(treeIdx, nid); char *name = treeIdx.getName(); char nameLen = strlen(name); char *serialized = new char[2*sizeof(int)+1+nameLen+serializedSize]; *(int *)serialized = channel->fromNative(nid); ((int *)serialized)[1] = channel->fromNative(treeIdx.getShot()); serialized[2*sizeof(int)] = nameLen; memcpy(&serialized[2*sizeof(int)+1], name, nameLen); dataManager->getSerialized(treeIdx, nid, &serialized[2*sizeof(int)+1+nameLen]); dataManager->addReader(treeIdx, nid, senderIdx); ChannelAddress *retAddr = chanFactory.getAddress(senderIdx); channel->sendMessage(retAddr, serialized, serializedSize + 2 * sizeof(int)+1+nameLen, DATA_TYPE); delete [] serialized; }
int Cache::flush(TreeDescriptor treeIdx, int nid) { char *data, *dim, *shape, *start, *end; char dataType; int dataSize, dimSize, numSamples, shapeSize, currDataSize, startSize, endSize; int status, errStatus = 1, actSamples; bool isTimestamped; NidChain *currChainNid, *prevChainNid; currChainNid = prevChainNid = chainHead; queueLock.lock(); while(currChainNid) { if(currChainNid->treeIdx == treeIdx && (nid == -1 || currChainNid->nid == nid)) { switch(currChainNid->mode) { case FLUSH_PUT_RECORD: status = dataManager.getData(currChainNid->treeIdx, currChainNid->nid,&dataType, &numSamples, &data, &dataSize); if(status &1 )status = putRecordInternal(treeIdx.getName(), treeIdx.getShot(), currChainNid->nid, dataType, numSamples, data, dataSize); if(!(status & 1)) { errStatus = status; } break; case FLUSH_BEGIN_SEGMENT: case FLUSH_UPDATE_SEGMENT: status = dataManager.getSegmentLimits(currChainNid->treeIdx, currChainNid->nid, currChainNid->idx, &start, &startSize, &end, &endSize, &isTimestamped); status = dataManager.getSegmentData(currChainNid->treeIdx, currChainNid->nid, currChainNid->idx, &dim, &dimSize, &data, &dataSize, &shape, &shapeSize, &currDataSize, &isTimestamped, &actSamples); if(status &1 )status = putSegmentInternal(treeIdx.getName(), treeIdx.getShot(), currChainNid->nid, start, startSize, end, endSize, dim, dimSize, data, dataSize, (int*)shape, shapeSize, currDataSize, isTimestamped, actSamples, currChainNid->mode == FLUSH_UPDATE_SEGMENT); if(!(status & 1)) { errStatus = status; } break; } if(currChainNid == chainHead) { chainHead = currChainNid->nxt; delete currChainNid; currChainNid = prevChainNid = chainHead; } else { prevChainNid->nxt = currChainNid->nxt; delete currChainNid; currChainNid = prevChainNid->nxt; } } else //Skip this descriptor { prevChainNid = currChainNid; currChainNid = currChainNid->nxt; } } queueLock.unlock(); return errStatus; }
void CoherencyManager::checkWrite(TreeDescriptor treeIdx, int nid) { int ownerIdx; bool isOwner; bool isWarm; int timestamp; char *warmList; int numWarm; char *readerList; int numReader; if(!chanFactory.isCommunicationEnabled()) return; dataManager->getCoherencyInfo(treeIdx, nid, isOwner, ownerIdx, isWarm, timestamp, warmList, numWarm, readerList, numReader); if(!isOwner) //It was not owner, update all nodes, possibly sending the whole data item (for warm nodes)nodes { int numAddresses; timestamp++; ChannelAddress **addresses = chanFactory.getOtherAddresses(numAddresses); char *name = treeIdx.getName(); char nameLen = strlen(name); char *outBuf = new char[3*sizeof(int)+1+1+nameLen]; *(unsigned int *)outBuf = channel->fromNative(nid); ((int *)outBuf)[1] = channel->fromNative(treeIdx.getShot()); outBuf[2*sizeof(int)] = nameLen; memcpy(&outBuf[2*sizeof(int) + 1], name, nameLen); int msgTimestamp = channel->fromNative(timestamp); memcpy(&outBuf[2*sizeof(int) + 1 + nameLen], &msgTimestamp, sizeof(int)); outBuf[3 * sizeof(int)+1+nameLen] = chanFactory.getThisAddressIdx(); //((unsigned int *)outBuf)[2] = channel->fromNative(timestamp); //outBuf[3 * sizeof(int)] = chanFactory.getThisAddressIdx(); dataManager->setCoherencyInfo(treeIdx, nid, true, -1, isWarm, timestamp, NULL, 0, NULL, 0); for(int i = 0; i < numAddresses; i++) { channel->sendMessage(addresses[i], outBuf, 3 * sizeof(int) + 1 + 1 + nameLen, OWNERSHIP_TYPE); } delete[] outBuf; } else if(numWarm > 0 || numReader > 0) //It is owner, send last data slot to all warm nodes and dirty message to all current readers { if(numWarm > 0) { int serializedSize = dataManager->getSerializedSize(treeIdx, nid); char *name = treeIdx.getName(); char nameLen = strlen(name); char *serialized = new char[serializedSize+2*sizeof(int)+1+nameLen]; *(int *)serialized = channel->fromNative(nid); ((int *)serialized)[1] = channel->fromNative(treeIdx.getShot()); serialized[2*sizeof(int)] = nameLen; memcpy(&serialized[2*sizeof(int)+1], name, nameLen); dataManager->getSerialized(treeIdx, nid, &serialized[2*sizeof(int)+1+nameLen]); for(int i = 0; i < numWarm; i++) { ChannelAddress *currAddr = chanFactory.getAddress(warmList[i]); channel->sendMessage(currAddr, serialized, serializedSize+2*sizeof(int)+1+nameLen, DATA_TYPE); } delete[] serialized; } for(int i = 0; i < numReader; i++) { char *name = treeIdx.getName(); char nameLen = strlen(name); ChannelAddress *currAddr = chanFactory.getAddress(readerList[i]); int msgNid = channel->fromNative(nid); int msgTreeIdx = channel->fromNative(treeIdx.getShot()); char *msgInfo = new char[2*sizeof(int) + 1+nameLen]; ((int *)msgInfo)[0] = msgNid; ((int *)msgInfo)[1] = msgTreeIdx; msgInfo[2*sizeof(int)] = nameLen; memcpy(&msgInfo[2*sizeof(int) + 1], name, nameLen); channel->sendMessage(currAddr, (char *)msgInfo, 2*sizeof(int)+1+nameLen, DIRTY_TYPE); delete[]msgInfo; } } }