Logo AND Algorithmique Numérique Distribuée

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