Logo AND Algorithmique Numérique Distribuée

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