]> AND Private Git Repository - loba.git/blob - simple_async.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
Wip++...
[loba.git] / simple_async.cpp
1 #include <cstring>              // strlen
2 #include <cstdio>               // sprintf
3 #include <time.h>               // clock()
4 #include <msg/msg.h>
5 #include <xbt/log.h>
6
7 // Creates a new log category and makes it the default
8 XBT_LOG_NEW_DEFAULT_CATEGORY(simu, "Simulation messages");
9
10 #define N_MBOX 5
11 #define N_MESG 16
12
13 // Failure exit status
14 enum {
15     EXIT_NO_FAILURE    = 0x00,  // no error
16     EXIT_FAILURE_ARGS  = 0x01,  // bad arguments
17     EXIT_FAILURE_INIT  = 0x02,  // failed to initialize simulator
18     EXIT_FAILURE_SIMU  = 0x04,  // simulation failed
19     EXIT_FAILURE_CLEAN = 0x08,  // error at cleanup
20 };
21
22 int sender(int, char *[])
23 {
24     char mbox_stack[N_MBOX][100];
25     msg_comm_t comm_stack[N_MBOX * N_MESG];
26     msg_comm_t *comm = comm_stack;
27     for (int i = 0 ; i < N_MBOX ; i++)
28         sprintf(mbox_stack[i], "MBox_%02d", i);
29
30     INFO0("Starting...");
31     int n = 0;
32     for (int i = 0 ; i < N_MBOX ; i++)
33         for (int j = 0 ; j < N_MESG ; j++) {
34             char task_name[100];
35             const char *mailbox = mbox_stack[i];
36             unsigned shift = j;
37             unsigned comm_size = 1 << shift;
38             m_task_t task;
39
40             sprintf(task_name, "Task_%02d", n);
41             task = MSG_task_create(task_name, 0, 1024.0 * comm_size, NULL);
42             INFO4("At %02d, send %s, size %.0f to \"%s\"", n,
43                   MSG_task_get_name(task),
44                   MSG_task_get_data_size(task), mailbox);
45             *comm++ = MSG_task_isend(task, mailbox);
46             ++n;
47         }
48
49     INFO0("Wait for communications to terminate...");
50     MSG_comm_waitall(comm_stack, comm - comm_stack, -1.0);
51
52     INFO0("Finished.");
53     return 0;
54 }
55
56 int receiver(int, char *[])
57 {
58     char mbox[N_MBOX][100];
59     int comm_count[N_MBOX];
60     m_task_t tasks[N_MBOX];
61     msg_comm_t comms[N_MBOX];
62
63     for (int i = 0 ; i < N_MBOX ; i++) {
64         sprintf(mbox[i], "MBox_%02d", i);
65         comm_count[i] = N_MESG;
66         tasks[i] = NULL;
67         comms[i] = NULL;
68     }
69
70     INFO0("Starting...");
71     xbt_dynar_t dcomms = xbt_dynar_new(sizeof(msg_comm_t), NULL);
72     for (int i = 0 ; i < N_MBOX ; i++) {
73         if (comm_count[i] > 0) {
74             comms[i] = MSG_task_irecv(&tasks[i], mbox[i]);
75             xbt_dynar_push(dcomms, &comms[i]);
76             --comm_count[i];
77         }
78     }
79     int n = 0;
80     while (xbt_dynar_length(dcomms)) {
81         MSG_comm_waitany(dcomms);
82         xbt_dynar_reset(dcomms);
83         for (int i = 0 ; i < N_MBOX ; i++) {
84             if (!comms[i])
85                 continue;
86             if (!MSG_comm_test(comms[i])) {
87                 xbt_dynar_push(dcomms, &comms[i]);
88                 continue;
89             }
90             MSG_comm_destroy(comms[i]);
91             comms[i] = NULL;
92
93             INFO4("At %02d, received %s, size %.0f from \"%s\"", n++,
94                   MSG_task_get_name(tasks[i]),
95                   MSG_task_get_data_size(tasks[i]),
96                   mbox[i]);
97
98             MSG_task_destroy(tasks[i]);
99             tasks[i] = NULL;
100
101             if (comm_count[i] > 0) {
102                 comms[i] = MSG_task_irecv(&tasks[i], mbox[i]);
103                 xbt_dynar_push(dcomms, &comms[i]);
104                 --comm_count[i];
105             }
106         }
107     }
108     xbt_dynar_free(&dcomms);
109
110     INFO0("Finished.");
111     return 0;
112 }
113
114 int main(int argc, char *argv[])
115 {
116     const char *platform_file;
117     const char *application_file;
118     // Note: variables used after THROW must be declared as volatile.
119     volatile int exit_status;   // global exit status
120     volatile double simulated_time = -1.0;
121     volatile clock_t start_time = clock();
122     xbt_ex_t ex;
123     MSG_error_t res;
124
125     // Initialize some MSG internal data.
126     // Note: MSG_global_init() may throw an exception, but it seems
127     // impossible to catch it correctly :-(
128     MSG_global_init(&argc, argv);
129
130     exit_status = EXIT_FAILURE_ARGS; // =====
131     TRY {
132
133         // Parse global parameters
134         if (argc != 3) {
135             INFO1("Usage: %s platform_file application_file", argv[0]);
136             THROW0(0, 0, "Failed to parse command line\n");
137         }
138         platform_file = argv[1];
139         application_file = argv[2];
140
141         INFO0(",----[ Simulation parameters ]");
142         INFO1("| platform_file.....: \"%s\"", platform_file);
143         INFO1("| application_file..: \"%s\"", application_file);
144         INFO0("`----");
145
146         exit_status = EXIT_FAILURE_INIT; // =====
147
148         // Register the main functions of an agent in a global table.
149         MSG_function_register("sender", sender);
150         MSG_function_register("receiver", receiver);
151
152         // Create the platform and the application.
153         MSG_create_environment(platform_file);
154         MSG_launch_application(application_file);
155
156         exit_status = EXIT_FAILURE_SIMU; // =====
157
158         // Launch the MSG simulation.
159         INFO0("Starting simulation...");
160         res = MSG_main();
161         INFO0("Simulation ended.");
162         simulated_time = MSG_get_clock();
163         if (res != MSG_OK)
164             THROW1(0, 0, "MSG_main() failed with status %#x", res);
165
166         exit_status = EXIT_NO_FAILURE; // =====
167     }
168     CATCH (ex) {
169         int len = strlen(ex.msg);
170         if (len > 0 && ex.msg[len - 1] == '\n')
171             len--;              // strip the ending '\n'
172         ERROR2("%.*s", len, ex.msg);
173         DEBUG3("Error from %s() in %s:%d", ex.func, ex.file, ex.line);
174         xbt_ex_free(ex);
175     }
176
177     // Clean the MSG simulation.
178     res = MSG_clean();
179     if (res != MSG_OK) {
180         ERROR1("MSG_clean() failed with status %#x", res);
181         exit_status |= EXIT_FAILURE_CLEAN;
182     }
183
184     // Report final simulation status.
185     if (simulated_time >= 0.0) {
186         clock_t end_time = clock();
187         double simulation_time =
188             (double )(end_time - start_time) / CLOCKS_PER_SEC;
189         INFO0(",----[ Results ]");
190         INFO1("| Total simulated time...: %g", simulated_time);
191         INFO1("| Total simulation time..: %g", simulation_time);
192         INFO0("`----");
193     }
194     if (exit_status == 0)
195         INFO0("Simulation succeeded.");
196     else
197         ERROR1("Simulation failed (%#x).", exit_status);
198
199     return exit_status;
200 }
201
202 // Local variables:
203 // mode: c++
204 // End: