rvroundtripstats.c

来自「h.248协议源码」· C语言 代码 · 共 136 行

C
136
字号
/******************************************************************************
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 + =
减小字号Ctrl + -
显示快捷键?