Logo AND Algorithmique Numérique Distribuée

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