forked from venkatarun95/genericCC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
traffic-generator.hh
119 lines (93 loc) · 3.36 KB
/
traffic-generator.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#ifndef TRAFFIC_GENERATOR_HH
#define TRAFFIC_GENERATOR_HH
#include <thread>
#include <vector>
#include <boost/random/uniform_int_distribution.hpp>
#include "ctcp.hh"
#include "exponential.hh"
#include "random.hh"
#include "remycc.hh"
template<class T>
class TrafficGenerator{
private:
enum TrafficType {EXPONENTIAL_ON_OFF, DETERMINISTIC_ON_OFF};
enum SwitchType {TIME_SWITCHED, BYTE_SWITCHED};
TrafficType _traffic_type;
SwitchType _switch_type;
union TrafficParams {
struct{
double _mean_off_unit;
double _mean_on_unit;
unsigned int num_cycles;
} _on_off;
} _traffic_params;
T &_ctcp;
std::vector< std::thread > _senders;
void send_data(int seed, int id);
public:
TrafficGenerator(T &s_ctcp, double s_mean_on_unit, double s_mean_off_unit, std::string traffic_params)
: _traffic_type(TrafficType::EXPONENTIAL_ON_OFF),
_switch_type(SwitchType::TIME_SWITCHED),
_traffic_params({ s_mean_off_unit, s_mean_on_unit, (unsigned int)-1 }),
_ctcp(s_ctcp),
_senders()
{
_traffic_params._on_off._mean_on_unit = s_mean_on_unit;
_traffic_params._on_off._mean_off_unit = s_mean_off_unit;
// parse traffic_params
size_t start_pos = 0;
while (start_pos < traffic_params.length()) {
size_t end_pos = traffic_params.find(',', start_pos);
if (end_pos == std::string::npos)
end_pos = traffic_params.length();
std::string arg = traffic_params.substr(start_pos, end_pos - start_pos);
if (arg == "exponential")
_traffic_type = TrafficType::EXPONENTIAL_ON_OFF;
else if (arg == "deterministic")
_traffic_type = TrafficType::DETERMINISTIC_ON_OFF;
else if (arg == "byte_switched"){
_switch_type = SwitchType::BYTE_SWITCHED;
}
else if (arg.substr(0, 11) == "num_cycles=")
_traffic_params._on_off.num_cycles = (unsigned int) \
atoi(arg.substr(11).c_str());
else
std::cout << "Unrecognised parameter: " << arg << endl;
start_pos = end_pos + 1;
}
}
void spawn_senders(int num_senders);
};
template<class T>
void TrafficGenerator<T>::send_data(int seed, int id) {
PRNG prng(seed);
Exponential on (1 / _traffic_params._on_off._mean_on_unit, prng);
Exponential off (1 / _traffic_params._on_off._mean_off_unit, prng);
unsigned int flow_id = 0;
while (1) {
double off_duration = off.sample();
double on_duration = on.sample();
if (_traffic_type == TrafficType::DETERMINISTIC_ON_OFF) {
off_duration = _traffic_params._on_off._mean_off_unit;
on_duration = _traffic_params._on_off._mean_on_unit;
}
std::this_thread::sleep_for(std::chrono::duration<double, std::milli>(unsigned(off_duration)));
bool byte_switched = (_switch_type == SwitchType::BYTE_SWITCHED);
_ctcp.send_data(on_duration, byte_switched, flow_id, id);
++ flow_id;
std::cout<<"Sender: "<<id<<", Flow: "<<flow_id<<". Transmitted for "<<on_duration<<(byte_switched?" bytes.":" ms.")<<endl<<std::flush;
if (flow_id >= _traffic_params._on_off.num_cycles)
break;
}
}
template<class T>
void TrafficGenerator<T>::spawn_senders(int num_senders) {
PRNG prng(global_PRNG());
// Have only one sender for now, since the NAT creates issues for multiple senders anyway
assert(num_senders == 1); // feature not yet implemented
int seed = boost::random::uniform_int_distribution<>()(prng);
int src_id = boost::random::uniform_int_distribution<>()(prng);
std::cout<<"Assigning Source ID: "<<src_id<<std::endl;
send_data(seed, src_id);
}
#endif