⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rvroundtripstats.c

📁 h.248协议源码
💻 C
字号:
/******************************************************************************
Filename:    rvroundtripstats.c
Description: class to keep round trip time statistics and compute 
             retransmission timeouts as outlined in RFC2988
*******************************************************************************
                Copyright (c) 2001 RADVision Inc.
*******************************************************************************
NOTICE:
This document contains information that is proprietary to RADVision Inc.
No part of this publication may be reproduced in any form whatsoever without
written prior approval by RADVision Inc.

RADVision Inc. reserves the right to revise this publication and make changes
without obligation to notify any person of such revisions or changes.
******************************************************************************/

#include "rvroundtripstats.h"

#ifdef RV_PRINTSRTTINFO
#include <stdio.h>
#endif

#define RvHrtimeAbs(t) ((t) > 0 ? (t) : -(t))
#define RV_ROUNDTRIPSTATS_SRTTMAX ((RvHrtime)60 * RV_TIME_NSECPERSEC)
#define RV_ROUNDTRIPSTATS_DEFAULTDEVIATIONMULTIPLIER 15

RvRetransTimeoutLimits *rvRetransTimeoutLimitsConstruct(RvRetransTimeoutLimits *limits,
	RvHrtime initial, RvHrtime min, RvHrtime max)
{
	limits->initial = initial;
	limits->min = min;
	limits->max = max;
	return limits;
}

RvRoundTripStats *rvRoundTripStatsConstruct(RvRoundTripStats *stats, RvRandomGenerator *randomGenerator)
{
	stats->valid = rvFalse;
	stats->k = RV_ROUNDTRIPSTATS_DEFAULTDEVIATIONMULTIPLIER;
	stats->randGen = randomGenerator;
	return stats;
}

void rvRoundTripStatsUpdate(RvRoundTripStats *stats, RvHrtime roundTripTime)
{
	if(stats->valid)
	{
		static const int ax = 8; /* 1/alpha */
		static const int bx = 4; /* 1/beta */
		stats->rttvar = ((bx-1) * stats->rttvar
			+ RvHrtimeAbs(stats->srtt - roundTripTime)) / bx;
		stats->srtt = ((ax-1) * stats->srtt + roundTripTime) / ax;
	}
	else
	{
		stats->srtt = roundTripTime;
		stats->rttvar = roundTripTime / 2;
		stats->valid = rvTrue;
	}

#ifdef RV_PRINTSRTTINFO
	printf("sample %d, srtt %d, rttvar %d\n",
		(int)(roundTripTime / RV_TIME_NSECPERMSEC), 
		(int)(stats->srtt / RV_TIME_NSECPERMSEC), 
		(int)(stats->rttvar / RV_TIME_NSECPERMSEC));
#endif
}

RvHrtime rvRoundTripStatsGetFirstRetransTimeout(RvRoundTripStats *stats, const RvRetransTimeoutLimits *limits)
{
	RvHrtime timeout;

	if(stats->valid)
	{
		RvTimespec timespec;
		const RvHrtime resolution = rvTimeConvertHrtime(rvTimeGetHrtimeRes(&timespec));
		
		timeout = stats->k * stats->rttvar;
		if(timeout < resolution)
			timeout = resolution;
		timeout += stats->srtt;
	}
	else
	{
		/* we have no rtt samples yet, so use configured initial timer value
		   and initialize srtt and rttvar. */
		timeout = limits->initial;
		stats->srtt = timeout;
		stats->rttvar = timeout / 2;
	}

	timeout = timeout < limits->min ? limits->min :
		timeout > limits->max ? limits->max : timeout;

#ifdef RV_PRINTSRTTINFO
	printf("first timeout %d\n", (int)(timeout / RV_TIME_NSECPERMSEC));
#endif

	return timeout;
}

RvHrtime rvRoundTripStatsGetNextRetransTimeout(RvRoundTripStats *stats, const RvRetransTimeoutLimits *limits)
{
	RvHrtime timeout;
	RvHrtime spray = rvRandomGeneratorGetValue(stats->randGen);

	spray *= stats->srtt + 1;
	spray /= (RvHrtime)rvRandomGeneratorGetMax(stats->randGen) + 1;
	timeout = spray + stats->srtt + stats->k * stats->rttvar;

	stats->srtt *= 2;

	/* bound SRTT to avoid overflow */
	if(stats->srtt > RV_ROUNDTRIPSTATS_SRTTMAX)
		stats->srtt = RV_ROUNDTRIPSTATS_SRTTMAX;

	timeout = timeout < limits->min ? limits->min :
		timeout > limits->max ? limits->max : timeout;

#ifdef RV_PRINTSRTTINFO
	printf("next timeout %d\n", (int)(timeout / RV_TIME_NSECPERMSEC));
#endif

	return timeout;
}

unsigned int rvRoundTripStatsGetDeviationMultiplier(const RvRoundTripStats *stats)
{
	return stats->k;
}

void rvRoundTripStatsSetDeviationMultiplier(RvRoundTripStats *stats, unsigned int k)
{
	stats->k = k;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -