From 825fe6086e463bfd069172bd45a6e39a83796d19 Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Sun, 16 Aug 2015 15:31:27 +0200 Subject: [PATCH] Implement send async --- include/simgrid/s4u/actor.hpp | 5 ++ include/simgrid/s4u/async.hpp | 74 +++++++++++++++++++++++++++ include/simgrid/s4u/comm.hpp | 74 +++++++++++++++++++++++++++ include/simgrid/s4u/mailbox.hpp | 5 +- src/s4u/s4u_actor.cpp | 18 ++++--- src/s4u/s4u_async.cpp | 28 ++++++++++ src/s4u/s4u_comm.cpp | 88 ++++++++++++++++++++++++++++++++ src/s4u/s4u_engine.cpp | 2 +- src/s4u/s4u_mailbox.cpp | 3 +- tools/cmake/DefinePackages.cmake | 4 ++ 10 files changed, 291 insertions(+), 10 deletions(-) create mode 100644 include/simgrid/s4u/async.hpp create mode 100644 include/simgrid/s4u/comm.hpp create mode 100644 src/s4u/s4u_async.cpp create mode 100644 src/s4u/s4u_comm.cpp diff --git a/include/simgrid/s4u/actor.hpp b/include/simgrid/s4u/actor.hpp index ec7e421fc5..5e4bfba745 100644 --- a/include/simgrid/s4u/actor.hpp +++ b/include/simgrid/s4u/actor.hpp @@ -11,6 +11,7 @@ namespace simgrid { namespace s4u { +class Comm; class Host; class Mailbox; @@ -39,6 +40,7 @@ class Mailbox; * */ class Actor { + friend Comm; public: Actor(const char*name, s4u::Host *host, int argc, char **argv); Actor(const char*name, s4u::Host *host, int argc, char **argv, double killTime); @@ -90,6 +92,9 @@ public: /** Block the actor until it delivers a string message (that will be copied) to the given mailbox */ void sendstr(Mailbox &chan, const char*msg); + /** Creates (but don't start) an async send action */ + Comm &send_init(Mailbox &chan); + protected: smx_process_t getInferior() {return p_smx_process;} private: diff --git a/include/simgrid/s4u/async.hpp b/include/simgrid/s4u/async.hpp new file mode 100644 index 0000000000..6d76288001 --- /dev/null +++ b/include/simgrid/s4u/async.hpp @@ -0,0 +1,74 @@ +/* Copyright (c) 2006-2015. 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. */ + +#ifndef SIMGRID_S4U_ASYNC_HPP +#define SIMGRID_S4U_ASYNC_HPP + +namespace simgrid { +namespace s4u { + +/* Forward declaration */ +class Comm; + +typedef enum { + inited, started, finished +} e_s4u_async_state_t; + +/** @brief Asynchronous Actions + * + * This class is the ancestor of every asynchronous actions, that is, of actions that do take time in the simulated world. + */ +class Async { + friend Comm; +protected: + Async(); + virtual ~Async(); + +private: + smx_synchro_t p_inferior = NULL; + +private: + e_s4u_async_state_t p_state = inited; +public: + /** Starts a previously created async. + * + * This function is optional: you can call wait() even if you didn't call start() + */ + virtual void start()=0; + /** Tests whether the given async is terminated yet */ + //virtual bool test()=0; + /** Blocks until the async is terminated */ + virtual void wait()=0; + /** Blocks until the async is terminated, or until the timeout is elapsed + * Raises: timeout exception.*/ + virtual void wait(double timeout)=0; + /** Cancel that async */ + //virtual void cancel(); + /** Retrieve the current state of the async */ + e_s4u_async_state_t getState() {return p_state;} + +private: + double p_remains = 0; +public: + /** Get the remaining amount of work that this Async entails. When it's 0, it's done. */ + double getRemains(); + /** Set the [remaining] amount of work that this Async will entail + * + * It is forbidden to change the amount of work once the Async is started */ + void setRemains(double remains); + +private: + void *p_userData = NULL; +public: + /** Put some user data onto the Async */ + void setUserData(void *data) {p_userData=data;} + /** Retrieve the user data of the Async */ + void *getUserData() { return p_userData; } +}; // class + +}}; // Namespace simgrid::s4u + +#endif /* SIMGRID_S4U_ASYNC_HPP */ diff --git a/include/simgrid/s4u/comm.hpp b/include/simgrid/s4u/comm.hpp new file mode 100644 index 0000000000..f8cfd8f0cc --- /dev/null +++ b/include/simgrid/s4u/comm.hpp @@ -0,0 +1,74 @@ +/* Copyright (c) 2006-2015. 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. */ + +#ifndef SIMGRID_S4U_COMM_HPP +#define SIMGRID_S4U_COMM_HPP + +#include "simgrid/s4u/async.hpp" +#include "simgrid/s4u/mailbox.hpp" + +namespace simgrid { +namespace s4u { + +class Mailbox; + +/** @brief Communication async + * + * Represents all asynchronous communications, that you can test or wait onto. + */ +class Comm : public Async { + Comm() : Async() {} +public: + virtual ~Comm(); + +public: + /** Creates (but don't start) an async send to the mailbox #dest */ + static Comm &send_init(Actor *sender, Mailbox &dest); + /** Creates and start an async send to the mailbox #dest */ + static Comm &send_async(s4u::Actor *sender, Mailbox &dest, void *data, int simulatedByteAmount); + /** Creates (but don't start) an async recv onto the mailbox #from */ + //static Comm &recv_init(Mailbox &from); + /** Creates and start an async recv to the mailbox #from */ + //static Comm &recv_async(Mailbox &from, void *data); + + void start() override; + void wait() override; + void wait(double timeout) override; + +private: + double p_rate=-1; +public: + /** Sets the maximal communication rate (in byte/sec). Must be done before start */ + void setRate(double rate); + +private: + void *p_srcBuff = NULL; + size_t p_srcBuffSize = sizeof(void*); +public: + /** Specify the data to send */ + void setSrcData(void * buff); + /** Specify the size of the data to send */ + void setSrcDataSize(size_t size); + /** Specify the data to send and its size */ + void setSrcData(void * buff, size_t size); + +private: /* FIXME: expose these elements in the API */ + int p_detached = 0; + int (*p_matchFunction)(void *, void *, smx_synchro_t) = NULL; + void (*p_cleanFunction)(void *) = NULL; + void (*p_copyDataFunction)(smx_synchro_t, void*, size_t) = NULL; + + + + +private: + Actor *p_sender = NULL; + Mailbox *p_mailbox = NULL; +}; + +}} // namespace simgrid::s4u + +#endif /* SIMGRID_S4U_COMM_HPP */ diff --git a/include/simgrid/s4u/mailbox.hpp b/include/simgrid/s4u/mailbox.hpp index cb3369ffe9..c519700750 100644 --- a/include/simgrid/s4u/mailbox.hpp +++ b/include/simgrid/s4u/mailbox.hpp @@ -13,6 +13,8 @@ namespace simgrid { namespace s4u { +class Comm; + /** @brief Mailboxes * * Rendez-vous point for network communications, similar to URLs on which you could post and retrieve data. @@ -21,7 +23,8 @@ namespace s4u { * sender and receiver. */ class Mailbox { - friend Actor; + friend Actor; // FIXME: remove it when recv async exist + friend Comm; private: Mailbox(const char*name, smx_rdv_t inferior); diff --git a/src/s4u/s4u_actor.cpp b/src/s4u/s4u_actor.cpp index 571e0ec162..173d6339ec 100644 --- a/src/s4u/s4u_actor.cpp +++ b/src/s4u/s4u_actor.cpp @@ -4,13 +4,14 @@ /* 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/actor.hpp" -#include "simgrid/s4u/mailbox.hpp" #include "xbt/log.h" #include "msg/msg_private.h" #include "msg/msg_mailbox.h" +#include "simgrid/s4u/actor.hpp" +#include "simgrid/s4u/comm.hpp" #include "simgrid/s4u/host.hpp" +#include "simgrid/s4u/mailbox.hpp" XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_actor,"S4U actors"); @@ -85,15 +86,18 @@ char *s4u::Actor::recvstr(Mailbox &chan) { char *res=NULL; size_t res_size=sizeof(res); + simcall_comm_recv(chan.getInferior(),&res,&res_size,NULL,NULL,NULL,-1 /* timeout */,-1 /*rate*/); return res; } void s4u::Actor::sendstr(Mailbox &chan, const char*msg) { - char *msg_cpy=xbt_strdup(msg); - smx_synchro_t comm = simcall_comm_isend(p_smx_process, chan.getInferior(), strlen(msg), - -1/*rate*/, msg_cpy, sizeof(void *), - NULL, NULL, NULL,NULL/*data*/, 0); - simcall_comm_wait(comm, -1/*timeout*/); + Comm c = Comm::send_init(this,chan); + c.setRemains(strlen(msg)); + c.setSrcData(xbt_strdup(msg),sizeof(char*)); + c.wait(); } +s4u::Comm &s4u::Actor::send_init(Mailbox &chan) { + return s4u::Comm::send_init(this, chan); +} diff --git a/src/s4u/s4u_async.cpp b/src/s4u/s4u_async.cpp new file mode 100644 index 0000000000..7088472ae3 --- /dev/null +++ b/src/s4u/s4u_async.cpp @@ -0,0 +1,28 @@ +/* Copyright (c) 2006-2015. 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 "xbt/log.h" +#include "msg/msg_private.h" +#include "msg/msg_mailbox.h" + +#include "simgrid/s4u/async.hpp" + +XBT_LOG_EXTERNAL_CATEGORY(s4u); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_async,s4u,"S4U asynchronous actions"); +using namespace simgrid; + +s4u::Async::Async() { + +} +s4u::Async::~Async() { + +} + +void s4u::Async::setRemains(double remains) { + xbt_assert(p_state == inited, "Cannot change the remaining amount of work once the Async is started"); + p_remains = remains; +} + diff --git a/src/s4u/s4u_comm.cpp b/src/s4u/s4u_comm.cpp new file mode 100644 index 0000000000..4ef20b7a94 --- /dev/null +++ b/src/s4u/s4u_comm.cpp @@ -0,0 +1,88 @@ +/* Copyright (c) 2006-2015. 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 "xbt/log.h" +#include "msg/msg_private.h" +#include "msg/msg_mailbox.h" + +#include "simgrid/s4u/comm.hpp" + +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_comm,s4u_async,"S4U asynchronous communications"); +using namespace simgrid; + +s4u::Comm::~Comm() { + +} + +s4u::Comm &s4u::Comm::send_init(s4u::Actor *sender, s4u::Mailbox &chan) { + s4u::Comm *res = new s4u::Comm(); + res->p_sender = sender; + res->p_mailbox = &chan; + + return *res; +} + +void s4u::Comm::setRate(double rate) { + xbt_assert(p_state==inited); + p_rate = rate; +} + +void s4u::Comm::setSrcData(void * buff) { + xbt_assert(p_state==inited); + p_srcBuff = buff; +} +void s4u::Comm::setSrcDataSize(size_t size){ + xbt_assert(p_state==inited); + p_srcBuffSize = size; +} +void s4u::Comm::setSrcData(void * buff, size_t size) { + xbt_assert(p_state==inited); + + p_srcBuff = buff; + p_srcBuffSize = size; +} + +void s4u::Comm::start() { + xbt_assert(p_state == inited); + + p_inferior = simcall_comm_isend(p_sender->getInferior(), p_mailbox->getInferior(), p_remains, p_rate, + p_srcBuff, p_srcBuffSize, + p_matchFunction, p_cleanFunction, p_copyDataFunction, + p_userData, p_detached); + p_state = started; +} +void s4u::Comm::wait() { + xbt_assert(p_state == started || p_state == inited); + + if (p_state == started) + simcall_comm_wait(p_inferior, -1/*timeout*/); + else // p_state == inited + /* Save a simcall and do directly a blocking send */ + simcall_comm_send(p_sender->getInferior(), p_mailbox->getInferior(), p_remains, p_rate, + p_srcBuff, p_srcBuffSize, + p_matchFunction, p_copyDataFunction, + p_userData, p_detached); + p_state = finished; +} +void s4u::Comm::wait(double timeout) { + xbt_assert(p_state == started || p_state == inited); + + if (p_state == inited) + start(); + simcall_comm_wait(p_inferior, timeout); +} + +s4u::Comm &s4u::Comm::send_async(s4u::Actor *sender, Mailbox &dest, void *data, int simulatedSize) { + s4u::Comm &res = s4u::Comm::send_init(sender, dest); + + res.setRemains(simulatedSize); + res.p_srcBuff = data; + res.p_srcBuffSize = sizeof(void*); + + res.start(); + return res; +} + diff --git a/src/s4u/s4u_engine.cpp b/src/s4u/s4u_engine.cpp index 43e2475b21..dc22416387 100644 --- a/src/s4u/s4u_engine.cpp +++ b/src/s4u/s4u_engine.cpp @@ -9,7 +9,7 @@ #include "mc/mc.h" #include "simgrid/s4u/engine.hpp" - +XBT_LOG_NEW_CATEGORY(s4u,"Log channels of the S4U (Simgrid for you) interface"); using namespace simgrid; double s4u::Engine::getClock() { diff --git a/src/s4u/s4u_mailbox.cpp b/src/s4u/s4u_mailbox.cpp index 781284fc3d..4c83d69bfa 100644 --- a/src/s4u/s4u_mailbox.cpp +++ b/src/s4u/s4u_mailbox.cpp @@ -10,7 +10,8 @@ #include "simgrid/s4u/mailbox.hpp" -XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_channel,"S4U Communication Mailboxes"); +XBT_LOG_EXTERNAL_CATEGORY(s4u); +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_channel,s4u,"S4U Communication Mailboxes"); using namespace simgrid; diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index 459c7dc96e..fdff550195 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -380,6 +380,8 @@ endif() set(S4U_SRC src/s4u/s4u_actor.cpp + src/s4u/s4u_async.cpp + src/s4u/s4u_comm.cpp src/s4u/s4u_engine.cpp src/s4u/s4u_host.cpp src/s4u/s4u_mailbox.cpp @@ -691,6 +693,8 @@ set(headers_to_install include/simgrid/host.h include/simgrid/link.h include/simgrid/s4u/actor.hpp + include/simgrid/s4u/async.hpp + include/simgrid/s4u/comm.hpp include/simgrid/s4u/engine.hpp include/simgrid/s4u/host.hpp include/simgrid/s4u/mailbox.hpp -- 2.20.1