From ffd3399be33c589c5a5e720958f6351fdf9b0706 Mon Sep 17 00:00:00 2001 From: cherierm Date: Fri, 12 Sep 2008 12:49:26 +0000 Subject: [PATCH 1/1] The previous files renamed. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@5916 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- src/cxx/MsgApplication.cxx | 199 +++++++++ src/cxx/MsgApplication.hpp | 151 +++++++ src/cxx/MsgApplicationHandler.cxx | 190 +++++++++ src/cxx/MsgApplicationHandler.hpp | 135 ++++++ src/cxx/MsgEnvironment.cxx | 159 +++++++ src/cxx/MsgEnvironment.hpp | 153 +++++++ src/cxx/MsgHost.cxx | 343 +++++++++++++++ src/cxx/MsgHost.hpp | 440 +++++++++++++++++++ src/cxx/MsgProcess.cxx | 677 ++++++++++++++++++++++++++++++ src/cxx/MsgProcess.hpp | 617 +++++++++++++++++++++++++++ src/cxx/MsgSimulation.cxx | 108 +++++ src/cxx/MsgSimulation.hpp | 61 +++ src/cxx/MsgTask.cxx | 542 ++++++++++++++++++++++++ src/cxx/MsgTask.hpp | 540 ++++++++++++++++++++++++ 14 files changed, 4315 insertions(+) create mode 100644 src/cxx/MsgApplication.cxx create mode 100644 src/cxx/MsgApplication.hpp create mode 100644 src/cxx/MsgApplicationHandler.cxx create mode 100644 src/cxx/MsgApplicationHandler.hpp create mode 100644 src/cxx/MsgEnvironment.cxx create mode 100644 src/cxx/MsgEnvironment.hpp create mode 100644 src/cxx/MsgHost.cxx create mode 100644 src/cxx/MsgHost.hpp create mode 100644 src/cxx/MsgProcess.cxx create mode 100644 src/cxx/MsgProcess.hpp create mode 100644 src/cxx/MsgSimulation.cxx create mode 100644 src/cxx/MsgSimulation.hpp create mode 100644 src/cxx/MsgTask.cxx create mode 100644 src/cxx/MsgTask.hpp diff --git a/src/cxx/MsgApplication.cxx b/src/cxx/MsgApplication.cxx new file mode 100644 index 0000000000..ff7b4ba233 --- /dev/null +++ b/src/cxx/MsgApplication.cxx @@ -0,0 +1,199 @@ +/* + * Application.cxx + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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. + * + */ + + /* Application member functions implementation. + */ + +#include + +#include + +#include +#include +#include + +#include + +#ifndef S_ISREG + #define S_ISREG(__mode) (((__mode) & S_IFMT) == S_IFREG) +#endif + +namespace SimGrid +{ + namespace Msg + { + + Application::Application() + { + this->file = NULL; + this->deployed = false; + } + + Application::Application(const Application& rApplication) + { + + this->file = rApplication.getFile(); + this->deployed = rApplication.isDeployed(); + } + + Application::Application(const char* file) + throw(NullPointerException, FileNotFoundException) + { + // check parameters + + if(!file) + throw NullPointerException("file"); + + struct stat statBuf = {0}; + + if(stat(file, &statBuf) < 0 || !S_ISREG(statBuf.st_mode)) + throw FileNotFoundException(file); + + this->file = file; + this->deployed = false; + } + + Application::~Application() + { + // NOTHING TODO + } + + void Application::deploy(const char* file) + throw(NullPointerException, FileNotFoundException, LogicException, MsgException) + { + // check logic + + if(this->deployed) + throw LogicException("application already deployed"); + + // check the parameters + + if(!file) + throw NullPointerException("file"); + + struct stat statBuf = {0}; + + if(stat(file, &statBuf) < 0 || !S_ISREG(statBuf.st_mode)) + throw FileNotFoundException(file); + + surf_parse_reset_parser(); + + // set the begin of the xml process element handler + surfxml_add_callback(STag_surfxml_process_cb_list, ApplicationHandler::onBeginProcess); + + // set the process arg handler + surfxml_add_callback(ETag_surfxml_argument_cb_list, ApplicationHandler::onProcessArg); + + // set the properties handler + surfxml_add_callback(STag_surfxml_prop_cb_list, ApplicationHandler::OnProperty); + + // set the end of the xml process element handler + surfxml_add_callback(ETag_surfxml_process_cb_list, ApplicationHandler::onEndProcess); + + surf_parse_open(file); + + // initialize the process factory used by the process handler to build the processes. + ApplicationHandler::onStartDocument(); + + if(surf_parse()) + throw MsgException("surf_parse() failed"); + + surf_parse_close(); + + // release the process factory + ApplicationHandler::onEndDocument(); + + this->file = file; + this->deployed = true; + } + + void Application::deploy(void) + throw(LogicException, MsgException) + { + // check logic + + if(this->deployed) + throw LogicException("application already deployed"); + + // check the parameters + if(!this->file) + throw LogicException("you must specify the xml file which describe the application\nuse Application::setFile()"); + + surf_parse_reset_parser(); + surfxml_add_callback(STag_surfxml_process_cb_list, ApplicationHandler::onBeginProcess); + surfxml_add_callback(ETag_surfxml_argument_cb_list, ApplicationHandler::onProcessArg); + surfxml_add_callback(STag_surfxml_prop_cb_list, ApplicationHandler::OnProperty); + surfxml_add_callback(ETag_surfxml_process_cb_list, ApplicationHandler::onEndProcess); + + // initialize the process factory used by the process handler to build the processes. + ApplicationHandler::onStartDocument(); + + surf_parse_open(file); + + if(surf_parse()) + throw MsgException("surf_parse() failed"); + + surf_parse_close(); + + this->deployed = true; + } + + bool Application::isDeployed(void) const + { + return this->deployed; + } + + void Application::setFile(const char* file) + throw (NullPointerException, FileNotFoundException, LogicException) + { + // check logic + + if(this->deployed) + throw LogicException("your are trying to change the file of an already deployed application"); + + // check parameters + + if(!file) + throw NullPointerException("file"); + + struct stat statBuf = {0}; + + if(stat(file, &statBuf) < 0 || !S_ISREG(statBuf.st_mode)) + throw FileNotFoundException("file (file not found)"); + + this->file = file; + + } + + const char* Application::getFile(void) const + { + return this->file; + } + + const Application& Application::operator = (const Application& rApplication) + throw(LogicException) + { + // check logic + + if(this->deployed) + throw LogicException("application already deployed"); + + this->file = rApplication.getFile(); + this->deployed = rApplication.isDeployed(); + + return *this; + } + } // namespace Msg +} // namespace SimGrid + + + diff --git a/src/cxx/MsgApplication.hpp b/src/cxx/MsgApplication.hpp new file mode 100644 index 0000000000..925c1efe07 --- /dev/null +++ b/src/cxx/MsgApplication.hpp @@ -0,0 +1,151 @@ +/* + * Application.hpp + * + * This file contains the declaration of the wrapper class of the native MSG task type. + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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 MSG_APPLICATION_HPP +#define MSG_APPLICATION_HPP + +#ifndef __cplusplus + #error Application.hpp requires C++ compilation (use a .cxx suffix) +#endif + +#include +#include +#include +#include + +namespace SimGrid +{ + namespace Msg + { + // Application wrapper class declaration. + class SIMGRIDX_EXPORT Application + { + public: + + /*! \brief Default constructor. + */ + Application(); + + /*! \brief Copy constructor. + */ + Application(const Application& rApplication); + + /* \brief A constructor which takes as parameter the xml file of the application. + * + * \exception If this constructor fails, it throws on of the exceptions described + * below: + * + * [NullPointerException] if the parameter file is NULL. + * + * [FileNotFoundException] if the file is not found. + */ + Application(const char* file) + throw(NullPointerException, FileNotFoundException); + + /*! \brief Destructor. + */ + virtual ~Application(); + + // Operations. + + /*! \brief Application::deploy() - deploy the appliction. + * + * \exception If this method fails, it throws an exception listed below: + * + * \exception [LogicException] if the xml file which describes the application + * is not yet specified or if the application is already + * deployed. + * [MsgException] if a internal exception occurs. + * + * \remark Before use this method, you must specify the xml file of the application to + * deploy. + * + * \see Application::setFile() + */ + + void deploy(void) + throw(LogicException, MsgException); + + /*! \brief Application::deploy() - Deploy the appliction. + * + * \return If successfuly the application is deployed. Otherwise + * the method throws an exception listed below. + * + * \exception [NullPointerException] if the parameter file is NULL. + * + * [FileNotFoundException] if the file is not found. + * + * [MsgException] if a internal exception occurs. + * + * [LogicException] if the application is already deployed. + * + * \ + */ + void deploy(const char* file) + throw(NullPointerException, FileNotFoundException, LogicException, MsgException); + + /*! \brief Application::isDeployed() - Tests if the application is deployed. + * + * \return This method returns true is the application is deployed. + * Otherwise the method returns false. + */ + bool isDeployed(void) const; + + + // Getters/setters + + /*! \brief Application::setFile() - this setter sets the value of the file of the application. + * + * \exception If this method fails, it throws on of the exceptions listed below: + * + * [NullPointerException] if the parameter file is NULL. + * + * [FileNotFoundException] if the file is not found. + + * [LogicException] if you try to set the value of the file of an + * application which is already deployed. + */ + void setFile(const char* file) + throw (NullPointerException, FileNotFoundException, LogicException); + + /*! \brief Application::getFile() - This getter returns the name of the xml file which describes the + * application of the simulation. + */ + const char* getFile(void) const; + + // Operators. + + /*! \brief Assignement operator. + * + * \exception [LogicException] if you try to assign an application already deployed. + */ + const Application& operator = (const Application& rApplication) + throw(LogicException); + + private: + // Attributes. + + // flag : if true the application was deployed. + bool deployed; + + // the xml file which describes the application of the simulation. + const char* file; + + }; + + } // namespace Msg +} // namespace SimGrid + +#endif // !MSG_APPLICATION_HPP + diff --git a/src/cxx/MsgApplicationHandler.cxx b/src/cxx/MsgApplicationHandler.cxx new file mode 100644 index 0000000000..dc70b2cd7f --- /dev/null +++ b/src/cxx/MsgApplicationHandler.cxx @@ -0,0 +1,190 @@ +/* + * ApplicationHandler.cxx + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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. + * + */ + + /* ApplicationHandler member functions implementation. + */ + + +#include +#include + +#include +#include + + + + + +#include + +#include +#include + + +namespace SimGrid +{ + namespace Msg + { + + ApplicationHandler::ProcessFactory* ApplicationHandler::processFactory = NULL; + + // Desable the default constructor, the copy constructor , the assignement operator + // and the destructor of this class. Assume that this class is static. + + // Default constructor. + ApplicationHandler::ApplicationHandler() + { + // NOTHING TODO + } + + // Copy constructor. + ApplicationHandler::ApplicationHandler(const ApplicationHandler& rApplicationHandler) + { + // NOTHING TODO + } + + // Destructor + ApplicationHandler::~ApplicationHandler() + { + // NOTHING TODO + } + + // Assignement operator. + const ApplicationHandler& ApplicationHandler::operator = (const ApplicationHandler& rApplicationHandler) + { + return *this; + } + + void ApplicationHandler::onStartDocument(void) + { + // instanciate the factory at the begining of the parsing + processFactory = new ProcessFactory(); + } + + void ApplicationHandler::onEndDocument(void) + { + // release the handler at the end of the parsing. + if(processFactory) + delete processFactory; + } + + void ApplicationHandler::onBeginProcess(void) + { + // set the process identity at the begin of the xml process element. + processFactory->setProcessIdentity(A_surfxml_process_host, A_surfxml_process_function); + } + + void ApplicationHandler::onProcessArg(void) + { + // register the argument of the current xml process element. + processFactory->registerProcessArg(A_surfxml_argument_value); + } + + void ApplicationHandler::OnProperty(void) + { + // set the property of the current xml process element. + processFactory->setProperty(A_surfxml_prop_id, A_surfxml_prop_value); + } + + void ApplicationHandler::onEndProcess(void) + { + // at the end of the xml process element create the wrapper process (of the native Msg process) + processFactory->createProcess(); + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Process factory connected member functions + + ApplicationHandler::ProcessFactory::ProcessFactory() + { + this->args = xbt_dynar_new(sizeof(char*),ApplicationHandler::ProcessFactory::freeCstr); + this->properties = NULL; // TODO instanciate the dictionary + this->hostName = NULL; + this->function = NULL; + } + + ApplicationHandler::ProcessFactory::~ProcessFactory() + { + xbt_dynar_free(&(this->args)); + } + + // create the cxx process wrapper. + void ApplicationHandler::ProcessFactory::createProcess() + throw (ClassNotFoundException, HostNotFoundException) + { + Host host; + Class* c; + Process* process; + + // try to dynamicaly create an instance of the process from its name (which is specified by the element function + // in the xml application file. + // if this static method fails, it throws an exception of the class ClassNotFoundException + c = Class::fromName(this->function); + process = reinterpret_cast(c->createObject()); + + // try to retrieve the host of the process from its name + // if this method fails, it throws an exception of the class HostNotFoundException + host = Host::getByName(this->hostName); + + // build the list of the arguments of the newly created process. + int argc = xbt_dynar_length(this->args); + + char** argv = (char**)calloc(argc, sizeof(char*)); + + for(int i = argc -1; i >= 0; i--) + xbt_dynar_pop(this->args, &(argv[i])); + + // finaly create the process (for more detail on the process creation see Process::create() + process->create(host, this->function , argc, argv); + + // TODO add the properties of the process + /*process->properties = this->properties; + this->properties = new Properties();*/ + } + + void ApplicationHandler::ProcessFactory::setProcessIdentity(const char* hostName, const char* function) + { + this->hostName = hostName; + this->function = function; + + /*if (!this->args->empty()) + this->args->clear(); + + if(!this->properties->empty()) + this->properties->clear();*/ + } + + // callback function used by the dynamic array to cleanup all of its elements. + void ApplicationHandler::ProcessFactory::freeCstr(void* cstr) + { + free(*(void**)cstr); + } + + void ApplicationHandler::ProcessFactory::registerProcessArg(const char* arg) + { + char* cstr = _strdup(arg); + xbt_dynar_push(this->args, &cstr); + } + + void ApplicationHandler::ProcessFactory::setProperty(const char* id, const char* value) + { + // TODO implement this function; + } + + const char* ApplicationHandler::ProcessFactory::getHostName(void) + { + return this->hostName; + } + + } // namespace Msg +} // namespace SimGrid + diff --git a/src/cxx/MsgApplicationHandler.hpp b/src/cxx/MsgApplicationHandler.hpp new file mode 100644 index 0000000000..46c7c8ad41 --- /dev/null +++ b/src/cxx/MsgApplicationHandler.hpp @@ -0,0 +1,135 @@ +/* + * ApplicationHandler.hpp + * + * This file contains the declaration of the wrapper class of the native MSG task type. + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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 MSG_APPLICATION_HANDLER_HPP +#define MSG_APPLICATION_HANDLER_HPP + +// Compilation C++ recquise +#ifndef __cplusplus + #error ApplicationHandler.hpp requires C++ compilation (use a .cxx suffix) +#endif + +#include +#include + +#include +#include + +namespace SimGrid +{ + namespace Msg + { + class Process; + + // Declaration of the class ApplicationHandler (Singleton). + class SIMGRIDX_EXPORT ApplicationHandler + { + //friend Process; + + public: + + class ProcessFactory + { + public: + + // the list of the argument of the process to create. + xbt_dynar_t args; + // the properties of the process to create + xbt_dict_t properties; + + private: + + // the current host name parsed + const char* hostName; + // the name of the class of the process + const char* function; + + public : + + // Default constructor. + ProcessFactory(); + + // Copy constructor. + ProcessFactory(const ProcessFactory& rProcessFactory); + + // Destructor. + virtual ~ProcessFactory(); + + // Set the identity of the current process. + void setProcessIdentity(const char* hostName, const char* function); + + // Register an argument of the current process. + void registerProcessArg(const char* arg); + + // Set the property of the current process. + void setProperty(const char* id, const char* value); + + // Return the host name of the current process. + const char* getHostName(void); + + // Create the current process. + void createProcess(void) + throw (ClassNotFoundException, HostNotFoundException); + + static void freeCstr(void* cstr); + + }; + + private : + + // Desable the default constructor, the copy constructor , the assignement operator + // and the destructor of this class. Assume that this class is static. + + // Default constructor. + ApplicationHandler(); + + // Copy constructor. + ApplicationHandler(const ApplicationHandler& rApplicationHandler); + + // Destructor + virtual ~ApplicationHandler(); + + // Assignement operator. + const ApplicationHandler& operator = (const ApplicationHandler& rApplicationHandler); + + // the process factory used by the application handler. + static ProcessFactory* processFactory; + + + public: + + // Handle the begining of the parsing of the xml file describing the application. + static void onStartDocument(void); + + // Handle at the end of the parsing. + static void onEndDocument(void); + + // Handle the begining of the parsing of a xml process element. + static void onBeginProcess(void); + + // Handle the parsing of an argument of the current xml process element. + static void onProcessArg(void); + + // Handle the parsing of a property of the currnet xml process element. + static void OnProperty(void); + + // Handle the end of the parsing of a xml process element + static void onEndProcess(void); + }; + + } // namespace Msg +} // namespace SimGrid + +#endif // !MSG_APPLICATION_HANDLER_HPP + diff --git a/src/cxx/MsgEnvironment.cxx b/src/cxx/MsgEnvironment.cxx new file mode 100644 index 0000000000..6bdbe33da7 --- /dev/null +++ b/src/cxx/MsgEnvironment.cxx @@ -0,0 +1,159 @@ +/* + * Environment.cxx + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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. + * + */ + + /* Environment member functions implementation. + */ + +#include + +#include + +#include +#include + +#include + +#ifndef S_ISREG + #define S_ISREG(__mode) (((__mode) & S_IFMT) == S_IFREG) +#endif + +namespace SimGrid +{ + namespace Msg + { + Environment::Environment() + { + this->file = NULL; + this->loaded = false; + } + + Environment::Environment(const Environment& rEnvironment) + { + this->file = rEnvironment.getFile(); + this->loaded = rEnvironment.isLoaded(); + } + + Environment::Environment(const char* file) + throw(NullPointerException, FileNotFoundException) + { + // check parameters + + if(!file) + throw NullPointerException("file (must not be NULL"); + + struct stat statBuf = {0}; + + if(stat(file, &statBuf) < 0 || !S_ISREG(statBuf.st_mode)) + throw FileNotFoundException("file (file not found)"); + + this->file = file; + this->loaded = false; + } + + Environment::~Environment() + { + // NOTHING TODO + } + + // Operations. + + void Environment::load(void) + throw(LogicException) + { + // check logic + + if(this->loaded) + throw LogicException("environement already loaded"); + + // check the parameters + if(!this->file) + throw LogicException("you must specify the xml file which describe the environment to load\nuse Environment::setFile()"); + + MSG_create_environment(file); + + this->loaded = true; + } + + void Environment::load(const char* file) + throw(NullPointerException, FileNotFoundException, LogicException) + { + // check logic + + if(this->loaded) + throw LogicException("environment already loaded"); + + // check the parameters + + if(!file) + throw NullPointerException("file"); + + struct stat statBuf = {0}; + + if(stat(file, &statBuf) < 0 || !S_ISREG(statBuf.st_mode)) + throw FileNotFoundException(file); + + MSG_create_environment(file); + + this->file = file; + this->loaded = true; + } + + bool Environment::isLoaded(void) const + { + return this->loaded; + } + + // Getters/setters + void Environment::setFile(const char* file) + throw(NullPointerException, FileNotFoundException, LogicException) + { + // check logic + + if(this->loaded) + throw LogicException("your are trying to change the file of an already loaded environment"); + + // check parameters + + if(!file) + throw NullPointerException("file (must not be NULL"); + + struct stat statBuf = {0}; + + if(stat(file, &statBuf) < 0 || !S_ISREG(statBuf.st_mode)) + throw FileNotFoundException("file (file not found)"); + + this->file = file; + } + + const char* Environment::getFile(void) const + { + return this->file; + } + + + const Environment& Environment::operator = (const Environment& rEnvironment) + throw(LogicException) + { + // check logic + + if(this->loaded) + throw LogicException("environment already loaded"); + + this->file = rEnvironment.getFile(); + this->loaded = rEnvironment.isLoaded(); + + return *this; + } + + } // namespace Msg +} // namespace SimGrid + diff --git a/src/cxx/MsgEnvironment.hpp b/src/cxx/MsgEnvironment.hpp new file mode 100644 index 0000000000..8f8e0a0e28 --- /dev/null +++ b/src/cxx/MsgEnvironment.hpp @@ -0,0 +1,153 @@ +/* + * Environment.hpp + * + * This file contains the declaration of the wrapper class of the native MSG task type. + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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 MSG_ENVIRONMENT_HPP +#define MSG_ENVIRONMENT_HPP + +#ifndef __cplusplus + #error Environment.hpp requires C++ compilation (use a .cxx suffix) +#endif + +#include +#include +#include +#include +#include + +namespace SimGrid +{ + namespace Msg + { + class NullPointerException; + class FileNotFoundException; + class InvalidArgumentException; + class LogicException; + class MsgException; + + // Environment class wrapper declaration + class SIMGRIDX_EXPORT Environment + { + public: + + /*! \brief Default constructor. + */ + Environment(); + + /*! \brief Copy constructor. + */ + Environment(const Environment& rEnvironment); + + /*! \brief Constructor. + * + * \param file The xml file describing the environment of the simulation. + * + * \exception If this constructor fails, it throws one of the exception + * described below: + * + * [NullPointerException] if the parameter file is NULL. + * + * [FileNotFoundException] if the file is not found. + */ + Environment(const char* file) + throw(NullPointerException, FileNotFoundException); + + /*! \brief Destructor. + */ + virtual ~Environment(); + + // Operations. + + /*! brief Environment::load() - Load the environment of a simulation. + * + * \exception If this method fails, it throws the exception described below: + * + * [LogicException] if the file of the environment is not yet specified or + * if the environment is already loaded. + */ + void load(void) + throw(LogicException); + + /*! \brief Environment::load() - Load the environment of a simulation. + * + * \param file The xml file describing the environment of the simulation. + * + * \exception If this method fails, it throws one of the exceptions described below. + * + * [NullPointerException] if the parameter file is NULL. + * + * [FileNotFoundException] if the specified file is not found. + * + * [LogicException] if the environment is already loaded. + */ + void load(const char* file) + throw(NullPointerException, FileNotFoundException, LogicException); + + /*! \brief Environment::isLoaded() - Tests if an environment is loaded. + * + * \return If the environment is loaded, the method returns true. Otherwise the method + * returns false. + */ + bool isLoaded(void) const; + + // Getters/setters + /*! \brief Environment::setFile() - Sets the xml file of the environment. + * + * \param file The file describing the environment. + * + * \exception If the method fails, it throws one of the exceptions described below: + * + * [NullPointerException] if the parameter file is NULL. + * + * [FileNotFoundException] if the file is not found. + * + * [LogicException] if the environment is already loaded. + */ + void setFile(const char* file) + throw(NullPointerException, FileNotFoundException, LogicException); + + /*! \brief Environment::getFile() - Gets the xml file environment description. + * + * \return The xml file describing the environment. + * + */ + const char* getFile(void) const; + + // Operators. + + /*! \brief Assignment operator. + * + * \exception If this operator fails, it throws the exception described below: + * + * [LogicException] if you try to assign a loaded environment. + */ + const Environment& operator = (const Environment& rEnvironment) + throw(LogicException); + + private: + + // Attributes. + + // the xml file which describe the environment of the simulation. + const char* file; + + // flag : is true the environment of the simulation is loaded. + bool loaded; + }; + + } // namespace Msg +} // namespace SimGrid + + +#endif // !MSG_ENVIRONMENT_HPP + diff --git a/src/cxx/MsgHost.cxx b/src/cxx/MsgHost.cxx new file mode 100644 index 0000000000..e11e124ceb --- /dev/null +++ b/src/cxx/MsgHost.cxx @@ -0,0 +1,343 @@ +/* + * Host.cxx + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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. + * + */ + + /* Host class member functions implementation. + */ + +#include +#include + +#include + +#include +#include + +#include +#include + +#include + +namespace SimGrid +{ + namespace Msg + { + Host::Host() + { + nativeHost = NULL; + data = NULL; + } + + Host::Host(const Host& rHost) + { + this->nativeHost = rHost.nativeHost; + this->data = rHost.getData(); + } + + Host::~Host() + { + // NOTHING TODO + } + + + Host& Host::getByName(const char* hostName) + throw(HostNotFoundException, NullPointerException, BadAllocException) + { + // check the parameters + if(!hostName) + throw NullPointerException("hostName"); + + m_host_t nativeHost = NULL; // native host. + Host* host = NULL; // wrapper host. + + if(!(nativeHost = MSG_get_host_by_name(hostName))) + throw HostNotFoundException(hostName); + + if(!nativeHost->data) + { // native host not associated yet with its wrapper + + // instanciate a new wrapper + if(!(host = new Host())) + throw BadAllocException(hostName); + + host->nativeHost = nativeHost; + + // the native host data field is set with its wrapper returned + nativeHost->data = (void*)host; + } + + // return the reference to cxx wrapper + return *((Host*)nativeHost->data); + } + + int Host::getNumber(void) + { + return MSG_get_host_number(); + } + + Host& Host::currentHost(void) + { + Host* host = NULL; + m_host_t nativeHost = MSG_host_self(); + + if(!nativeHost->data) + { + // the native host not yet associated with its wrapper + + // instanciate a new wrapper + host = new Host(); + + host->nativeHost = nativeHost; + + nativeHost->data = (void*)host; + } + else + { + host = (Host*)nativeHost->data; + } + + return *host; + } + + void Host::all(Host*** hosts, int* len) + throw(InvalidArgumentException, BadAllocException) + { + // check the parameters + if(!hosts) + throw InvalidArgumentException("hosts"); + + if(len < 0) + throw InvalidArgumentException("len parameter must be positive"); + + int count = xbt_fifo_size(msg_global->host); + + if(*len < count) + throw InvalidArgumentException("len parameter must be more than the number of installed host\n (use Host::getNumber() to get the number of hosts)"); + + int index; + m_host_t nativeHost; + Host* host; + + m_host_t* table = (m_host_t *)xbt_fifo_to_array(msg_global->host); + + for(index = 0; index < count; index++) + { + nativeHost = table[index]; + host = (Host*)(nativeHost->data); + + if(!host) + { + if(!(host = new Host())) + { + // release all allocated memory. + for(int i = 0; i < index; i++) + delete (*(hosts)[i]); + + throw BadAllocException("to fill the table of the hosts installed on your platform"); + } + + host->nativeHost = nativeHost; + nativeHost->data = (void*)host; + } + + (*hosts)[index] = host; + } + + *len = count; + } + + const char* Host::getName(void) const + { + return nativeHost->name; + } + + void Host::setData(void* data) + { + this->data = data; + } + + void* Host::getData(void) const + { + return this->data; + } + + int Host::getRunningTaskNumber(void) const + { + return MSG_get_host_msgload(nativeHost); + } + + double Host::getSpeed(void) const + { + return MSG_get_host_speed(nativeHost); + } + + bool Host::hasData(void) const + { + return (NULL != this->data); + } + + int Host::isAvailable(void) const + { + return SIMIX_host_get_state(nativeHost->simdata->smx_host); + } + + void Host::put(int channel, Task* task) + throw(MsgException, InvalidArgumentException) + { + // checks the parameters + if(channel < 0) + throw InvalidArgumentException("channel (must be more or equal to zero)"); + + if(MSG_OK != MSG_task_put_with_timeout(task->nativeTask, nativeHost, channel , -1.0)) + throw MsgException("MSG_task_put_with_timeout() failed"); + } + + void Host::put(int channel, Task* task, double timeout) + throw(MsgException, InvalidArgumentException) + { + // checks the parameters + if(channel < 0) + throw InvalidArgumentException("channel (must be more or equal to zero)"); + + if(timeout < 0.0 && timeout != -1.0) + throw InvalidArgumentException("timeout (must be more or equal to zero or equal to -1.0)"); + + + if(MSG_OK != MSG_task_put_with_timeout(task->nativeTask, nativeHost, channel , timeout)) + throw MsgException("MSG_task_put_with_timeout() failed"); + } + + void Host::putBounded(int channel, Task* task, double maxRate) + throw(MsgException, InvalidArgumentException) + { + // checks the parameters + if(channel < 0) + throw InvalidArgumentException("channel (must be more or equal to zero)"); + + if(maxRate < 0.0 && maxRate != -1.0) + throw InvalidArgumentException("maxRate (must be more or equal to zero or equal to -1.0)"); + + if(MSG_OK != MSG_task_put_bounded(task->nativeTask, nativeHost, channel, maxRate)) + throw MsgException("MSG_task_put_bounded() failed"); + } + + void Host::send(Task* task) + throw(MsgException, BadAllocException) + { + MSG_error_t rv; + + char* alias = (char*)calloc(strlen(this->getName())+ strlen(Process::currentProcess().getName()) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", this->getName(),Process::currentProcess().getName()); + + rv = MSG_task_send_with_timeout(task->nativeTask, alias, -1.0); + + free(alias); + + if(MSG_OK != rv) + throw MsgException("MSG_task_send_with_timeout() failed"); + } + + void Host::send(const char* alias, Task* task) + throw(InvalidArgumentException, MsgException) + { + // check the parameters + if(!alias) + throw InvalidArgumentException("alias (must not be NULL)"); + + if(MSG_OK != MSG_task_send_with_timeout(task->nativeTask, alias, -1.0)) + throw MsgException("MSG_task_send_with_timeout() failed"); + } + + void Host::send(Task* task, double timeout) + throw(InvalidArgumentException, BadAllocException, MsgException) + { + // check the parameters + if(timeout < 0 && timeout != -1.0) + throw InvalidArgumentException("timeout (must be positive or equal to zero or equal to -1.0)"); + + MSG_error_t rv; + + char* alias = (char*)calloc(strlen(this->getName()) + strlen(Process::currentProcess().getName()) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", this->getName(),Process::currentProcess().getName()); + + + rv = MSG_task_send_with_timeout(task->nativeTask, alias, timeout); + + free(alias); + + if(MSG_OK != rv) + throw MsgException("MSG_task_send_with_timeout() failed"); + } + + void Host::send(const char* alias, Task* task, double timeout) + throw(InvalidArgumentException, MsgException) + { + // check the parameter + + if(!alias) + throw InvalidArgumentException("alias (must not be NULL)"); + + if(timeout < 0 && timeout != -1.0) + throw InvalidArgumentException("timeout (must be positive or equal to zero or equal to -1.0)"); + + if(MSG_OK != MSG_task_send_with_timeout(task->nativeTask, alias, timeout)) + throw MsgException("MSG_task_send_with_timeout() failed"); + } + + + void Host::sendBounded(Task* task, double maxRate) + throw(InvalidArgumentException, BadAllocException, MsgException) + { + if(maxRate < 0 && maxRate != -1.0) + throw InvalidArgumentException("maxRate (must be positive or equal to zero or equal to -1.0)"); + + MSG_error_t rv; + + char* alias = (char*)calloc(strlen(this->getName()) + strlen(Process::currentProcess().getName()) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", this->getName(),Process::currentProcess().getName()); + + rv = MSG_task_send_bounded(task->nativeTask, alias, maxRate); + + free(alias); + + if(MSG_OK != rv) + throw MsgException("MSG_task_send_bounded() failed"); + } + + void Host::sendBounded(const char* alias, Task* task, double maxRate) + throw(InvalidArgumentException, MsgException) + { + // check the parameters + if(!alias) + throw InvalidArgumentException("alias (must not be NULL)"); + + if(maxRate < 0 && maxRate != -1) + throw InvalidArgumentException("maxRate (must be positive or equal to zero or equal to -1.0)"); + + if(MSG_OK != MSG_task_send_bounded(task->nativeTask, alias, maxRate)) + throw MsgException("MSG_task_send_bounded() failed"); + + } + } // namspace Msg +} // namespace SimGrid + diff --git a/src/cxx/MsgHost.hpp b/src/cxx/MsgHost.hpp new file mode 100644 index 0000000000..c012513828 --- /dev/null +++ b/src/cxx/MsgHost.hpp @@ -0,0 +1,440 @@ +/* + * Host.hpp + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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 MSG_HOST_HPP +#define MSG_HOST_HPP + + +/*! \brief Host class declaration. + * + * An host instance represents a location (any possible place) where a process may run. + * Thus it is represented as a physical resource with computing capabilities, some + * mailboxes to enable running process to communicate with remote ones, and some private + * data that can be only accessed by local process. An instance of this class is always + * binded with the corresponding native host. All the native hosts are automaticaly created + * during the call of the static method Msg::createEnvironment(). This method takes as parameter + * the platform file which describes all elements of the platform (host, link, root..). + * You never need to create an host your self. + * + * The best way to get an host is to call the static method + * Host.getByName() which returns a reference. + * + * For example to get the instance of the host. If your platform + * file description contains an host named "Jacquelin" : + * + * \verbatim +using namespace SimGrid.Msg; + +Host jacquelin; + +try +{ + jacquelin = Host::getByName("Jacquelin"); +} +catch(HostNotFoundException e) +{ + cerr << e.toString(); +} +... +\endverbatim + * + */ + +#ifndef __cplusplus + #error Host.hpp requires C++ compilation (use a .cxx suffix) +#endif + +#include + +#include +#include +#include +#include +#include + + + +// namespace SimGrid::Msg +namespace SimGrid +{ + namespace Msg + { + class Task; + class Process; + + // Declaration of the class SimGrid::Msg::Host. + class SIMGRIDX_EXPORT Host // final class. + { + friend class Process; + friend class Task; + + // Desable the default constructor. + // The best way to get an host instance is to use the static method Host::getByName(). + + public : + + // Default constructor (desabled). + Host(); + + public: + + // Copy constructor (desabled). + Host(const Host& rHost); + + // Destructor (desable). + virtual ~Host(); + + // Operations + + /*! \brief Host::getByName() - returns an host by its name + * + * This static method returns a reference to the host instance associated + * with a native host of your platform. This is the best way to get a host. + * + * \param hostName The name of the host. + * + * \return If successful the method returns a reference to the instance + * associated with the native host having the name specified + * as parameter of your platform. Otherwise the method throws + * one of the exceptions detailed below. + * + * \exception [HostNotFoundException] if no host with the specified name + * was found. + * [InvalidArgumentException] if the hostName parameter is invalid (NULL). + * [BadAllocException] if there is not enough memory to allocate the host. + */ + static Host& getByName(const char* hostName) + throw(HostNotFoundException, NullPointerException, BadAllocException); + + /*! \brief Host::getNumber() - returns the number of the installed hosts. + * + * \return The number of hosts installed. + */ + static int getNumber(void); + + + /*! \brief Host::currentHost() - This static method returns the location on which the current + * process is executed. + * + * \return The host of the current process. + * + * \see Process::currentProcess(). + */ + static Host& currentHost(void); + + /*! \brief Host::all() - This static method retrieves all of the hosts of the installed platform. + * + * \param hosts A pointer to array of Host pointers that receives all the hosts of the platform. + * + * \param len A pointer to the length of the table of pointers. + * + * \return If successful the hosts table is filled and + * the parameter len is set with the number of hosts of the platform. + * Otherwise the method throw one of the exception described below. + * + * \exception [InvalidArgumentException] if the parameter hosts is invalid or + * if the parameter len is negative or + * less than the number of hosts installed + * on the current platform. + * [BadAllocException] If the method can't allocate memory to fill + * the table of hosts. + * + * + * \remark To get the number of hosts installed on your platform use the static method + * Host::getNumber(). + * + * \see Host::getNumber(). + * + *\verbatim + * // This example show how to use this method to get the list of hosts installed on your platform. + * + * using namespace SimGrid::Msg; + * using + * + * // (1) get the number of hosts. + * int number = Host::getNumber(); + * + * // (2) allocate the array that receives the list of hosts. + * HostPtr* ar = new HostPtr[number]; // HostPtr is defined as (typedef Host* HostPtr at the end of the + * // declaration of this class. + * + * // (3) call the method + * try + * { + * Host::all(&ar, &number); + * } + * catch(BadAllocException e) + * { + * cerr << e.toString() << endl; + * ... + * } + * catch(InvalidArgumentException e) + * { + * cerr << e.toString() << endl; + * .. + * } + * + * // (4) use the table of host (for example print all the name of all the hosts); + * + * for(int i = 0; i < number ; i++) + * cout << ar[i]->getName() << endl; + * + * ... + * + * // (5) release the allocate table + * + * delete[] ar; + * + */ + static void all(Host*** hosts /*in|out*/, int* len /*in|out*/) + throw(InvalidArgumentException, BadAllocException) ; + + /*! \brief Host::getName() - This method return the name of the Msg host object. + * + * \return The name of the host object. + */ + const char* getName(void) const; + + /*! \brief Host::setData() - Set the user data of an host object. + * + * \param data The user data to set. + */ + void setData(void* data); + + /*! \brief Host::getData() - Get the user data of a host object. + * + * \return The user data of the host object. + */ + void* getData(void) const; + + /*! \brief Host::hasData() - Test if an host object has some data. + * + * \return This method returns true if the host object has some user data. + * Otherwise the method returns false. + */ + bool hasData(void) const; + + /*! \brief Host::getRunningTaskNumber() - returns the number of tasks currently running on a host. + * + * \return The number of task currently running of the host object. + * + * \remark The external load is not taken in account. + */ + int getRunningTaskNumber(void) const; + + /*! \brief Host::getSpeed() - returns the speed of the processor of a host, + * regardless of the current load of the machine. + * + * \return The speed of the processor of the host in flops. + */ + double getSpeed(void) const; + + /*! \brief Host::isAvailable - tests if an host is availabled. + * + * \return Is the host is availabled the method returns + * 1. Otherwise the method returns 0. + */ + int isAvailable(void) const; + + /* ! \brief Host::put() - put a task on the given channel of a host . + * + * \param channel The channel where to put the task. + * \param rTask A refercence to the task object containing the native task to + * put on the channel specified by the parameter channel. + * + * \return If successful the task is puted on the specified channel. Otherwise + * the method throws one of the exceptions described below. + * + * \exception [MsgException] if an internal error occurs. + * [InvalidArgumentException] if the value of the channel specified as + * parameter is negative. + */ + void put(int channel, Task* task) + throw(MsgException, InvalidArgumentException); + + /* ! \brief Host::put() - put a task on the given channel of a host object (waiting at most timeout seconds). + * + * \param channel The channel where to put the task. + * \param rTask A refercence to the task object containing the native task to + * put on the channel specified by the parameter channel. + * \param timeout The timeout in seconds. + * + * \return If successful the task is puted on the specified channel. Otherwise + * the method throws one of the exceptions described below. + * + * \exception [MsgException] if an internal error occurs. + * [InvalidArgumentException] if the value of the channel specified as + * parameter is negative or if the timeout value + * is less than zero and différent of -1. + * + * \remark To specify no timeout set the timeout value with -1.0. + */ + void put(int channel, Task* task, double timeout) + throw(MsgException, InvalidArgumentException); + + /* ! \brief Host::putBounded() - put a task on the given channel of a host object (capping the emission rate to maxrate). + * + * \param channel The channel where to put the task. + * \param rTask A refercence to the task object containing the native task to + * put on the channel specified by the parameter channel. + * \param maxRate The maximum rate. + * + * \return If successful the task is puted on the specified channel. Otherwise + * the method throws one of the exceptions described below. + * + * \exception [MsgException] if an internal error occurs. + * [InvalidArgumentException] if the value of the channel specified as + * parameter is negative or if the maxRate parameter value + * is less than zero and différent of -1.0. + * + * \remark To specify no rate set the maxRate parameter value with -1.0. + */ + void putBounded(int channel, Task* task, double maxRate) + throw(MsgException, InvalidArgumentException); + + /* ! brief Host::send() - sends the given task to mailbox identified by the default alias. + * + * \param rTask A reference to the task object containing the native msg task to send. + * + * \return If successful the task is sended to the default mailbox. Otherwise the + * method throws one of the exceptions described below. + * + * \exception [BadAllocException] if there is not enough memory to allocate + * the default alias variable. + * [MsgException] if an internal error occurs. + */ + void send(Task* task) + throw(MsgException, BadAllocException); + + /* ! brief Host::send() - sends the given task to mailbox identified by the specified alias parameter. + * + * \param rTask A reference to the task object containing the native msg task to send. + * \param alias The alias of the mailbox where to send the task. + * + * \return If successful the task is sended to the default mailbox. Otherwise the + * method throws one of the exceptions described below. + * + * \exception [InvalidArgumentException] if alias parameter is invalid (NULL). + * [BadAllocException] if there is not enough memory to allocate + * the default alias variable. + * [MsgException] if an internal error occurs. + */ + void send(const char* alias, Task* task) + throw(InvalidArgumentException, MsgException); + + /* ! brief Host::send() - sends the given task to mailbox identified by the default alias + * (waiting at most timeout seconds). + * + * \param rTask A reference to the task object containing the native msg task to send. + * \param timeout The timeout value to wait for. + * + * \return If successful the task is sended to the default mailbox. Otherwise the + * method throws one of the exceptions described below. + * + * \exception [BadAllocException] if there is not enough memory to allocate + * the default alias variable. + * [InvalidArgumentException] if the timeout value is negative and different of + * -1.0. + * [MsgException] if an internal error occurs. + * + * \remark To specify no timeout set the timeout value with -1.0 or use the previous + * version of this method. + * + */ + void send(Task* task, double timeout) + throw(InvalidArgumentException, BadAllocException, MsgException); + + /* ! brief Host::send() - sends the given task to mailbox identified by the parameter alias + * (waiting at most timeout seconds). + * + * \param alias The alias of the mailbox to send the task. + * \param rTask A reference to the task object containing the native msg task to send. + * \param timeout The timeout value to wait for. + * + * \return If successful the task is sended to the default mailbox. Otherwise the + * method throws one of the exceptions described below. + * + * \exception [InvalidArgumentException] if the timeout value is negative and different of + * -1.0 or if the alias parameter is invalid (NULL). + * [MsgException] if an internal error occurs. + * + * \remark To specify no timeout set the timeout value with -1.0 or use the previous + * version of this method. + * + */ + void send(const char* alias, Task* task, double timeout) + throw(InvalidArgumentException, MsgException); + + /* ! brief Host::sendBounded() - sends the given task to mailbox associated to the default alias + * (capping the emission rate to maxRate). + * + * \param rTask A reference to the task object containing the native msg task to send. + * \param maxRate The maximum rate value. + * + * \return If successful the task is sended to the default mailbox. Otherwise the + * method throws one of the exceptions described below. + * + * \exception [InvalidArgumentException] if the maximum rate value is negative and different of + * -1.0. + * [MsgException] if an internal error occurs. + * [BadAllocException] if there is not enough memory to allocate + * the default alias variable. + * + * \remark To specify no rate set its value with -1.0. + * + */ + void sendBounded(Task* task, double maxRate) + throw(InvalidArgumentException, BadAllocException, MsgException); + + /* ! brief Host::sendBounded() - sends the given task to mailbox identified by the parameter alias + * (capping the emission rate to maxRate). + * + * \param alias The alias of the mailbox where to send the task. + * \param rTask A reference to the task object containing the native msg task to send. + * \param maxRate The maximum rate value. + * + * \return If successful the task is sended to the default mailbox. Otherwise the + * method throws one of the exceptions described below. + * + * \exception [InvalidArgumentException] if the maximum rate value is negative and different of + * -1.0 or if the alias parameter is invalid (NULL). + * [MsgException] if an internal error occurs. + * + * \remark To specify no rate set its value with -1.0. + * + */ + void sendBounded(const char* alias, Task* task, double maxRate) + throw(InvalidArgumentException, MsgException); + + protected: + // Attributes. + + /** + * This attribute represents the msg native host object. + * It is set automaticatly during the call of the static + * method Host::getByName(). + * + * \see Host::getByName(). + */ + m_host_t nativeHost; + + private: + /** + * User host data. + */ + void* data; + }; + + typedef Host* HostPtr; + } // namespace Msg +} // namespace SimGrid + +#endif // !MSG_HOST_HPP diff --git a/src/cxx/MsgProcess.cxx b/src/cxx/MsgProcess.cxx new file mode 100644 index 0000000000..d6b450473c --- /dev/null +++ b/src/cxx/MsgProcess.cxx @@ -0,0 +1,677 @@ +/* + * Process.cxx + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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. + * + */ + + /* Process member functions implementation. + */ + +#include + + +#include +#include +#include + +#include +#include + +#include +#include +#include + + + +namespace SimGrid +{ + namespace Msg + { + + MSG_IMPLEMENT_DYNAMIC(Process, Object) + + // Default constructor. + Process::Process() + { + this->nativeProcess = NULL; + } + + Process::Process(const char* hostName, const char* name) + throw(NullPointerException, HostNotFoundException, BadAllocException) + { + // check the parameters + + if(!name) + throw NullPointerException("name"); + + if(!hostName) + throw NullPointerException("hostName"); + + Host host = Host::getByName(hostName); + + create(host, name, 0, NULL); + } + + Process::Process(const Host& rHost, const char* name) + throw(NullPointerException) + { + if(!name) + throw NullPointerException("name"); + + create(rHost, name, 0, NULL); + } + + Process::Process(const Host& rHost, const char* name, int argc, char** argv) + throw(NullPointerException, InvalidArgumentException, LogicException) + { + + // check the parameters + + if(!name) + throw NullPointerException("name"); + + if(argc < 0) + throw InvalidArgumentException("argc (must be positive)"); + + if(!argc && argv) + throw LogicException("argv is not NULL but argc is zero"); + + if(argc && !argv) + throw LogicException("argv is NULL but argc is not zero"); + + create(rHost, name, argc, argv); + } + + Process::Process(const char* hostName, const char* name, int argc, char** argv) + throw(NullPointerException, InvalidArgumentException, LogicException, HostNotFoundException, BadAllocException) + { + // check the parameters + + if(!name) + throw NullPointerException("name"); + + if(!hostName) + throw NullPointerException("hostName"); + + if(argc < 0) + throw InvalidArgumentException("argc (must be positive)"); + + if(!argc && argv) + throw LogicException("argv is not NULL but argc is zero"); + + if(argc && !argv) + throw LogicException("argv is NULL but argc is not zero"); + + Host host = Host::getByName(hostName); + + create(host, name, argc, argv); + } + + int Process::killAll(int resetPID) + { + return MSG_process_killall(resetPID); + } + + void Process::suspend(void) + throw(MsgException) + { + if(MSG_OK != MSG_process_suspend(nativeProcess)) + throw MsgException("MSG_process_suspend() failed"); + } + + void Process::resume(void) + throw(MsgException) + { + if(MSG_OK != MSG_process_resume(nativeProcess)) + throw MsgException("MSG_process_resume() failed"); + } + + int Process::isSuspended(void) + { + return MSG_process_is_suspended(nativeProcess); + } + + Host& Process::getHost(void) + { + m_host_t nativeHost = MSG_process_get_host(nativeProcess); + + // return the reference to the Host object + return (*((Host*)nativeHost->data)); + } + + Process& Process::fromPID(int PID) + throw(ProcessNotFoundException, InvalidArgumentException, MsgException) + { + // check the parameters + + if(PID < 1) + throw InvalidArgumentException("PID (the PID of the process to retrieve is less than 1)"); + + Process* process = NULL; + m_process_t nativeProcess = MSG_process_from_PID(PID); + + if(!nativeProcess) + throw ProcessNotFoundException(PID); + + process = Process::fromNativeProcess(nativeProcess); + + if(!process) + throw MsgException("Process::fromNativeProcess() failed"); + + return (*process); + } + + int Process::getPID(void) + { + return MSG_process_get_PID(nativeProcess); + } + + int Process::getPPID(void) + { + return MSG_process_get_PPID(nativeProcess); + } + + const char* Process::getName(void) const + { + return nativeProcess->name; + } + + Process& Process::currentProcess(void) + throw(MsgException) + { + Process* currentProcess = NULL; + m_process_t currentNativeProcess = MSG_process_self(); + + + if(!currentNativeProcess) + throw MsgException("MSG_process_self() failed"); + + currentProcess = Process::fromNativeProcess(currentNativeProcess); + + if(!currentProcess) + throw MsgException("Process::fromNativeProcess() failed"); + + return (*currentProcess); + } + + int Process::currentProcessPID(void) + { + return MSG_process_self_PID(); + } + + + int Process::currentProcessPPID(void) + { + return MSG_process_self_PPID(); + } + + void Process::migrate(const Host& rHost) + throw(MsgException) + { + if(MSG_OK != MSG_process_change_host(rHost.nativeHost)) + throw MsgException("MSG_process_change_host()"); + + } + + void Process::sleep(double seconds) + throw(InvalidArgumentException, MsgException) + { + // check the parameters. + if(seconds <= 0) + throw InvalidArgumentException("seconds (must not be less or equals to zero"); + + if(MSG_OK != MSG_process_sleep(seconds)) + throw MsgException("MSG_process_sleep()"); + + } + + void Process::putTask(const Host& rHost, int channel, Task* task) + throw(InvalidArgumentException, MsgException) + { + // check the parameters + + if(channel < 0) + throw InvalidArgumentException("channel (must not be negative)"); + + if(MSG_OK != MSG_task_put_with_timeout(task->nativeTask, rHost.nativeHost, channel, -1.0)) + throw MsgException("MSG_task_put_with_timeout()"); + } + + void Process::putTask(const Host& rHost, int channel, Task* task, double timeout) + throw(InvalidArgumentException, MsgException) + { + // check the parameters + if(channel < 0) + throw InvalidArgumentException("channel (must not be negative)"); + + if(timeout < 0 && timeout != -1.0) + throw InvalidArgumentException("timeout (must not be less than zero and different of -1.0)"); + + if(MSG_OK != MSG_task_put_with_timeout(task->nativeTask, rHost.nativeHost, channel, timeout)) + throw MsgException("MSG_task_put_with_timeout() failed"); + } + + Task* Process::getTask(int channel) + throw(InvalidArgumentException, MsgException) + { + // check the parameters + + if(channel < 0) + throw InvalidArgumentException("channel (must not be negative)"); + + m_task_t nativeTask = NULL; + + if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, -1.0, NULL)) + throw MsgException("MSG_task_get_ext() failed"); + + return (Task*)(nativeTask->data); + } + + Task* Process::getTask(int channel, double timeout) + throw(InvalidArgumentException, MsgException) + { + // check the parameters + if(channel < 0) + throw InvalidArgumentException("channel (must not be negative)"); + + if(timeout < 0 && timeout != -1.0) + throw InvalidArgumentException("timeout (must not be less than zero and different of -1.0)"); + + m_task_t nativeTask = NULL; + + if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, timeout, NULL)) + throw MsgException("MSG_task_get_ext() failed"); + + return (Task*)(nativeTask->data); + } + + Task* Process::getTask(int channel, const Host& rHost) + throw(InvalidArgumentException, MsgException) + { + // check the parameters + if(channel < 0) + throw InvalidArgumentException("channel (must not be negative)"); + + m_task_t nativeTask = NULL; + + if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, -1.0, rHost.nativeHost)) + throw MsgException("MSG_task_get_ext() failed"); + + return (Task*)(nativeTask->data); + } + + Task* Process::getTask(int channel, double timeout, const Host& rHost) + throw(InvalidArgumentException, MsgException) + { + // check the parameters + if(channel < 0) + throw InvalidArgumentException("channel (must not be negative)"); + + if(timeout < 0 && timeout != -1.0) + throw InvalidArgumentException("timeout (must not be less than zero and different of -1.0)"); + + m_task_t nativeTask = NULL; + + if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, timeout, rHost.nativeHost)) + throw MsgException("MSG_task_get_ext() failed"); + + return (Task*)(nativeTask->data); + } + + void Process::sendTask(const char* alias, Task* task, double timeout) + throw(NullPointerException, InvalidArgumentException, MsgException) + { + // check the parameters + + if(!alias) + throw NullPointerException("alias"); + + if(timeout < 0 && timeout !=-1.0) + throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)"); + + if(MSG_OK != MSG_task_send_with_timeout(task->nativeTask, alias ,timeout)) + throw MsgException("MSG_task_send_with_timeout()"); + + } + + void Process::sendTask(const char* alias, Task* task) + throw(NullPointerException, MsgException) + { + // check the parameters + + if(!alias) + throw NullPointerException("alias"); + + if(MSG_OK != MSG_task_send_with_timeout(task->nativeTask, alias ,-1.0)) + throw MsgException("MSG_task_send_with_timeout()"); + } + + void Process::sendTask(Task* task) + throw(BadAllocException, MsgException) + { + char* alias = (char*)calloc( strlen(this->getHost().getName()) + strlen(nativeProcess->name) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name); + + MSG_error_t rv = MSG_task_send_with_timeout(task->nativeTask, alias ,-1.0); + + free(alias); + + if(MSG_OK != rv) + throw MsgException("MSG_task_send_with_timeout()"); + } + + void Process::sendTask(Task* task, double timeout) + throw(BadAllocException, InvalidArgumentException, MsgException) + { + // check the parameters + + if(timeout < 0 && timeout !=-1.0) + throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)"); + + char* alias = (char*)calloc( strlen(this->getHost().getName()) + strlen(nativeProcess->name) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name); + + MSG_error_t rv = MSG_task_send_with_timeout(task->nativeTask, alias ,timeout); + + free(alias); + + if(MSG_OK != rv) + throw MsgException("MSG_task_send_with_timeout()"); + } + + Task* Process::receiveTask(const char* alias) + throw(NullPointerException, MsgException) + { + // check the parameters + + if(!alias) + throw NullPointerException(alias); + + m_task_t nativeTask = NULL; + + if (MSG_OK != MSG_task_receive_ext(&nativeTask,alias, -1.0, NULL)) + throw MsgException("MSG_task_receive_ext() failed"); + + return (Task*)(nativeTask->data); + } + + + Task* Process::receiveTask(void) + throw(BadAllocException, MsgException) + { + + char* alias = (char*)calloc( strlen(this->getHost().getName()) + strlen(nativeProcess->name) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name); + + m_task_t nativeTask = NULL; + + MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, -1.0, NULL); + + free(alias); + + if(MSG_OK != rv) + throw MsgException("MSG_task_receive_ext() failed"); + + return (Task*)(nativeTask->data); + } + + + Task* Process::receiveTask(const char* alias, double timeout) + throw(NullPointerException, InvalidArgumentException, MsgException) + { + // check the parameters + + if(!alias) + throw NullPointerException("alias"); + + if(timeout < 0 && timeout !=-1.0) + throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)"); + + m_task_t nativeTask = NULL; + + if(MSG_OK != MSG_task_receive_ext(&nativeTask, alias, timeout, NULL)) + throw MsgException("MSG_task_receive_ext() failed"); + + return (Task*)(nativeTask->data); + } + + + Task* Process::receiveTask(double timeout) + throw(InvalidArgumentException, BadAllocException, MsgException) + { + // check the parameters + + if(timeout < 0 && timeout !=-1.0) + throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)"); + + + char* alias = (char*)calloc( strlen(this->getHost().getName()) + strlen(nativeProcess->name) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name); + + m_task_t nativeTask = NULL; + + MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, timeout, NULL); + + free(alias); + + if(MSG_OK != rv) + throw MsgException("MSG_task_receive_ext() failed"); + + return (Task*)(nativeTask->data); + } + + + Task* Process::receiveTask(const char* alias, double timeout, const Host& rHost) + throw(NullPointerException, InvalidArgumentException, MsgException) + { + // check the parameters + + if(!alias) + throw NullPointerException("alias"); + + if(timeout < 0 && timeout !=-1.0) + throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)"); + + m_task_t nativeTask = NULL; + + if(MSG_OK != MSG_task_receive_ext(&nativeTask, alias, timeout, rHost.nativeHost)) + throw MsgException("MSG_task_receive_ext() failed"); + + return (Task*)(nativeTask->data); + } + + + Task* Process::receiveTask(double timeout, const Host& rHost) + throw(BadAllocException, InvalidArgumentException, MsgException) + { + // check the parameters + + if(timeout < 0 && timeout !=-1.0) + throw InvalidArgumentException("timeout (the timeout value must not be negative and different than -1.0)"); + + char* alias = (char*)calloc( strlen(this->getHost().getName()) + strlen(nativeProcess->name) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name); + + m_task_t nativeTask = NULL; + + MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, timeout, rHost.nativeHost); + + free(alias); + + if(MSG_OK != rv) + throw MsgException("MSG_task_receive_ext() failed"); + + return (Task*)(nativeTask->data); + } + + + Task* Process::receiveTask(const char* alias, const Host& rHost) + throw(NullPointerException, MsgException) + { + + // check the parameters + + if(!alias) + throw NullPointerException("alias"); + + m_task_t nativeTask = NULL; + + if(MSG_OK != MSG_task_receive_ext(&nativeTask, alias, -1.0, rHost.nativeHost)) + throw MsgException("MSG_task_receive_ext() failed"); + + return (Task*)(nativeTask->data); + } + + Task* Process::receiveTask(const Host& rHost) + throw(BadAllocException, MsgException) + { + char* alias = (char*)calloc( strlen(this->getHost().getName()) + strlen(nativeProcess->name) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name); + + m_task_t nativeTask = NULL; + + MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, -1.0, rHost.nativeHost); + + free(alias); + + if(MSG_OK != rv) + throw MsgException("MSG_task_receive_ext() failed"); + + return (Task*)(nativeTask->data); + } + + void Process::create(const Host& rHost, const char* name, int argc, char** argv) + throw(InvalidArgumentException) + { + char alias[MAX_ALIAS_NAME + 1] = {0}; + msg_mailbox_t mailbox; + + + // try to retrieve the host where to create the process from its name + m_host_t nativeHost = rHost.nativeHost; + + if(!nativeHost) + throw InvalidArgumentException("rHost"); + + /* allocate the data of the simulation */ + this->nativeProcess = xbt_new0(s_m_process_t,1); + this->nativeProcess->simdata = xbt_new0(s_simdata_process_t,1); + this->nativeProcess->name = _strdup(name); + this->nativeProcess->simdata->m_host = nativeHost; + this->nativeProcess->simdata->PID = msg_global->PID++; + + // realloc the list of the arguments to add the pointer to this process instance at the end + if(argc) + { + argv = (char**)realloc(argv , (argc + 2) * sizeof(char*)); + } + else + { + argv = (char**)calloc(2 ,sizeof(char*)); + } + + // add the pointer to this instance at the end of the list of the arguments of the process + // so the static method Process::run() (passed as argument of the MSG function xbt_context_new()) + // can retrieve the concerned process object by the run + // so Process::run() can call the method main() of the good process + // for more detail see Process::run() method + argv[argc] = NULL; + argv[argc + 1] = (char*)this; + + this->nativeProcess->simdata->argc = argc; + this->nativeProcess->simdata->argv = argv; + + this->nativeProcess->simdata->s_process = SIMIX_process_create( + this->nativeProcess->name, + Process::run, + (void*)this->nativeProcess, + nativeHost->name, + argc, + argv, + NULL); + + if (SIMIX_process_self()) + {/* someone created me */ + this->nativeProcess->simdata->PPID = MSG_process_get_PID((m_process_t)SIMIX_process_self()->data); + } + else + { + this->nativeProcess->simdata->PPID = -1; + } + + this->nativeProcess->simdata->last_errno = MSG_OK; + + /* add the process to the list of the processes of the simulation */ + xbt_fifo_unshift(msg_global->process_list, this->nativeProcess); + + sprintf(alias,"%s:%s",(this->nativeProcess->simdata->m_host->simdata->smx_host)->name,this->nativeProcess->name); + + mailbox = MSG_mailbox_new(alias); + + MSG_mailbox_set_hostname(mailbox, this->nativeProcess->simdata->m_host->simdata->smx_host->name); + } + + Process* Process::fromNativeProcess(m_process_t nativeProcess) + { + return ((Process*)(nativeProcess->simdata->argv[nativeProcess->simdata->argc + 1])); + + } + + int Process::run(int argc, char** argv) + { + + // the last argument of the process is the pointer to the process to run + // for more detail see Process::create() method + return ((Process*)argv[argc + 1])->main(argc, argv); + + } + + int Process::main(int argc, char** argv) + { + throw LogicException("Process::main() not implemented"); + } + + /*void* Process::operator new(size_t size) + { + // TODO + } + + void Process::operator delete(void* p) + { + // TODO + }*/ + + } // namespace Msg + +} // namespace SimGrid + diff --git a/src/cxx/MsgProcess.hpp b/src/cxx/MsgProcess.hpp new file mode 100644 index 0000000000..8ae0898eac --- /dev/null +++ b/src/cxx/MsgProcess.hpp @@ -0,0 +1,617 @@ +/* + * Process.hpp + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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 MSG_PROCESS_HPP +#define MSG_PROCESS_HPP + +// Compilation C++ recquise +#ifndef __cplusplus + #error Process.hpp requires C++ compilation (use a .cxx suffix) +#endif + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace SimGrid +{ + namespace Msg + { + class ApplicationHandler; + class Host; + class Task; + + // SimGrid::Msg::Process class declaration. + class SIMGRIDX_EXPORT Process : public Object + { + friend class ApplicationHandler::ProcessFactory; + + MSG_DECLARE_DYNAMIC(Process); + + public: + + // Disable the default constructor. + Process(); + + + /*! \brief Constructs a process from the name of the host and its name. + * + * \param hostName The host name of the process to create. + * \param name The name of the process to create. + * + * \exception If the constructor failed, it throws one of the exceptions described + * below: + * + * [NullPointerException] if the name of the process is NULL or if the + * name of the host is NULL. + * [HostNotFoundException] if the host is not found. + */ + Process(const char* hostName, const char* name) + throw(NullPointerException, HostNotFoundException, BadAllocException); + + /*! \brief Constructs a process from a reference to an host object and its name. + * + * \param rHost A reference to the host object representing the native + * MSG host where to create the process. + * \param name The name of the process to create. + * + * \exception If the constructor failed, it throws the exception described + * below: + * + * [NullPointerException] if the name of process is NULL. + */ + Process(const Host& rHost, const char* name) + throw(NullPointerException); + + /*! brief Construct a proces from reference to an host object and the name of the process. + * This constuctor takes also the list of the arguments of the process. + * + * \param host A reference to the host where to create the process. + * \param name The name of the process to create. + * \param argc The number of the arguments of the process to create. + * \param argv The list of arguments of the process to create. + * + * \exception If the constructor failed, it throws one of the exceptions described + * below: + * + * [NullPointerException] if the name of the host is NULL or + * if the name of the process is NULL. + * [InvalidArgumentException] if the value of the parameter argv is + * negative. + * [LogicException] if the parameter argv is NULL and the + * parameter argc is different than zero + * if the parameter argv is not NULL and + * the parameter argc is zero. + */ + Process(const Host& rHost, const char* name, int argc, char** argv) + throw(NullPointerException, InvalidArgumentException, LogicException); + + /*! brief Constructs a proces from the name of a host and the name of the process. + * This constuctor takes also the list of the arguments of the process. + * + * \param hostName The name of the host where to create the process. + * \param name The name of the process to create. + * \param argc The number of the arguments of the process to create. + * \param argv The list of arguments of the process to create. + * + * \exception If the constructor failed, it throws one of the exceptions described + * below: + * + * [NullPointerException] if the name of the process or if the name + * of the host is NULL. + * [InvalidArgumentException] if the value of the parameter argv is + * negative. + * [LogicException] if the parameter argv is NULL and the + * parameter argc is different than zero + * if the parameter argv is not NULL and + * the parameter argc is zero. + * [HostNotFoundException] if the specified host is no found. + */ + Process(const char* hostName, const char* name, int argc, char** argv) + throw(NullPointerException, InvalidArgumentException, LogicException, HostNotFoundException, BadAllocException); + + /*! \brief Process::killAll() - kill all the running processes of the simulation. + * + * \param resetPID Should we reset the PID numbers. A negative number means no reset + * and a positive number will be used to set the PID of the next newly + * created process. + * + * \return The static method returns the PID of the next created process. + */ + static int killAll(int resetPID); + + /*! \brief Process::suspend() - Suspend an MSG process. + * + * \excetpion If this method failed, it throws one the exception described below: + * + * [MsgException] if an internal exception occurs during the operation. + */ + void suspend(void) + throw(MsgException); + + + + /*! \brief Process::resume() - Resume the MSG process. + * + * \exception If this method failed, it throws the exception described below: + * + * [MsgException] if an internal exception occurs during the operation. + */ + void resume(void) + throw(MsgException); + + /*! \brief Process::isSuspend() - Tests if a process is suspended. + * + * \return This method returns 1 is the process is suspended. + * Otherwise the method returns 0. + */ + int isSuspended(void); + + /*! \brief Process::getHost() - Retrieves the host of a process object. + * + * \return The method returns a reference to the + * host of the process. + * + */ + Host& getHost(void); + + /*! \brief Process::fromPID() - Retrieves a process from its PID. + * + * \param PID The PID of the process to retrieve. + * + * \return If successful the method returns a reference to + * to process. Otherwise, the method throws one of + * the exceptions described below: + * + * \exception [ProcessNotFoundException] if the process is not found (no process with this PID). + * + * [InvalidArgumentException] if the parameter PID is less than 1. + * + * [MsgException] if a native error occurs during the operation. + */ + static Process& fromPID(int PID) + throw(ProcessNotFoundException, InvalidArgumentException, MsgException); + + /*! \brief Process::getPID() - Gets the PID of a process object. + * + * \return This method returns the PID of a process object. + */ + int getPID(void); + + /*! \brief Process::getPPID() - Gets the parent PID of a process object. + * + * \return This method returns the parent PID of a process object. + */ + int getPPID(void); + + /*! \brief Process::getName() - Gets the name of a process object. + * + * \return This method returns the name of a process object. + */ + const char* getName(void) const; + + /*! \brief Process::currentProcess() - Retrieves the current process. + * + * \return This method returns a reference to the current process. Otherwise + * the method throws the excepction described below: + * + * \exception [MsgException] if an internal exception occurs. + */ + static Process& currentProcess(void) + throw (MsgException); + + /*! \brief Process::currentProcessPID() - Retrieves the PID of the current process. + * + * \return This method returns the PID of the current process. + */ + static int currentProcessPID(void); + + /*! \brief Process::currentProcessPPID() - Retrieves the parent PID of the current process. + * + * \return This method returns the parent PID of the current process. + */ + static int currentProcessPPID(void); + + /*! \brief Process::migrate() - Migrate a process object to an another host. + * + * \param rHost A reference to the host to migrate the process to. + * + * \return If successful the method migrate the process to the specified + * host. Otherwise the method throws the exception described + * below: + * + * \exception [MsgException] if an internal exception occurs. + */ + void migrate(const Host& rHost) + throw(MsgException); + + /*! \brief Process::sleep() - Makes the current process sleep until time seconds have elapsed. + * + * \param seconds The number of seconds to sleep. + * + * \execption If this method failed, it throws one of the exceptions described + * below: + * + * [InvalidArgumentException] if the parameter seconds is + * less or equals to zero. + * + * [MsgException] if an internal exception occurs. + */ + static void sleep(double seconds) + throw(InvalidArgumentException, MsgException); + + /*! \brief Process::putTask() - This method puts a task on a given channel of a given host. + * + * \exception If this method failed, it throws one of the exceptions described + * below: + * + * [InvalidArgumentException] if the channel number is negative. + * + * [MsgException] if an internal exception occurs. + */ + void putTask(const Host& rHost, int channel, Task* task) + throw(InvalidArgumentException, MsgException); + + /*! \brief Process::putTask() - This method puts a task on a given channel of a given host (waiting at most given time). + * + * \exception If this method failed, it throws one of the exceptions described below: + * + * [MsgException] if an internal error occurs. + * + * [InvalidArgumentException] if the value of the channel specified as + * parameter is negative or if the timeout value + * is less than zero and différent of -1. + * + * \remark Set the timeout with -1.0 to disable it. + */ + void putTask(const Host& rHost, int channel, Task* task, double timeout) + throw(InvalidArgumentException, MsgException); + + /*! \brief Process::getTask() - Retrieves a task from a channel number (waiting at most given time). + * + * \param channel The number of the channel where to get the task. + * + * \return If successful the method returns a reference to + * the getted task. Otherwise the method throws one + * of the exceptions described below: + * + * \exception [InvalidArgumentException] if the channel number is negative. + * + * [MsgException] if an internal exception occurs. + */ + Task* getTask(int channel) + throw(InvalidArgumentException, MsgException); + + /*! \brief Process::taskGet() - Retrieves a task from a channel number (waiting at most given time). + * + * \param channel The number of the channel where to get the task. + * \param timeout The timeout value. + * + * \return If successful the method returns a reference to + * the getted task. Otherwise the method throws one + * of the exceptions described below: + * + * \exception [InvalidArgumentException] if the channel number is negative + * or if the timeout value is less than + * zero and different of -1.0. + * [MsgException] if an internal exception occurs. + */ + Task* getTask(int channel, double timeout) + throw(InvalidArgumentException, MsgException); + + /*! \brief Process::taskGet() - Retrieves a task from a channel number and a host. + * + * \param channel The number of the channel where to get the task. + * \param host The host of the channel to get the task. + * + * \return If successful the method returns a reference to + * the getted task. Otherwise the method throws one + * of the exceptions described below. + * + * \exception [InvalidArgumentException] if the channel number is negative. + * [MsgException] if an internal exception occurs. + */ + Task* getTask(int channel, const Host& rHost) + throw(InvalidArgumentException, MsgException); + + /*! \brief Process::taskGet() - Retrieves a task from a channel number and a host (waiting at most given time). + * + * \param channel The number of the channel where to get the task. + * \param timeout The timeout value. + * \param rHost The host owning the channel. + * + * \return If successful the method returns a reference to + * the getted task. Otherwise the method throws one + * of the exceptions described below: + * + * \exception [InvalidArgumentException] if the channel number is negative or + * if the timeout value is negative and different + * of -1.0. + * [MsgException] if an internal exception occurs. + * + * \remark Set the timeout with -1.0 to disable it. + */ + Task* getTask(int channel, double timeout, const Host& rHost) + throw(InvalidArgumentException, MsgException); + + /*! \brief Process::sendTask() - Sends the given task in the mailbox identified by the specified alias + * (waiting at most given time). + * + * \param alias The alias of the mailbox where to send the task. + * \param rTask A reference to the task object to send. + * \param timeout The timeout value. + * + * \exception If this method failed, it throws one of the exceptions described below: + * + * [NullPointerException] if the alias specified as parameter is NULL. + * + * [InvalidArgumentException] if the timeout value is negative and different than + * -1.0 + * [MsgException] if an internal exception occurs. + * + * \remark Set the timeout with -1.0 to disable it. + */ + void sendTask(const char* alias, Task* task, double timeout) + throw(NullPointerException, InvalidArgumentException, MsgException); + + /*! \brief Process::sendTask() - Sends the given task in the mailbox identified by the specified alias. + * + * \param alias The alias of the mailbox where to send the task. + * \param rTask A reference to the task object to send. + * + * \exception If this method failed, it throws one of the exceptions described below: + * + * [NullPointerException] if the alias parameter is NULL. + * + * [MsgException] if an internal exception occurs. + * + */ + void sendTask(const char* alias, Task* task) + throw(NullPointerException, MsgException); + + /*! \brief Process::sendTask() - Sends the given task in the mailbox identified by the default alias. + * + * \param rTask A reference to the task object to send. + * + * \exception If this method failed, it throws one of the exceptions described below: + * + * [BadAllocException] if there is not enough memory to build the default alias. + * + * [MsgException] if an internal exception occurs. + * + */ + void sendTask(Task* task) + throw(BadAllocException, MsgException); + + /*! \brief Process::sendTask() - Sends the given task in the mailbox identified by the default alias + * (waiting at most given time). + * + * \param rTask A reference to the task object to send. + * \param timeout The timeout value. + * + * \exception If this method failed, it throws one of the exceptions described below: + * + * [BadAllocException] if there is not enough memory to build the default alias. + * + * [InvalidArgumentException] if the timeout value is negative and different than -1.0. + * + * [MsgException] if an internal exception occurs. + * + * \remark set the timeout value with -1.0 to disable it. + */ + void sendTask(Task* task, double timeout) + throw(BadAllocException, InvalidArgumentException, MsgException); + + /*! \brief Process::receiveTask() - Retrieves a task from the mailbox identified by the alias specified as + * parameter. + * + * \param alias The alias of the mailbox where to retrieve the task. + * + * \return If succcessful, the method returns a task of the mailbox. Otherwise, the method + * throws one of the exceptions described below: + * + * \exception [NullPointerException] if the parameter alias is NULL. + * + * [MsgException] if an internal exception occurs. + */ + Task* receiveTask(const char* alias) + throw(NullPointerException, MsgException); + + /*! \brief Process::receiveTask() - Retrieves a task from the mailbox identified by the default alias. + * + * \return If succcessful, the method returns a task of the mailbox. Otherwise, the method + * throws one of the exceptions described below: + * + * \exception [BadAllocException] if there is not enough memory to build the alias. + * [MsgException] if an internal exception occurs. + */ + Task* receiveTask(void) + throw(BadAllocException, MsgException); + + /*! \brief Process::receiveTask() - Retrieves a task from the mailbox identified by the alias specified as + * parameter(waiting at most given time). + * + * \param alias The alias of the mailbox where to retrieve the task. + * \param timeout The timeout value. + * + * \return If succcessful, the method returns a task of the mailbox. Otherwise, the method + * throws one of the exceptions described below. + * + * \exception [InvalidArgumentException] if the timeout value is negative or different of -1.0. + * + * [NullPointerException] if the parameter alias is NULL. + * + * [MsgException] if an internal exception occurs. + */ + Task* receiveTask(const char* alias, double timeout) + throw(NullPointerException, InvalidArgumentException, MsgException); + + /*! \brief Process::receiveTask() - Retrieves a task from the mailbox identified by the default alias + * (waiting at most given time). + * + * \param timeout The timeout value. + * + * \return If succcessful, the method returns a task of the mailbox. Otherwise, the method + * throws one of the exceptions described below: + * + * \exception [InvalidArgumentException] if the timeout value is negative or different than -1.0. + * + * [BadAllocException] if there is not enough memory to build the alias. + * + * [MsgException] if an internal exception occurs. + */ + Task* receiveTask(double timeout) + throw(InvalidArgumentException, BadAllocException, MsgException); + + /*! \brief Process::receiveTask() - Retrieves a task from the mailbox identified by the alias specified as + * parameter located on a given host (waiting at most given time). + * + * \param alias The alias of the mailbox where to retrieve the task. + * \param timeout The timeout value. + * \param rHost A reference to the host object owning the mailbox. + * + * \return If succcessful, the method returns a task of the mailbox. Otherwise, the method + * throws one of the exceptions described below: + * + * \exception [InvalidArgumentException] if the timeout value is negative or different of -1.0. + * + * [NullPointerException] if the parameter alias is NULL. + * + * [MsgException] if an internal exception occurs. + */ + Task* receiveTask(const char* alias, double timeout, const Host& rHost) + throw(NullPointerException, InvalidArgumentException, MsgException); + + /*! \brief Process::receiveTask() - Retrieves a task from the mailbox identified by default alias + * and located on a given host (waiting at most given time). + * + * \param timeout The timeout value. + * \param rHost A reference to the host object owning the mailbox. + * + * \return If succcessful, the method returns a task of the mailbox. Otherwise, the method + * throws one of the exceptions described below: + * + * \exception [InvalidArgumentException] if the timeout value is negative and different than -1.0. + * + * [BadAllocException] if there is not enough memory to build the default alias. + * + * [MsgException] if an internal exception occurs. + */ + Task* receiveTask(double timeout, const Host& rHost) + throw(BadAllocException, InvalidArgumentException, MsgException); + + /*! \brief Process::receiveTask() - Retrieves a task from the mailbox identified by the alias + * specified as parameter and located on a given host. + * + * \param alias The alias using to identify the mailbox from which to get the task. + * \param rHost A reference to the host object owning the mailbox. + * + * \return If succcessful, the method returns a task of the mailbox. Otherwise, the method + * throws one of the exceptions described below: + * + * \exception [NullPointerException] if the parameter alias is NULL. + * + * [MsgException] if an internal exception occurs. + */ + Task* receiveTask(const char* alias, const Host& rHost) + throw(NullPointerException, MsgException); + + /*! \brief Process::receiveTask() - Retrieves a task from the mailbox identified by default alias + * and located on a given host. + * + * \param rHost A reference to the host object owning the mailbox. + * + * \return If succcessful, the method returns a task of the mailbox. Otherwise, the method + * throws one of the exceptions described below: + * + * \exception [BadAllocException] if there is not enough memory to build the alias. + * + * [MsgException] if an internal exception occurs. + */ + Task* receiveTask(const Host& rHost) + throw(BadAllocException, MsgException); + + + private: + + /* Process::create() - Creates a process on a given host. + * + * param rHost A reference to a host object where to create the process. + * param name The name of the process to create. + * param argc The number of argument to pass to the main function of the process. + * param argv The list of the arguments of the main function of the process. + * + * exception If this method failed, it throws one of the exceptions described below: + * + * [HostNotFoundException] if the host specified as parameter doesn't exist. + */ + void create(const Host& rHost, const char* name, int argc, char** argv) + throw(InvalidArgumentException); + + /* Process::fromNativeProcess() - Retrieves the process wrapper associated with a native process. + * + * \param nativeProcess The native process to get the wrapper. + * + * \return The wrapper associated with the native process specified as parameter. + */ + static Process* fromNativeProcess(m_process_t nativeProcess); + + + public: + + /* Process::run() - used to set the field code of the context of the process. + */ + static int run(int argc, char** argv); + + /*! \brief Process::main() - This virtual pure function is the main function of the process. + * You must override this function for each new class of process that you create. + * + * \param argc The number of parameters of the main function. + * \param argv The list of the parameter of the main function. + * + * \return The exit code of the main function. + */ + virtual int main(int argc, char** argv); + + // Operators. + + /* + // Override the operator new(). + void* operator new(size_t size); + + // Override the operator delete(). + void operator delete(void* p); + */ + + private: + + // Attributes. + + m_process_t nativeProcess; // pointer to the native msg process. + + }; + + } //namepace Msg + +} // namespace SimGrid + +#endif // !MSG_PROCESS_HPP + diff --git a/src/cxx/MsgSimulation.cxx b/src/cxx/MsgSimulation.cxx new file mode 100644 index 0000000000..ee08c4a4ae --- /dev/null +++ b/src/cxx/MsgSimulation.cxx @@ -0,0 +1,108 @@ +/* + * Simulation.cxx + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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. + * + */ + + /* Simulation member functions implementation. + */ + + +#include +#include + +#include + +#include + + +#include + +namespace SimGrid +{ + namespace Msg + { + int Simulation::execute(int argc, char** argv) + { + if(argc < 3) + { + info("Usage: Msg platform_file deployment_file"); + return 1; + } + + // initialize the MSG simulator. Must be done before anything else (even logging). + init(argc, argv); + + // the environment to load + Environment env; + + // the application to deploy + Application app; + + + // try to load the environment described by the xml file (argv[1]) + try + { + env.load(argv[1]); + } + catch(FileNotFoundException e) + { + info(e.toString()); + finalize(); + return 1; + } + + // try to deploy the application described by the xml file deployment (argv[2]) + try + { + app.deploy(argv[2]); + } + catch(FileNotFoundException e) + { + info(e.toString()); + finalize(); + return 1; + } + + //try to run the simulation the given application on the given environment + try + { + run(); + } + catch(MsgException e) + { + info(e.toString()); + finalize(); + return 1; + } + + // finalize the MSG simulator + try + { + finalize(); + } + catch(MsgException e) + { + info(e.toString()); + return 1; + } + + return 0; + } + + void Simulation::run(void) + throw (MsgException) + { + if(MSG_OK != MSG_main()) + throw MsgException("MSG_main() failed"); + } + } // namespace Msg +} // namespace SimGrid + + diff --git a/src/cxx/MsgSimulation.hpp b/src/cxx/MsgSimulation.hpp new file mode 100644 index 0000000000..c2eeefbc61 --- /dev/null +++ b/src/cxx/MsgSimulation.hpp @@ -0,0 +1,61 @@ +/* + * Simulation.hpp + * + * This file contains the declaration of the wrapper class of the native MSG task type. + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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 MSG_SIMULATION_HPP +#define MSG_SIMULATION_HPP + +#ifndef __cplusplus + #error Sumulation.hpp requires C++ compilation (use a .cxx suffix) +#endif + +#include +#include + +namespace SimGrid +{ + namespace Msg + { + class MsgException; + class FileNotFoundException; + + // Simulation class declaration. + class SIMGRIDX_EXPORT Simulation + { + public : + + Simulation(){}; + + Simulation(const Simulation& rSimulation); + + virtual ~Simulation(){}; + + // Operations. + + int execute(int argc, char** argv); + + private: + + void run(void) + throw (MsgException); + + + // Operators. + const Simulation& operator = (const Simulation& rSimulation); + }; + + } // namespace Msg +} // namespace SimGrid + +#endif // !MSG_SIMULATION_HPP + diff --git a/src/cxx/MsgTask.cxx b/src/cxx/MsgTask.cxx new file mode 100644 index 0000000000..820e473483 --- /dev/null +++ b/src/cxx/MsgTask.cxx @@ -0,0 +1,542 @@ +/* + * Task.cxx + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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. + * + */ + + /* Task member functions implementation. + */ + +#include +#include + +#include + +#include +#include + +#include + +namespace SimGrid +{ + namespace Msg + { + + MSG_IMPLEMENT_DYNAMIC(Task, Object) + + Task::Task() + { + nativeTask = NULL; + } + + + Task::Task(const Task& rTask) + { + this->nativeTask = rTask.nativeTask; + } + + + Task::~Task() + throw(MsgException) + { + if(NULL != nativeTask) + if(MSG_OK != MSG_task_destroy(nativeTask)) + throw MsgException("MSG_task_destroy() failed"); + } + + + Task::Task(const char* name, double computeDuration, double messageSize) + throw(InvalidArgumentException, NullPointerException) + { + + if(computeDuration < 0) + throw InvalidArgumentException("computeDuration"); + + if(messageSize < 0) + throw InvalidArgumentException("messageSize"); + + if(!name) + throw NullPointerException("name"); + + // create the task + nativeTask = MSG_task_create(name, computeDuration, messageSize, NULL); + + nativeTask->data = (void*)this; + } + + Task::Task(const char* name, Host* hosts, double* computeDurations, double* messageSizes, int hostCount) + throw(NullPointerException, InvalidArgumentException) + { + // check the parameters + + if(!name) + throw NullPointerException("name"); + + if(!hosts) + throw NullPointerException("hosts"); + + if(!computeDurations) + throw NullPointerException("computeDurations"); + + if(!messageSizes) + throw NullPointerException("messageSizes"); + + if(!hostCount) + throw InvalidArgumentException("hostCount (must not be zero)"); + + + m_host_t* nativeHosts; + double* durations; + double* sizes; + + + nativeHosts = xbt_new0(m_host_t, hostCount); + durations = xbt_new0(double,hostCount); + sizes = xbt_new0(double, hostCount * hostCount); + + + for(int index = 0; index < hostCount; index++) + { + + nativeHosts[index] = hosts[index].nativeHost; + durations[index] = computeDurations[index]; + } + + for(int index = 0; index < hostCount*hostCount; index++) + sizes[index] = messageSizes[index]; + + + nativeTask = MSG_parallel_task_create(name, hostCount, nativeHosts, durations, sizes,NULL); + + + + this->nativeTask->data = (void*)this; + + } + + const char* Task::getName(void) const + { + return nativeTask->name; + } + + Process& Task::getSender(void) const + { + m_process_t nativeProcess = MSG_task_get_sender(nativeTask); + + return (*((Process*)(nativeProcess->data))); + } + + Host& Task::getSource(void) const + { + m_host_t nativeHost = MSG_task_get_source(nativeTask); + + return (*((Host*)(nativeHost->data))); + } + + double Task::getComputeDuration(void) const + { + return MSG_task_get_compute_duration(nativeTask); + } + + double Task::getRemainingDuration(void) const + { + return MSG_task_get_remaining_computation(nativeTask); + } + + void Task::setPriority(double priority) + throw(InvalidArgumentException) + { + // check the parameters + + if(priority < 0.0) + throw InvalidArgumentException("priority"); + + MSG_task_set_priority(nativeTask, priority); + } + + Task* Task::get(int channel) + throw(InvalidArgumentException, MsgException) + { + // check the parameters + + if(channel < 0) + throw InvalidArgumentException("channel (must not be negative)"); + + m_task_t nativeTask = NULL; + + if(MSG_OK != MSG_task_get_ext(&nativeTask, channel , -1.0, NULL)) + throw MsgException("MSG_task_get_ext() failed"); + + return ((Task*)(nativeTask->data)); + } + + Task* Task::get(int channel, const Host& rHost) + throw(InvalidArgumentException, MsgException) + { + // check the parameters + + if(channel < 0) + throw InvalidArgumentException("channel (must not be negative)"); + + m_task_t nativeTask = NULL; + + + if(MSG_OK != MSG_task_get_ext(&nativeTask, channel , -1.0, rHost.nativeHost)) + throw MsgException("MSG_task_get_ext() failed"); + + return (Task*)(nativeTask->data); + } + + Task* Task::get(int channel, double timeout, const Host& rHost) + throw(InvalidArgumentException, MsgException) + { + // check the parameters + + if(channel < 0) + throw InvalidArgumentException("channel (must not be negative)"); + + if(timeout < 0 && timeout !=-1.0) + throw InvalidArgumentException("timeout (must not be negative and different thant -1.0)"); + + m_task_t nativeTask = NULL; + + + if(MSG_OK != MSG_task_get_ext(&nativeTask, channel , timeout, rHost.nativeHost)) + throw MsgException("MSG_task_get_ext() failed"); + + return (Task*)(nativeTask->data); + } + + int Task::probe(int channel) + throw(InvalidArgumentException) + { + // check the parameters + + if(channel < 0) + throw InvalidArgumentException("channel (must not be negative)"); + + return MSG_task_Iprobe(channel); + } + + int Task::probe(int channel, const Host& rHost) + throw(InvalidArgumentException) + { + // check the parameters + + if(channel < 0) + throw InvalidArgumentException("channel (must not be negative)"); + + return MSG_task_probe_from_host(channel,rHost.nativeHost); + } + + void Task::execute(void) + throw(MsgException) + { + if(MSG_OK != MSG_task_execute(nativeTask)) + throw MsgException("MSG_task_execute() failed"); + } + + void Task::cancel(void) + throw(MsgException) + { + if(MSG_OK != MSG_task_cancel(nativeTask)) + throw MsgException("MSG_task_cancel() failed"); + } + + void Task::send(void) + throw(BadAllocException, MsgException) + { + char* alias = (char*)calloc(strlen(Process::currentProcess().getName()) + strlen(Host::currentHost().getName()) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", Host::currentHost().getName(), Process::currentProcess().getName()); + + MSG_error_t rv = MSG_task_send_with_timeout(nativeTask, alias, -1.0); + + free(alias); + + if(MSG_OK != rv) + throw MsgException("MSG_task_send_with_timeout() failed"); + } + + void Task::send(const char* alias) + throw(NullPointerException, MsgException) + { + // check the parameters + + if(!alias) + throw NullPointerException("alias"); + + if(MSG_OK != MSG_task_send_with_timeout(nativeTask, alias, -1.0)) + throw MsgException("MSG_task_send_with_timeout() failed"); + } + + void Task::send(double timeout) + throw(BadAllocException, InvalidArgumentException, MsgException) + { + // check the parameters + + if(timeout < 0 && timeout != -1.0) + throw InvalidArgumentException("timeout (must not be negative and different than -1.0"); + + char* alias = (char*)calloc(strlen(Process::currentProcess().getName()) + strlen(Host::currentHost().getName()) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", Host::currentHost().getName(), Process::currentProcess().getName()); + + MSG_error_t rv = MSG_task_send_with_timeout(nativeTask, alias, timeout); + + free(alias); + + if(MSG_OK != rv) + throw MsgException("MSG_task_send_with_timeout() failed"); + } + + void Task::send(const char* alias, double timeout) + throw(NullPointerException, InvalidArgumentException, MsgException) + { + // check the parameters + + if(!alias) + throw NullPointerException("alias"); + + if(timeout < 0 && timeout != -1.0) + throw InvalidArgumentException("timeout (must not be negative and different than -1.0"); + + + if(MSG_OK != MSG_task_send_with_timeout(nativeTask, alias, timeout)) + throw MsgException("MSG_task_send_with_timeout() failed"); + } + + void Task::sendBounded(double maxRate) + throw(BadAllocException, InvalidArgumentException, MsgException) + { + // check the parameters + + if(maxRate < 0 && maxRate != -1.0) + throw InvalidArgumentException("maxRate (must not be negative and different than -1.0"); + + char* alias = (char*)calloc(strlen(Process::currentProcess().getName()) + strlen(Host::currentHost().getName()) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", Host::currentHost().getName(), Process::currentProcess().getName()); + + MSG_error_t rv = MSG_task_send_bounded(nativeTask, alias, maxRate); + + free(alias); + + if(MSG_OK != rv) + throw MsgException("MSG_task_send_bounded() failed"); + + } + + void Task::sendBounded(const char* alias, double maxRate) + throw(NullPointerException, InvalidArgumentException, MsgException) + { + // check the parameters + + if(maxRate < 0 && maxRate != -1.0) + throw InvalidArgumentException("maxRate (must not be negative and different than -1.0"); + + if(!alias) + throw NullPointerException("alias"); + + if(MSG_OK != MSG_task_send_bounded(nativeTask, alias, maxRate)) + throw MsgException("MSG_task_send_bounded() failed"); + } + + Task* Task::receive(void) + throw(BadAllocException, MsgException) + { + char* alias = (char*)calloc(strlen(Process::currentProcess().getName()) + strlen(Host::currentHost().getName()) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", Host::currentHost().getName(), Process::currentProcess().getName()); + + m_task_t nativeTask = NULL; + + MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, -1.0, NULL); + + free(alias); + + if(MSG_OK != rv) + throw MsgException("MSG_task_receive_ext() failed"); + + return (Task*)(nativeTask->data); + } + + Task* Task::receive(const char* alias) + throw(NullPointerException, MsgException) + { + // check the parameters + + if(!alias) + throw NullPointerException("alias"); + + m_task_t nativeTask = NULL; + + if(MSG_OK != MSG_task_receive_ext(&nativeTask, alias, -1.0, NULL)) + throw MsgException("MSG_task_receive_ext() failed"); + + return (Task*)(nativeTask->data); + } + + Task* Task::receive(const char* alias, double timeout) + throw(NullPointerException, InvalidArgumentException, MsgException) + { + // check the parameters + + if(!alias) + throw NullPointerException("alias"); + + if(timeout < 0 && timeout != -1.0) + throw InvalidArgumentException("timeout (must not be negative and differnt than -1.0)"); + + m_task_t nativeTask = NULL; + + if(MSG_OK != MSG_task_receive_ext(&nativeTask, alias, timeout, NULL)) + throw MsgException("MSG_task_receive_ext() failed"); + + return (Task*)(nativeTask->data); + } + + Task* Task::receive(const char* alias, const Host& rHost) + throw(NullPointerException, MsgException) + { + // check the parameters + + if(!alias) + throw NullPointerException("alias"); + + m_task_t nativeTask = NULL; + + if(MSG_OK != MSG_task_receive_ext(&nativeTask, alias, -1.0, rHost.nativeHost)) + throw MsgException("MSG_task_receive_ext() failed"); + + return (Task*)(nativeTask->data); + } + + Task* Task::receive(const char* alias, double timeout, const Host& rHost) + throw(NullPointerException, InvalidArgumentException, MsgException) + { + // check the parameters + + if(!alias) + throw NullPointerException("alias"); + + if(timeout < 0 && timeout != -1.0) + throw InvalidArgumentException("timeout (must not be negative and differnt than -1.0)"); + + m_task_t nativeTask = NULL; + + + if(MSG_OK != MSG_task_receive_ext(&nativeTask, alias, timeout, rHost.nativeHost)) + throw MsgException("MSG_task_receive_ext() failed"); + + return (Task*)(nativeTask->data); + } + + int Task::listen(void) + throw(BadAllocException) + { + char* alias = (char*)calloc(strlen(Process::currentProcess().getName()) + strlen(Host::currentHost().getName()) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", Host::currentHost().getName(), Process::currentProcess().getName()); + + int rv = MSG_task_listen(alias); + + free(alias); + + return rv; + } + + int Task::listen(const char* alias) + throw(NullPointerException) + { + // check the parameters + + if(!alias) + throw NullPointerException("alias"); + + return MSG_task_listen(alias); + } + + int Task::listenFrom(void) + throw(BadAllocException) + { + char* alias = (char*)calloc(strlen(Process::currentProcess().getName()) + strlen(Host::currentHost().getName()) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", Host::currentHost().getName(), Process::currentProcess().getName()); + + int rv = MSG_task_listen_from(alias); + + free(alias); + + return rv; + } + + int Task::listenFrom(const char* alias) + throw(NullPointerException) + { + if(!alias) + throw NullPointerException("alias"); + + return MSG_task_listen_from(alias); + + } + + int Task::listenFromHost(const Host& rHost) + throw(BadAllocException) + { + char* alias = (char*)calloc(strlen(Process::currentProcess().getName()) + strlen(Host::currentHost().getName()) + 2, sizeof(char)); + + if(!alias) + throw BadAllocException("alias"); + + sprintf(alias,"%s:%s", Host::currentHost().getName(), Process::currentProcess().getName()); + + int rv = MSG_task_listen_from_host(alias, rHost.nativeHost); + + free(alias); + + return rv; + } + + int Task::listenFromHost(const char* alias, const Host& rHost) + throw(NullPointerException) + { + // check the parameters + if(!alias) + throw NullPointerException("alias"); + + return MSG_task_listen_from_host(alias, rHost.nativeHost); + } + + const Task& Task::operator = (const Task& rTask) + { + this->nativeTask = rTask.nativeTask; + return *this; + } + } // namespace Msg +} // namespace SimGrid + diff --git a/src/cxx/MsgTask.hpp b/src/cxx/MsgTask.hpp new file mode 100644 index 0000000000..e8bfd38d16 --- /dev/null +++ b/src/cxx/MsgTask.hpp @@ -0,0 +1,540 @@ +/* + * Task.hpp + * + * This file contains the declaration of the wrapper class of the native MSG task type. + * + * Copyright 2006,2007 Martin Quinson, Malek Cherier + * All right 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 MSG_TASK_HPP +#define MSG_TASK_HPP + +// Compilation C++ recquise +#ifndef __cplusplus + #error Task.hpp requires C++ compilation (use a .cxx suffix) +#endif + +#include + +#include +#include +#include +#include +#include + +#include + +namespace SimGrid +{ + namespace Msg + { + class Process; + class Host; + + // SimGrid::Msg::Task wrapper class declaration. + class SIMGRIDX_EXPORT Task : public Object + { + MSG_DECLARE_DYNAMIC(Task); + + friend class Process; + friend class Host; + + protected: + // Default constructor. + Task(); + + public: + /*! \brief Copy constructor. + */ + Task(const Task& rTask); + + /*! \brief Destructor. + * + * \exception If the destructor failed, it throw the exception described below: + * + * [MsgException] if a native exception occurs. + */ + virtual ~Task() + throw(MsgException); + + /*! \brief Constructs an new task with the specified processing amount and amount + * of data needed. + * + * \param name Task's name + * \param computeDuration A value of the processing amount (in flop) needed to process the task. + * If 0, then it cannot be executed with the execute() method. + * This value has to be >= 0. + * \param messageSize A value of amount of data (in bytes) needed to transfert this task. + * If 0, then it cannot be transfered with the get() and put() methods. + * This value has to be >= 0. + * + * \exception If this method failed, it throws one of the exceptions described below: + * + * [InvalidArgumentException] if the parameter computeDuration or messageSize + * is negative. + * [NullPointerException] if the parameter name is NULL. + * + * [MsgException] if a internal exception occurs. + */ + Task(const char* name, double computeDuration, double messageSize) + throw (InvalidArgumentException, NullPointerException); + + /*! \Constructs an new parallel task with the specified processing amount and amount for each host + * implied. + * + * \param name The name of the parallel task. + * \param hosts The list of hosts implied by the parallel task. + * \param computeDurations The amount of operations to be performed by each host of \a hosts. + * \param messageSizes A matrix describing the amount of data to exchange between hosts. + * \hostCount The number of hosts implied in the parallel task. + * + * \exception If this method fails, it throws one of the exceptions described below: + * + * [NullPointerException] if the parameter name is NULL or + * if the parameter computeDurations is NULL or + * if the parameter messageSizes is NULL + * + * [InvalidArgumentException] if the parameter hostCount is negative or zero. + */ + Task(const char* name, Host* hosts, double* computeDurations, double* messageSizes, int hostCount) + throw(NullPointerException, InvalidArgumentException); + + + /*! \brief Task::getName() - Gets the names of the task. + * + * \return The name of the task. + */ + const char* getName(void) const; + + /*! \brief Task::getSender() - Gets the sender of the task. + * + * \return A reference to the sender of the task. + */ + Process& getSender(void) const; + + /*! \brief Task::getSource() - Gets the source of the task. + * + * \return A reference to the source of the task. + */ + Host& getSource(void) const; + + /*! \brief Task::getComputeDuration() - Get the computing amount of the task. + * + * \return The computing amount of the task. + */ + + double getComputeDuration(void) const; + + /*! \brief Task::getRemainingDuration() - Gets the remaining computation. + * + * \return The remining computation of the task. + */ + double getRemainingDuration(void) const; + + /*! \brief Task::setPrirority() - Sets the priority of the computation of the task. + * The priority doesn't affect the transfert rate. For example a + * priority of 2 will make the task receive two times more cpu than + * the other ones. + * + * \param priority The new priority of the task. + * + * execption If this method fails, it throws the exception described below: + * + * [InvalidArgumentException] if the parameter priority is negative. + */ + void setPriority(double priority) + throw(InvalidArgumentException); + + /*! \brief Task::get() - Gets a task from the specified channel of the host of the current process. + * + * \param channel The channel number to get the task. + * + * \return If successful the method returns the task. Otherwise the method throws one + * of the exceptions described below: + * + * \exception [InvalidArgumentException] if the channel parameter is negative. + * + * [MsgException] if an internal excpetion occurs. + */ + static Task* get(int channel) + throw(InvalidArgumentException, MsgException); + + /*! \brief Task::get() - Gets a task from the given channel number of the given host. + * + * \param channel The channel number. + * \param rHost A reference of the host owning the channel. + * + * \return If successful, the method returns the task. Otherwise the method + * throw one of the exceptions described below: + * + * \exception [InvalidArgumentException] if the channel number is negative. + * + * [MsgException] if an internal exception occurs. + */ + static Task* get(int channel, const Host& rHost) + throw(InvalidArgumentException, MsgException); + + /*! \brief Task::get() - Gets a task from the specified channel of the specified host + * (waiting at most given time). + * + * \param channel The channel number. + * \param timeout The timeout value. + * \param rHost A reference to the host owning the channel. + * + * \return If successful, the method returns the task. Otherwise the method returns + * one of the exceptions described below: + * + * \exception [InvalidArgumentException] if the channel number is negative or + * if the timeout value is negative and + * different than -1.0. + * [MsgException] if an internal exception occurs. + */ + static Task* get(int channel, double timeout, const Host& rHost) + throw(InvalidArgumentException, MsgException); + + /*! \brief Task::probe() - Probes whether there is a waiting task on the given channel of local host. + * + * \param channel The channel number. + * + * \return If there is a waiting task on the channel the method returns 1. Otherwise + * the method returns 0. + * + * \exception If this method fails, it throws the exception described below: + * + * [InvalidArgumentException] if the parameter channel is negative. + */ + static int probe(int channel) + throw(InvalidArgumentException); + + /*! \brief Task::probe() - Counts tasks waiting on the given channel of local host and sent by given host. + * + * \param channel The channel id. + * \param rHost A reference to the host that has sent the task. + * + * \return The number of tasks. + * + * \exception [InvalidArgumentException] if the parameter channel is negative. + */ + static int probe(int channel, const Host& rHost) + throw(InvalidArgumentException); + + /*! \brief Task::execute() - This method executes a task on the location on which the + * process is running. + * + * \exception If this method fails, it returns the exception described below: + * + * [MsgException] if an internal exception occurs. + */ + void execute(void) + throw(MsgException); + + /*! \brief Task::cancel() - This method cancels a task. + * + * \exception If this method fails, it returns the exception described below: + * + * [MsgException] if an internal exception occurs. + */ + void cancel(void) + throw(MsgException); + + /*! \brief Task::send() - Send the task on the mailbox identified by the default alias. + * + * \exception If this method failed, it returns one of the exceptions described + * below: + * + * [BadAllocException] if there is not enough memory to build the default alias. + * + * [MsgException] if an internal exception occurs. + */ + void send(void) + throw(BadAllocException, MsgException); + + /*! \brief Task::send() - Send the task on the mailbox identified by the given alias. + * + * \param alias The alias of the mailbox where to send the task. + * + * \exception If this method failed, it returns one of the exceptions described + * below: + * + * [NullPointerException] if there parameter alias is NULL. + * + * [MsgException] if an internal exception occurs. + */ + void send(const char* alias) + throw(NullPointerException, MsgException); + + /*! \brief Task::send() - Send the task on the mailbox identified by the default alias + * (waiting at most given time). + * + * \param timeout The timeout value. + * + * \exception If this method failed, it returns one of the exceptions described + * below: + * + * [BadAllocException] if there is not enough memory to build the default alias. + * + * [InvalidArgumentException] if the timeout value is negative or different -1.0. + * + * [MsgException] if an internal exception occurs. + */ + void send(double timeout) + throw(BadAllocException, InvalidArgumentException, MsgException); + + /*! \brief Task::send() - Send the task on the mailbox identified by a given alias + * (waiting at most given time). + * + * \param alias The alias of the mailbox where to send the task. + * \param timeout The timeout value. + * + * \exception If this method failed, it returns one of the exceptions described + * below: + * + * [NullPointerException] if alias parameter is NULL. + * + * [InvalidArgumentException] if the timeout value is negative or different -1.0. + * + * [MsgException] if an internal exception occurs. + */ + void send(const char* alias, double timeout) + throw(NullPointerException, InvalidArgumentException, MsgException); + + /*! \brief Task::sendBounded() - Sends the task on the mailbox identified by the default alias. + * (capping the emision rate to maxrate). + * + * \param maxRate The maximum rate value. + * + * \exception If this method failed, it throws one of the exceptions described below: + * + * [BadAllocException] if there is not enough memory to build the default alias. + * + * [InvalidArgumentException] if the parameter maxRate is negative and different + * than -1.0. + * + * [MsgException] if an internal exception occurs. + */ + void sendBounded(double maxRate) + throw(BadAllocException, InvalidArgumentException, MsgException); + + /*! \brief Task::sendBounded() - Sends the task on the mailbox identified by the given alias. + * (capping the emision rate to maxrate). + * + *\ param alias The alias of the mailbox where to send the task. + * \param maxRate The maximum rate value. + * + * \exception If this method failed, it throws one of the exceptions described below: + * + * [NullPointerException] if the alias parameter is NULL. + * + * [InvalidArgumentException] if the parameter maxRate is negative and different + * than -1.0. + * + * [MsgException] if an internal exception occurs. + */ + void sendBounded(const char* alias, double maxRate) + throw(NullPointerException, InvalidArgumentException, MsgException); + + + /*! \brief Task::receive() - Receives a task from the mailbox identified by the default alias (located + * on the local host). + * + * \return A reference to the task. + * + * \exception If this method failed, it throws one of the exception described below: + * + * [BadAllocException] if there is not enough memory to build the default alias. + * + * [MsgException] if an internal exception occurs. + */ + /*static Task& receive(void) + throw(BadAllocException, MsgException);*/ + + static Task* receive(void) + throw(BadAllocException, MsgException); + + /*! \brief Task::receive() - Receives a task from the mailbox identified by a given alias (located + * on the local host). + * + * \alias The alias of the mailbox. + * + * \return A reference to the task. + * + * \exception If this method failed, it throws one of the exception described below: + * + * [NullPointerException] if the alias parameter is NULL. + * + * [MsgException] if an internal exception occurs. + */ + /*static Task& receive(const char* alias) + throw(NullPointerException, MsgException);*/ + static Task* receive(const char* alias) + throw(NullPointerException, MsgException); + + /*! \brief Task::receive() - Receives a task from the mailbox identified by a given alias (located + * on the local host and waiting at most given time). + * + * \alias The alias of the mailbox. + * \timeout The timeout value. + * + * \return A reference to the task. + * + * \exception If this method failed, it throws one of the exception described below: + * + * [NullPointerException] if the alias parameter is NULL. + * + * [InvalidArgumentException] if the timeout value is negatif and different than + * -1.0. + * + * [MsgException] if an internal exception occurs. + */ + static Task* receive(const char* alias, double timeout) + throw(NullPointerException, InvalidArgumentException, MsgException); + + /*! \brief Task::receive() - Receives a task from the mailbox identified by a given alias located + * on the given host. + * + * \alias The alias of the mailbox. + * \rHost The location of the mailbox. + * + * \return A reference to the task. + * + * \exception If this method failed, it throws one of the exception described below: + * + * [NullPointerException] if the alias parameter is NULL. + * + * [MsgException] if an internal exception occurs. + */ + static Task* receive(const char* alias, const Host& rHost) + throw(NullPointerException, MsgException); + + /*! \brief Task::receive() - Receives a task from the mailbox identified by a given alias located + * on the given host (and waiting at most given time). + * + * \alias The alias of the mailbox. + * \timeout The timeout value. + * \rHost The location of the mailbox. + * + * \return A reference to the task. + * + * \exception If this method failed, it throws one of the exception described below: + * + * [NullPointerException] if the alias parameter is NULL. + * + * [InvalidArgumentException] if the timeout value is negatif and different than + * -1.0. + * + * [MsgException] if an internal exception occurs. + */ + static Task* receive(const char* alias, double timeout, const Host& rHost) + throw(NullPointerException, InvalidArgumentException, MsgException); + + /*! \brief Task::listen() - Listen whether there is a waiting task on the mailbox + * identified by the default alias of local host. + * + * \return If there is a waiting task on the mailbox the method returns true. + * Otherwise the method returns false. + * + * \exception If this method fails, it throws one of the exceptions described below: + * + * [BadAllocException] if there is not enough memory to build the default alias. + */ + static int listen(void) + throw(BadAllocException); + + /*! \brief Task::listen() - Listen whether there is a waiting task on the mailbox + * identified by the given alias of local host. + * + * \param alias The alias of the mailbox. + * + * \return If there is a waiting task on the mailbox the method returns 1. + * Otherwise the method returns 0. + * + * \exception If this method fails, it throws one of the exceptions described below: + * + * [NullPointerException] if the parameter alias is NULL. + */ + static int listen(const char* alias) + throw(NullPointerException); + + /*! \brief Task::listenFrom() - Tests whether there is a pending communication on the mailbox + * identified by the default alias, and who sent it. + * + * \return If there is a pending communication on the mailbox, the method returns + * the PID of it sender. Otherwise the method returns -1. + * + * \exception If this method fails, it throws the exception described below: + * + * [BadAllocException] if there is not enough memory to build the default + * alias. + */ + static int listenFrom(void) + throw(BadAllocException); + + /*! \brief Task::listenFrom() - Tests whether there is a pending communication on the mailbox + * identified by the specified alias, and who sent it. + * + * \alias The alias of the mailbox. + * + * \return If there is a pending communication on the mailbox, the method returns + * the PID of it sender. Otherwise the method returns -1. + * + * \exception If this method fails, it throws the exception described below: + * + * [NullPointerException] if the alias parameter is NULL. + */ + static int listenFrom(const char* alias) + throw(NullPointerException); + + /*! \brief Task::listenFromHost() - Tests whether there is a pending communication on the mailbox + * identified by the default alias and located on the host of the current process, and who sent it. + * + * \param rHost The location of the mailbox. + * + * \return If there is a pending communication on the mailbox, the method returns + * the PID of it sender. Otherwise the method returns -1. + * + * \exception If this method fails, it throws the exception described below: + * + * [BadAllocException] if there is not enough memory to build the default + * alias. + */ + static int listenFromHost(const Host& rHost) + throw(BadAllocException); + + /*! \brief Task::listenFromHost() - Tests whether there is a pending communication on the mailbox + * identified by the default alias and located on the host of the current process, and who sent it. + * + * \param rHost The location of the mailbox. + * + * \return If there is a pending communication on the mailbox, the method returns + * the PID of it sender. Otherwise the method returns -1. + * + * \exception If this method fails, it throws the exception described below: + * + * [BadAllocException] if there is not enough memory to build the default + * alias. + */ + static int listenFromHost(const char* alias, const Host& rHost) + throw(NullPointerException); + + virtual const Task& operator= (const Task& rTask); + + protected: + + // Attributes. + + m_task_t nativeTask; // the native MSG task. + }; + + } // namespace Msg +} // namespace SimGrid + +typedef Task* TaskPtr; + +#endif // §MSG_TASK_HPP + -- 2.20.1