//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;
}
示例#5
0
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;
		}
	}
}