Statistics
| Branch: | Tag: | Revision:

sssimulator / td.c @ 80f4c362

History | View | Annotate | Download (3.76 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 *delayfile;
12
FILE *statusfile;
13
static int ts;
14
static struct peer *peers;
15
static struct chunk *chunks;
16
static int num_peers;
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 (delayfile) {
72
            fprintf(delayfile, "%d,%d,%d,%d\n", t, p, peers[p].chunks[idx]->chunk,  t - peers[p].chunks[idx]->chunk);
73
            fflush(delayfile);
74
        }
75
        if (chunks[peers[p].chunks[idx]->chunk].received == num_peers) {
76
          if (resfile) {
77
            fprintf(resfile, "Chunk %d received at %d in %d\n", peers[p].chunks[idx]->chunk, t, t - peers[p].chunks[idx]->chunk);
78
            fflush(resfile);
79
          }
80
        }
81
      }
82
    }
83
  }
84
#if 0
85
  for (c = 0; c < num_chunks; j++) {
86
    if (completed[c] == 0) {
87
      completed[c] = t;
88
      for (p = 0; p < num_peers; p++) {
89
        if (peers[p].chunks[c] == NULL) {
90
          completed[c] = 0;
91
        }
92
      }
93
    }
94
  }
95
#endif
96

    
97
  return cnt;
98
}
99

    
100
struct chunk *td_loop(struct peer *p, int np, int num_chunks, int server_period)
101
{
102
  int done, t;
103

    
104
  chunks = malloc(num_chunks * sizeof(struct chunk));
105
  if (chunks == NULL) {
106
    perror("MAlloc");
107

    
108
    return NULL;
109
  }
110
  memset(chunks, 0, num_chunks * sizeof(struct chunk));
111
  num_peers = np;
112
  peers = p;
113
  ts = server_period;
114

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

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

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

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

    
135
      peer_send(&peers[i], t, &chunk, &target);
136
      if (target != NULL) {
137
        peers[i].chunks[win_idx(&peers[i], chunk)]->dl += ts;
138
        chunk_send(chunk, target, peers[i].chunks[win_idx(&peers[i], chunk)]->dl);
139
      }
140
    }
141
    t++;
142
  }
143

    
144
  return chunks;
145
}