-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmodel_driver.c
115 lines (98 loc) · 2.55 KB
/
model_driver.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//The C driver file for a ROSS model
//This file includes:
// - an initialization function for each LP type
// - a forward event function for each LP type
// - a reverse event function for each LP type
// - a finalization function for each LP type
//Includes
#include <stdio.h>
#include "ross.h"
#include "model.h"
//Helper Functions
void SWAP (double *a, double *b) {
double tmp = *a;
*a = *b;
*b = tmp;
}
//Init function
// - called once for each LP
// ! LP can only send messages to itself during init !
void model_init (state *s, tw_lp *lp) {
int self = lp->gid;
// init state data
s->rcvd_count_H = 0;
s->rcvd_count_G = 0;
s->value = -1;
// Init message to myself
tw_event *e = tw_event_new(self, 1, lp);
message *msg = tw_event_data(e);
msg->type = HELLO;
msg->contents = tw_rand_unif(lp->rng);
msg->sender = self;
tw_event_send(e);
}
//Forward event handler
void model_event (state *s, tw_bf *bf, message *in_msg, tw_lp *lp) {
int self = lp->gid;
// initialize the bit field
*(int *) bf = (int) 0;
// update the current state
// however, save the old value in the 'reverse' message
SWAP(&(s->value), &(in_msg->contents));
// handle the message
switch (in_msg->type) {
case HELLO :
{
s->rcvd_count_H++;
break;
}
case GOODBYE :
{
s->rcvd_count_G++;
break;
}
default :
printf("Unhandeled forward message type %d\n", in_msg->type);
}
tw_event *e = tw_event_new(self, 1, lp);
message *msg = tw_event_data(e);
//# randomly choose message type
double random = tw_rand_unif(lp->rng);
if (random < 0.5) {
msg->type = HELLO;
} else {
msg->type = GOODBYE;
}
msg->contents = tw_rand_unif(lp->rng);
msg->sender = self;
tw_event_send(e);
}
//Reverse Event Handler
void model_event_reverse (state *s, tw_bf *bf, message *in_msg, tw_lp *lp) {
int self = lp->gid;
// undo the state update using the value stored in the 'reverse' message
SWAP(&(s->value), &(in_msg->contents));
// handle the message
switch (in_msg->type) {
case HELLO :
{
s->rcvd_count_H--;
break;
}
case GOODBYE :
{
s->rcvd_count_G--;
break;
}
default :
printf("Unhandeled reverse message type %d\n", in_msg->type);
}
// don't forget to undo all rng calls
tw_rand_reverse_unif(lp->rng);
tw_rand_reverse_unif(lp->rng);
}
//report any final statistics for this LP
void model_final (state *s, tw_lp *lp){
int self = lp->gid;
printf("%d handled %d Hello and %d Goodbye messages\n", self, s->rcvd_count_H, s->rcvd_count_G);
}