-/* Copyright (c) 2007-2019. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2007-2021. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/s4u.hpp"
#include <vector>
-#define PIECE_SIZE 65536
-#define MESSAGE_BUILD_CHAIN_SIZE 40
-#define MESSAGE_SEND_DATA_HEADER_SIZE 1
+constexpr unsigned PIECE_SIZE = 65536;
+constexpr unsigned MESSAGE_BUILD_CHAIN_SIZE = 40;
+constexpr unsigned MESSAGE_SEND_DATA_HEADER_SIZE = 1;
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_chainsend, "Messages specific for chainsend");
class ChainMessage {
public:
- simgrid::s4u::MailboxPtr prev_ = nullptr;
- simgrid::s4u::MailboxPtr next_ = nullptr;
+ simgrid::s4u::Mailbox* prev_ = nullptr;
+ simgrid::s4u::Mailbox* next_ = nullptr;
unsigned int num_pieces = 0;
- explicit ChainMessage(simgrid::s4u::MailboxPtr prev, simgrid::s4u::MailboxPtr next, const unsigned int num_pieces)
+ explicit ChainMessage(simgrid::s4u::Mailbox* prev, simgrid::s4u::Mailbox* next, const unsigned int num_pieces)
: prev_(prev), next_(next), num_pieces(num_pieces)
{
}
class Peer {
public:
- simgrid::s4u::MailboxPtr prev = nullptr;
- simgrid::s4u::MailboxPtr next = nullptr;
- simgrid::s4u::MailboxPtr me = nullptr;
+ simgrid::s4u::Mailbox* prev = nullptr;
+ simgrid::s4u::Mailbox* next = nullptr;
+ simgrid::s4u::Mailbox* me = nullptr;
std::vector<simgrid::s4u::CommPtr> pending_recvs;
std::vector<simgrid::s4u::CommPtr> pending_sends;
void joinChain()
{
- ChainMessage* msg = static_cast<ChainMessage*>(me->get());
- prev = msg->prev_;
- next = msg->next_;
- total_pieces = msg->num_pieces;
+ auto msg = me->get_unique<ChainMessage>();
+ prev = msg->prev_;
+ next = msg->next_;
+ total_pieces = msg->num_pieces;
XBT_DEBUG("Peer %s got a 'BUILD_CHAIN' message (prev: %s / next: %s)", me->get_cname(),
prev ? prev->get_cname() : nullptr, next ? next->get_cname() : nullptr);
- delete msg;
}
void forwardFile()
{
- void* received;
+ FilePiece* received;
bool done = false;
while (not done) {
- simgrid::s4u::CommPtr comm = me->get_async(&received);
+ simgrid::s4u::CommPtr comm = me->get_async<FilePiece>(&received);
pending_recvs.push_back(comm);
int idx = simgrid::s4u::Comm::wait_any(&pending_recvs);
simgrid::s4u::CommPtr send = next->put_async(received, MESSAGE_SEND_DATA_HEADER_SIZE + PIECE_SIZE);
pending_sends.push_back(send);
} else
- delete static_cast<FilePiece*>(received);
+ delete received;
received_pieces++;
received_bytes += PIECE_SIZE;
class Broadcaster {
public:
- simgrid::s4u::MailboxPtr first = nullptr;
- std::vector<simgrid::s4u::MailboxPtr> mailboxes;
+ simgrid::s4u::Mailbox* first = nullptr;
+ std::vector<simgrid::s4u::Mailbox*> mailboxes;
unsigned int piece_count;
void buildChain()
{
- auto cur = mailboxes.begin();
- simgrid::s4u::MailboxPtr prev = nullptr;
- simgrid::s4u::MailboxPtr last = nullptr;
-
/* Build the chain if there's at least one peer */
- if (cur != mailboxes.end()) {
- /* init: prev=NULL, host=current cur, next=next cur */
- simgrid::s4u::MailboxPtr next = *cur;
- first = next;
-
- /* This iterator iterates one step ahead: cur is current iterated element, but is actually next in the chain */
- do {
- /* following steps: prev=last, host=next, next=cur */
- ++cur;
- prev = last;
- simgrid::s4u::MailboxPtr current_mailbox = next;
- if (cur != mailboxes.end())
- next = *cur;
- else
- next = nullptr;
-
- XBT_DEBUG("Building chain--broadcaster:\"%s\" dest:\"%s\" prev:\"%s\" next:\"%s\"",
- simgrid::s4u::Host::current()->get_cname(), current_mailbox->get_cname(),
- prev ? prev->get_cname() : nullptr, next ? next->get_cname() : nullptr);
-
- /* Send message to current peer */
- current_mailbox->put(new ChainMessage(prev, next, piece_count), MESSAGE_BUILD_CHAIN_SIZE);
-
- last = current_mailbox;
- } while (cur != mailboxes.end());
+ if (not mailboxes.empty())
+ first = mailboxes.front();
+
+ for (unsigned i = 0; i < mailboxes.size(); i++) {
+ simgrid::s4u::Mailbox* prev = i > 0 ? mailboxes[i - 1] : nullptr;
+ simgrid::s4u::Mailbox* next = i < mailboxes.size() - 1 ? mailboxes[i + 1] : nullptr;
+ XBT_DEBUG("Building chain--broadcaster:\"%s\" dest:\"%s\" prev:\"%s\" next:\"%s\"",
+ simgrid::s4u::Host::current()->get_cname(), mailboxes[i]->get_cname(),
+ prev ? prev->get_cname() : nullptr, next ? next->get_cname() : nullptr);
+ /* Send message to current peer */
+ mailboxes[i]->put(new ChainMessage(prev, next, piece_count), MESSAGE_BUILD_CHAIN_SIZE);
}
}
{
XBT_DEBUG("peer");
- Peer* p = new Peer();
+ Peer p;
double start_time = simgrid::s4u::Engine::get_clock();
- p->joinChain();
- p->forwardFile();
+ p.joinChain();
+ p.forwardFile();
- simgrid::s4u::Comm::wait_all(&p->pending_sends);
+ simgrid::s4u::Comm::wait_all(&p.pending_sends);
double end_time = simgrid::s4u::Engine::get_clock();
- XBT_INFO("### %f %llu bytes (Avg %f MB/s); copy finished (simulated).", end_time - start_time, p->received_bytes,
- p->received_bytes / 1024.0 / 1024.0 / (end_time - start_time));
-
- delete p;
+ XBT_INFO("### %f %llu bytes (Avg %f MB/s); copy finished (simulated).", end_time - start_time, p.received_bytes,
+ p.received_bytes / 1024.0 / 1024.0 / (end_time - start_time));
}
static void broadcaster(int hostcount, unsigned int piece_count)
{
XBT_DEBUG("broadcaster");
- Broadcaster* bc = new Broadcaster(hostcount, piece_count);
- bc->buildChain();
- bc->sendFile();
-
- delete bc;
+ Broadcaster bc(hostcount, piece_count);
+ bc.buildChain();
+ bc.sendFile();
}
int main(int argc, char* argv[])