Statistics
| Branch: | Tag: | Revision:

sssimulator / ed.c @ master

History | View | Annotate | Download (6.64 KB)

1 659ba19d Luca Baldesi
/*
2
 * this is sssim: the simple & stupid simulator
3
 *
4
 *  copyright (c) 2015 luca baldesi
5
 *
6
 *  this is free software; see gpl-3.0.txt
7
 */
8
9 52770a8f Luca Baldesi
#include "ed.h"
10 f850347b Luca Baldesi
#include <stdint.h>
11 52770a8f Luca Baldesi
12
FILE *resfile;
13 80f4c362 Luca Baldesi
FILE *delayfile;
14 52770a8f Luca Baldesi
FILE *statusfile;
15 32c9a7bc Luca Baldesi
extern float convergence_precision;
16 f850347b Luca Baldesi
extern uint32_t analysis_window;
17 4123e0f7 Luca Baldesi
extern int per_link_events;
18 52770a8f Luca Baldesi
19
struct ed_simulator {
20
        struct chunk * chunks;
21
        struct peer * peers;
22
        struct event_scheduler * sched;
23
        int num_chunks;
24
        int num_peers;
25
        int ts;
26
};
27
28
struct ed_simulator * ed_simulator_new(struct chunk * c, int num_chunks, struct peer * peers, int num_peers, int server_period)
29
{
30
        struct ed_simulator * eds;
31
32
        eds = (struct ed_simulator *) malloc (sizeof(struct ed_simulator));
33
        eds->sched = event_scheduler_new(0);
34
        eds->chunks = c;
35
        eds->ts = server_period;
36
        eds->peers = peers;
37
        eds->num_chunks = num_chunks;
38
        eds->num_peers = num_peers;
39
        return eds;
40
}
41
42
double ed_simulator_time(const struct ed_simulator *eds)
43
{
44
        return event_scheduler_elapsed_time(eds->sched);
45
}
46
47
int ed_simulator_server_period(const struct ed_simulator *eds)
48
{
49
        return eds->ts;
50
}
51
52
void ed_simulator_destroy(struct ed_simulator ** eds)
53
{
54
        struct action_event * ae;
55
56
        if(eds && *eds)
57
        {
58
                while(event_scheduler_queue_length(((*eds)->sched)))
59
                {
60
                        ae = event_scheduler_pop(((*eds)->sched));
61
                        action_event_destroy(&ae);
62
                }
63
                event_scheduler_destroy(&((*eds)->sched));
64
                free(*eds);
65
                *eds = NULL;
66
        }
67
}
68
69
void ed_simulator_inc_chunk_counter(struct ed_simulator * eds, int k)
70
{
71
        if (eds && eds->chunks && eds->num_chunks > k)
72
                eds->chunks[k].received += 1;        
73
}
74
75
void ed_simulator_update_chunk_delay(struct ed_simulator * eds, int k)
76
{
77
        int gen_time;
78
        float delay;
79
80
        gen_time = k;
81
        if (eds && eds->chunks && eds->num_chunks > k)
82
        {
83
                delay = event_scheduler_elapsed_time(eds->sched) - gen_time;
84
//                fprintf(stderr,"[DEBUG] delay: %f\n", delay);
85
                eds->chunks[k].avg_delay += delay;
86
                eds->chunks[k].max_delay = max(eds->chunks[k].max_delay, delay);
87
        }
88
}
89
90
void ed_simulator_schedule(struct ed_simulator * eds, struct action_event * ae, double interval)
91
{
92
        if(eds && ae)
93
        {
94 bf3d3ebd Luca Baldesi
                event_scheduler_insert(eds->sched, ae, interval, LOW_EVENT_PRIORITY);
95 52770a8f Luca Baldesi
        }
96
}
97
98
void ed_simulator_send_chunk(struct ed_simulator * eds, int chunk, struct peer * dst, float dl)
99
{
100
        int idx;
101
102
//        fprintf(stderr,"[DEBUG] sending %d\n", chunk);
103
        if(eds && dst && chunk < eds->num_chunks && dl >= 0)
104
        {
105
                idx = win_idx(dst, chunk);
106
                if(dst->recv_chunks[idx])
107
                        fprintf(stderr,"[ERROR] sending a chunk to a peer which is already receiving it\n");
108
                if(dst->chunks[idx])
109
                {
110
                        dst->recv_chunks[idx] = dst->chunks[idx]; // we reuse the same struct avoiding mallocs
111
                        dst->chunks[idx] = NULL;
112
                } else
113
                        dst->recv_chunks[idx] = (struct chunk_instance *) malloc (sizeof(struct chunk_instance));
114
115
                dst->recv_chunks[idx]->chunk = chunk;
116
                dst->recv_chunks[idx]->dl = dl;
117
                dst->latest_not_needed = max(chunk, dst->latest_not_needed);
118
                ed_simulator_inc_chunk_counter(eds, chunk);
119 bf3d3ebd Luca Baldesi
                event_scheduler_insert(eds->sched, peer_reception_event_new(eds, dst, chunk), RECEPTION_DELAY, HIGH_EVENT_PRIORITY);
120 52770a8f Luca Baldesi
        }
121
}
122
123
void ed_simulator_receive_chunk(struct ed_simulator *eds, struct peer *p, int chunk)
124
{
125
        int idx;
126
127
        //fprintf(stderr,"[DEBUG] receiving %d\n", chunk);
128
        idx = win_idx(p, chunk);
129
        if(p->recv_chunks[idx])
130
        {
131
                p->chunks[idx] = p->recv_chunks[idx];
132
                p->recv_chunks[idx] = NULL;
133
                p->chunks[idx]->completed = event_scheduler_elapsed_time(eds->sched);
134
//                fprintf(stderr,"[DEBUG] peer %d receives chunk %d ", p->id, chunk);
135
                ed_simulator_update_chunk_delay(eds, chunk);
136 80f4c362 Luca Baldesi
                if (delayfile) {
137
                    fprintf(delayfile, "%f,%d,%d,%f\n", ed_simulator_time(eds), p->id, p->chunks[idx]->chunk, ed_simulator_time(eds) - p->chunks[idx]->chunk);
138
                    fflush(delayfile);
139
                }
140 52770a8f Luca Baldesi
                if (eds->chunks[chunk].received == eds->num_peers && resfile) 
141
                {
142
                    fprintf(resfile, "Chunk %d received at %f in %f\n", p->chunks[idx]->chunk, ed_simulator_time(eds), ed_simulator_time(eds) - p->chunks[idx]->chunk);
143
                    fflush(resfile);
144
                }
145
        }
146
}
147
148
void ed_simulator_status_print(struct ed_simulator * eds)
149
{
150
        status_print(statusfile, eds->peers, eds->num_peers, eds->chunks, eds->num_chunks, event_scheduler_elapsed_time(eds->sched));
151
}
152
153
void ed_simulator_gen_events(struct ed_simulator *eds)
154
{
155 4123e0f7 Luca Baldesi
        int i, j;
156 52770a8f Luca Baldesi
157
        if(eds)
158
        {
159
                ed_simulator_schedule(eds, source_event_new(eds), 0);
160
                for (i = 0; i < eds->num_peers; i++) 
161 4123e0f7 Luca Baldesi
                        if (per_link_events)
162
                                for (j = 0; j < eds->peers[i].neigh_size; j++) 
163
                                        ed_simulator_schedule(eds, link_offer_event_new(eds, &(eds->peers[i]), j), 0 );
164
                        else
165
                                ed_simulator_schedule(eds, peer_offer_event_new(eds, &(eds->peers[i])), 0 );
166 52770a8f Luca Baldesi
        }
167
}
168
169
int ed_simulator_events(struct ed_simulator * eds)
170
{
171
        int res = -1;
172
        if (eds)
173
                res = event_scheduler_queue_length(eds->sched);
174
        return res;
175
}
176
177
int ed_simulator_num_chunks(struct ed_simulator *eds)
178
{
179
        return eds->num_chunks;
180
}
181
182
struct action_event * ed_simulator_pick_event(struct ed_simulator * eds)
183
{
184
        if(eds)
185
                return event_scheduler_pop(eds->sched);
186
        return NULL;
187
}
188
189
int ed_simulator_network_activity(struct ed_simulator *eds)
190
{
191
        int i, chunk, t, activity = 0;
192
        struct peer * dst;
193 0c449069 Luca Baldesi
        FILE *swap = trace;
194
195
        trace = NULL; //disable tracing
196 52770a8f Luca Baldesi
197
        t = ((int) ed_simulator_time(eds));
198
        if (t < eds->num_chunks)
199
                activity = 1;
200
201
        i = 0;
202
        while (!activity && i < eds->num_peers)
203
        {
204
                peer_send(&(eds->peers[i]), t, &chunk, &dst);
205
                if (dst)
206
                {
207
                        //fprintf(stderr,"[DEBUG] peer %d has still something to offer\n", dst->id);
208
                        activity = 1;
209
                }
210
                chunk = 0;
211
                while (!activity && chunk < eds->peers[i].buf_size)
212
                {
213
                        if (eds->peers[i].recv_chunks[chunk])
214
                        {
215
                                //fprintf(stderr,"[DEBUG] peer %d has still something to receive %d\n", eds->peers[i].id, chunk);
216
                                activity = 1;
217
                        }
218
                        chunk++;
219
                }
220
                i++;
221
        }
222 0c449069 Luca Baldesi
        trace = swap; // re-enable tracing
223 52770a8f Luca Baldesi
        return activity;
224
}
225
226
struct chunk *ed_loop(struct peer *p, int np, int num_chunks, int server_period)
227
{
228
        struct ed_simulator * eds;
229
        struct chunk * chunks;
230
        struct action_event * ae;
231 32c9a7bc Luca Baldesi
        struct stats * stat = NULL;
232 52770a8f Luca Baldesi
233
        chunks = malloc(num_chunks * sizeof(struct chunk));
234
        if (chunks == NULL) {
235
                perror("MAlloc");
236
                return NULL;
237
        }
238
        memset(chunks, 0, num_chunks * sizeof(struct chunk));
239
240
        eds = ed_simulator_new(chunks, num_chunks, p, np, server_period);
241
        ed_simulator_gen_events(eds);
242
243 32c9a7bc Luca Baldesi
        while(ed_simulator_network_activity(eds) &&
244
                        !(convergence_precision && 
245 f850347b Luca Baldesi
                         chunk_stats_converge(&stat, chunks, num_chunks, p, np, ed_simulator_time(eds), analysis_window)))
246 52770a8f Luca Baldesi
        {
247
                //fprintf(stderr,"[DEBUG] another round, time %f\n", ed_simulator_time(eds));
248
                ae = ed_simulator_pick_event(eds);
249
                action_event_trigger(ae);
250 32c9a7bc Luca Baldesi
                //chunk_stats_print(stat, PLAIN_STATS);
251 52770a8f Luca Baldesi
        }
252 f850347b Luca Baldesi
        chunk_stats_converge(&stat, chunks, num_chunks, p, np, ed_simulator_time(eds), analysis_window);
253 32c9a7bc Luca Baldesi
        chunk_stats_print(stat, CSV_STATS);
254 f850347b Luca Baldesi
        if(stat)
255
                free(stat);
256 52770a8f Luca Baldesi
        ed_simulator_destroy(&eds);
257
258
        return chunks;
259
}