Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of framagit.org:simgrid/simgrid
[simgrid.git] / examples / cpp / mc-bugged2-liveness / s4u-mc-bugged2-liveness.cpp
1 /* Copyright (c) 2012-2023. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 /***************************** Bugged2 ****************************************/
7 /* This example implements a centralized mutual exclusion algorithm.          */
8 /* One client stay always in critical section                                 */
9 /* LTL property checked : !(GFcs)                                             */
10 /******************************************************************************/
11
12 #include <simgrid/modelchecker.h>
13 #include <simgrid/s4u.hpp>
14
15 XBT_LOG_NEW_DEFAULT_CATEGORY(bugged2_liveness, "my log messages");
16 namespace sg4 = simgrid::s4u;
17
18 class Message {
19 public:
20   enum class Kind { GRANT, NOT_GRANT, REQUEST };
21   Kind kind                             = Kind::GRANT;
22   sg4::Mailbox* return_mailbox          = nullptr;
23   explicit Message(Message::Kind kind, sg4::Mailbox* mbox) : kind(kind), return_mailbox(mbox) {}
24 };
25
26 int cs = 0;
27
28 static void coordinator()
29 {
30   bool CS_used = false; // initially the CS is idle
31   std::queue<sg4::Mailbox*> requests;
32
33   sg4::Mailbox* mbox = sg4::Mailbox::by_name("coordinator");
34
35   while (true) {
36     auto m = mbox->get_unique<Message>();
37     if (m->kind == Message::Kind::REQUEST) {
38       if (CS_used) {
39         XBT_INFO("CS already used.");
40         m->return_mailbox->put(new Message(Message::Kind::NOT_GRANT, mbox), 1000);
41       } else { // can serve it immediately
42         XBT_INFO("CS idle. Grant immediately");
43         m->return_mailbox->put(new Message(Message::Kind::GRANT, mbox), 1000);
44         CS_used = true;
45       }
46     } else { // that's a release. Check if someone was waiting for the lock
47       XBT_INFO("CS release. resource now idle");
48       CS_used = false;
49     }
50   }
51 }
52
53 static void client(int id)
54 {
55   aid_t my_pid = sg4::this_actor::get_pid();
56
57   sg4::Mailbox* my_mailbox = sg4::Mailbox::by_name(std::to_string(id));
58
59   while (true) {
60     XBT_INFO("Client (%d) asks the request", id);
61     sg4::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::REQUEST, my_mailbox), 1000);
62
63     auto grant = my_mailbox->get_unique<Message>();
64
65     if (grant->kind == Message::Kind::GRANT) {
66       XBT_INFO("Client (%d) got the answer (grant). Sleep a bit and release it", id);
67       if (id == 1)
68         cs = 1;
69     } else {
70       XBT_INFO("Client (%d) got the answer (not grant). Try again", id);
71     }
72
73     sg4::this_actor::sleep_for(my_pid);
74   }
75 }
76
77 int main(int argc, char* argv[])
78 {
79   sg4::Engine e(&argc, argv);
80
81   MC_automaton_new_propositional_symbol_pointer("cs", &cs);
82
83   e.load_platform(argv[1]);
84
85   sg4::Actor::create("coordinator", e.host_by_name("Tremblay"), coordinator);
86   sg4::Actor::create("client", e.host_by_name("Fafard"), client, 1);
87   sg4::Actor::create("client", e.host_by_name("Boivin"), client, 2);
88
89   e.run();
90
91   return 0;
92 }