1 /* Copyright (c) 2010-2021. The SimGrid Team. All rights reserved. */
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. */
6 /* This example validates the behaviour in presence of node and link fault.
7 * Each test scenario consists in one host/actor (named sender) sending one message to another host/actor.
8 * The space to cover is quite large, since we consider:
9 * * communication types (eager, rendez-vous, one-sided=detached)
10 * * use type (synchronous, asynchronous, init)
11 * * fault type (sender node, link, receiver node)
12 * * any legal permutation of the scenario steps
14 * This program also presents a way to simulate applications that are resilient to links and node faults.
15 * Essentially, it catches exceptions related to communications and it clears the mailboxes when one of the nodes gets turned off.
16 * However, this model would suppose that there would be 2 mailboxes for each pair of nodes, which is probably unacceptable.
22 #include <simgrid/kernel/ProfileBuilder.hpp>
23 #include <simgrid/s4u.hpp>
28 namespace sg4 = simgrid::s4u;
29 namespace pr = simgrid::kernel::profile;
31 XBT_LOG_NEW_DEFAULT_CATEGORY(comm_fault_scenarios, "Messages specific for this s4u example");
33 /*************************************************************************************************/
35 // Constants for platform configuration
36 constexpr double HostComputePower = 1e9; // FLOPs
37 constexpr double LinkBandwidth = 1e9; // Bytes/second
38 constexpr double LinkLatency = 1e-6; // Seconds
40 // Constants for application behaviour
41 constexpr uint64_t MsgSize = LinkBandwidth / 2;
43 /*************************************************************************************************/
54 //ONESIDE_INIT is equivalent to ONESIDE_ASYNC
57 enum class Action { SLEEP, PUT, GET, START, WAIT, DIE, END };
59 static const char* to_string(const Action x)
81 double rel_time; // Time relative to Scenario startTime
82 enum { STATE, ACTION } type;
83 enum { LNK, SND, RCV } entity;
94 std::vector<Step> steps;
98 static std::string to_string(const Scenario& s)
100 std::stringstream ss;
101 ss <<"#"<< s.index << "[" << s.start_time << "s," << s.start_time + s.duration << "s[: (";
103 case CommType::EAGER_SYNC:
106 case CommType::EAGER_ASYNC:
109 case CommType::EAGER_INIT:
112 case CommType::RDV_SYNC:
115 case CommType::RDV_ASYNC:
118 case CommType::RDV_INIT:
121 case CommType::ONESIDE_SYNC:
122 ss << "ONESIDE_SYNC";
124 case CommType::ONESIDE_ASYNC:
125 ss << "ONESIDE_ASYNC";
129 ss << ") Expected: S:" << to_string(s.snd_expected) << " R:" << to_string(s.rcv_expected) << " Steps: ";
130 for (const Step& step : s.steps) {
131 ss << "+" << step.rel_time << "s:";
132 switch (step.entity) {
144 if (step.type == Step::STATE) {
151 ss << "." << to_string(step.action_type);
155 return ss.str().c_str();
158 std::vector<Scenario> scenarios;
159 sg4::Mailbox* mbox_eager = nullptr;
160 sg4::Mailbox* mbox_rdv = nullptr;
165 static size_t scenario;
167 sg4::Host* other_host;
169 sg4::CommPtr do_put(CommType type, double& send_value)
172 case CommType::EAGER_SYNC:
173 mbox_eager->put(&send_value, MsgSize);
175 case CommType::EAGER_ASYNC:
176 return mbox_eager->put_async(&send_value, MsgSize);
177 case CommType::EAGER_INIT:
178 return mbox_eager->put_init(&send_value, MsgSize);
179 case CommType::RDV_SYNC:
180 mbox_rdv->put(&send_value, MsgSize);
182 case CommType::RDV_ASYNC:
183 return mbox_rdv->put_async(&send_value, MsgSize);
184 case CommType::RDV_INIT:
185 return mbox_rdv->put_init(&send_value, MsgSize);
186 case CommType::ONESIDE_SYNC:
187 sg4::Comm::sendto(sg4::this_actor::get_host(), other_host, MsgSize);
189 case CommType::ONESIDE_ASYNC:
190 return sg4::Comm::sendto_async(sg4::this_actor::get_host(), other_host, MsgSize);
195 void send_message(const Scenario& s)
197 std::string scenario_string = to_string(s);
198 XBT_DEBUG("Will try: %s", scenario_string.c_str());
200 sg4::CommPtr comm = nullptr;
201 Action expected = s.snd_expected;
202 double end_time = s.start_time + s.duration;
203 send_value = end_time;
204 size_t step_index = 0;
206 sg4::this_actor::sleep_until(s.start_time);
208 //Make sure we have a clean slate
209 xbt_assert(not mbox_eager->listen(),"Eager mailbox should be empty when starting a test");
210 xbt_assert(not mbox_rdv->listen(),"RDV mailbox should be empty when starting a test");
212 for (; step_index < s.steps.size(); step_index++) {
213 const Step& step = s.steps[step_index];
214 if (step.entity != Step::SND || step.type != Step::ACTION)
218 sg4::this_actor::sleep_until(s.start_time + step.rel_time);
219 } catch (std::exception& e) {
220 XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what());
224 // Check if the other host is still OK.
225 if (not other_host->is_on())
228 // Perform the action
230 switch (step.action_type) {
232 comm=do_put(s.type, send_value);
241 xbt_die("Not a valid action for SND");
243 } catch (std::exception& e) {
244 XBT_DEBUG("During %s, failed to send message because of a %s exception (%s)", to_string(step.action_type),
245 typeid(e).name(), e.what());
251 sg4::this_actor::sleep_until(end_time);
252 } catch (std::exception& e) {
253 XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what());
256 Action outcome = Action::END;
257 if (step_index < s.steps.size()) {
258 const Step& step = s.steps[step_index];
259 assert(step.entity == Step::SND && step.type == Step::ACTION);
260 outcome = step.action_type;
263 if (outcome != expected) {
264 XBT_ERROR("Expected %s but got %s in %s", to_string(expected), to_string(outcome), scenario_string.c_str());
266 XBT_DEBUG("OK: %s", scenario_string.c_str());
268 sg4::this_actor::sleep_until(end_time);
270 xbt_assert(not mbox_eager->listen(), "Mailbox should not have ongoing communication!");
271 xbt_assert(not mbox_rdv->listen(), "Mailbox should not have ongoing communication!");
276 explicit SendAgent(int id, sg4::Host* other_host) : id(id), other_host(other_host) {}
281 XBT_DEBUG("Host %i starts run %i and scenario %lu.", id, run, scenario);
282 while (scenario < scenarios.size()) {
283 Scenario& s = scenarios[scenario];
290 int SendAgent::run = 0;
291 size_t SendAgent::scenario = 0;
293 /*************************************************************************************************/
298 static size_t scenario;
300 sg4::Host* other_host;
302 sg4::CommPtr do_get(CommType type, double*& receive_ptr)
305 case CommType::EAGER_SYNC:
306 receive_ptr = mbox_eager->get<double>();
308 case CommType::EAGER_ASYNC:
309 return mbox_eager->get_async(&receive_ptr);
310 case CommType::EAGER_INIT:
311 return mbox_eager->get_init()->set_dst_data((void**)(&receive_ptr));
312 case CommType::RDV_SYNC:
313 receive_ptr = mbox_rdv->get<double>();
315 case CommType::RDV_ASYNC:
316 return mbox_rdv->get_async(&receive_ptr);
317 case CommType::RDV_INIT:
318 return mbox_rdv->get_init()->set_dst_data((void**)(&receive_ptr));
319 case CommType::ONESIDE_SYNC:
320 case CommType::ONESIDE_ASYNC:
321 xbt_die("No get in One Sided comunications!");
326 void receive_message(const Scenario& s)
328 sg4::CommPtr comm = nullptr;
329 CommType type = s.type;
330 Action expected = s.rcv_expected;
331 double end_time = s.start_time + s.duration;
332 double* receive_ptr = nullptr;
333 size_t step_index = 0;
334 sg4::this_actor::sleep_until(s.start_time);
336 //Make sure we have a clean slate
337 xbt_assert(not mbox_eager->listen(),"Eager mailbox should be empty when starting a test");
338 xbt_assert(not mbox_rdv->listen(),"RDV mailbox should be empty when starting a test");
340 for (; step_index < s.steps.size(); step_index++) {
341 const Step& step = s.steps[step_index];
342 if (step.entity != Step::RCV || step.type != Step::ACTION)
346 sg4::this_actor::sleep_until(s.start_time + step.rel_time);
347 } catch (std::exception& e) {
348 XBT_DEBUG("During Sleep, failed to receive message because of a %s exception (%s)", typeid(e).name(), e.what());
352 // Check if the other host is still OK.
353 if (not other_host->is_on())
356 // Perform the action
358 switch (step.action_type) {
360 comm = do_get(type, receive_ptr);
369 xbt_die("Not a valid action for RCV");
371 } catch (std::exception& e) {
372 XBT_DEBUG("During %s, failed to receive message because of a %s exception (%s)", to_string(step.action_type),
373 typeid(e).name(), e.what());
379 sg4::this_actor::sleep_until(end_time - .1);
380 } catch (std::exception& e) {
381 XBT_DEBUG("During Sleep, failed to send message because of a %s exception (%s)", typeid(e).name(), e.what());
384 Action outcome = Action::END;
385 std::string scenario_string = to_string(s);
386 if (step_index < s.steps.size()) {
387 const Step& step = s.steps[step_index];
388 assert(step.entity == Step::RCV && step.type == Step::ACTION);
389 outcome = step.action_type;
390 } else if (s.type!=CommType::ONESIDE_SYNC &&
391 s.type!=CommType::ONESIDE_ASYNC
393 //One sided / detached operations do not actually transfer anything
394 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());
402 if (outcome != expected) {
403 XBT_ERROR("Expected %s but got %s in %s", to_string(expected), to_string(outcome), scenario_string.c_str());
405 XBT_DEBUG("OK: %s", scenario_string.c_str());
408 sg4::this_actor::sleep_until(end_time);
409 xbt_assert(not mbox_eager->listen(), "Mailbox should not have ongoing communication!");
410 xbt_assert(not mbox_rdv->listen(), "Mailbox should not have ongoing communication!");
414 explicit ReceiveAgent(int id, sg4::Host* other_host) : id(id), other_host(other_host) {}
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];
429 int ReceiveAgent::run = 0;
430 size_t ReceiveAgent::scenario = 0;
432 /*************************************************************************************************/
434 static void on_host_state_change(sg4::Host const& host)
436 XBT_DEBUG("Host %s is now %s", host.get_cname(), host.is_on() ? "ON " : "OFF");
437 if(not host.is_on()) {
443 static void on_link_state_change(sg4::Link const& link)
445 XBT_DEBUG("Link %s is now %s", link.get_cname(), link.is_on() ? "ON " : "OFF");
448 static void addStateEvent(std::ostream& out, double date, bool isOn)
451 out << date << " 1\n";
453 out << date << " 0\n";
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)
460 if(std::find(active_indices.begin(),active_indices.end(),index)!=active_indices.end()) {
461 // Update fault profiles
462 for (Step& step : steps) {
463 assert(step.rel_time < duration);
464 if (step.type != Step::STATE)
466 int val = step.new_state ? 1 : 0;
467 switch (step.entity) {
469 sndP << start_time + step.rel_time << " " << val << std::endl;
472 rcvP << start_time + step.rel_time << " " << val << std::endl;
475 lnkP << start_time + step.rel_time << " " << val << std::endl;
479 scenarios.push_back({type, start_time, duration, snd_expected, rcv_expected, steps, index});
483 start_time += duration;
487 /*************************************************************************************************/
489 // State profiles for the resources
490 std::string SndStateProfile;
491 std::string RcvStateProfile;
492 std::string LnkStateProfile;
494 /*************************************************************************************************/
496 double build_scenarios(std::vector<int>& active_indices );
498 int main(int argc, char* argv[])
501 sg4::Engine e(&argc, argv);
503 std::vector<int> active_indices;
504 //Parse index of tests that need to be run
506 int previous_index=-1;
507 bool is_range_last=false;
508 for(int i=1; i<argc; i++) {
509 if(not strcmp(argv[i],"-"))
512 int index=atoi(argv[i]);
513 xbt_assert(index>previous_index);
515 for(int j=previous_index+1;j<=index;j++)
516 active_indices.push_back(j);
518 active_indices.push_back(index);
520 previous_index=index;
524 double end_time = build_scenarios(active_indices);
526 XBT_INFO("Will run for %f seconds", end_time);
529 mbox_eager = e.mailbox_by_name_or_create("eager");
530 mbox_rdv = e.mailbox_by_name_or_create("rdv");
531 sg4::NetZone* zone = sg4::create_full_zone("Top");
532 pr::Profile* profile_sender = pr::ProfileBuilder::from_string("sender_profile", SndStateProfile, 0);
533 sg4::Host* sender_host = zone->create_host("senderHost", HostComputePower)->set_state_profile(profile_sender)->seal();
534 pr::Profile* profile_receiver = pr::ProfileBuilder::from_string("receiver_profile", RcvStateProfile, 0);
535 sg4::Host* receiver_host = zone->create_host("receiverHost", HostComputePower)->set_state_profile(profile_receiver)->seal();
536 sg4::ActorPtr sender = sg4::Actor::create("sender", sender_host, SendAgent(0, receiver_host));
537 sender->set_auto_restart(true);
538 sg4::ActorPtr receiver = sg4::Actor::create("receiver", receiver_host, ReceiveAgent(1, sender_host));
539 receiver->set_auto_restart(true);
540 pr::Profile* profile_link = pr::ProfileBuilder::from_string("link_profile", LnkStateProfile, 0);
542 zone->create_link("link", LinkBandwidth)->set_latency(LinkLatency)->set_state_profile(profile_link)->seal();
543 zone->add_route(sender_host->get_netpoint(), receiver_host->get_netpoint(), nullptr, nullptr,
544 {sg4::LinkInRoute{link}}, false);
546 sg4::Host::on_state_change.connect(on_host_state_change);
547 sg4::Link::on_state_change_cb(on_link_state_change);
549 e.run_until(end_time);
551 //Make sure we have a clean slate
552 xbt_assert(not mbox_eager->listen(),"Eager mailbox should be empty in the end");
553 xbt_assert(not mbox_rdv->listen(),"RDV mailbox should be empty in the end");
557 /*************************************************************************************************/
559 // A bunch of dirty macros to help readability (supposedly)
560 #define _MK(type, duration, snd_expected, rcv_expected, steps...) \
561 active+=prepareScenario(CommType::type, index, start_time, duration, sndP, rcvP, lnkP, Action::snd_expected, Action::rcv_expected, \
562 {steps}, active_indices )
564 #define LOFF(relTime) \
566 relTime, Step::STATE, Step::LNK, Action::END, false \
568 #define LON(relTime) \
570 relTime, Step::STATE, Step::LNK, Action::END, true \
573 #define SOFF(relTime) \
575 relTime, Step::STATE, Step::SND, Action::END, false \
577 #define SON(relTime) \
579 relTime, Step::STATE, Step::SND, Action::END, true \
581 #define SPUT(relTime) \
583 relTime, Step::ACTION, Step::SND, Action::PUT, false \
585 #define SWAT(relTime) \
587 relTime, Step::ACTION, Step::SND, Action::WAIT, false \
590 #define ROFF(relTime) \
592 relTime, Step::STATE, Step::RCV, Action::END, false \
594 #define RON(relTime) \
596 relTime, Step::STATE, Step::RCV, Action::END, true \
598 #define RGET(relTime) \
600 relTime, Step::ACTION, Step::RCV, Action::GET, false \
602 #define RWAT(relTime) \
604 relTime, Step::ACTION, Step::RCV, Action::WAIT, false \
607 double build_scenarios(std::vector<int>& active_indices )
610 // Build the set of simulation stages
611 std::stringstream sndP;
612 std::stringstream rcvP;
613 std::stringstream lnkP;
615 double start_time = 0;
619 // EAGER SYNC use cases
621 _MK(EAGER_SYNC, 1, END, END, SPUT(.2), RGET(.4));
622 _MK(EAGER_SYNC, 1, END, END, RGET(.2), SPUT(.4));
624 _MK(EAGER_SYNC, 2, PUT, DIE, ROFF(.1), SPUT(.2), RON(1));
625 _MK(EAGER_SYNC, 2, PUT, DIE, SPUT(.2), ROFF(.3), RON(1));
626 _MK(EAGER_SYNC, 2, PUT, DIE, SPUT(.2), RGET(.4), ROFF(.5), RON(1));
627 _MK(EAGER_SYNC, 2, PUT, DIE, RGET(.2), SPUT(.4), ROFF(.5), RON(1));
629 _MK(EAGER_SYNC, 2, DIE, GET, SPUT(.2), SOFF(.3), RGET(.4), SON(1));
630 _MK(EAGER_SYNC, 2, DIE, GET, SPUT(.2), RGET(.4), SOFF(.5), SON(1));
632 _MK(EAGER_SYNC, 2, PUT, GET, LOFF(.1), SPUT(.2), RGET(.4), LON(1));
633 _MK(EAGER_SYNC, 2, PUT, GET, SPUT(.2), LOFF(.3), RGET(.4), LON(1));
634 _MK(EAGER_SYNC, 2, PUT, GET, SPUT(.2), RGET(.4), LOFF(.5), LON(1));
635 _MK(EAGER_SYNC, 2, PUT, GET, LOFF(.1), RGET(.2), SPUT(.4), LON(1));
636 _MK(EAGER_SYNC, 2, PUT, GET, RGET(.2), LOFF(.3), SPUT(.4), LON(1));
637 _MK(EAGER_SYNC, 2, PUT, GET, RGET(.2), SPUT(.4), LOFF(.5), LON(1));
639 // EAGER ASYNC use cases
641 _MK(EAGER_ASYNC, 2, END, END, SPUT(.2), SWAT(.4), RGET(.6), RWAT(.8));
642 _MK(EAGER_ASYNC, 2, END, END, SPUT(.2), RGET(.4), SWAT(.6), RWAT(.8));
643 _MK(EAGER_ASYNC, 2, END, END, SPUT(.2), RGET(.4), RWAT(.6), SWAT(.8));
644 _MK(EAGER_ASYNC, 2, END, END, RGET(.2), SPUT(.4), SWAT(.6), RWAT(.8));
645 _MK(EAGER_ASYNC, 2, END, END, RGET(.2), SPUT(.4), RWAT(.6), SWAT(.8));
646 _MK(EAGER_ASYNC, 2, END, END, RGET(.2), RWAT(.4), SPUT(.6), SWAT(.8));
649 _MK(EAGER_ASYNC, 2, PUT, DIE, ROFF(.1), SPUT(.2), SWAT(.4), RON(1));
650 _MK(EAGER_ASYNC, 2, WAIT, DIE, SPUT(.2), ROFF(.3), SWAT(.4), RON(1));
651 _MK(EAGER_ASYNC, 2, PUT, DIE, RGET(.2), ROFF(.3), SPUT(.4), SWAT(.6), RON(1));
652 _MK(EAGER_ASYNC, 2, WAIT, DIE, SPUT(.2), SWAT(.4), ROFF(.5), RON(1));
653 _MK(EAGER_ASYNC, 2, WAIT, DIE, SPUT(.2), RGET(.4), ROFF(.5), SWAT(.6), RON(1));
654 _MK(EAGER_ASYNC, 2, WAIT, DIE, RGET(.2), SPUT(.4), ROFF(.5), SWAT(.6), RON(1));
655 _MK(EAGER_ASYNC, 2, PUT , DIE, RGET(.2), RWAT(.4), ROFF(.5), SPUT(.6), SWAT(.8), RON(1));
656 _MK(EAGER_ASYNC, 2, WAIT, DIE, SPUT(.2), SWAT(.4), RGET(.6), ROFF(.7), RON(1));
657 _MK(EAGER_ASYNC, 2, WAIT, DIE, SPUT(.2), RGET(.4), SWAT(.6), ROFF(.7), RON(1));
658 _MK(EAGER_ASYNC, 2, WAIT, DIE, SPUT(.2), RGET(.4), RWAT(.6), ROFF(.7), SWAT(.8), RON(1));
659 _MK(EAGER_ASYNC, 2, WAIT, DIE, RGET(.2), SPUT(.4), SWAT(.6), ROFF(.7), RON(1));
660 _MK(EAGER_ASYNC, 2, WAIT, DIE, RGET(.2), SPUT(.4), RWAT(.6), ROFF(.7), SWAT(.8), RON(1));
661 _MK(EAGER_ASYNC, 2, WAIT, DIE, RGET(.2), RWAT(.4), SPUT(.6), ROFF(.7), SWAT(.8), RON(1));
662 // Sender off (only cases where sender did put, because otherwise receiver cannot find out there was a fault)
663 _MK(EAGER_ASYNC, 2, DIE, GET, SPUT(.2), SOFF(.3), RGET(.4), RWAT(.6), SON(1));
664 _MK(EAGER_ASYNC, 2, DIE, WAIT, RGET(.2), SPUT(.4), SOFF(.5), RWAT(.6), SON(1));
665 _MK(EAGER_ASYNC, 2, DIE, WAIT, SPUT(.2), RGET(.4), SOFF(.5), RWAT(.6), SON(1));
666 _MK(EAGER_ASYNC, 2, DIE, GET, SPUT(.2), SWAT(.4), SOFF(.5), RGET(.6), RWAT(.8), SON(1));
667 _MK(EAGER_ASYNC, 2, DIE, WAIT, RGET(.2), RWAT(.4), SPUT(.6), SOFF(.7), SON(1));
668 _MK(EAGER_ASYNC, 2, DIE, WAIT, RGET(.2), SPUT(.4), RWAT(.6), SOFF(.7), SON(1));
669 _MK(EAGER_ASYNC, 2, DIE, WAIT, RGET(.2), SPUT(.4), SWAT(.6), SOFF(.7), RWAT(.8), SON(1));
670 _MK(EAGER_ASYNC, 2, DIE, WAIT, SPUT(.2), RGET(.4), RWAT(.6), SOFF(.7), SON(1));
671 _MK(EAGER_ASYNC, 2, DIE, WAIT, SPUT(.2), RGET(.4), SWAT(.6), SOFF(.7), RWAT(.8), SON(1));
672 _MK(EAGER_ASYNC, 2, DIE, WAIT, SPUT(.2), SWAT(.4), RGET(.6), SOFF(.7), RWAT(.8), SON(1));
674 _MK(EAGER_ASYNC, 2, WAIT, WAIT, LOFF(.1), SPUT(.2), SWAT(.4), RGET(.6), RWAT(.8), LON(1));
675 _MK(EAGER_ASYNC, 2, WAIT, WAIT, LOFF(.1), SPUT(.2), RGET(.4), SWAT(.6), RWAT(.8), LON(1));
676 _MK(EAGER_ASYNC, 2, WAIT, WAIT, LOFF(.1), SPUT(.2), RGET(.4), RWAT(.6), SWAT(.8), LON(1));
677 _MK(EAGER_ASYNC, 2, WAIT, WAIT, LOFF(.1), RGET(.2), SPUT(.4), SWAT(.6), RWAT(.8), LON(1));
678 _MK(EAGER_ASYNC, 2, WAIT, WAIT, LOFF(.1), RGET(.2), SPUT(.4), RWAT(.6), SWAT(.8), LON(1));
679 _MK(EAGER_ASYNC, 2, WAIT, WAIT, LOFF(.1), RGET(.2), RWAT(.4), SPUT(.6), SWAT(.8), LON(1));
680 _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), LOFF(.3), SWAT(.4), RGET(.6), RWAT(.8), LON(1));
681 _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), LOFF(.3), RGET(.4), SWAT(.6), RWAT(.8), LON(1));
682 _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), LOFF(.3), RGET(.4), RWAT(.6), SWAT(.8), LON(1));
683 _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), LOFF(.3), SPUT(.4), SWAT(.6), RWAT(.8), LON(1));
684 _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), LOFF(.3), SPUT(.4), RWAT(.6), SWAT(.8), LON(1));
685 _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), LOFF(.3), RWAT(.4), SPUT(.6), SWAT(.8), LON(1));
686 _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), SWAT(.4), LOFF(.5), RGET(.6), RWAT(.8), LON(1));
687 _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), LOFF(.5), SWAT(.6), RWAT(.8), LON(1));
688 _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), LOFF(.5), RWAT(.6), SWAT(.8), LON(1));
689 _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), LOFF(.5), SWAT(.6), RWAT(.8), LON(1));
690 _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), LOFF(.5), RWAT(.6), SWAT(.8), LON(1));
691 _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), RWAT(.4), LOFF(.5), SPUT(.6), SWAT(.8), LON(1));
692 _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), SWAT(.4), RGET(.6), LOFF(.7), RWAT(.8), LON(1));
693 _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), SWAT(.6), LOFF(.7), RWAT(.8), LON(1));
694 _MK(EAGER_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), RWAT(.6), LOFF(.7), SWAT(.8), LON(1));
695 _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), SWAT(.6), LOFF(.7), RWAT(.8), LON(1));
696 _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), RWAT(.6), LOFF(.7), SWAT(.8), LON(1));
697 _MK(EAGER_ASYNC, 2, WAIT, WAIT, RGET(.2), RWAT(.4), SPUT(.6), LOFF(.7), SWAT(.8), LON(1));
699 // RDV SYNC use cases
702 _MK(RDV_SYNC, 1, END, END, SPUT(.2), RGET(.4));
703 _MK(RDV_SYNC, 1, END, END, RGET(.2), SPUT(.4));
706 _MK(RDV_SYNC, 2, PUT, DIE, ROFF(.1), SPUT(.2), RON(1));
707 _MK(RDV_SYNC, 2, PUT, DIE, SPUT(.2), ROFF(.3), RON(1)); //Fails because put comm cancellation does not trigger sender exception
708 _MK(RDV_SYNC, 2, PUT, DIE, SPUT(.2), RGET(.4), ROFF(.5), RON(1));
709 _MK(RDV_SYNC, 2, PUT, DIE, RGET(.2), SPUT(.4), ROFF(.5), RON(1));
711 _MK(RDV_SYNC, 2, DIE, GET, SPUT(.2), RGET(.4), SOFF(.5), SON(1));
713 _MK(RDV_SYNC, 2, PUT, GET, LOFF(.1), SPUT(.2), RGET(.4), LON(1));
714 _MK(RDV_SYNC, 2, PUT, GET, SPUT(.2), LOFF(.3), RGET(.4), LON(1));
715 _MK(RDV_SYNC, 2, PUT, GET, SPUT(.2), RGET(.4), LOFF(.5), LON(1));
716 _MK(RDV_SYNC, 2, PUT, GET, LOFF(.1), RGET(.2), SPUT(.4), LON(1));
717 _MK(RDV_SYNC, 2, PUT, GET, RGET(.2), LOFF(.3), SPUT(.4), LON(1));
718 _MK(RDV_SYNC, 2, PUT, GET, RGET(.2), SPUT(.4), LOFF(.5), LON(1));
720 // RDV ASYNC use cases
722 _MK(RDV_ASYNC, 2, END, END, SPUT(.2), SWAT(.4), RGET(.6), RWAT(.8));
723 _MK(RDV_ASYNC, 2, END, END, SPUT(.2), RGET(.4), SWAT(.6), RWAT(.8));
724 _MK(RDV_ASYNC, 2, END, END, SPUT(.2), RGET(.4), RWAT(.6), SWAT(.8));
725 _MK(RDV_ASYNC, 2, END, END, RGET(.2), SPUT(.4), SWAT(.6), RWAT(.8));
726 _MK(RDV_ASYNC, 2, END, END, RGET(.2), SPUT(.4), RWAT(.6), SWAT(.8));
727 _MK(RDV_ASYNC, 2, END, END, RGET(.2), RWAT(.4), SPUT(.6), SWAT(.8));
729 _MK(RDV_ASYNC, 2, PUT, DIE, ROFF(.1), SPUT(.2), SWAT(.4), RON(1));
730 _MK(RDV_ASYNC, 2, WAIT, DIE, SPUT(.2), ROFF(.3), SWAT(.4), RON(1));
731 _MK(RDV_ASYNC, 2, PUT, DIE, RGET(.2), ROFF(.3), SPUT(.4), SWAT(.6), RON(1));
732 _MK(RDV_ASYNC, 2, WAIT, DIE, SPUT(.2), SWAT(.4), ROFF(.5), RON(1)); //Fails because put comm cancellation does not trigger sender exception
733 _MK(RDV_ASYNC, 2, WAIT, DIE, SPUT(.2), RGET(.4), ROFF(.5), SWAT(.6), RON(1));
734 _MK(RDV_ASYNC, 2, WAIT, DIE, RGET(.2), SPUT(.4), ROFF(.5), SWAT(.6), RON(1));
735 _MK(RDV_ASYNC, 2, PUT , DIE, RGET(.2), RWAT(.4), ROFF(.5), SPUT(.6), SWAT(.8), RON(1));
736 _MK(RDV_ASYNC, 2, WAIT, DIE, SPUT(.2), SWAT(.4), RGET(.6), ROFF(.7), RON(1));
737 _MK(RDV_ASYNC, 2, WAIT, DIE, SPUT(.2), RGET(.4), SWAT(.6), ROFF(.7), RON(1));
738 _MK(RDV_ASYNC, 2, WAIT, DIE, SPUT(.2), RGET(.4), RWAT(.6), ROFF(.7), SWAT(.8), RON(1));
739 _MK(RDV_ASYNC, 2, WAIT, DIE, RGET(.2), SPUT(.4), SWAT(.6), ROFF(.7), RON(1));
740 _MK(RDV_ASYNC, 2, WAIT, DIE, RGET(.2), SPUT(.4), RWAT(.6), ROFF(.7), SWAT(.8), RON(1));
741 _MK(RDV_ASYNC, 2, WAIT, DIE, RGET(.2), RWAT(.4), SPUT(.6), ROFF(.7), SWAT(.8), RON(1));
742 // Sender off (only cases where sender did put, because otherwise receiver cannot find out there was a fault)
743 _MK(RDV_ASYNC, 2, DIE, GET, SPUT(.2), SOFF(.3), RGET(.4), RWAT(.6), SON(1));
744 _MK(RDV_ASYNC, 2, DIE, WAIT, RGET(.2), SPUT(.4), SOFF(.5), RWAT(.6), SON(1));
745 _MK(RDV_ASYNC, 2, DIE, WAIT, SPUT(.2), RGET(.4), SOFF(.5), RWAT(.6), SON(1));
746 _MK(RDV_ASYNC, 2, DIE, GET, SPUT(.2), SWAT(.4), SOFF(.5), RGET(.6), RWAT(.8), SON(1));
747 _MK(RDV_ASYNC, 2, DIE, WAIT, RGET(.2), RWAT(.4), SPUT(.6), SOFF(.7), SON(1));
748 _MK(RDV_ASYNC, 2, DIE, WAIT, RGET(.2), SPUT(.4), RWAT(.6), SOFF(.7), SON(1));
749 _MK(RDV_ASYNC, 2, DIE, WAIT, RGET(.2), SPUT(.4), SWAT(.6), SOFF(.7), RWAT(.8), SON(1));
750 _MK(RDV_ASYNC, 2, DIE, WAIT, SPUT(.2), RGET(.4), RWAT(.6), SOFF(.7), SON(1));
751 _MK(RDV_ASYNC, 2, DIE, WAIT, SPUT(.2), RGET(.4), SWAT(.6), SOFF(.7), RWAT(.8), SON(1));
752 _MK(RDV_ASYNC, 2, DIE, WAIT, SPUT(.2), SWAT(.4), RGET(.6), SOFF(.7), RWAT(.8), SON(1));
754 _MK(RDV_ASYNC, 2, WAIT, WAIT, LOFF(.1), SPUT(.2), SWAT(.4), RGET(.6), RWAT(.8), LON(1));
755 _MK(RDV_ASYNC, 2, WAIT, WAIT, LOFF(.1), SPUT(.2), RGET(.4), SWAT(.6), RWAT(.8), LON(1));
756 _MK(RDV_ASYNC, 2, WAIT, WAIT, LOFF(.1), SPUT(.2), RGET(.4), RWAT(.6), SWAT(.8), LON(1));
757 _MK(RDV_ASYNC, 2, WAIT, WAIT, LOFF(.1), RGET(.2), SPUT(.4), SWAT(.6), RWAT(.8), LON(1));
758 _MK(RDV_ASYNC, 2, WAIT, WAIT, LOFF(.1), RGET(.2), SPUT(.4), RWAT(.6), SWAT(.8), LON(1));
759 _MK(RDV_ASYNC, 2, WAIT, WAIT, LOFF(.1), RGET(.2), RWAT(.4), SPUT(.6), SWAT(.8), LON(1));
760 _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), LOFF(.3), SWAT(.4), RGET(.6), RWAT(.8), LON(1));
761 _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), LOFF(.3), RGET(.4), SWAT(.6), RWAT(.8), LON(1));
762 _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), LOFF(.3), RGET(.4), RWAT(.6), SWAT(.8), LON(1));
763 _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), LOFF(.3), SPUT(.4), SWAT(.6), RWAT(.8), LON(1));
764 _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), LOFF(.3), SPUT(.4), RWAT(.6), SWAT(.8), LON(1));
765 _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), LOFF(.3), RWAT(.4), SPUT(.6), SWAT(.8), LON(1));
766 _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), SWAT(.4), LOFF(.5), RGET(.6), RWAT(.8), LON(1));
767 _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), LOFF(.5), SWAT(.6), RWAT(.8), LON(1));
768 _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), LOFF(.5), RWAT(.6), SWAT(.8), LON(1));
769 _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), LOFF(.5), SWAT(.6), RWAT(.8), LON(1));
770 _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), LOFF(.5), RWAT(.6), SWAT(.8), LON(1));
771 _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), RWAT(.4), LOFF(.5), SPUT(.6), SWAT(.8), LON(1));
772 _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), SWAT(.4), RGET(.6), LOFF(.7), RWAT(.8), LON(1));
773 _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), SWAT(.6), LOFF(.7), RWAT(.8), LON(1));
774 _MK(RDV_ASYNC, 2, WAIT, WAIT, SPUT(.2), RGET(.4), RWAT(.6), LOFF(.7), SWAT(.8), LON(1));
775 _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), SWAT(.6), LOFF(.7), RWAT(.8), LON(1));
776 _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), SPUT(.4), RWAT(.6), LOFF(.7), SWAT(.8), LON(1));
777 _MK(RDV_ASYNC, 2, WAIT, WAIT, RGET(.2), RWAT(.4), SPUT(.6), LOFF(.7), SWAT(.8), LON(1));
779 // ONESIDE SYNC use cases
782 _MK(ONESIDE_SYNC, 1, END, END, SPUT(.2));
784 _MK(ONESIDE_SYNC, 2, PUT, DIE, ROFF(.1), SPUT(.2), RON(1));
785 _MK(ONESIDE_SYNC, 2, PUT, DIE, SPUT(.2), ROFF(.3), RON(1));
787 _MK(ONESIDE_SYNC, 2, DIE, END, SPUT(.2), SOFF(.3), SON(1));
789 _MK(ONESIDE_SYNC, 2, PUT, END, LOFF(.1), SPUT(.2), LON(1));
790 _MK(ONESIDE_SYNC, 2, PUT, END, SPUT(.2), LOFF(.3), LON(1));
792 // ONESIDE ASYNC use cases
794 _MK(ONESIDE_ASYNC, 2, END, END, SPUT(.2), SWAT(.4));
796 _MK(ONESIDE_ASYNC, 2, PUT, DIE, ROFF(.1), SPUT(.2), SWAT(.4), RON(1));
797 _MK(ONESIDE_ASYNC, 2, WAIT, DIE, SPUT(.2), ROFF(.3), SWAT(.4), RON(1));
798 _MK(ONESIDE_ASYNC, 2, WAIT, DIE, SPUT(.2), SWAT(.4), ROFF(.5), RON(1));
800 _MK(ONESIDE_ASYNC, 2, DIE, END, SPUT(.2), SOFF(.3), SON(1));
802 _MK(ONESIDE_ASYNC, 2, WAIT, END, LOFF(.1), SPUT(.2), SWAT(.4), LON(1));
803 _MK(ONESIDE_ASYNC, 2, WAIT, END, SPUT(.2), LOFF(.3), SWAT(.4), LON(1));
804 _MK(ONESIDE_ASYNC, 2, WAIT, END, SPUT(.2), SWAT(.4), LOFF(.5), LON(1));
807 SndStateProfile = sndP.str();
808 RcvStateProfile = rcvP.str();
809 LnkStateProfile = lnkP.str();
811 XBT_INFO("Will execute %i active scenarios out of %i.",active,index);
812 return start_time + 1;