Statistics
| Branch: | Revision:

streamers / measures.c @ a723a046

History | View | Annotate | Download (9.77 KB)

1
/*
2
 *  Copyright (c) 2010 Csaba Kiraly
3
 *
4
 *  This is free software; see gpl-3.0.txt
5
 */
6
#include <stdio.h>
7
#include <stdint.h>
8
#include <string.h>
9
#include <math.h>
10
#ifndef NAN        //NAN is missing in some old math.h versions
11
#define NAN            (0.0/0.0)
12
#endif
13
#ifndef INFINITY
14
#define INFINITY       (1.0/0.0)
15
#endif
16
#include <sys/time.h>
17

    
18
#include "measures.h"
19
#include "grapes_msg_types.h"
20
#include "streamer.h"
21

    
22
struct timeval print_tdiff = {3600, 0};
23
struct timeval tstartdiff = {60, 0};
24
static struct timeval tstart;
25
static struct timeval print_tstart;
26
static struct timeval tnext;
27

    
28
struct measures {
29
  int duplicates;
30
  int chunks;
31
  int played;
32
  int64_t sum_reorder_delay;
33

    
34
  int chunks_received_dup, chunks_received_nodup, chunks_received_old;
35
  int sum_hopcount;
36
  int64_t sum_receive_delay;
37

    
38
  int chunks_sent;
39

    
40
  uint64_t sum_neighsize;
41
  int samples_neighsize;
42

    
43
  uint64_t bytes_sent, bytes_sent_chunk, bytes_sent_sign, bytes_sent_topo;
44
  int msgs_sent, msgs_sent_chunk, msgs_sent_sign, msgs_sent_topo;
45

    
46
  uint64_t bytes_recvd, bytes_recvd_chunk, bytes_recvd_sign, bytes_recvd_topo;
47
  int msgs_recvd, msgs_recvd_chunk, msgs_recvd_sign, msgs_recvd_topo;
48

    
49
  uint64_t sum_offers_in_flight;
50
  int samples_offers_in_flight;
51
  double sum_queue_delay;
52
  int samples_queue_delay;
53

    
54
  int offers;
55
  int accepts;
56
};
57

    
58
static struct measures m;
59

    
60
void clean_measures()
61
{
62
  memset(&m, 0, sizeof(m));
63
}
64

    
65
double tdiff_sec(const struct timeval *a, const struct timeval *b)
66
{
67
  struct timeval tdiff;
68
  timersub(a, b, &tdiff);
69
  return tdiff.tv_sec + tdiff.tv_usec / 1000000.0;
70
}
71

    
72
void print_measure(const char *name, double value)
73
{
74
  static const struct nodeID *my_addr;
75
  static char *my_addr_str;
76

    
77
  //cache address to avoid recalculating it at every call
78
  if (my_addr != get_my_addr()) {
79
    if (my_addr) nodeid_free(my_addr);
80
    my_addr = nodeid_dup(get_my_addr());
81
    my_addr_str = strdup(node_addr(my_addr));
82
  }
83

    
84
  fprintf(stderr,"abouttopublish,%s,,,%s,%f,,,%f\n", my_addr_str, name, value, tdiff_sec(&tnext, &tstart));
85
}
86

    
87
void print_measures()
88
{
89
  struct timeval tnow;
90
  double timespan;
91

    
92
  gettimeofday(&tnow, NULL);
93
  timespan = tdiff_sec(&tnow, &print_tstart);
94

    
95
  if (m.chunks) print_measure("PlayoutRatio", (double)m.played / m.chunks);
96
  if (m.chunks) print_measure("ReorderDelay(ok&lost)", (double)m.sum_reorder_delay / 1e6 / m.chunks);
97
  if (m.samples_neighsize) print_measure("NeighSize", (double)m.sum_neighsize / m.samples_neighsize);
98
  if (m.chunks_received_nodup) print_measure("OverlayDistance(intime&nodup)", (double)m.sum_hopcount / m.chunks_received_nodup);
99
  if (m.chunks_received_nodup) print_measure("ReceiveDelay(intime&nodup)", (double)m.sum_receive_delay / 1e6 / m.chunks_received_nodup);
100

    
101
  if (timerisset(&print_tstart)) print_measure("ChunkRate", (double) m.chunks / timespan);
102
  if (timerisset(&print_tstart)) print_measure("ChunkReceiveRate(all)", (double) (m.chunks_received_old + m.chunks_received_nodup + m.chunks_received_dup)  / timespan);
103
  if (timerisset(&print_tstart)) print_measure("ChunkReceiveRate(old)", (double) m.chunks_received_old / timespan);
104
  if (timerisset(&print_tstart)) print_measure("ChunkReceiveRate(intime&nodup)", (double) m.chunks_received_nodup / timespan);
105
  if (timerisset(&print_tstart)) print_measure("ChunkReceiveRate(intime&dup)", (double) m.chunks_received_dup / timespan);
106
  if (timerisset(&print_tstart)) print_measure("ChunkSendRate", (double) m.chunks_sent / timespan);
107

    
108
  if (timerisset(&print_tstart)) {
109
    print_measure("SendRateMsgs(all)", (double) m.msgs_sent / timespan);
110
    print_measure("SendRateMsgs(chunk)", (double) m.msgs_sent_chunk / timespan);
111
    print_measure("SendRateMsgs(sign)", (double) m.msgs_sent_sign / timespan);
112
    print_measure("SendRateMsgs(topo)", (double) m.msgs_sent_topo / timespan);
113
    print_measure("SendRateMsgs(other)", (double) (m.msgs_sent - m.msgs_sent_chunk - m.msgs_sent_sign - m.msgs_sent_topo) / timespan);
114

    
115
    print_measure("SendRateBytes(all)", (double) m.bytes_sent / timespan);
116
    print_measure("SendRateBytes(chunk)", (double) m.bytes_sent_chunk / timespan);
117
    print_measure("SendRateBytes(sign)", (double) m.bytes_sent_sign / timespan);
118
    print_measure("SendRateBytes(topo)", (double) m.bytes_sent_topo / timespan);
119
    print_measure("SendRateBytes(other)", (double) (m.bytes_sent - m.bytes_sent_chunk - m.bytes_sent_sign - m.bytes_sent_topo) / timespan);
120

    
121
    print_measure("RecvRateMsgs(all)", (double) m.msgs_recvd / timespan);
122
    print_measure("RecvRateMsgs(chunk)", (double) m.msgs_recvd_chunk / timespan);
123
    print_measure("RecvRateMsgs(sign)", (double) m.msgs_recvd_sign / timespan);
124
    print_measure("RecvRateMsgs(topo)", (double) m.msgs_recvd_topo / timespan);
125
    print_measure("RecvRateMsgs(other)", (double) (m.msgs_recvd - m.msgs_recvd_chunk - m.msgs_recvd_sign - m.msgs_recvd_topo) / timespan);
126

    
127
    print_measure("RecvRateBytes(all)", (double) m.bytes_recvd / timespan);
128
    print_measure("RecvRateBytes(chunk)", (double) m.bytes_recvd_chunk / timespan);
129
    print_measure("RecvRateBytes(sign)", (double) m.bytes_recvd_sign / timespan);
130
    print_measure("RecvRateBytes(topo)", (double) m.bytes_recvd_topo / timespan);
131
    print_measure("RecvRateBytes(other)", (double) (m.bytes_recvd - m.bytes_recvd_chunk - m.bytes_recvd_sign - m.bytes_recvd_topo) / timespan);
132
  }
133

    
134
  if (m.chunks_received_old + m.chunks_received_nodup + m.chunks_received_dup) print_measure("ReceiveRatio(intime&nodup-vs-all)", (double)m.chunks_received_nodup / (m.chunks_received_old + m.chunks_received_nodup + m.chunks_received_dup));
135

    
136
  if (m.samples_offers_in_flight) print_measure("OffersInFlight", (double)m.sum_offers_in_flight / m.samples_offers_in_flight);
137
  if (m.samples_queue_delay) print_measure("QueueDelay", m.sum_queue_delay / m.samples_queue_delay);
138

    
139
  if (timerisset(&print_tstart)) {
140
    print_measure("OfferRate", (double) m.offers / timespan);
141
    print_measure("AcceptRate", (double) m.accepts / timespan);
142
  }
143
  if (m.offers) print_measure("OfferAcceptRatio", (double)m.accepts / m.offers);
144
}
145

    
146
bool print_every()
147
{
148
  static bool startup = true;
149
  struct timeval tnow;
150

    
151
  gettimeofday(&tnow, NULL);
152
  if (startup) {
153
    if (!timerisset(&tstart)) {
154
      timeradd(&tnow, &tstartdiff, &tstart);
155
      print_tstart = tstart;
156
    }
157
    if (timercmp(&tnow, &tstart, <)) {
158
      return false;
159
    } else {
160
      startup = false;
161
    }
162
  }
163

    
164
  if (!timerisset(&tnext)) {
165
    timeradd(&tstart, &print_tdiff, &tnext);
166
  }
167
  if (!timercmp(&tnow, &tnext, <)) {
168
    print_measures();
169
    clean_measures();
170
    print_tstart = tnext;
171
    timeradd(&tnext, &print_tdiff, &tnext);
172
  }
173
  return true;
174
}
175

    
176
/*
177
 * Register duplicate arrival
178
*/
179
void reg_chunk_duplicate()
180
{
181
  if (!print_every()) return;
182

    
183
  m.duplicates++;
184
}
185

    
186
/*
187
 * Register playout/loss of a chunk before playout
188
*/
189
void reg_chunk_playout(int id, bool b, uint64_t timestamp)
190
{
191
  struct timeval tnow;
192

    
193
  if (!print_every()) return;
194

    
195
  m.played += b ? 1 : 0;
196
  m.chunks++;
197
  gettimeofday(&tnow, NULL);
198
  m.sum_reorder_delay += (tnow.tv_usec + tnow.tv_sec * 1000000ULL) - timestamp;
199
}
200

    
201
/*
202
 * Register actual neghbourhood size
203
*/
204
void reg_neigh_size(int s)
205
{
206
  if (!print_every()) return;
207

    
208
  m.sum_neighsize += s;
209
  m.samples_neighsize++;
210
}
211

    
212
/*
213
 * Register chunk receive event
214
*/
215
void reg_chunk_receive(int id, uint64_t timestamp, int hopcount, bool old, bool dup)
216
{
217
  struct timeval tnow;
218

    
219
  if (!print_every()) return;
220

    
221
  if (old) {
222
    m.chunks_received_old++;
223
  } else {
224
    if (dup) { //duplicate detection works only for in-time arrival
225
      m.chunks_received_dup++;
226
    } else {
227
      m.chunks_received_nodup++;
228
      m.sum_hopcount += hopcount;
229
      gettimeofday(&tnow, NULL);
230
      m.sum_receive_delay += (tnow.tv_usec + tnow.tv_sec * 1000000ULL) - timestamp;
231
    }
232
  }
233
}
234

    
235
/*
236
 * Register chunk send event
237
*/
238
void reg_chunk_send(int id)
239
{
240
  if (!print_every()) return;
241

    
242
  m.chunks_sent++;
243
}
244

    
245
/*
246
 * Register chunk accept evemt
247
*/
248
void reg_offer_accept(bool b)
249
{
250
  if (!print_every()) return;
251

    
252
  m.offers++;
253
  if (b) m.accepts++;
254
}
255

    
256
/*
257
 * messages sent (bytes vounted at message content level)
258
*/
259
void reg_message_send(int size, uint8_t type)
260
{
261
  if (!print_every()) return;
262

    
263
  m.bytes_sent += size;
264
  m.msgs_sent++;
265

    
266
  switch (type) {
267
   case MSG_TYPE_CHUNK:
268
     m.bytes_sent_chunk+= size;
269
     m.msgs_sent_chunk++;
270
     break;
271
   case MSG_TYPE_SIGNALLING:
272
     m.bytes_sent_sign+= size;
273
     m.msgs_sent_sign++;
274
     break;
275
   case MSG_TYPE_TOPOLOGY:
276
   case MSG_TYPE_TMAN:
277
     m.bytes_sent_topo+= size;
278
     m.msgs_sent_topo++;
279
     break;
280
   default:
281
     break;
282
  }
283
}
284

    
285
/*
286
 * messages sent (bytes vounted at message content level)
287
*/
288
void reg_message_recv(int size, uint8_t type)
289
{
290
  if (!print_every()) return;
291

    
292
  m.bytes_recvd += size;
293
  m.msgs_recvd++;
294

    
295
  switch (type) {
296
   case MSG_TYPE_CHUNK:
297
     m.bytes_recvd_chunk+= size;
298
     m.msgs_recvd_chunk++;
299
     break;
300
   case MSG_TYPE_SIGNALLING:
301
     m.bytes_recvd_sign+= size;
302
     m.msgs_recvd_sign++;
303
     break;
304
   case MSG_TYPE_TOPOLOGY:
305
   case MSG_TYPE_TMAN:
306
     m.bytes_recvd_topo+= size;
307
     m.msgs_recvd_topo++;
308
     break;
309
   default:
310
     break;
311
  }
312
}
313

    
314
/*
315
 * Register the number of offers in flight
316
*/
317
void reg_offers_in_flight(int running_offers_threads)
318
{
319
  if (!print_every()) return;
320

    
321
  m.sum_offers_in_flight += running_offers_threads;
322
  m.samples_offers_in_flight++;
323
}
324

    
325
/*
326
 * Register the sample for RTT
327
*/
328
void reg_queue_delay(double last_queue_delay)
329
{
330
  if (!print_every()) return;
331

    
332
  m.sum_queue_delay += last_queue_delay;
333
  m.samples_queue_delay++;
334
}
335

    
336
/*
337
 * Initialize peer level measurements
338
*/
339
void init_measures()
340
{
341
}
342

    
343
/*
344
 * End peer level measurements
345
*/
346
void end_measures()
347
{
348
  print_measures();
349
}
350

    
351
/*
352
 * Initialize p2p measurements towards a peer
353
*/
354
void add_measures(struct nodeID *id)
355
{
356
}
357

    
358
/*
359
 * Delete p2p measurements towards a peer
360
*/
361
void delete_measures(struct nodeID *id)
362
{
363
}
364

    
365
double get_receive_delay(void) {
366
        return m.chunks_received_nodup ? (double)m.sum_receive_delay / 1e6 / m.chunks_received_nodup : NAN;
367
}