Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
model-checker : increase tesh timeouts
[simgrid.git] / examples / msg / mc / centralized_mutex.c
1 /* Copyright (c) 2012. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7
8 /***************** Centralized Mutual Exclusion Algorithm *********************/
9 /* This example implements a centralized mutual exclusion algorithm.          */
10 /* There is no bug on it, it is just provided to test the state space         */
11 /* reduction of DPOR.                                                         */
12 /******************************************************************************/
13
14 #include "msg/msg.h"
15
16 #define AMOUNT_OF_CLIENTS 4
17 #define CS_PER_PROCESS 2
18 XBT_LOG_NEW_DEFAULT_CATEGORY(centralized, "my log messages");
19
20 int coordinator(int argc, char **argv);
21 int client(int argc, char **argv);
22
23 int coordinator(int argc, char *argv[])
24 {
25   xbt_dynar_t requests = xbt_dynar_new(sizeof(char *), NULL);   // dynamic vector storing requests (which are char*)
26   int CS_used = 0;              // initially the CS is idle
27   int todo = AMOUNT_OF_CLIENTS * CS_PER_PROCESS;        // amount of releases we are expecting
28   while (todo > 0) {
29     msg_task_t task = NULL;
30     MSG_task_receive(&task, "coordinator");
31     const char *kind = MSG_task_get_name(task); //is it a request or a release?
32     if (!strcmp(kind, "request")) {     // that's a request
33       char *req = MSG_task_get_data(task);
34       if (CS_used) {            // need to push the request in the vector
35         XBT_INFO("CS already used. Queue the request");
36         xbt_dynar_push(requests, &req);
37       } else {                  // can serve it immediatly
38         XBT_INFO("CS idle. Grant immediatly");
39         msg_task_t answer = MSG_task_create("grant", 0, 1000, NULL);
40         MSG_task_send(answer, req);
41         CS_used = 1;
42       }
43     } else {                    // that's a release. Check if someone was waiting for the lock
44       if (!xbt_dynar_is_empty(requests)) {
45         XBT_INFO("CS release. Grant to queued requests (queue size: %lu)",
46               xbt_dynar_length(requests));
47         char *req;
48         xbt_dynar_pop(requests, &req);
49         MSG_task_send(MSG_task_create("grant", 0, 1000, NULL), req);
50         todo--;
51       } else {                  // nobody wants it
52         XBT_INFO("CS release. resource now idle");
53         CS_used = 0;
54         todo--;
55       }
56     }
57     MSG_task_destroy(task);
58   }
59   XBT_INFO("Received all releases, quit now");
60   return 0;
61 }
62
63 int client(int argc, char *argv[])
64 {
65   int my_pid = MSG_process_get_PID(MSG_process_self());
66   // use my pid as name of mailbox to contact me
67   char *my_mailbox = bprintf("%d", my_pid);
68   // request the CS 3 times, sleeping a bit in between
69   int i;
70   for (i = 0; i < CS_PER_PROCESS; i++) {
71     XBT_INFO("Ask the request");
72     MSG_task_send(MSG_task_create("request", 0, 1000, my_mailbox),
73                   "coordinator");
74     // wait the answer
75     msg_task_t grant = NULL;
76     MSG_task_receive(&grant, my_mailbox);
77     MSG_task_destroy(grant);
78     XBT_INFO("got the answer. Sleep a bit and release it");
79     MSG_process_sleep(1);
80     MSG_task_send(MSG_task_create("release", 0, 1000, NULL),
81                   "coordinator");
82     MSG_process_sleep(my_pid);
83   }
84   XBT_INFO("Got all the CS I wanted, quit now");
85   return 0;
86 }
87
88 int main(int argc, char *argv[])
89 {
90   MSG_init(&argc, argv);
91   MSG_create_environment("../msg_platform.xml");
92   MSG_function_register("coordinator", coordinator);
93   MSG_function_register("client", client);
94   MSG_launch_application("deploy_mutex.xml");
95   MSG_main();
96   return 0;
97 }