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

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