EwmaThroughputSensor.cc 2.72 KB
Newer Older
Robert Ricci's avatar
Robert Ricci committed
1 2
/*
 * Copyright (c) 2006 University of Utah and the Flux Group.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * 
 * {{{EMULAB-LICENSE
 * 
 * This file is part of the Emulab network testbed software.
 * 
 * This file is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 * 
 * This file is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 * License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this file.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * }}}
Robert Ricci's avatar
Robert Ricci committed
22 23
 */

24 25 26 27 28 29
// EwmaThroughputSensor.cc

#include "lib.h"
#include "EwmaThroughputSensor.h"
#include "ThroughputSensor.h"
#include "CommandOutput.h"
30
#include "StateSensor.h"
31 32 33 34

using namespace std;

EwmaThroughputSensor::EwmaThroughputSensor(
35 36
  ThroughputSensor const * newThroughputSource,
  StateSensor const * newState)
37 38
  : maxThroughput(0)
  , bandwidth(0.0)
39
  , throughputSource(newThroughputSource)
40
  , state(newState)
41 42 43 44 45
{
}

void EwmaThroughputSensor::localSend(PacketInfo * packet)
{
46 47
  ackValid = false;
  sendValid = true;
48 49 50 51
}

void EwmaThroughputSensor::localAck(PacketInfo * packet)
{
52 53
  sendValid = false;
  if (throughputSource->isAckValid() && state->isAckValid())
54
  {
55 56
    int latest = throughputSource->getThroughputInKbps();
    if (state->isSaturated())
57
    {
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
      // The link is saturated, so we know that the throughput
      // measurement is the real bandwidth.
      if (bandwidth == 0.0)
      {
        bandwidth = latest;
      }
      else
      {
        static const double alpha = 0.1;
        bandwidth = bandwidth*(1.0-alpha) + latest*alpha;
      }
      // We have got an actual bandwidth measurement, so reset
      // maxThroughput accordingly.
      maxThroughput = static_cast<int>(bandwidth);
      ostringstream buffer;
      buffer << static_cast<int>(bandwidth);
      global::output->genericMessage(AUTHORITATIVE_BANDWIDTH, buffer.str(),
                                     packet->elab);
76 77 78
    }
    else
    {
79 80 81 82 83 84 85 86 87 88 89
      // The link isn't saturated, so we don't know whether this
      // throughput measurement represents real bandwidth or not.
      if (latest > maxThroughput)
      {
        maxThroughput = latest;
        // Send out a tentative number
        ostringstream buffer;
        buffer << maxThroughput;
        global::output->genericMessage(TENTATIVE_THROUGHPUT, buffer.str(),
                                       packet->elab);
      }
90
    }
91
    ackValid = true;
92 93 94
  }
  else
  {
95
    ackValid = false;
96 97
  }
}