Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Added message before the test
[simgrid.git] / teshsuite / s4u / comm-fault-scenarios / comm-fault-scenarios.cpp
1 /* Copyright (c) 2010-2021. 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 /* This example shows how to simulate a non-linear resource sharing for
7  * network links.
8  */
9
10 #include <algorithm>
11 #include <random>
12 #include <simgrid/kernel/ProfileBuilder.hpp>
13 #include <simgrid/s4u.hpp>
14 #include <sstream>
15 #include <time.h>
16 #include <vector>
17
18
19 //#include "../../src/kernel/activity/ActivityImpl.hpp"
20
21 namespace sg4 = simgrid::s4u;
22 namespace pr  = simgrid::kernel::profile;
23
24 XBT_LOG_NEW_DEFAULT_CATEGORY(comm_fault_scenarios, "Messages specific for this s4u example");
25
26 /*************************************************************************************************/
27
28 // Constants for platform configuration
29
30 constexpr double HostComputePower = 1e9;  // FLOPs
31 constexpr double LinkBandwidth    = 1e9;  // Bytes/second
32 constexpr double LinkLatency      = 1e-6; // Seconds
33
34 // Constants for application behaviour
35
36 constexpr uint64_t MsgSize = LinkBandwidth / 2;
37
38 /*************************************************************************************************/
39
40 enum class CommType {
41   EAGER_SYNC,
42   EAGER_ASYNC,
43   EAGER_INIT,
44   RDV_SYNC,
45   RDV_ASYNC,
46   RDV_INIT,
47   ONESIDE_SYNC,
48   ONESIDE_ASYNC,
49   ONESIDE_INIT
50 };
51
52 enum class Action { SLEEP, PUT, GET, START, WAIT, DIE, END };
53
54 static const char* to_string(const Action x)
55 {
56
57   switch (x) {
58     case Action::END:
59       return "Success";
60     case Action::SLEEP:
61       return "Sleep";
62     case Action::PUT:
63       return "Put";
64     case Action::GET:
65       return "Get";
66     case Action::START:
67       return "Start";
68     case Action::WAIT:
69       return "Wait";
70     case Action::DIE:
71       return "Die!";
72   };
73   return "";
74 }
75
76 struct Step {
77   double rel_time; // Time relative to Scenario startTime
78   enum { STATE, ACTION } type;
79   enum { LNK, SND, RCV } entity;
80   Action action_type;
81   bool new_state;
82 };
83
84 struct Scenario {
85   CommType type;
86   double start_time;
87   double duration;
88   Action snd_expected;
89   Action rcv_expected;
90   std::vector<Step> steps;
91   int index;
92 };
93
94 static std::string to_string(const Scenario& s)
95 {
96
97   std::stringstream ss;
98   ss <<"#"<< s.index << "[" << s.start_time << "s," << s.start_time + s.duration << "s[: (";
99   switch (s.type) {
100     case CommType::EAGER_SYNC:
101       ss << "EAGER_SYNC";
102       break;
103     case CommType::EAGER_ASYNC:
104       ss << "EAGER_ASYNC";
105       break;
106     case CommType::EAGER_INIT:
107       ss << "EAGER_INIT";
108       break;
109     case CommType::RDV_SYNC:
110       ss << "RDV_SYNC";
111       break;
112     case CommType::RDV_ASYNC:
113       ss << "RDV_ASYNC";
114       break;
115     case CommType::RDV_INIT:
116       ss << "RDV_INIT";
117       break;
118     case CommType::ONESIDE_SYNC:
119       ss << "ONESIDE_SYNC";
120       break;
121     case CommType::ONESIDE_ASYNC:
122       ss << "ONESIDE_ASYNC";
123       break;
124     case CommType::ONESIDE_INIT:
125       ss << "ONESIDE_INIT";
126       break;
127   }
128   ss << ") Expected: S:" << to_string(s.snd_expected) << " R:" << to_string(s.rcv_expected) << " Steps: ";
129   for (const Step& step : s.steps) {
130     ss << "+" << step.rel_time << "s:";
131     switch (step.entity) {
132       case Step::LNK:
133         ss << "LNK";
134         break;
135       case Step::SND:
136         ss << "SND";
137         break;
138       case Step::RCV:
139         ss << "RCV";
140         break;
141     }
142
143     if (step.type == Step::STATE) {
144       ss << "->";
145       if (step.new_state)
146         ss << "ON";
147       else
148         ss << "OFF";
149     } else {
150       ss << "." << to_string(step.action_type);
151     }
152     ss << " ";
153   }
154
155   return ss.str().c_str();
156 }
157
158 std::vector<Scenario> scenarios;
159
160 sg4::Mailbox* mbox_eager = nullptr;
161 sg4::Mailbox* mbox_rdv   = nullptr;
162
163 class SendAgent {
164
165   static int run;
166   static size_t scenario;
167
168   int id;
169   sg4::Host* other_host;
170
171   sg4::CommPtr do_put(CommType type, double& send_value)
172   {
173     switch (type) {
174       case CommType::EAGER_SYNC:
175         mbox_eager->put(&send_value, MsgSize);
176         return nullptr;
177       case CommType::EAGER_ASYNC:
178         return mbox_eager->put_async(&send_value, MsgSize);
179       case CommType::EAGER_INIT:
180         return mbox_eager->put_init(&send_value, MsgSize);
181       case CommType::RDV_SYNC:
182         mbox_rdv->put(&send_value, MsgSize);
183         return nullptr;
184       case CommType::RDV_ASYNC:
185         return mbox_rdv->put_async(&send_value, MsgSize);
186       case CommType::RDV_INIT:
187         return mbox_rdv->put_init(&send_value, MsgSize);
188       case CommType::ONESIDE_SYNC:
189         sg4::Comm::sendto(sg4::this_actor::get_host(), other_host, MsgSize);
190         return nullptr;
191       case CommType::ONESIDE_ASYNC:
192         return sg4::Comm::sendto_async(sg4::this_actor::get_host(), other_host, MsgSize);
193       case CommType::ONESIDE_INIT:
194         return sg4::Comm::sendto_init()->set_payload_size(MsgSize);
195         // FIXME: how to set hosts? sg4::this_actor::get_host(),other_host
196     }
197     return nullptr;
198   }
199
200   void send_message(const Scenario& s)
201   {
202     std::string scenario_string = to_string(s);
203      XBT_DEBUG("Will try: %s", scenario_string.c_str());
204     double send_value;
205     sg4::CommPtr comm = nullptr;
206     // CommType type=s.type;
207     Action expected = s.snd_expected;
208     double end_time = s.start_time + s.duration;
209     // double curr_rel_time=0;
210     send_value        = end_time;
211     size_t step_index = 0;
212
213     sg4::this_actor::sleep_until(s.start_time);
214     for (; step_index < s.steps.size(); step_index++) {
215       const Step& step = s.steps[step_index];
216       if (step.entity != Step::SND || step.type != Step::ACTION)
217         continue;
218
219       try {
220         sg4::this_actor::sleep_until(s.start_time + step.rel_time);
221       } catch (std::exception& e) {
222         XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what());
223         break;
224       }
225
226       // Check if the other host is still OK.
227       if (not other_host->is_on())
228         break;
229
230       // Perform the action
231       try {
232         switch (step.action_type) {
233           case Action::PUT:
234             comm=do_put(s.type, send_value);
235             break;
236           case Action::START:
237             comm->start();
238             break;
239           case Action::WAIT:
240             comm->wait();
241             break;
242           default:
243             xbt_die("Not a valid action for SND");
244         }
245       } catch (std::exception& e) {
246         XBT_DEBUG("During %s, failed to send message because of a %s exception (%s)", to_string(step.action_type),
247                   typeid(e).name(), e.what());
248         break;
249       }
250
251       //xbt_assert(comm->get_impl()->get_refcount()==1);
252     }
253
254     try {
255       sg4::this_actor::sleep_until(end_time);
256     } catch (std::exception& e) {
257       XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what());
258     }
259
260     Action outcome              = Action::END;
261     if (step_index < s.steps.size()) {
262       const Step& step = s.steps[step_index];
263       assert(step.entity == Step::SND && step.type == Step::ACTION);
264       outcome = step.action_type;
265     }
266
267     if (outcome != expected) {
268       XBT_ERROR("Expected %s but got %s in %s", to_string(expected), to_string(outcome), scenario_string.c_str());
269     } else {
270       XBT_DEBUG("OK: %s", scenario_string.c_str());
271     }
272     sg4::this_actor::sleep_until(end_time);
273
274     xbt_assert(not mbox_eager->listen(), "Mailbox should not have ongoing communication!");
275     xbt_assert(not mbox_rdv->listen(), "Mailbox should not have ongoing communication!");
276
277   }
278
279 public:
280   explicit SendAgent(int id, sg4::Host* other_host) : id(id), other_host(other_host) {}
281
282   void operator()()
283   {
284     run++;
285     XBT_DEBUG("Host %i starts run %i and scenario %lu.", id, run, scenario);
286     while (scenario < scenarios.size()) {
287       Scenario& s = scenarios[scenario];
288       scenario++;
289       send_message(s);
290     }
291   }
292 };
293
294 int SendAgent::run         = 0;
295 size_t SendAgent::scenario = 0;
296
297 /*************************************************************************************************/
298
299 class ReceiveAgent {
300
301   static int run;
302   static size_t scenario;
303
304   int id;
305   sg4::Host* other_host;
306
307   sg4::CommPtr do_get(CommType type, double*& receive_ptr)
308   {
309     switch (type) {
310       case CommType::EAGER_SYNC:
311         receive_ptr = mbox_eager->get<double>();
312         return nullptr;
313       case CommType::EAGER_ASYNC:
314         return mbox_eager->get_async(&receive_ptr);
315       case CommType::EAGER_INIT:
316         return mbox_eager->get_init()->set_dst_data((void**)(&receive_ptr));
317
318       case CommType::RDV_SYNC:
319         receive_ptr = mbox_rdv->get<double>();
320         return nullptr;
321       case CommType::RDV_ASYNC:
322         return mbox_rdv->get_async(&receive_ptr);
323       case CommType::RDV_INIT:
324         return mbox_rdv->get_init()->set_dst_data((void**)(&receive_ptr));
325
326       case CommType::ONESIDE_SYNC:
327       case CommType::ONESIDE_ASYNC:
328       case CommType::ONESIDE_INIT:
329         xbt_die("No get in One Sided comunications!");
330     }
331     return nullptr;
332   }
333
334   void receive_message(const Scenario& s)
335   {
336     sg4::CommPtr comm = nullptr;
337     CommType type     = s.type;
338     Action expected   = s.rcv_expected;
339     double end_time   = s.start_time + s.duration;
340     // double curr_rel_time=0;
341     double* receive_ptr = nullptr;
342     size_t step_index   = 0;
343     sg4::this_actor::sleep_until(s.start_time);
344     for (; step_index < s.steps.size(); step_index++) {
345       const Step& step = s.steps[step_index];
346       if (step.entity != Step::RCV || step.type != Step::ACTION)
347         continue;
348
349       try {
350         sg4::this_actor::sleep_until(s.start_time + step.rel_time);
351       } catch (std::exception& e) {
352         XBT_DEBUG("During Sleep, failed to receive message because of a %s exception (%s)", typeid(e).name(), e.what());
353         break;
354       }
355
356       // Check if the other host is still OK.
357       if (not other_host->is_on())
358         break;
359
360       // Perform the action
361       try {
362         switch (step.action_type) {
363           case Action::GET:
364             comm = do_get(type, receive_ptr);
365             break;
366           case Action::START:
367             comm->start();
368             break;
369           case Action::WAIT:
370             comm->wait();
371             break;
372           default:
373             xbt_die("Not a valid action for RCV");
374         }
375       } catch (std::exception& e) {
376         XBT_DEBUG("During %s, failed to receive message because of a %s exception (%s)", to_string(step.action_type),
377                   typeid(e).name(), e.what());
378         break;
379       }
380     }
381
382     try {
383       sg4::this_actor::sleep_until(end_time - .1);
384     } catch (std::exception& e) {
385       XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what());
386     }
387
388     Action outcome              = Action::END;
389     std::string scenario_string = to_string(s);
390     if (step_index < s.steps.size()) {
391       const Step& step = s.steps[step_index];
392       assert(step.entity == Step::RCV && step.type == Step::ACTION);
393       outcome = step.action_type;
394     } else if (receive_ptr == nullptr) {
395       XBT_ERROR("Received address is NULL in %s", scenario_string.c_str());
396     } else if (*receive_ptr != end_time) {
397       XBT_ERROR("Received value invalid: expected %f but got %f in %s", end_time, *receive_ptr,
398                 scenario_string.c_str());
399     }
400
401     if (outcome != expected) {
402       XBT_ERROR("Expected %s but got %s in %s", to_string(expected), to_string(outcome), scenario_string.c_str());
403     } else {
404       XBT_DEBUG("OK: %s", scenario_string.c_str());
405     }
406     sg4::this_actor::sleep_until(end_time);
407
408     xbt_assert(not mbox_eager->listen(), "Mailbox should not have ongoing communication!");
409     xbt_assert(not mbox_rdv->listen(), "Mailbox should not have ongoing communication!");
410
411   }
412
413 public:
414   explicit ReceiveAgent(int id, sg4::Host* other_host) : id(id), other_host(other_host) {}
415
416   void operator()()
417   {
418     run++;
419     XBT_DEBUG("Host %i starts run %i and scenario %lu.", id, run, scenario);
420     mbox_eager->set_receiver(sg4::Actor::self());
421     while (scenario < scenarios.size()) {
422       Scenario& s = scenarios[scenario];
423       scenario++;
424       receive_message(s);
425     }
426   }
427 };
428
429 int ReceiveAgent::run         = 0;
430 size_t ReceiveAgent::scenario = 0;
431
432 /*************************************************************************************************/
433
434 static void on_host_state_change(sg4::Host const& host)
435 {
436   XBT_DEBUG("Host %s is now %s", host.get_cname(), host.is_on() ? "ON " : "OFF");
437   if(host.is_on()) {
438     mbox_eager->clear();
439     mbox_rdv->clear();
440   }
441 }
442
443 static void on_link_state_change(sg4::Link const& link)
444 {
445   XBT_DEBUG("Link %s is now %s", link.get_cname(), link.is_on() ? "ON " : "OFF");
446 }
447
448 static void addStateEvent(std::ostream& out, double date, bool isOn)
449 {
450   if (isOn)
451     out << date << " 1\n";
452   else
453     out << date << " 0\n";
454 }
455
456 static int prepareScenario(CommType type, int& index, double& start_time, double duration, std::ostream& sndP, std::ostream& rcvP,
457                             std::ostream& lnkP, Action snd_expected, Action rcv_expected, std::vector<Step> steps, std::vector<int> active_indices)
458 {
459
460   int ret=0;
461   if(std::find(active_indices.begin(),active_indices.end(),index)!=active_indices.end()) {
462     // Update fault profiles
463     for (Step& step : steps) {
464       assert(step.rel_time < duration);
465       if (step.type != Step::STATE)
466         continue;
467       int val = step.new_state ? 1 : 0;
468       switch (step.entity) {
469         case Step::SND:
470           sndP << start_time + step.rel_time << " " << val << std::endl;
471           break;
472         case Step::RCV:
473           rcvP << start_time + step.rel_time << " " << val << std::endl;
474           break;
475         case Step::LNK:
476           lnkP << start_time + step.rel_time << " " << val << std::endl;
477           break;
478       }
479     }
480     scenarios.push_back({type, start_time, duration, snd_expected, rcv_expected, steps, index}); 
481     ret=1;
482   }
483   index++;
484   start_time += duration;
485   return ret;
486 }
487
488 /*************************************************************************************************/
489
490 // State profiles for the resources
491 std::string SndStateProfile;
492 std::string RcvStateProfile;
493 std::string LnkStateProfile;
494
495 /*************************************************************************************************/
496
497 double build_scenarios(std::vector<int>& active_indices );
498
499 int main(int argc, char* argv[])
500 {
501
502   sg4::Engine e(&argc, argv);
503
504   std::vector<int> active_indices;
505   //Parse index of tests that need to be run
506
507   int previous_index=-1;
508   bool is_range_last=false;
509   for(int i=1; i<argc; i++) {
510     if(not strcmp(argv[i],"-"))
511       is_range_last=true;
512     else {
513       int index=atoi(argv[i]);
514       xbt_assert(index>previous_index);
515       if(is_range_last) 
516         for(int j=previous_index+1;j<=index;j++)
517           active_indices.push_back(j);
518       else
519          active_indices.push_back(index);
520        is_range_last=false;
521        previous_index=index;
522     }
523   }
524
525   double end_time = build_scenarios(active_indices);
526
527   XBT_INFO("Will run for %f seconds", end_time);
528
529
530   mbox_eager = e.mailbox_by_name_or_create("eager");
531   mbox_rdv   = e.mailbox_by_name_or_create("rdv");
532
533   sg4::NetZone* zone = sg4::create_full_zone("Top");
534
535   pr::Profile* profile_sender = pr::ProfileBuilder::from_string("sender_profile", SndStateProfile, 0);
536   sg4::Host* sender_host = zone->create_host("senderHost", HostComputePower)->set_state_profile(profile_sender)->seal();
537   pr::Profile* profile_receiver = pr::ProfileBuilder::from_string("receiver_profile", RcvStateProfile, 0);
538   sg4::Host* receiver_host = zone->create_host("receiverHost", HostComputePower)->set_state_profile(profile_receiver)->seal();
539
540   sg4::ActorPtr sender = sg4::Actor::create("sender", sender_host, SendAgent(0, receiver_host));
541   sender->set_auto_restart(true);
542
543   sg4::ActorPtr receiver = sg4::Actor::create("receiver", receiver_host, ReceiveAgent(1, sender_host));
544   receiver->set_auto_restart(true);
545
546   pr::Profile* profile_link = pr::ProfileBuilder::from_string("link_profile", LnkStateProfile, 0);
547   sg4::Link* link =
548       zone->create_link("link", LinkBandwidth)->set_latency(LinkLatency)->set_state_profile(profile_link)->seal();
549
550   zone->add_route(sender_host->get_netpoint(), receiver_host->get_netpoint(), nullptr, nullptr,
551                   {sg4::LinkInRoute{link}}, false);
552   zone->seal();
553
554   sg4::Host::on_state_change.connect(on_host_state_change);
555   sg4::Link::on_state_change_cb(on_link_state_change);
556
557   e.run_until(end_time);
558
559   return 0;
560 }
561
562 /*************************************************************************************************/
563
564 // A bunch of dirty macros to help readability (supposedly)
565 #define _MK(type, duration, snd_expected, rcv_expected, steps...)                                                      \
566   active+=prepareScenario(CommType::type, index, start_time, duration, sndP, rcvP, lnkP, Action::snd_expected, Action::rcv_expected,  \
567                   {steps}, active_indices )
568 // Link
569 #define LOFF(relTime)                                                                                                  \
570   {                                                                                                                    \
571     relTime, Step::STATE, Step::LNK, Action::END, false                                                                \
572   }
573 #define LON(relTime)                                                                                                   \
574   {                                                                                                                    \
575     relTime, Step::STATE, Step::LNK, Action::END, true                                                                 \
576   }
577 // Sender
578 #define SOFF(relTime)                                                                                                  \
579   {                                                                                                                    \
580     relTime, Step::STATE, Step::SND, Action::END, false                                                                \
581   }
582 #define SON(relTime)                                                                                                   \
583   {                                                                                                                    \
584     relTime, Step::STATE, Step::SND, Action::END, true                                                                 \
585   }
586 #define SPUT(relTime)                                                                                                  \
587   {                                                                                                                    \
588     relTime, Step::ACTION, Step::SND, Action::PUT, false                                                               \
589   }
590 #define SWAT(relTime)                                                                                                  \
591   {                                                                                                                    \
592     relTime, Step::ACTION, Step::SND, Action::WAIT, false                                                              \
593   }
594 // Receiver
595 #define ROFF(relTime)                                                                                                  \
596   {                                                                                                                    \
597     relTime, Step::STATE, Step::RCV, Action::END, false                                                                \
598   }
599 #define RON(relTime)                                                                                                   \
600   {                                                                                                                    \
601     relTime, Step::STATE, Step::RCV, Action::END, true                                                                 \
602   }
603 #define RGET(relTime)                                                                                                  \
604   {                                                                                                                    \
605     relTime, Step::ACTION, Step::RCV, Action::GET, false                                                               \
606   }
607 #define RWAT(relTime)                                                                                                  \
608   {                                                                                                                    \
609     relTime, Step::ACTION, Step::RCV, Action::WAIT, false                                                              \
610   }
611
612 double build_scenarios(std::vector<int>& active_indices )
613 {
614
615   // Build the set of simulation stages
616   std::stringstream sndP;
617   std::stringstream rcvP;
618   std::stringstream lnkP;
619
620   double start_time = 0;
621   int index=0;
622   int active=0;
623
624   // EAGER SYNC use cases
625   // All good
626   _MK(EAGER_SYNC, 1, END, END, SPUT(.2), RGET(.4));
627   _MK(EAGER_SYNC, 1, END, END, RGET(.2), SPUT(.4));
628   // Receiver off
629   _MK(EAGER_SYNC, 2, PUT, DIE, ROFF(.1), SPUT(.2), RON(1));
630   _MK(EAGER_SYNC, 2, PUT, DIE, SPUT(.2), ROFF(.3), RON(1));
631   _MK(EAGER_SYNC, 2, PUT, DIE, SPUT(.2), RGET(.4), ROFF(.5), RON(1));
632   _MK(EAGER_SYNC, 2, PUT, DIE, RGET(.2), SPUT(.4), ROFF(.5), RON(1));
633   // Sender off
634   _MK(EAGER_SYNC, 2, DIE, GET, SPUT(.2), SOFF(.3), RGET(.4), SON(1));
635   _MK(EAGER_SYNC, 2, DIE, GET, SPUT(.2), RGET(.4), SOFF(.5), SON(1));
636   // Link off
637   _MK(EAGER_SYNC, 2, PUT, GET, LOFF(.1), SPUT(.2), RGET(.4), LON(1));
638   _MK(EAGER_SYNC, 2, PUT, GET, SPUT(.2), LOFF(.3), RGET(.4), LON(1));
639   _MK(EAGER_SYNC, 2, PUT, GET, SPUT(.2), RGET(.4), LOFF(.5), LON(1));
640   _MK(EAGER_SYNC, 2, PUT, GET, LOFF(.1), RGET(.2), SPUT(.4), LON(1));
641   _MK(EAGER_SYNC, 2, PUT, GET, RGET(.2), LOFF(.3), SPUT(.4), LON(1));
642   _MK(EAGER_SYNC, 2, PUT, GET, RGET(.2), SPUT(.4), LOFF(.5), LON(1));
643
644   // EAGER ASYNC use cases
645   // All good
646   _MK(EAGER_ASYNC, 2, END, END, SPUT(.2), SWAT(.4), RGET(.6), RWAT(.8));
647   _MK(EAGER_ASYNC, 2, END, END, SPUT(.2), RGET(.4), SWAT(.6), RWAT(.8));
648   _MK(EAGER_ASYNC, 2, END, END, SPUT(.2), RGET(.4), RWAT(.6), SWAT(.8));
649   _MK(EAGER_ASYNC, 2, END, END, RGET(.2), SPUT(.4), SWAT(.6), RWAT(.8));
650   _MK(EAGER_ASYNC, 2, END, END, RGET(.2), SPUT(.4), RWAT(.6), SWAT(.8));
651   _MK(EAGER_ASYNC, 2, END, END, RGET(.2), RWAT(.4), SPUT(.6), SWAT(.8));
652   
653   // Receiver off
654   _MK(EAGER_ASYNC, 2, PUT, DIE, ROFF(.1), SPUT(.2), SWAT(.4), RON(1));
655   _MK(EAGER_ASYNC, 2, WAIT, DIE, SPUT(.2), ROFF(.3), SWAT(.4), RON(1));
656   _MK(EAGER_ASYNC, 2, PUT, DIE, RGET(.2), ROFF(.3), SPUT(.4), SWAT(.6), RON(1));
657   _MK(EAGER_ASYNC, 2, WAIT, DIE, SPUT(.2), SWAT(.4), ROFF(.5), RON(1));
658   _MK(EAGER_ASYNC, 2, WAIT, DIE, SPUT(.2), RGET(.4), ROFF(.5), SWAT(.6), RON(1));
659   _MK(EAGER_ASYNC, 2, WAIT, DIE, RGET(.2), SPUT(.4), ROFF(.5), SWAT(.6), RON(1));
660   _MK(EAGER_ASYNC, 2, PUT , DIE, RGET(.2), RWAT(.4), ROFF(.5), SPUT(.6), SWAT(.8), RON(1));
661   _MK(EAGER_ASYNC, 2, WAIT, DIE, SPUT(.2), SWAT(.4), RGET(.6), ROFF(.7), RON(1));
662   _MK(EAGER_ASYNC, 2, WAIT, DIE, SPUT(.2), RGET(.4), SWAT(.6), ROFF(.7), RON(1));
663   _MK(EAGER_ASYNC, 2, WAIT, DIE, SPUT(.2), RGET(.4), RWAT(.6), ROFF(.7), SWAT(.8), RON(1));
664   _MK(EAGER_ASYNC, 2, WAIT, DIE, RGET(.2), SPUT(.4), SWAT(.6), ROFF(.7), RON(1));
665   _MK(EAGER_ASYNC, 2, WAIT, DIE, RGET(.2), SPUT(.4), RWAT(.6), ROFF(.7), SWAT(.8), RON(1));
666   _MK(EAGER_ASYNC, 2, WAIT, DIE, RGET(.2), RWAT(.4), SPUT(.6), ROFF(.7), SWAT(.8), RON(1));
667   // Sender off (only cases where sender did put, because otherwise receiver cannot find out there was a fault)
668   _MK(EAGER_ASYNC, 2, DIE, GET, SPUT(.2), SOFF(.3), RGET(.4), RWAT(.6), SON(1));
669   _MK(EAGER_ASYNC, 2, DIE, WAIT, RGET(.2), SPUT(.4), SOFF(.5), RWAT(.6), SON(1));
670   _MK(EAGER_ASYNC, 2, DIE, WAIT, SPUT(.2), RGET(.4), SOFF(.5), RWAT(.6), SON(1));
671   _MK(EAGER_ASYNC, 2, DIE, GET, SPUT(.2), SWAT(.4), SOFF(.5), RGET(.6), RWAT(.8), SON(1));
672   _MK(EAGER_ASYNC, 2, DIE, WAIT, RGET(.2), RWAT(.4), SPUT(.6), SOFF(.7), SON(1));
673   _MK(EAGER_ASYNC, 2, DIE, WAIT, RGET(.2), SPUT(.4), RWAT(.6), SOFF(.7), SON(1));
674   _MK(EAGER_ASYNC, 2, DIE, WAIT, RGET(.2), SPUT(.4), SWAT(.6), SOFF(.7), RWAT(.8), SON(1));
675   _MK(EAGER_ASYNC, 2, DIE, WAIT, SPUT(.2), RGET(.4), RWAT(.6), SOFF(.7), SON(1));
676   _MK(EAGER_ASYNC, 2, DIE, WAIT, SPUT(.2), RGET(.4), SWAT(.6), SOFF(.7), RWAT(.8), SON(1));
677   _MK(EAGER_ASYNC, 2, DIE, WAIT, SPUT(.2), SWAT(.4), RGET(.6), SOFF(.7), RWAT(.8), SON(1));
678   // Link off
679   _MK(EAGER_ASYNC, 2, WAIT, WAIT, LOFF(.1), SPUT(.2), SWAT(.4), RGET(.6), RWAT(.8), LON(1));
680   _MK(EAGER_ASYNC, 2, WAIT, WAIT, LOFF(.1), SPUT(.2), RGET(.4), SWAT(.6), RWAT(.8), LON(1));
681   _MK(EAGER_ASYNC, 2, WAIT, WAIT, LOFF(.1), SPUT(.2), RGET(.4), RWAT(.6), SWAT(.8), LON(1));
682   _MK(EAGER_ASYNC, 2, WAIT, WAIT, LOFF(.1), RGET(.2), SPUT(.4), SWAT(.6), RWAT(.8), LON(1));
683   _MK(EAGER_ASYNC, 2, WAIT, WAIT, LOFF(.1), RGET(.2), SPUT(.4), RWAT(.6), SWAT(.8), LON(1));
684   _MK(EAGER_ASYNC, 2, WAIT, WAIT, LOFF(.1), RGET(.2), RWAT(.4), SPUT(.6), SWAT(.8), LON(1));
685   _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), LOFF(.3), SWAT(.4), RGET(.6), RWAT(.8), LON(1));
686   _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), LOFF(.3), RGET(.4), SWAT(.6), RWAT(.8), LON(1));
687   _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), LOFF(.3), RGET(.4), RWAT(.6), SWAT(.8), LON(1));
688   _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), LOFF(.3), SPUT(.4), SWAT(.6), RWAT(.8), LON(1));
689   _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), LOFF(.3), SPUT(.4), RWAT(.6), SWAT(.8), LON(1));
690   _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), LOFF(.3), RWAT(.4), SPUT(.6), SWAT(.8), LON(1));
691   _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), SWAT(.4), LOFF(.5), RGET(.6), RWAT(.8), LON(1));
692   _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), LOFF(.5), SWAT(.6), RWAT(.8), LON(1));
693   _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), LOFF(.5), RWAT(.6), SWAT(.8), LON(1));
694   _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), LOFF(.5), SWAT(.6), RWAT(.8), LON(1));
695   _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), LOFF(.5), RWAT(.6), SWAT(.8), LON(1));
696   _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), RWAT(.4), LOFF(.5), SPUT(.6), SWAT(.8), LON(1));
697   _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), SWAT(.4), RGET(.6), LOFF(.7), RWAT(.8), LON(1));
698   _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), SWAT(.6), LOFF(.7), RWAT(.8), LON(1));
699   _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), RWAT(.6), LOFF(.7), SWAT(.8), LON(1));
700   _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), SWAT(.6), LOFF(.7), RWAT(.8), LON(1));
701   _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), RWAT(.6), LOFF(.7), SWAT(.8), LON(1));
702   _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), RWAT(.4), SPUT(.6), LOFF(.7), SWAT(.8), LON(1));
703
704   // RDV SYNC use cases
705
706   // All good
707   _MK(RDV_SYNC, 1, END, END, SPUT(.2), RGET(.4));
708   _MK(RDV_SYNC, 1, END, END, RGET(.2), SPUT(.4));
709   
710   // Receiver off
711   _MK(RDV_SYNC, 2, PUT, DIE, ROFF(.1), SPUT(.2), RON(1));
712   _MK(RDV_SYNC, 2, PUT, DIE, SPUT(.2), ROFF(.3), RON(1));
713   _MK(RDV_SYNC, 2, PUT, DIE, SPUT(.2), RGET(.4), ROFF(.5), RON(1));
714   _MK(RDV_SYNC, 2, PUT, DIE, RGET(.2), SPUT(.4), ROFF(.5), RON(1));
715   // Sender off
716   _MK(RDV_SYNC, 2, DIE, GET, SPUT(.2), RGET(.4), SOFF(.5), SON(1));
717   // Link off
718   _MK(RDV_SYNC, 2, PUT, GET, LOFF(.1), SPUT(.2), RGET(.4), LON(1));
719   _MK(RDV_SYNC, 2, PUT, GET, SPUT(.2), LOFF(.3), RGET(.4), LON(1));
720   _MK(RDV_SYNC, 2, PUT, GET, SPUT(.2), RGET(.4), LOFF(.5), LON(1));
721   _MK(RDV_SYNC, 2, PUT, GET, LOFF(.1), RGET(.2), SPUT(.4), LON(1));
722   _MK(RDV_SYNC, 2, PUT, GET, RGET(.2), LOFF(.3), SPUT(.4), LON(1));
723   _MK(RDV_SYNC, 2, PUT, GET, RGET(.2), SPUT(.4), LOFF(.5), LON(1));
724
725   // RDV ASYNC use cases
726   // All good
727   _MK(RDV_ASYNC, 2, END, END, SPUT(.2), SWAT(.4), RGET(.6), RWAT(.8));
728   _MK(RDV_ASYNC, 2, END, END, SPUT(.2), RGET(.4), SWAT(.6), RWAT(.8));
729   _MK(RDV_ASYNC, 2, END, END, SPUT(.2), RGET(.4), RWAT(.6), SWAT(.8));
730   _MK(RDV_ASYNC, 2, END, END, RGET(.2), SPUT(.4), SWAT(.6), RWAT(.8));
731   _MK(RDV_ASYNC, 2, END, END, RGET(.2), SPUT(.4), RWAT(.6), SWAT(.8));
732   _MK(RDV_ASYNC, 2, END, END, RGET(.2), RWAT(.4), SPUT(.6), SWAT(.8));
733   // Receiver off
734   _MK(RDV_ASYNC, 2, PUT, DIE, ROFF(.1), SPUT(.2), SWAT(.4), RON(1));
735   _MK(RDV_ASYNC, 2, WAIT, DIE, SPUT(.2), ROFF(.3), SWAT(.4), RON(1));
736   _MK(RDV_ASYNC, 2, PUT, DIE, RGET(.2), ROFF(.3), SPUT(.4), SWAT(.6), RON(1));
737   _MK(RDV_ASYNC, 2, WAIT, DIE, SPUT(.2), SWAT(.4), ROFF(.5), RON(1));
738   _MK(RDV_ASYNC, 2, WAIT, DIE, SPUT(.2), RGET(.4), ROFF(.5), SWAT(.6), RON(1));
739   _MK(RDV_ASYNC, 2, WAIT, DIE, RGET(.2), SPUT(.4), ROFF(.5), SWAT(.6), RON(1));
740   _MK(RDV_ASYNC, 2, PUT , DIE, RGET(.2), RWAT(.4), ROFF(.5), SPUT(.6), SWAT(.8), RON(1));
741   _MK(RDV_ASYNC, 2, WAIT, DIE, SPUT(.2), SWAT(.4), RGET(.6), ROFF(.7), RON(1));
742   _MK(RDV_ASYNC, 2, WAIT, DIE, SPUT(.2), RGET(.4), SWAT(.6), ROFF(.7), RON(1));
743   _MK(RDV_ASYNC, 2, WAIT, DIE, SPUT(.2), RGET(.4), RWAT(.6), ROFF(.7), SWAT(.8), RON(1));
744   _MK(RDV_ASYNC, 2, WAIT, DIE, RGET(.2), SPUT(.4), SWAT(.6), ROFF(.7), RON(1));
745   _MK(RDV_ASYNC, 2, WAIT, DIE, RGET(.2), SPUT(.4), RWAT(.6), ROFF(.7), SWAT(.8), RON(1));
746   _MK(RDV_ASYNC, 2, WAIT, DIE, RGET(.2), RWAT(.4), SPUT(.6), ROFF(.7), SWAT(.8), RON(1));
747   // Sender off (only cases where sender did put, because otherwise receiver cannot find out there was a fault)
748   _MK(RDV_ASYNC, 2, DIE, GET, SPUT(.2), SOFF(.3), RGET(.4), RWAT(.6), SON(1));
749   _MK(RDV_ASYNC, 2, DIE, WAIT, RGET(.2), SPUT(.4), SOFF(.5), RWAT(.6), SON(1));
750   _MK(RDV_ASYNC, 2, DIE, WAIT, SPUT(.2), RGET(.4), SOFF(.5), RWAT(.6), SON(1));
751   _MK(RDV_ASYNC, 2, DIE, GET, SPUT(.2), SWAT(.4), SOFF(.5), RGET(.6), RWAT(.8), SON(1));
752   _MK(RDV_ASYNC, 2, DIE, WAIT, RGET(.2), RWAT(.4), SPUT(.6), SOFF(.7), SON(1));
753   _MK(RDV_ASYNC, 2, DIE, WAIT, RGET(.2), SPUT(.4), RWAT(.6), SOFF(.7), SON(1));
754   _MK(RDV_ASYNC, 2, DIE, WAIT, RGET(.2), SPUT(.4), SWAT(.6), SOFF(.7), RWAT(.8), SON(1));
755   _MK(RDV_ASYNC, 2, DIE, WAIT, SPUT(.2), RGET(.4), RWAT(.6), SOFF(.7), SON(1));
756   _MK(RDV_ASYNC, 2, DIE, WAIT, SPUT(.2), RGET(.4), SWAT(.6), SOFF(.7), RWAT(.8), SON(1));
757   _MK(RDV_ASYNC, 2, DIE, WAIT, SPUT(.2), SWAT(.4), RGET(.6), SOFF(.7), RWAT(.8), SON(1));
758   // Link off
759   _MK(RDV_ASYNC, 2, WAIT, WAIT, LOFF(.1), SPUT(.2), SWAT(.4), RGET(.6), RWAT(.8), LON(1));
760   _MK(RDV_ASYNC, 2, WAIT, WAIT, LOFF(.1), SPUT(.2), RGET(.4), SWAT(.6), RWAT(.8), LON(1));
761   _MK(RDV_ASYNC, 2, WAIT, WAIT, LOFF(.1), SPUT(.2), RGET(.4), RWAT(.6), SWAT(.8), LON(1));
762   _MK(RDV_ASYNC, 2, WAIT, WAIT, LOFF(.1), RGET(.2), SPUT(.4), SWAT(.6), RWAT(.8), LON(1));
763   _MK(RDV_ASYNC, 2, WAIT, WAIT, LOFF(.1), RGET(.2), SPUT(.4), RWAT(.6), SWAT(.8), LON(1));
764   _MK(RDV_ASYNC, 2, WAIT, WAIT, LOFF(.1), RGET(.2), RWAT(.4), SPUT(.6), SWAT(.8), LON(1));
765   _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), LOFF(.3), SWAT(.4), RGET(.6), RWAT(.8), LON(1));
766   _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), LOFF(.3), RGET(.4), SWAT(.6), RWAT(.8), LON(1));
767   _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), LOFF(.3), RGET(.4), RWAT(.6), SWAT(.8), LON(1));
768   _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), LOFF(.3), SPUT(.4), SWAT(.6), RWAT(.8), LON(1));
769   _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), LOFF(.3), SPUT(.4), RWAT(.6), SWAT(.8), LON(1));
770   _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), LOFF(.3), RWAT(.4), SPUT(.6), SWAT(.8), LON(1));
771   _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), SWAT(.4), LOFF(.5), RGET(.6), RWAT(.8), LON(1));
772   _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), LOFF(.5), SWAT(.6), RWAT(.8), LON(1));
773   _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), LOFF(.5), RWAT(.6), SWAT(.8), LON(1));
774   _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), LOFF(.5), SWAT(.6), RWAT(.8), LON(1));
775   _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), LOFF(.5), RWAT(.6), SWAT(.8), LON(1));
776   _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), RWAT(.4), LOFF(.5), SPUT(.6), SWAT(.8), LON(1));
777   _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), SWAT(.4), RGET(.6), LOFF(.7), RWAT(.8), LON(1));
778   _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), SWAT(.6), LOFF(.7), RWAT(.8), LON(1));
779   _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), RWAT(.6), LOFF(.7), SWAT(.8), LON(1));
780   _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), SWAT(.6), LOFF(.7), RWAT(.8), LON(1));
781   _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), RWAT(.6), LOFF(.7), SWAT(.8), LON(1));
782   _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), RWAT(.4), SPUT(.6), LOFF(.7), SWAT(.8), LON(1));
783
784   // ONESIDE SYNC use cases
785
786   // All good
787   _MK(ONESIDE_SYNC, 1, END, END, SPUT(.2));
788   // Receiver off
789   _MK(ONESIDE_SYNC, 2, PUT, DIE, ROFF(.1), SPUT(.2), RON(1));
790   _MK(ONESIDE_SYNC, 2, PUT, DIE, SPUT(.2), ROFF(.3), RON(1));
791   // Link off
792   _MK(ONESIDE_SYNC, 2, PUT, GET, LOFF(.1), SPUT(.2), LON(1));
793   _MK(ONESIDE_SYNC, 2, PUT, GET, SPUT(.2), LOFF(.3), LON(1));
794
795   // ONESIDE ASYNC use cases
796   // All good
797   _MK(ONESIDE_ASYNC, 2, END, END, SPUT(.2), SWAT(.4));
798   // Receiver off
799   _MK(ONESIDE_ASYNC, 2, PUT, DIE, ROFF(.1), SPUT(.2), SWAT(.4), RON(1));
800   _MK(ONESIDE_ASYNC, 2, WAIT, DIE, SPUT(.2), ROFF(.3), SWAT(.4), RON(1));
801   _MK(ONESIDE_ASYNC, 2, WAIT, DIE, SPUT(.2), SWAT(.4), ROFF(.5), RON(1));
802   // Link off
803   _MK(ONESIDE_ASYNC, 2, WAIT, WAIT, LOFF(.1), SPUT(.2), SWAT(.4), LON(1));
804   _MK(ONESIDE_ASYNC, 2, WAIT, WAIT, SPUT(.2), LOFF(.3), SWAT(.4), LON(1));
805   _MK(ONESIDE_ASYNC, 2, WAIT, WAIT, SPUT(.2), SWAT(.4), LOFF(.5), LON(1));
806
807
808   SndStateProfile = sndP.str();
809   RcvStateProfile = rcvP.str();
810   LnkStateProfile = lnkP.str();
811
812   XBT_INFO("Will execute %i active scenarios out of %i.",active,index);
813   return start_time + 1;
814 }