Example #1
0
File: bpclock.c Project: b/ION
static void	applyRateControl(Sdr sdr)
{
	BpVdb		*vdb = getBpVdb();
	PsmPartition	ionwm = getIonwm();
	Throttle	*throttle;
	PsmAddress	elt;
	VInduct		*induct;
	VOutduct	*outduct;
	long		capacityLimit;

	sdr_begin_xn(sdr);	/*	Just to lock memory.		*/

	/*	Recalculate limit on local bundle generation.		*/

	manageProductionThrottle(vdb);

	/*	Enable some bundle acquisition.				*/

	for (elt = sm_list_first(ionwm, vdb->inducts); elt;
			elt = sm_list_next(ionwm, elt))
	{
		induct = (VInduct *) psp(ionwm, sm_list_data(ionwm, elt));
		throttle = &(induct->acqThrottle);
		capacityLimit = throttle->nominalRate << 1;
		throttle->capacity += throttle->nominalRate;
		if (throttle->capacity > capacityLimit)
		{
			throttle->capacity = capacityLimit;
		}

		if (throttle->capacity > 0)
		{
			sm_SemGive(throttle->semaphore);
		}
	}

	/*	Enable some bundle transmission.			*/

	for (elt = sm_list_first(ionwm, vdb->outducts); elt;
			elt = sm_list_next(ionwm, elt))
	{
		outduct = (VOutduct *) psp(ionwm, sm_list_data(ionwm, elt));
		throttle = &(outduct->xmitThrottle);
		capacityLimit = throttle->nominalRate << 1;
		throttle->capacity += throttle->nominalRate;
		if (throttle->capacity > capacityLimit)
		{
			throttle->capacity = capacityLimit;
		}

		if (throttle->capacity > 0)
		{
			sm_SemGive(throttle->semaphore);
		}
	}

	sdr_exit_xn(sdr);	/*	Unlock memory.			*/
}
Example #2
0
static void	infoProfile(int tokenCount, char **tokens)
{
	DtpcVdb		*vdb = getDtpcVdb();
	Profile		*vprofile;
	PsmAddress	elt;
	PsmPartition	wm = getIonwm();
	unsigned int	profileID;

	if (tokenCount != 3)
	{
		SYNTAX_ERROR;
		return;
	}
	
	profileID = atoi(tokens[2]);
	for (elt = sm_list_first(wm, vdb->profiles); elt;
			elt = sm_list_next(wm, elt))
	{
		vprofile = (Profile *) psp(wm, sm_list_data(wm, elt));
		if (vprofile->profileID == profileID)
		{
			break;
		}
	}

	if (elt == 0)
	{
		printText("Unknown profile.");
		return;
	}

	printProfile(vprofile);
}
Example #3
0
void	removeEmbargo(IonNode *node, uvast neighborNodeNbr)
{
	PsmPartition	ionwm = getIonwm();
	PsmAddress	elt;
	PsmAddress	addr;
	Embargo		*embargo;

	CHKVOID(node);
	for (elt = sm_list_first(ionwm, node->embargoes); elt;
			elt = sm_list_next(ionwm, elt))
	{
		addr = sm_list_data(ionwm, elt);
		embargo = (Embargo *) psp(ionwm, addr);
		CHKVOID(embargo);
		if (embargo->nodeNbr < neighborNodeNbr)
		{
			continue;
		}

		if (embargo->nodeNbr > neighborNodeNbr)
		{
			return;	/*	Embargo not found.		*/
		}

		break;		/*	Found the embargo to remove.	*/
	}

	if (elt == 0)
	{
		return;		/*	Embargo not found.		*/
	}

	oK(sm_list_delete(ionwm, elt, NULL, NULL));
	psm_free(ionwm, addr);
}
Example #4
0
void	sptrace_clear(PsmPartition trace)
{
	PsmAddress	traceHeaderAddress;
	TraceHeader	*trh;
	PsmAddress	elt;
	PsmAddress	nextElt;
	PsmAddress	itemAddress;
	TraceItem	*item;

	if (!trace) return;
	traceHeaderAddress = psm_get_root(trace);
	trh = (TraceHeader *) psp(trace, traceHeaderAddress);
	CHKVOID(trh);
	for (elt = sm_list_first(trace, trh->log); elt; elt = nextElt)
	{
		nextElt = sm_list_next(trace, elt);
		itemAddress = sm_list_data(trace, elt);
		item = (TraceItem *) psp(trace, itemAddress);
		CHKVOID(item);
		if (item->opType == OP_ALLOCATE || item->opType == OP_FREE)
		{
			if (item->refOpNbr == 0)
			{
				continue;	/*	Not matched.	*/
			}

			/*	Delete matched activity from log.	*/

			psm_free(trace, itemAddress);
			CHKVOID(sm_list_delete(trace, elt, NULL, NULL) == 0);
		}
	}
}
Example #5
0
Object	sdr_list_next(Sdr sdrv, Object elt)
{
	//TODO stub
	//SdrListElt	eltBuffer;

	//CHKZERO(sdrFetchSafe(sdrv));
	CHKZERO(elt);
	//sdrFetch(eltBuffer, (Address) elt);
	//return eltBuffer.next;
	return sm_list_next(sdrv, elt);
}
Example #6
0
void	rfx_stop()
{
	PsmPartition	ionwm = getIonwm();
	IonVdb		*vdb = getIonVdb();
	int		i;
	PsmAddress	elt;
	PsmAddress	nextElt;
	PsmAddress	addr;
	Requisition	*req;

	/*	Safely shut down the ZCO flow control system.		*/

	for (i = 0; i < 1; i++)
	{
		for (elt = sm_list_first(ionwm, vdb->requisitions[i]); elt;
				elt = nextElt)
		{
			nextElt = sm_list_next(ionwm, elt);
			addr = sm_list_data(ionwm, elt);
			req = (Requisition *) psp(ionwm, addr);
			sm_SemEnd(req->semaphore);
			psm_free(ionwm, addr);
			sm_list_delete(ionwm, elt, NULL, NULL);
		}
	}

	//zco_unregister_callback();

	/*	Stop the rfx clock if necessary.			*/
	/*
	if (vdb->clockPid != ERROR)
	{
		sm_TaskKill(vdb->clockPid, SIGTERM);
		while (sm_TaskExists(vdb->clockPid))
		{
			microsnooze(100000);
		}

		vdb->clockPid = ERROR;
	}
	*/
	/*	Wipe out all red-black trees involved in routing,
	 *	for reconstruction on restart.				*/

	sm_rbt_destroy(ionwm, vdb->contactIndex, rfx_erase_data, NULL);
	sm_rbt_destroy(ionwm, vdb->rangeIndex, rfx_erase_data, NULL);
	sm_rbt_destroy(ionwm, vdb->timeline, rfx_erase_data, NULL);
	vdb->contactIndex = sm_rbt_create(ionwm);
	vdb->rangeIndex = sm_rbt_create(ionwm);
	vdb->timeline = sm_rbt_create(ionwm);
}
Example #7
0
static void	dropVdb(PsmPartition wm, PsmAddress vdbAddress)
{
	IonVdb		*vdb;
	int		i;
	PsmAddress	elt;
	PsmAddress	nextElt;
	PsmAddress	addr;
	Requisition	*req;

	vdb = (IonVdb *) psp(wm, vdbAddress);

	/*	Time-ordered list of probes can simply be destroyed.	*/

	sm_list_destroy(wm, vdb->probes, rfx_erase_data, NULL);

	/*	Three of the red-black tables in the Vdb are
	 *	emptied and recreated by rfx_stop().  Destroy them.	*/

	sm_rbt_destroy(wm, vdb->contactIndex, NULL, NULL);
	sm_rbt_destroy(wm, vdb->rangeIndex, NULL, NULL);
	sm_rbt_destroy(wm, vdb->timeline, NULL, NULL);

	/*	cgr_stop clears all routing objects, so nodes and
	 *	neighbors themselves can now be deleted.		*/

	sm_rbt_destroy(wm, vdb->nodes, destroyIonNode, NULL);
	sm_rbt_destroy(wm, vdb->neighbors, rfx_erase_data, NULL);

	/*	Safely shut down the ZCO flow control system.		*/

	for (i = 0; i < 1; i++)
	{
		for (elt = sm_list_first(wm, vdb->requisitions[i]); elt;
				elt = nextElt)
		{
			nextElt = sm_list_next(wm, elt);
			addr = sm_list_data(wm, elt);
			req = (Requisition *) psp(wm, addr);
			sm_SemEnd(req->semaphore);
			psm_free(wm, addr);
			sm_list_delete(wm, elt, NULL, NULL);
		}
	}

	//zco_unregister_callback();
}
Example #8
0
static void	listProfiles(int tokenCount, char **tokens)
{
	PsmPartition	wm = getIonwm();
	PsmAddress	elt;
	Profile		*vprofile;

	if (tokenCount != 2)
	{
		SYNTAX_ERROR;
		return;
	}	

	for (elt = sm_list_first(wm, (getDtpcVdb())->profiles); elt;
			elt = sm_list_next(wm, elt))
	{
		vprofile = (Profile *) psp(wm, sm_list_data(wm, elt));
		printProfile(vprofile);
	}
}
Example #9
0
static PsmAddress	findFileName(PsmPartition trace, TraceHeader *trh,
				char *sourceFileName)
{
	PsmAddress	elt;
	PsmAddress	filenameAddress;
	char		*filename;
	int		buflen;

	for (elt = sm_list_first(trace, trh->files); elt;
			elt = sm_list_next(trace, elt))
	{
		filenameAddress = sm_list_data(trace, elt);
		filename = (char *) psp(trace, filenameAddress);
		if (strcmp(filename, sourceFileName) == 0)
		{
			return filenameAddress;
		}
	}

	/*	This is a source file we haven't heard of before.	*/

	buflen = strlen(sourceFileName) + 1;
	filenameAddress = psm_zalloc(trace, buflen);
	if (filenameAddress == 0)
	{
		discardEvent(trace);
		return 0;
	}

	/*	Add this source file to the list for the trace.		*/

	istrcpy((char *) psp(trace, filenameAddress), sourceFileName, buflen);
	if (sm_list_insert_last(trace, trh->files, filenameAddress) == 0)
	{
		discardEvent(trace);
		return 0;
	}

	return filenameAddress;
}
Example #10
0
File: bpclock.c Project: b/ION
static int	adjustThrottles()
{
	PsmPartition	ionwm = getIonwm();
	IonVdb		*ionvdb = getIonVdb();
	BpVdb		*bpvdb = getBpVdb();
	PsmAddress	elt;
	VOutduct	*outduct;
	unsigned long	nodeNbr;
	IonNeighbor	*neighbor;
	PsmAddress	nextElt;
	int		delta;
	VInduct		*induct;

	/*	Only the LTP induct and outduct throttles can be
	 *	dynamically adjusted in response to changes in data
	 *	rate between the local node and its neighbors, because
	 *	(currently) there is no mechanism for mapping neighbor
	 *	node number to duct name for any other CL protocol.
	 *	For LTP, duct name is LTP engine number which, by
	 *	convention, is identical to BP node number.  For all
	 *	other CL protocols, duct nominal data rate is initially
	 *	set to the protocol's configured nominal data rate and
	 *	is never subsequently modified.
	 *	
	 *	So, first we find the LTP induct if any.		*/

	for (elt = sm_list_first(ionwm, bpvdb->inducts); elt;
			elt = sm_list_next(ionwm, elt))
	{
		induct = (VInduct *) psp(ionwm, sm_list_data(ionwm, elt));
		if (strcmp(induct->protocolName, "ltp") == 0)
		{
			break;	/*	Found the LTP induct.		*/
		}
	}

	if (elt == 0)		/*	No LTP induct; nothing to do.	*/
	{
		return 0;
	}

	/*	Now update all LTP outducts, and the induct as well,
	 *	inferring the existence of Neighbors in the process.	*/

	for (elt = sm_list_first(ionwm, bpvdb->outducts); elt;
			elt = sm_list_next(ionwm, elt))
	{
		outduct = (VOutduct *) psp(ionwm, sm_list_data(ionwm, elt));
		if (strcmp(outduct->protocolName, "ltp") != 0)
		{
			continue;
		}

		nodeNbr = atol(outduct->ductName);
		neighbor = findNeighbor(ionvdb, nodeNbr, &nextElt);
		if (neighbor == NULL)
		{
			neighbor = addNeighbor(ionvdb, nodeNbr, nextElt);
			if (neighbor == NULL)
			{
				putErrmsg("Can't adjust outduct throttle.",
						NULL);
				return -1;
			}
		}

		if (neighbor->xmitRate != neighbor->prevXmitRate)
		{
#ifndef ION_NOSTATS
			if (neighbor->nodeNbr != getOwnNodeNbr())
			{
			/*	We report and clear transmission
			 *	statistics as necessary.  NOTE that
			 *	this procedure is based on the
			 *	assumption that the local node is
			 *	in LTP transmission contact with
			 *	AT MOST ONE neighbor at any time.
			 *	For more complex topologies it will
			 *	need to be redesigned.			*/

				if (neighbor->xmitRate == 0)
				{
					/*	End of xmit contact.	*/
					reportAllStateStats();
					clearAllStateStats();
				}
				else if (neighbor->prevXmitRate == 0)
				{
					/*	Start of xmit contact.	*/
					reportAllStateStats();
					clearAllStateStats();
				}
			}
#endif
			outduct->xmitThrottle.nominalRate = neighbor->xmitRate;
			neighbor->prevXmitRate = neighbor->xmitRate;
		}

		/*	Note that the LTP induct is aggregate; the
		 *	duct's nominal rate is the sum of the rates
		 *	at which all neighbors are expected to be
		 *	transmitting to the local node at any given
		 *	moment.  So we must add the change in rate
		 *	for each known neighbor to the aggregate
		 *	nominal reception rate for the induct.		*/

		if (neighbor->recvRate != neighbor->prevRecvRate)
		{
#ifndef ION_NOSTATS
			if (neighbor->nodeNbr != getOwnNodeNbr())
			{
			/*	We report and clear reception
			 *	statistics as necessary.  NOTE that
			 *	this procedure is based on the
			 *	assumption that the local node is
			 *	in LTP reception contact with
			 *	AT MOST ONE neighbor at any time.
			 *	For more complex topologies it will
			 *	need to be redesigned.			*/

				if (neighbor->recvRate == 0)
				{
					/*	End of recv contact.	*/
					reportAllStateStats();
					clearAllStateStats();
				}
				else if (neighbor->prevRecvRate == 0)
				{
					/*	Start of recv contact.	*/
					reportAllStateStats();
					clearAllStateStats();
				}
			}
#endif
			delta = neighbor->recvRate - neighbor->prevRecvRate;
			induct->acqThrottle.nominalRate += delta;
			neighbor->prevRecvRate = neighbor->recvRate;
		}
	}

	return 0;
}
Example #11
0
File: ltpclock.c Project: b/ION
static int	manageLinks(Sdr sdr, time_t currentTime)
{
	PsmPartition	ionwm = getIonwm();
	LtpVdb		*ltpvdb = getLtpVdb();
	IonVdb		*ionvdb = getIonVdb();
	PsmAddress	elt;
	LtpVspan	*vspan;
	Object		obj;
	LtpSpan		span;
	IonNeighbor	*neighbor;
	PsmAddress	nextElt;
	unsigned long	priorXmitRate;

	sdr_begin_xn(sdr);
	for (elt = sm_list_first(ionwm, ltpvdb->spans); elt;
			elt = sm_list_next(ionwm, elt))
	{
		vspan = (LtpVspan *) psp(ionwm, sm_list_data(ionwm, elt));

		/*	Finish aggregation as necessary.		*/

		obj = sdr_list_data(sdr, vspan->spanElt);
		sdr_stage(sdr, (char *) &span, obj, sizeof(LtpSpan));
		if (span.lengthOfBufferedBlock > 0)
		{
			span.ageOfBufferedBlock++;
			sdr_write(sdr, obj, (char *) &span, sizeof(LtpSpan));
			if (span.ageOfBufferedBlock >= span.aggrTimeLimit)
			{
				sm_SemGive(vspan->bufFullSemaphore);
			}
		}

		/*	Find Neighbor object encapsulating the current
		 *	known state of this LTP engine.			*/

		neighbor = findNeighbor(ionvdb, vspan->engineId, &nextElt);
		if (neighbor == NULL)
		{
			neighbor = addNeighbor(ionvdb, vspan->engineId,
					nextElt);
			if (neighbor == NULL)
			{
				putErrmsg("Can't update span.", NULL);
				return -1;
			}
		}

		if (neighbor->xmitRate == 0)
		{
			if (vspan->localXmitRate > 0)
			{
				vspan->localXmitRate = 0;
				ltpStopXmit(vspan);
			}
		}
		else
		{
			if (vspan->localXmitRate == 0)
			{
				vspan->localXmitRate = neighbor->xmitRate;
				ltpStartXmit(vspan);
			}
		}

		if (neighbor->fireRate == 0)
		{
			if (vspan->remoteXmitRate > 0)
			{
				priorXmitRate = vspan->remoteXmitRate;
				vspan->remoteXmitRate = 0;
				if (ltpSuspendTimers(vspan, elt, currentTime,
						priorXmitRate))
				{
					putErrmsg("Can't manage links.", NULL);
					return -1;
				}
			}
		}
		else
		{
			if (vspan->remoteXmitRate == 0)
			{
				vspan->remoteXmitRate = neighbor->fireRate;
				if (ltpResumeTimers(vspan, elt, currentTime,
						vspan->remoteXmitRate))
				{
					putErrmsg("Can't manage links.", NULL);
					return -1;
				}
			}
		}

		if (neighbor->recvRate == 0)
		{
			vspan->receptionRate = 0;
		}
		else
		{
			vspan->receptionRate = neighbor->recvRate;
		}

		if (neighbor->owltInbound != vspan->owltInbound)
		{
			vspan->owltInbound = neighbor->owltInbound;
		}

		if (neighbor->owltOutbound != vspan->owltOutbound)
		{
			vspan->owltOutbound = neighbor->owltOutbound;
		}
	}

	if (sdr_end_xn(sdr) < 0)
	{
		putErrmsg("ltpclock failed managing links.", NULL);
		return -1;
	}

	return 0;
}
Example #12
0
void	sptrace_report(PsmPartition trace, int verbose)
{
	PsmAddress	traceHeaderAddress;
	TraceHeader	*trh;
	PsmAddress	elt;
	TraceItem	*item;
	char		*fileName;
	char		buffer[384];
	int		len;
	char		buf2[256];

	if (!trace) return;
	traceHeaderAddress = psm_get_root(trace);
	trh = (TraceHeader *) psp(trace, traceHeaderAddress);
	CHKVOID(trh);
	for (elt = sm_list_first(trace, trh->log); elt;
			elt = sm_list_next(trace, elt))
	{
		item = (TraceItem *) psp(trace, sm_list_data(trace, elt));
		CHKVOID(item);
		fileName = (char *) psp(trace, item->fileName);
		isprintf(buffer, sizeof buffer, "(%5d) at line %6d of %32.32s \
(pid %5d): ", item->opNbr, item->lineNbr, fileName, item->taskId);
		len = strlen(buffer);
		switch (item->opType)
		{
		case OP_ALLOCATE:
			isprintf(buf2, sizeof buf2, "allocated object %6ld of \
size %6d, ", item->objectAddress, item->objectSize);
			istrcpy(buffer + len, buf2, sizeof buffer - len);
			if (item->refOpNbr == 0)
			{
				len = strlen(buffer);
				istrcpy(buffer + len, "never freed",
						sizeof buffer - len);
			}
			else
			{
				if (!verbose)
				{
					continue;
				}

				len = strlen(buffer);
				fileName = (char *) psp(trace,
						item->refFileName);
				isprintf(buf2, sizeof buf2, "freed in (%5d) \
at line %6d of %32.32s (pid %5d)", item->refOpNbr, item->refLineNbr, fileName,
					 	item->refTaskId);
				istrcpy(buffer + len, buf2,
						sizeof buffer - len);
			}

			break;

		case OP_MEMO:
			isprintf(buf2, sizeof buf2, "re %6ld, '%.128s'",
					item->objectAddress,
					(char *) psp(trace, item->msg));
			istrcpy(buffer + len, buf2, sizeof buffer - len);
			break;

		case OP_FREE:
			isprintf(buf2, sizeof buf2, "freed object %6ld, ",
					item->objectAddress);
			istrcpy(buffer + len, buf2, sizeof buffer - len);
			if (item->refOpNbr == 0)
			{
				len = strlen(buffer);
				istrcpy(buffer + len, "not currently allocated",
						sizeof buffer - len);
			}
			else
			{
				if (!verbose)
				{
					continue;
				}

				len = strlen(buffer);
				fileName = (char *) psp(trace,
						item->refFileName);
				CHKVOID(fileName);
				isprintf(buf2, sizeof buf2, "allocated in \
(%5d) at line %6d of %32.32s (pid %5d)", item->refOpNbr, item->refLineNbr,
						fileName, item->refTaskId);
				istrcpy(buffer + len, buf2,
						sizeof buffer - len);
			}

			break;
		}

		writeMemo(buffer);
	}
}
Example #13
0
File: ipnfw.c Project: b/ION
static int	enqueueToNeighbor(Bundle *bundle, Object bundleObj,
			unsigned long nodeNbr, unsigned long serviceNbr)
{
	FwdDirective	directive;
	char		*decoration;
	char		stationEid[64];
	IonNode		*stationNode;
	PsmAddress	nextElt;
	PsmPartition	ionwm;
	PsmAddress	snubElt;
	IonSnub		*snub;

	if (ipn_lookupPlanDirective(nodeNbr, bundle->id.source.c.serviceNbr, 
			bundle->id.source.c.nodeNbr, &directive) == 0)
	{
		return 0;
	}

	/*	The station node is a neighbor.				*/

#if BP_URI_RFC
	decoration = "dtn::";
#else
	decoration = "";
#endif
	isprintf(stationEid, sizeof stationEid, "%.5sipn:%lu.%lu", decoration,
			nodeNbr, serviceNbr);

	/*	Is neighbor refusing to be a station for bundles?	*/

	stationNode = findNode(getIonVdb(), nodeNbr, &nextElt);
	if (stationNode)
	{
		ionwm = getIonwm();
		for (snubElt = sm_list_first(ionwm, stationNode->snubs);
				snubElt; snubElt = sm_list_next(ionwm, snubElt))
		{
			snub = (IonSnub *) psp(ionwm, sm_list_data(ionwm,
					snubElt));
			if (snub->nodeNbr < nodeNbr)
			{
				continue;
			}

			if (snub->nodeNbr > nodeNbr)
			{
				break;	/*	Not refusing bundles.	*/
			}

			/*	Neighbor is refusing bundles; give up.	*/

			return 0;
		}
	}

	if (enqueueToDuct(&directive, bundle, bundleObj, stationEid) < 0)
	{
		putErrmsg("Can't enqueue bundle.", NULL);
		return -1;
	}

	return 0;
}
Example #14
0
int	addEmbargo(IonNode *node, uvast neighborNodeNbr)
{
	PsmPartition	ionwm = getIonwm();
	PsmAddress	nextElt;
	PsmAddress	elt;
	Embargo		*embargo;
	PsmAddress	addr;

	/*	Find insertion point in embargoes list.			*/

	CHKERR(node);
	nextElt = 0;
	for (elt = sm_list_first(ionwm, node->embargoes); elt;
			elt = sm_list_next(ionwm, elt))
	{
		embargo = (Embargo *) psp(ionwm, sm_list_data(ionwm, elt));
		CHKERR(embargo);
		if (embargo->nodeNbr < neighborNodeNbr)
		{
			continue;
		}

		if (embargo->nodeNbr > neighborNodeNbr)
		{
			nextElt = elt;
			break;	/*	Have found insertion point.	*/
		}

		return 0;	/*	Embargo has already been added.	*/
	}

	addr = psm_zalloc(ionwm, sizeof(Embargo));
	if (addr == 0)
	{
		putErrmsg("Can't add embargo.", NULL);
		return -1;
	}

	if (nextElt)
	{
		elt = sm_list_insert_before(ionwm, nextElt, addr);
	}
	else
	{
		elt = sm_list_insert_last(ionwm, node->embargoes, addr);
	}

	if (elt == 0)
	{
		psm_free(ionwm, addr);
		putErrmsg("Can't add embargo.", NULL);
		return -1;
	}

	embargo = (Embargo *) psp(ionwm, addr);
	CHKERR(embargo);
	embargo->nodeNbr = neighborNodeNbr;
	embargo->probeIsDue = 0;
	postProbeEvent(node, embargo);	/*	Initial probe event.	*/
	return 0;
}