Statistics
| Branch: | Tag: | Revision:

sssimulator / td.c @ 32c9a7bc

History | View | Annotate | Download (3.89 KB)

1
#include <stdlib.h>
2
#include <stdio.h>
3
#include <string.h>
4

    
5
#include "core.h"
6
#include "sched.h"
7
#include "stats.h"
8
#include "td.h"
9

    
10
FILE *resfile;
11
FILE *statusfile;
12
static int ts;
13
static struct peer *peers;
14
static struct chunk *chunks;
15
static int num_peers;
16
extern float convergence_precision;
17

    
18
int comp(int chunk)
19
{
20
  return (chunks[chunk].received == num_peers);
21
}
22

    
23

    
24
///==========================================================
25
///     the network model :)
26
///==========================================================
27
//chunks propagate through receiver's recv_chunks array
28
static void chunk_send(int k, struct peer *p, int dl)
29
{
30
#if 0
31
  if (p->chunks[k]) {
32
    fprintf(stderr, "Error: sending chunk %d to %d which already has it!\n", k, p->id);
33
    exit(-1);
34
  }
35
#endif
36
  if (p->recv_chunks[win_idx(p, k)]) {
37
    fprintf(stderr, "Error: sending chunk %d (idx: %d) to %d which already receives it (%d)!\n", k, win_idx(p, k), p->id, p->recv_chunks[k]->chunk);
38
    exit(-1);
39
  }
40
  if (p->chunks[win_idx(p, k)]) {
41
    p->recv_chunks[win_idx(p, k)] = p->chunks[win_idx(p, k)];
42
    p->chunks[win_idx(p, k)] = NULL;
43
  } else {
44
    p->recv_chunks[win_idx(p, k)] = malloc(sizeof(struct chunk_instance));
45
  }
46
  p->recv_chunks[win_idx(p, k)]->dl = dl;
47
  p->recv_chunks[win_idx(p, k)]->chunk = k;
48

    
49
  //CACHE latest_not_needed
50
  p->latest_not_needed = max(k,p->latest_not_needed);
51
  chunks[k].received += 1;
52
}
53

    
54
static int receive(int t)
55
{
56
  int p, c;
57
  int cnt;
58

    
59
  cnt = 0;
60
  for (p = 0; p < num_peers; p++) {
61
    for (c = 0; c < peers[p].buf_size; c++) {
62
      int idx = win_idx(&peers[p], c /* + peers[p].buf_size*/);
63

    
64
      if (peers[p].recv_chunks[idx]) {
65
        cnt++;
66
        peers[p].chunks[idx] = peers[p].recv_chunks[idx];
67
        peers[p].chunks[idx]->completed = t;
68
        peers[p].recv_chunks[idx] = NULL;
69
        chunks[peers[p].chunks[idx]->chunk].avg_delay += t - peers[p].chunks[idx]->chunk;
70
        chunks[peers[p].chunks[idx]->chunk].max_delay = max(chunks[peers[p].chunks[idx]->chunk].max_delay, t - peers[p].chunks[idx]->chunk);
71
        if (chunks[peers[p].chunks[idx]->chunk].received == num_peers) {
72
          if (resfile) {
73
            fprintf(resfile, "Chunk %d received at %d in %d\n", peers[p].chunks[idx]->chunk, t, t - peers[p].chunks[idx]->chunk);
74
            fflush(resfile);
75
          }
76
        }
77
      }
78
    }
79
  }
80
#if 0
81
  for (c = 0; c < num_chunks; j++) {
82
    if (completed[c] == 0) {
83
      completed[c] = t;
84
      for (p = 0; p < num_peers; p++) {
85
        if (peers[p].chunks[c] == NULL) {
86
          completed[c] = 0;
87
        }
88
      }
89
    }
90
  }
91
#endif
92

    
93
  return cnt;
94
}
95

    
96
struct chunk *td_loop(struct peer *p, int np, int num_chunks, int server_period)
97
{
98
  int done, t;
99
  struct stats * stat = NULL;
100

    
101
  chunks = malloc(num_chunks * sizeof(struct chunk));
102
  if (chunks == NULL) {
103
    perror("MAlloc");
104

    
105
    return NULL;
106
  }
107
  memset(chunks, 0, num_chunks * sizeof(struct chunk));
108

    
109
  num_peers = np;
110
  peers = p;
111
  ts = server_period;
112

    
113
  done = 0; t = 0;  // t is the time in chunk time (discrete)
114
  while (!done) {
115
    int i;
116
    struct peer *target;
117

    
118
    // loop stuff
119
    done = ((t != 0) && (receive(t) == 0));
120
    status_print(statusfile, peers, num_peers, chunks, num_chunks, t);
121
    if (trace) fprintf(trace, "Time %d:\n", t);
122

    
123
    // source seeding
124
    source_send(t, &target);
125
    if (target != NULL) {
126
      chunk_send(t, target, t + ts);
127
    }
128

    
129
    // peer offering
130
    for (i = 0; i < num_peers; i++) {
131
      int chunk;
132

    
133
      peer_send(&peers[i], t, &chunk, &target);
134
      if (target != NULL) {
135
        peers[i].chunks[win_idx(&peers[i], chunk)]->dl += ts;
136
        chunk_send(chunk, target, peers[i].chunks[win_idx(&peers[i], chunk)]->dl);
137
      }
138
    }
139
    t++;
140
    if (convergence_precision && chunk_stats_converge(&stat, chunks, num_chunks, peers, num_peers, t - 1))
141
            done = 1;
142
  }
143
  chunk_stats_converge(&stat, chunks, num_chunks, peers, num_peers, t - 1);
144
  chunk_stats_print(stat, CSV_STATS);
145
  if (stat) free(stat);
146

    
147
  return chunks;
148
}