Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid
[simgrid.git] / examples / smpi / mc / mutual_exclusion.c
1 #include <stdio.h>
2 #include <mpi.h>
3 #include <simgrid/modelchecker.h>
4
5 #define GRANT_TAG 0
6 #define REQUEST_TAG 1
7 #define RELEASE_TAG 2
8
9 int main(int argc, char **argv){
10
11   int err, size, rank;
12   int recv_buff;
13   MPI_Status status;
14   int CS_used = 0;
15   xbt_dynar_t requests = xbt_dynar_new(sizeof(int), NULL);
16   
17   /* Initialize MPI */
18   err = MPI_Init(&argc, &argv);
19   if(err !=  MPI_SUCCESS){
20     printf("MPI initialization failed !\n");
21     exit(1);
22   }
23
24   MC_ignore(&(status.count), sizeof(status.count));
25
26   /* Get number of processes */
27   err = MPI_Comm_size(MPI_COMM_WORLD, &size);
28   /* Get id of this process */
29   err = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
30
31   if(rank == 0){ /* Coordinator */
32     while(1){
33       MPI_Recv(&recv_buff, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
34       if(status.MPI_TAG == REQUEST_TAG){
35         if(CS_used){
36           printf("CS already used. Queue the request.\n");
37           xbt_dynar_push(requests, &recv_buff);
38         }else{
39           printf("CS idle. Grant immediatly.\n");
40           MPI_Send(&rank, 1, MPI_INT, recv_buff, GRANT_TAG, MPI_COMM_WORLD);
41           CS_used = 1;
42         }
43       }else{
44         if(!xbt_dynar_is_empty(requests)){
45           printf("CS release. Grant to queued requests (queue size: %lu)",
46               xbt_dynar_length(requests));
47           xbt_dynar_shift(requests, &recv_buff);
48           MPI_Send(&rank, 1, MPI_INT, recv_buff, GRANT_TAG, MPI_COMM_WORLD);
49           CS_used = 1;
50         }else{
51           printf("CS release. Resource now idle.\n");
52           CS_used = 0;
53         }
54       }
55     }
56   }else{ /* Client */
57     while(1){
58       printf("%d asks the request.\n", rank);
59       MPI_Send(&rank, 1, MPI_INT, 0, REQUEST_TAG, MPI_COMM_WORLD);
60     
61       MPI_Recv(&recv_buff, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
62     
63       printf("%d got the answer. Release it.\n", rank);
64       MPI_Send(&rank, 1, MPI_INT, 0, RELEASE_TAG, MPI_COMM_WORLD);
65     
66     }
67   }
68
69   MPI_Finalize();
70
71   return 0;
72 }