streamers / measures-monl.c @ e07f702e
History | View | Annotate | Download (10.8 KB)
1 | 7f591208 | Csaba Kiraly | /*
|
---|---|---|---|
2 | * Copyright (c) 2010 Csaba Kiraly
|
||
3 | *
|
||
4 | * This is free software; see gpl-3.0.txt
|
||
5 | */
|
||
6 | 6ebe1428 | Csaba Kiraly | #include <math.h> |
7 | 8d3d4722 | Csaba Kiraly | #ifndef NAN //NAN is missing in some old math.h versions |
8 | #define NAN (0.0/0.0) |
||
9 | #endif
|
||
10 | #ifndef INFINITY
|
||
11 | #define INFINITY (1.0/0.0) |
||
12 | #endif
|
||
13 | 6ebe1428 | Csaba Kiraly | |
14 | 4bf91643 | Csaba Kiraly | #include <mon.h> |
15 | #include <ml.h> |
||
16 | 9c4f8e7e | Csaba Kiraly | #include <net_helper.h> |
17 | 652c8557 | CsabaKiraly | #include <grapes_msg_types.h> |
18 | 4bf91643 | Csaba Kiraly | |
19 | 581339c4 | Csaba Kiraly | #include "channel.h" |
20 | 4bf91643 | Csaba Kiraly | #include "dbg.h" |
21 | 9c4f8e7e | Csaba Kiraly | #include "measures.h" |
22 | 4bf91643 | Csaba Kiraly | |
23 | b5da4b64 | CsabaKiraly | #define PEER_PUBLISH_INTERVAL 10 //in seconds |
24 | #define P2P_PUBLISH_INTERVAL 60 //in seconds |
||
25 | fa3d8a23 | CsabaKiraly | |
26 | 52ed89e5 | CsabaKiraly | extern const char *peername; |
27 | |||
28 | 4bf91643 | Csaba Kiraly | typedef struct nodeID { |
29 | socketID_handle addr; |
||
30 | int connID; // connection associated to this node, -1 if myself |
||
31 | int refcnt;
|
||
32 | //a quick and dirty static vector for measures TODO: make it dinamic
|
||
33 | 4fb864eb | Csaba Kiraly | MonHandler mhs[20];
|
34 | 4bf91643 | Csaba Kiraly | int n_mhs;
|
35 | } nodeID; |
||
36 | |||
37 | 19d6b4ca | Csaba Kiraly | static MonHandler chunk_dup, chunk_playout, neigh_size, chunk_receive, chunk_send, offer_accept, chunk_hops, chunk_delay, playout_delay;
|
38 | 832f8211 | CsabaKiraly | //static MonHandler rx_bytes_chunk_per_sec, tx_bytes_chunk_per_sec, rx_bytes_sig_per_sec, tx_bytes_sig_per_sec;
|
39 | //static MonHandler rx_chunks, tx_chunks;
|
||
40 | 6dad7ee8 | Csaba Kiraly | |
41 | 598b51d8 | Csaba Kiraly | /*
|
42 | * Initialize one measure
|
||
43 | */
|
||
44 | a5c0b447 | Csaba Kiraly | void add_measure(MonHandler *mh, MeasurementId id, MeasurementCapabilities mc, MonParameterValue rate, const char *pubname, enum stat_types st[], int length, SocketId dst, MsgType mt) |
45 | { |
||
46 | *mh = monCreateMeasure(id, mc); |
||
47 | 749c1cf3 | Csaba Kiraly | if (rate) monSetParameter (*mh, P_PUBLISHING_RATE, rate);
|
48 | if (length) monPublishStatisticalType(*mh, pubname, channel_get_name(), st , length, NULL); |
||
49 | a5c0b447 | Csaba Kiraly | monActivateMeasure(*mh, dst, mt); |
50 | } |
||
51 | |||
52 | 598b51d8 | Csaba Kiraly | /*
|
53 | * Register duplicate arrival
|
||
54 | */
|
||
55 | 6dad7ee8 | Csaba Kiraly | void reg_chunk_duplicate()
|
56 | { |
||
57 | if (!chunk_dup) {
|
||
58 | 37842c00 | Csaba Kiraly | enum stat_types st[] = {SUM, RATE};
|
59 | 45395cd8 | CsabaKiraly | // number of chunks which have been received more then once
|
60 | b5da4b64 | CsabaKiraly | add_measure(&chunk_dup, GENERIC, 0, PEER_PUBLISH_INTERVAL, "ChunkDuplicates", st, sizeof(st)/sizeof(enum stat_types), NULL, MSG_TYPE_ANY); //[chunks] |
61 | 88e094f7 | Csaba Kiraly | monNewSample(chunk_dup, 0); //force publish even if there are no events |
62 | 6dad7ee8 | Csaba Kiraly | } |
63 | monNewSample(chunk_dup, 1);
|
||
64 | } |
||
65 | |||
66 | 598b51d8 | Csaba Kiraly | /*
|
67 | * Register playout/loss of a chunk before playout
|
||
68 | */
|
||
69 | 19d6b4ca | Csaba Kiraly | void reg_chunk_playout(int id, bool b, uint64_t timestamp) |
70 | 6dad7ee8 | Csaba Kiraly | { |
71 | 38e0991d | Csaba Kiraly | static MonHandler chunk_loss_burst_size;
|
72 | static int last_arrived_chunk = -1; |
||
73 | |||
74 | 19d6b4ca | Csaba Kiraly | struct timeval tnow;
|
75 | 277afdf0 | Csaba Kiraly | if (!chunk_playout && b) { //don't count losses before the first arrived chunk |
76 | f15c9b7a | CsabaKiraly | enum stat_types st[] = {WIN_AVG, AVG, SUM, RATE};
|
77 | 45395cd8 | CsabaKiraly | //number of chunks played
|
78 | b5da4b64 | CsabaKiraly | add_measure(&chunk_playout, GENERIC, 0, PEER_PUBLISH_INTERVAL, "ChunksPlayed", st, sizeof(st)/sizeof(enum stat_types), NULL, MSG_TYPE_ANY); //[chunks] |
79 | 6dad7ee8 | Csaba Kiraly | } |
80 | monNewSample(chunk_playout, b); |
||
81 | 19d6b4ca | Csaba Kiraly | |
82 | if (!playout_delay) {
|
||
83 | enum stat_types st[] = {WIN_AVG, WIN_VAR};
|
||
84 | 45395cd8 | CsabaKiraly | //delay after reorder buffer, however http module does not use reorder buffer
|
85 | add_measure(&playout_delay, GENERIC, 0, PEER_PUBLISH_INTERVAL, "ReorderDelay", st, sizeof(st)/sizeof(enum stat_types), NULL, MSG_TYPE_ANY); //[seconds] |
||
86 | 19d6b4ca | Csaba Kiraly | } |
87 | 38e0991d | Csaba Kiraly | if (b) { //count delay only if chunk has arrived |
88 | gettimeofday(&tnow, NULL);
|
||
89 | monNewSample(playout_delay, ((int64_t)(tnow.tv_usec + tnow.tv_sec * 1000000ULL) - (int64_t)timestamp) / 1000000.0); |
||
90 | } |
||
91 | |||
92 | 461946de | CsabaKiraly | //if (!chunk_loss_burst_size) {
|
93 | // enum stat_types st[] = {WIN_AVG, WIN_VAR};
|
||
94 | 45395cd8 | CsabaKiraly | // // number of consecutive lost chunks
|
95 | // add_measure(&chunk_loss_burst_size, GENERIC, 0, PEER_PUBLISH_INTERVAL, "ChunkLossBurstSize", st, sizeof(st)/sizeof(enum stat_types), NULL, MSG_TYPE_ANY); //[chunks]
|
||
96 | 461946de | CsabaKiraly | //}
|
97 | 38e0991d | Csaba Kiraly | if (b) {
|
98 | if (last_arrived_chunk >= 0) { |
||
99 | int burst_size = id - 1 - last_arrived_chunk; |
||
100 | if (burst_size) monNewSample(chunk_loss_burst_size, burst_size);
|
||
101 | } |
||
102 | last_arrived_chunk = id; |
||
103 | } |
||
104 | 6dad7ee8 | Csaba Kiraly | } |
105 | |||
106 | 598b51d8 | Csaba Kiraly | /*
|
107 | * Register actual neghbourhood size
|
||
108 | */
|
||
109 | 6dad7ee8 | Csaba Kiraly | void reg_neigh_size(int s) |
110 | { |
||
111 | if (!neigh_size) {
|
||
112 | enum stat_types st[] = {LAST};
|
||
113 | 45395cd8 | CsabaKiraly | // number of peers in the neighboorhood
|
114 | b5da4b64 | CsabaKiraly | add_measure(&neigh_size, GENERIC, 0, PEER_PUBLISH_INTERVAL, "NeighSize", st, sizeof(st)/sizeof(enum stat_types), NULL, MSG_TYPE_ANY); //[peers] |
115 | 6dad7ee8 | Csaba Kiraly | } |
116 | monNewSample(neigh_size, s); |
||
117 | } |
||
118 | 4bf91643 | Csaba Kiraly | |
119 | 598b51d8 | Csaba Kiraly | /*
|
120 | 88e094f7 | Csaba Kiraly | * Register chunk receive event
|
121 | */
|
||
122 | 14e5c21e | Csaba Kiraly | void reg_chunk_receive(int id, uint64_t timestamp, int hopcount, bool old, bool dup) |
123 | 88e094f7 | Csaba Kiraly | { |
124 | efb3861d | Csaba Kiraly | struct timeval tnow;
|
125 | |||
126 | 88e094f7 | Csaba Kiraly | if (!chunk_receive) {
|
127 | enum stat_types st[] = {RATE};
|
||
128 | 45395cd8 | CsabaKiraly | // total number of received chunks per second
|
129 | add_measure(&chunk_receive, GENERIC, 0, PEER_PUBLISH_INTERVAL, "TotalRxChunk", st, sizeof(st)/sizeof(enum stat_types), NULL, MSG_TYPE_ANY); //[chunks/s] |
||
130 | 88e094f7 | Csaba Kiraly | monNewSample(chunk_receive, 0); //force publish even if there are no events |
131 | } |
||
132 | monNewSample(chunk_receive, 1);
|
||
133 | ccfc425d | Csaba Kiraly | |
134 | if (!chunk_hops) {
|
||
135 | 45395cd8 | CsabaKiraly | enum stat_types st[] = {WIN_AVG};
|
136 | // number of hops from source on the p2p network
|
||
137 | add_measure(&chunk_hops, GENERIC, 0, PEER_PUBLISH_INTERVAL, "OverlayHops", st, sizeof(st)/sizeof(enum stat_types), NULL, MSG_TYPE_ANY); //[peers] |
||
138 | ccfc425d | Csaba Kiraly | } |
139 | monNewSample(chunk_hops, hopcount); |
||
140 | efb3861d | Csaba Kiraly | |
141 | if (!chunk_delay) {
|
||
142 | enum stat_types st[] = {WIN_AVG, WIN_VAR};
|
||
143 | 45395cd8 | CsabaKiraly | // time elapsed since the source emitted the chunk
|
144 | add_measure(&chunk_delay, GENERIC, 0, PEER_PUBLISH_INTERVAL, "ReceiveDelay", st, sizeof(st)/sizeof(enum stat_types), NULL, MSG_TYPE_ANY); //[seconds] |
||
145 | efb3861d | Csaba Kiraly | } |
146 | gettimeofday(&tnow, NULL);
|
||
147 | f01eb1f0 | Csaba Kiraly | monNewSample(chunk_delay, ((int64_t)(tnow.tv_usec + tnow.tv_sec * 1000000ULL) - (int64_t)timestamp) / 1000000.0); |
148 | 88e094f7 | Csaba Kiraly | } |
149 | |||
150 | /*
|
||
151 | * Register chunk send event
|
||
152 | */
|
||
153 | void reg_chunk_send(int id) |
||
154 | { |
||
155 | if (!chunk_send) {
|
||
156 | enum stat_types st[] = {RATE};
|
||
157 | 45395cd8 | CsabaKiraly | add_measure(&chunk_send, GENERIC, 0, PEER_PUBLISH_INTERVAL, "TotalTxChunk", st, sizeof(st)/sizeof(enum stat_types), NULL, MSG_TYPE_ANY); //[chunks/s] |
158 | 88e094f7 | Csaba Kiraly | monNewSample(chunk_send, 0); //force publish even if there are no events |
159 | } |
||
160 | monNewSample(chunk_send, 1);
|
||
161 | } |
||
162 | |||
163 | /*
|
||
164 | 80ab1a60 | Csaba Kiraly | * Register chunk accept evemt
|
165 | */
|
||
166 | void reg_offer_accept(bool b) |
||
167 | { |
||
168 | if (!offer_accept) {
|
||
169 | 45395cd8 | CsabaKiraly | enum stat_types st[] = {WIN_AVG};
|
170 | // ratio between number of offers and number of accepts
|
||
171 | add_measure(&offer_accept, GENERIC, 0, PEER_PUBLISH_INTERVAL, "OfferAccept", st, sizeof(st)/sizeof(enum stat_types), NULL, MSG_TYPE_ANY); //[no unit -> ratio] |
||
172 | 80ab1a60 | Csaba Kiraly | } |
173 | monNewSample(offer_accept, b); |
||
174 | } |
||
175 | |||
176 | /*
|
||
177 | 598b51d8 | Csaba Kiraly | * Initialize peer level measurements
|
178 | */
|
||
179 | b7e82bd2 | Csaba Kiraly | void init_measures()
|
180 | { |
||
181 | 52ed89e5 | CsabaKiraly | if (peername) monSetPeerName(peername);
|
182 | b7e82bd2 | Csaba Kiraly | } |
183 | |||
184 | 598b51d8 | Csaba Kiraly | /*
|
185 | a8a31ce0 | Csaba Kiraly | * End peer level measurements
|
186 | */
|
||
187 | void end_measures()
|
||
188 | { |
||
189 | } |
||
190 | |||
191 | /*
|
||
192 | 598b51d8 | Csaba Kiraly | * Initialize p2p measurements towards a peer
|
193 | */
|
||
194 | 4bf91643 | Csaba Kiraly | void add_measures(struct nodeID *id) |
195 | { |
||
196 | // Add measures
|
||
197 | int j = 0; |
||
198 | 45395cd8 | CsabaKiraly | enum stat_types stwinavgwinvar[] = {WIN_AVG, WIN_VAR};
|
199 | 5fdc076b | napawine@discreet05.disi.unitn.it | enum stat_types stwinavg[] = {WIN_AVG};
|
200 | 45395cd8 | CsabaKiraly | enum stat_types stwinavgrate[] = {WIN_AVG, RATE};
|
201 | 1e71f9f6 | MarcoMellia | // enum stat_types stsum[] = {SUM};
|
202 | enum stat_types stsumwinsumrate[] = {SUM, PERIOD_SUM, WIN_SUM, RATE};
|
||
203 | 4bf91643 | Csaba Kiraly | |
204 | dprintf("adding measures to %s\n",node_addr(id));
|
||
205 | 826dab2b | Csaba Kiraly | |
206 | 4bf91643 | Csaba Kiraly | /* HopCount */
|
207 | 45395cd8 | CsabaKiraly | // number of hops at IP level
|
208 | 28402571 | CsabaKiraly | add_measure(&id->mhs[j++], HOPCOUNT, PACKET | IN_BAND, P2P_PUBLISH_INTERVAL, "HopCount", stwinavg, sizeof(stwinavg)/sizeof(enum stat_types), id->addr, MSG_TYPE_SIGNALLING); //[IP hops] |
209 | 3bce5816 | Csaba Kiraly | |
210 | 9bbdb696 | Csaba Kiraly | /* Round Trip Time */
|
211 | 45395cd8 | CsabaKiraly | add_measure(&id->mhs[j++], RTT, PACKET | IN_BAND, P2P_PUBLISH_INTERVAL, "RoundTripDelay", stwinavgwinvar, sizeof(stwinavgwinvar)/sizeof(enum stat_types), id->addr, MSG_TYPE_SIGNALLING); //[seconds] |
212 | 3bce5816 | Csaba Kiraly | |
213 | 9bbdb696 | Csaba Kiraly | /* Loss */
|
214 | 0a98e1ad | RobertBirke | add_measure(&id->mhs[j++], SEQWIN, PACKET | IN_BAND, 0, NULL, NULL, 0, id->addr, MSG_TYPE_CHUNK); |
215 | b5da4b64 | CsabaKiraly | add_measure(&id->mhs[j++], LOSS, PACKET | IN_BAND, P2P_PUBLISH_INTERVAL, "LossRate", stwinavg, sizeof(stwinavg)/sizeof(enum stat_types), id->addr, MSG_TYPE_CHUNK); //LossRate_avg [probability 0..1] LossRate_rate [lost_pkts/sec] |
216 | a5c0b447 | Csaba Kiraly | |
217 | 45395cd8 | CsabaKiraly | /* RX,TX volume in bytes (only chunks) */
|
218 | add_measure(&id->mhs[j++], RX_BYTE, PACKET | IN_BAND, P2P_PUBLISH_INTERVAL, "RxBytesChunk", stsumwinsumrate, sizeof(stsumwinsumrate)/sizeof(enum stat_types), id->addr, MSG_TYPE_CHUNK); //[bytes] |
||
219 | add_measure(&id->mhs[j++], TX_BYTE, PACKET | IN_BAND, P2P_PUBLISH_INTERVAL, "TxBytesChunk", stsumwinsumrate, sizeof(stsumwinsumrate)/sizeof(enum stat_types), id->addr, MSG_TYPE_CHUNK); //[bytes] |
||
220 | a5c0b447 | Csaba Kiraly | |
221 | 45395cd8 | CsabaKiraly | /* RX,TX volume in bytes (only signaling) */
|
222 | add_measure(&id->mhs[j++], RX_BYTE, PACKET | IN_BAND, P2P_PUBLISH_INTERVAL, "RxBytesSig", stsumwinsumrate, sizeof(stsumwinsumrate)/sizeof(enum stat_types), id->addr, MSG_TYPE_SIGNALLING); //[bytes] |
||
223 | add_measure(&id->mhs[j++], TX_BYTE, PACKET | IN_BAND, P2P_PUBLISH_INTERVAL, "TxBytesSig", stsumwinsumrate, sizeof(stsumwinsumrate)/sizeof(enum stat_types), id->addr, MSG_TYPE_SIGNALLING); //[bytes] |
||
224 | a5c0b447 | Csaba Kiraly | |
225 | // Chunks
|
||
226 | 45395cd8 | CsabaKiraly | add_measure(&id->mhs[j++], RX_PACKET, DATA | IN_BAND, P2P_PUBLISH_INTERVAL, "RxChunks", stwinavgrate, sizeof(stwinavgrate)/sizeof(enum stat_types), id->addr, MSG_TYPE_CHUNK); //RxChunks_sum [chunks] RxChunks_rate [chunks/sec] |
227 | add_measure(&id->mhs[j++], TX_PACKET, DATA | IN_BAND, P2P_PUBLISH_INTERVAL, "TxChunks", stwinavgrate, sizeof(stwinavgrate)/sizeof(enum stat_types), id->addr, MSG_TYPE_CHUNK); //TxChunks_sum [chunks] TxChunks_rate [chunks/sec] |
||
228 | 52e0506a | Csaba Kiraly | // // Capacity
|
229 | e07f702e | Csaba Kiraly | add_measure(&id->mhs[j++], CLOCKDRIFT, PACKET | IN_BAND, 0, NULL, NULL, 0, id->addr, MSG_TYPE_CHUNK); |
230 | monSetParameter (id->mhs[j-1], P_CLOCKDRIFT_ALGORITHM, 1); |
||
231 | add_measure(&id->mhs[j++], CORRECTED_DELAY, PACKET | IN_BAND, 0, NULL, NULL, 0, id->addr, MSG_TYPE_CHUNK); |
||
232 | add_measure(&id->mhs[j++], CAPACITY_CAPPROBE, PACKET | IN_BAND, P2P_PUBLISH_INTERVAL, "Capacity", stwinavg, sizeof(stwinavg)/sizeof(enum stat_types), id->addr, MSG_TYPE_CHUNK); //[bytes/s] |
||
233 | monSetParameter (id->mhs[j-1], P_CAPPROBE_DELAY_TH, -1); //disable: seems to have implementation problems |
||
234 | // monSetParameter (id->mhs[j-1], P_CAPPROBE_PKT_TH, 5);
|
||
235 | 52e0506a | Csaba Kiraly | // monSetParameter (mh, P_CAPPROBE_PKT_TH, 100);
|
236 | // monSetParameter (mh, P_CAPPROBE_IPD_TH, 60);
|
||
237 | // monPublishStatisticalType(mh, NULL, st , sizeof(st)/sizeof(enum stat_types), repoclient);
|
||
238 | |||
239 | 8ad22666 | Csaba Kiraly | // for static must not be more then 10 or whatever size is in net_helper-ml.c
|
240 | id->n_mhs = j; |
||
241 | 4bf91643 | Csaba Kiraly | } |
242 | |||
243 | 598b51d8 | Csaba Kiraly | /*
|
244 | * Delete p2p measurements towards a peer
|
||
245 | */
|
||
246 | 4bf91643 | Csaba Kiraly | void delete_measures(struct nodeID *id) |
247 | { |
||
248 | dprintf("deleting measures from %s\n",node_addr(id));
|
||
249 | 667e0d87 | Csaba Kiraly | while(id->n_mhs) {
|
250 | monDestroyMeasure(id->mhs[--(id->n_mhs)]); |
||
251 | 4bf91643 | Csaba Kiraly | } |
252 | } |
||
253 | 0cc83624 | Csaba Kiraly | |
254 | 598b51d8 | Csaba Kiraly | /*
|
255 | * Helper to retrieve a measure
|
||
256 | */
|
||
257 | 74a5d4ae | CsabaKiraly | double get_measure(struct nodeID *id, int j, enum stat_types st) |
258 | 0cc83624 | Csaba Kiraly | { |
259 | 667e0d87 | Csaba Kiraly | return (id->n_mhs > j) ? monRetrieveResult(id->mhs[j], st) : NAN;
|
260 | 0cc83624 | Csaba Kiraly | } |
261 | |||
262 | 598b51d8 | Csaba Kiraly | /*
|
263 | 6ebe1428 | Csaba Kiraly | * Hopcount to a given peer
|
264 | */
|
||
265 | 74a5d4ae | CsabaKiraly | int get_hopcount(struct nodeID *id){ |
266 | 6ebe1428 | Csaba Kiraly | double r = get_measure(id, 0, LAST); |
267 | return isnan(r) ? -1 : (int) r; |
||
268 | } |
||
269 | |||
270 | /*
|
||
271 | 598b51d8 | Csaba Kiraly | * RTT to a given peer in seconds
|
272 | */
|
||
273 | 74a5d4ae | CsabaKiraly | double get_rtt(struct nodeID *id){ |
274 | b50f3724 | Csaba Kiraly | return get_measure(id, 1, WIN_AVG); |
275 | 9bbdb696 | Csaba Kiraly | } |
276 | |||
277 | 598b51d8 | Csaba Kiraly | /*
|
278 | 282c2129 | Csaba Kiraly | * average RTT to a set of peers in seconds
|
279 | */
|
||
280 | 74a5d4ae | CsabaKiraly | double get_average_rtt(struct nodeID **ids, int len){ |
281 | 282c2129 | Csaba Kiraly | int i;
|
282 | int n = 0; |
||
283 | double sum = 0; |
||
284 | |||
285 | for (i = 0; i < len; i++) { |
||
286 | double l = get_rtt(ids[i]);
|
||
287 | if (!isnan(l)) {
|
||
288 | sum += l; |
||
289 | n++; |
||
290 | } |
||
291 | } |
||
292 | return (n > 0) ? sum / n : NAN; |
||
293 | } |
||
294 | |||
295 | /*
|
||
296 | 598b51d8 | Csaba Kiraly | * loss ratio from a given peer as 0..1
|
297 | */
|
||
298 | 74a5d4ae | CsabaKiraly | double get_lossrate(struct nodeID *id){ |
299 | b5da4b64 | CsabaKiraly | return get_measure(id, 3, WIN_AVG); |
300 | 0cc83624 | Csaba Kiraly | } |
301 | d4eb745c | Csaba Kiraly | |
302 | 8cabbbda | Csaba Kiraly | /*
|
303 | * average loss ratio from a set of peers as 0..1
|
||
304 | */
|
||
305 | 74a5d4ae | CsabaKiraly | double get_average_lossrate(struct nodeID **ids, int len){ |
306 | d4eb745c | Csaba Kiraly | int i;
|
307 | int n = 0; |
||
308 | double sum = 0; |
||
309 | |||
310 | for (i = 0; i < len; i++) { |
||
311 | double l = get_lossrate(ids[i]);
|
||
312 | if (!isnan(l)) {
|
||
313 | sum += l; |
||
314 | n++; |
||
315 | } |
||
316 | } |
||
317 | return (n > 0) ? sum / n : NAN; |
||
318 | } |
||
319 | 65e2b5a8 | CsabaKiraly | |
320 | double get_receive_delay(void) { |
||
321 | return chunk_delay ? monRetrieveResult(chunk_delay, WIN_AVG) : NAN;
|
||
322 | } |