Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
04ac7e4137e2f9e06b1e7054fd60d2fceb71afe1
[simgrid.git] / teshsuite / c / async-waitany / async-waitany.c
1 /* Copyright (c) 2010-2020. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "simgrid/actor.h"
7 #include "simgrid/comm.h"
8 #include "simgrid/engine.h"
9 #include "simgrid/forward.h"
10 #include "simgrid/mailbox.h"
11 #include "xbt/asserts.h"
12 #include "xbt/log.h"
13 #include "xbt/str.h"
14
15 #include <stdio.h> /* snprintf */
16
17 XBT_LOG_NEW_DEFAULT_CATEGORY(async_waitany, "Messages specific for this example");
18
19 static int sender(int argc, char* argv[])
20 {
21   xbt_assert(argc == 4, "Expecting 3 parameters from the XML deployment file but got %d", argc);
22   long messages_count  = xbt_str_parse_int(argv[1], "Invalid amount of tasks: %s");
23   long msg_size        = xbt_str_parse_int(argv[2], "Invalid communication size: %s");
24   long receivers_count = xbt_str_parse_int(argv[3], "Invalid amount of receivers: %s");
25
26   /* Dynar in which we store all ongoing communications */
27   xbt_dynar_t pending_comms = xbt_dynar_new(sizeof(sg_comm_t), NULL);
28   ;
29
30   /* Make a dynar of the mailboxes to use */
31   xbt_dynar_t mboxes = xbt_dynar_new(sizeof(sg_mailbox_t), NULL);
32   for (long i = 0; i < receivers_count; i++) {
33     char mailbox_name[80];
34     snprintf(mailbox_name, 79, "receiver-%ld", (i));
35     xbt_dynar_push_as(mboxes, sg_mailbox_t, sg_mailbox_by_name(mailbox_name));
36   }
37
38   /* Start dispatching all messages to receivers, in a round robin fashion */
39   for (int i = 0; i < messages_count; i++) {
40     char msg_content[80];
41     snprintf(msg_content, 79, "Message_%d", i);
42     sg_mailbox_t mbox = (sg_mailbox_t)xbt_dynar_get_ptr(mboxes, i % receivers_count);
43
44     XBT_INFO("Send '%s' to '%s'", msg_content, sg_mailbox_get_name(mbox));
45
46     sg_comm_t comm = sg_mailbox_put_async(mbox, xbt_strdup(msg_content), msg_size);
47     xbt_dynar_push_as(pending_comms, sg_comm_t, comm);
48   }
49   /* Start sending messages to let the workers know that they should stop */
50   for (int i = 0; i < receivers_count; i++) {
51     XBT_INFO("Send 'finalize' to 'receiver-%d'", i);
52     char* end_msg  = xbt_strdup("finalize");
53     sg_comm_t comm = sg_mailbox_put_async((sg_mailbox_t)xbt_dynar_get_ptr(mboxes, i % receivers_count), end_msg, 0);
54     xbt_dynar_push_as(pending_comms, sg_comm_t, comm);
55     xbt_free(end_msg);
56   }
57
58   XBT_INFO("Done dispatching all messages");
59
60   /* Now that all message exchanges were initiated, wait for their completion, in order of termination.
61    *
62    * This loop waits for first terminating message with wait_any() and remove it with erase(), until all comms are
63    * terminated
64    * Even in this simple example, the pending comms do not terminate in the exact same order of creation.
65    */
66   while (!xbt_dynar_is_empty(pending_comms)) {
67     int changed_pos = sg_comm_wait_any_for(pending_comms, -1);
68     xbt_dynar_remove_at(pending_comms, changed_pos, NULL);
69     if (changed_pos != 0)
70       XBT_INFO("Remove the %dth pending comm: it terminated earlier than another comm that was initiated first.",
71                changed_pos);
72   }
73
74   xbt_dynar_free(&pending_comms);
75   xbt_dynar_free(&mboxes);
76
77   XBT_INFO("Goodbye now!");
78   return 0;
79 }
80
81 static int receiver(int argc, char* argv[])
82 {
83   xbt_assert(argc == 2, "Expecting one parameter from the XML deployment file but got %d", argc);
84   int id = xbt_str_parse_int(argv[1], "ID should be numerical, not %s");
85   char mailbox_name[80];
86   snprintf(mailbox_name, 79, "receiver-%d", id);
87   sg_mailbox_t mbox = sg_mailbox_by_name(mailbox_name);
88   XBT_INFO("Wait for my first message on '%s'", mailbox_name);
89   while (1) {
90     char* received = (char*)sg_mailbox_get(mbox);
91     XBT_INFO("I got a '%s'.", received);
92     if (!strcmp(received, "finalize")) { // If it's a finalize message, we're done
93       xbt_free(received);
94       break;
95     }
96     xbt_free(received);
97   }
98
99   XBT_INFO("I'm done. See you!");
100   return 0;
101 }
102
103 int main(int argc, char* argv[])
104 {
105   simgrid_init(&argc, argv);
106   xbt_assert(argc > 2,
107              "Usage: %s platform_file deployment_file\n"
108              "\tExample: %s msg_platform.xml msg_deployment.xml\n",
109              argv[0], argv[0]);
110
111   simgrid_load_platform(argv[1]);
112
113   simgrid_register_function("sender", sender);
114   simgrid_register_function("receiver", receiver);
115   simgrid_load_deployment(argv[2]);
116
117   simgrid_run();
118
119   XBT_INFO("Simulation time %g", simgrid_get_clock());
120
121   return 0;
122 }