Logo AND Algorithmique Numérique Distribuée

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