From 0f767a4eb0cf070d331e73d9be7d2c2be4f71dd5 Mon Sep 17 00:00:00 2001 From: cherierm Date: Wed, 14 May 2008 15:57:57 +0000 Subject: [PATCH] started of C++ wrappers for Msg git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@5425 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- src/cxx/0bject.hpp | 275 ++++++++++++++++ src/cxx/ApplicationHandler.cxx | 70 ++++ src/cxx/ApplicationHandler.hpp | 102 ++++++ src/cxx/Host.cxx | 277 ++++++++++++++++ src/cxx/Host.hpp | 92 ++++++ src/cxx/HostNotFoundException.cxx | 0 src/cxx/MsgException.cxx | 0 src/cxx/MsgException.hpp | 43 +++ src/cxx/MsgNative.hpp | 126 +++++++ src/cxx/Object.cxx | 149 +++++++++ src/cxx/Process.cxx | 525 ++++++++++++++++++++++++++++++ src/cxx/Process.hpp | 148 +++++++++ src/cxx/Task.cxx | 183 +++++++++++ src/cxx/Task.hpp | 78 +++++ 14 files changed, 2068 insertions(+) create mode 100644 src/cxx/0bject.hpp create mode 100644 src/cxx/ApplicationHandler.cxx create mode 100644 src/cxx/ApplicationHandler.hpp create mode 100644 src/cxx/Host.cxx create mode 100644 src/cxx/Host.hpp create mode 100644 src/cxx/HostNotFoundException.cxx create mode 100644 src/cxx/MsgException.cxx create mode 100644 src/cxx/MsgException.hpp create mode 100644 src/cxx/MsgNative.hpp create mode 100644 src/cxx/Object.cxx create mode 100644 src/cxx/Process.cxx create mode 100644 src/cxx/Process.hpp create mode 100644 src/cxx/Task.cxx create mode 100644 src/cxx/Task.hpp diff --git a/src/cxx/0bject.hpp b/src/cxx/0bject.hpp new file mode 100644 index 0000000000..cf0b8d1596 --- /dev/null +++ b/src/cxx/0bject.hpp @@ -0,0 +1,275 @@ + + +#ifndef MSG_OBJECT_H +#define MSG_OBJECT_H + +// Compilation C++ recquise +#ifndef __cplusplus + #error object.hpp requires C++ compilation (use a .cxx suffix) +#endif + +#include + +namespace msg +{ + ////////////////////////////////////////////////////////////////////////////// + // Macros + + // Returns the runtime class of the class_name object. + #define MSG_GET_CLASS(class_name) \ + ((Class*)(&class_name::class##class_name)) + + // Declare the class class_name as dynamic + #define MSG_DECLARE_DYNAMIC(class_name) \ + public: \ + static const Class class##class_name; \ + virtual Class* getClass() const; \ + static Object* createObject(); \ + + // The runtime class implementation. + #define MSG_IMPLEMENT_CLASS(class_name, base_class_name, pfn,class_init) \ + const Class class_name::class##class_name = { \ + #class_name, sizeof(class class_name),pfn, \ + MSG_GET_CLASS(base_class_name), NULL,class_init}; \ + Class* class_name::getClass() const \ + { return MSG_GET_CLASS(class_name); } \ + + // CreateObject implementation. + #define HX_IMPLEMENT_DYNAMIC(class_name, base_class_name) \ + Object* class_name::createObject() \ + { return (Object*)(new class_name); } \ + DeclaringClass _declaringClass_##class_name(MSG_GET_CLASS(class_name)); \ + MSG_IMPLEMENT_CLASS(class_name, base_class_name, \ + class_name::createObject, &_declaringClass_##class_name) \ + + + ////////////////////////////////////////////////////////////////////////////// + // Classes declared in this file. + + class Object; // The msg object. + + ////////////////////////////////////////////////////////////////////////////// + // Structures declared in this files. + + struct Class; // used during the rtti operations + struct DeclaringClass; // used during the instances registration. + + + class DeclaringClasses; + + ////////////////////////////////////////////////////////////////////////////// + // Global functions + + // Used during the registration. + void DeclareClass(Class* c); + + ////////////////////////////////////////////////////////////////////////////// + // DeclaringClass + + struct DeclaringClass + { + // Constructor : add the runtime classe in the list. + DeclaringClass(Class* c); + + // Destructor + virtual ~DeclaringClass(void); + + // Attributes : + // the list of runtime classes. + static DeclaringClasses* declaringClasses; + }; + + #define MSG_DELCARING_CLASSES (*(DeclaringClass::declaringClasses)) + + + struct Class + { + + // Attributes + + const char* name; // class name. + int typeSize; // type size. + Object* (*createObjectFn)(void); // pointer to the create object function. + Class* baseClass; // the runtime class of the runtime class. + Class* next; // the next runtime class in the list. + const DeclaringClass* declaringClass; // used during the registration of the class. + + // Operations + + // Create the runtime class from its name. + static Class* fromName(const char* name); + + // Create an object from the name of the its class. + static Object* createObject(const char* name); + + // Create an instance of the class. + Object* createObject(void); + + // Return true is the class is dervived from the base class baseClass. + bool isDerivedFrom(const Class* baseClass) const; + + }; + + // Create an instance of the class. + inline Object* Class::createObject(void) + { + return (*createObjectFn)(); + } + + + class Object + { + public: + + // Default constructor. + Object(){} + + // Destructor. + virtual ~Object(){} + + // Operations. + + // Get the runtime class. + virtual Class* getClass(void) const; + + // Returns true if the class is derived from the class baseClass. Otherwise + // the method returns false. + bool isDerivedFrom(const Class* baseClass) const; + + // Returns true if the object is valid. Otherwise the method returns false. + virtual bool isValid(void) const; + + // Operators. + + // Attributes. + + // The runtime class. + static const Class classObject; + }; + + // inline member functions of the class Object. + + // Returns the runtime class of the object. + inline Class* Object::getClass(void) const + { + return MSG_GET_CLASS(Object); + } + + // Returns true if the class is derived from the class pBaseClass. Otherwise + // the method returns false. + inline bool Object::isDerivedFrom(const Class* baseClass) const + { + return (getClass()->isDerivedFrom(baseClass)); + } + + // Returns true if the object is valid. Otherwise the method returns false. + inline bool Object::isValid(void) const + { + // returns always true. + return true; + } + + class DeclaringClasses + { + public: + + // Constructor. + DeclaringClasses(); + + // Destructor. + virtual ~DeclaringClasses(){} + + // Operations. + + // Add the class at the head of the list. + void addHead(Class* c); + + // Get the runtime class of the head of the list. + Class* getHead(void) const ; + + // Remove the class from the list (don't destroy it). + bool remove(Class* c); + + // Remove the head of the list. + Class* removeHead(void); + + // Return true if the list is empty. + + bool isEmpty(void) const; + + // Remove of the elements of the list. + void removeAll(void); + + // Get the number of classes in the list. + unsigned int getCount(void); + + void lock(void){} + + void unlock(void){} + + //Attributes + + // The head of the list. + Class* head; + + private: + + // Attributes + + // The number of elements of the list. + unsigned int count; + }; + + + // Constructor (Add the class in the list). + inline DeclaringClass::DeclaringClass(Class* c) + { + if(!declaringClasses) + declaringClasses = new DeclaringClasses(); + + DeclareClass(c); + } + + // Destructor. + inline DeclaringClass::~DeclaringClass() + { + /*if(NULL != declaringClasses) + delete declaringClasses; + + declaringClasses=NULL;*/ + + } + + // Returns the number of elements of the list. + inline unsigned int DeclaringClasses::getCount() + { + return count; + } + + // Returns the head of the list. + inline Class* DeclaringClasses::getHead() const + { + return head; + } + + // Returns true if the list is empty. Otherwise this function + // returns false. + inline bool DeclaringClasses::isEmpty() const + { + return(!head); + } + + // Removes all the elements of the list. + inline void DeclaringClasses::removeAll() + { + head = 0; + count=0; + } + + +} + +using namespace msg; + +#endif // !MSG_OBJECT_H + diff --git a/src/cxx/ApplicationHandler.cxx b/src/cxx/ApplicationHandler.cxx new file mode 100644 index 0000000000..7b5f81692a --- /dev/null +++ b/src/cxx/ApplicationHandler.cxx @@ -0,0 +1,70 @@ +#include + +namespace msg +{ + +ApplicationHandler::ProcessFactory::processFactory = NULL; + +void ApplicationHandler::onStartDocument(void) +{ + processFactory = new ProcessFactory(); +} + +void ApplicationHandler::onEndDocument(void) +{ + if(processFactory) + delete processFactroy; +} + +void ApplicationHandler::onBeginProcess(void) +{ + processFactory->setProcessIdentity(A_surfxml_process_host, A_surfxml_process_function); +} + +void ApplicationHandler::onProcessArg(void) +{ + processFactory->registerProcessArg(A_surfxml_argument_value); +} + +void ApplicationHandler::OnProperty(void) +{ + processFactory->setProperty(A_surfxml_prop_id, A_surfxml_prop_value); +} + +void ApplicationHandler::onEndProcess(void) +{ + processFactory->createProcess(); +} + +void ApplicationHandler::ProcessFactory::createProcess() + { + Process* process = (Process*)Class::fromName(this->function); + + Host host = Host::getByName(this->hostName); + + process->create(); + + Strings* args = processFactory->args; + + int size = args->size(); + + for (int index = 0; index < size; index++) + process->args->push_back(args->at(index)); + + process->properties = this->properties; + this->properties = new Properties(); + } + +void ApplicationHandler::ProcessFactory::setProcessIdentity(const string& hostName, const string& function) +{ + this->hostName = hostName; + this->function = function; + + if (!this->args->empty()) + this->args->clear(); + + if(!this->properties->empty()) + this->properties->clear(); +} + +} \ No newline at end of file diff --git a/src/cxx/ApplicationHandler.hpp b/src/cxx/ApplicationHandler.hpp new file mode 100644 index 0000000000..d45032132d --- /dev/null +++ b/src/cxx/ApplicationHandler.hpp @@ -0,0 +1,102 @@ +#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 + +namespace msg +{ + + struct Compare + { + public bool operator(const string& first, const string& second) + { + return first.compare(second); + } + }; + + typedef vector Strings; + + typedef map Properties; + + +class ApplicationHandler +{ +private : + // Default constructor. + ApplicationHandler(); + + // Copy constructor. + ApplicationHandler(const ApplicationHandler& rApplicationHandler); + + // Destructor + virtual ~ApplicationHandler(); + + class ProcessFactory + { + public: + + Strings* args; + Properties* properties; + + private: + string hostName; + string function; + + public : + + ProcessFactory() + { + this->args = new Strings(); + this->properties = new Properties(); + this->hostName = NULL; + this->function = NULL; + } + + void setProcessIdentity(const string& hostName, const string& function); + + void registerProcessArg(const string& arg) + { + this->args->push_back(arg); + } + + void setProperty(const string& id, const string& value) + { + this->properties->insert(Properties::value_type(id,value)); + } + + const String& getHostName(void) + { + return this->hostName; + } + + void createProcess(void); + + }; + + static ProcessFactory* processFactory; + + public: + + static void onStartDocument(void); + + static void onEndDocument(void); + + static void onBeginProcess(void); + + static void onProcessArg(void); + + static void OnProperty(void); + + static void onEndProcess(void); +}; + +} + +#endif // !MSG_APPLICATION_HANDLER_HPP + \ No newline at end of file diff --git a/src/cxx/Host.cxx b/src/cxx/Host.cxx new file mode 100644 index 0000000000..e1adb5f959 --- /dev/null +++ b/src/cxx/Host.cxx @@ -0,0 +1,277 @@ +#include + +namespace msg +{ +// Default constructor. +Host::Host() +{ + nativeHost = NULL; + data = NULL; +} + +// Copy constructor. +Host::Host(const Host& rHost) +{ +} + +// Destructor. +Host::~Host() +{ + nativeHost = NULL; +} + +// Operations + +Host& Host::getByName(const char* hostName) +throw(HostNotFoundException) +{ + m_host_t nativeHost; // native host. + Host* host = NULL; // wrapper host. + + /* get the host by name (the hosts are created during the grid resolution) */ + nativeHost = MSG_get_host_by_name(name); + DEBUG2("MSG gave %p as native host (simdata=%p)",nativeHost,nativeHost->simdata); + + if(!nativeHost) + {// invalid host name + // TODO throw HostNotFoundException + return NULL; + } + + if(!nativeHost->data) + { // native host not associated yet with its wrapper + + // instanciate a new wrapper + host = new Host(); + + 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; +} + +int Host::all(Host** hosts) +{ + int count = xbt_fifo_size(msg_global->host); + + *hosts = new Host[count]; + 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) + { + host = new Host(); + + host->nativeHost = nativeHost; + nativeHost->data = (void*)host; + } + + hosts[index] = host; + } + + return count; +} + + +const char* Host::getName(void) const +{ + return nativeHost->name; +} + + +void Host::setData(void* data) +{ + this->data = data; +} + +// Getters/setters + +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->simdata->smx_host); +} + +bool Host::hasData(void) const +{ + return (NULL != this->data); +} + +bool Host::isAvailable(void) const +{ + return (bool)SIMIX_host_get_state(nativeHost->simdata->smx_host); +} + +void Host::put(int channel, const Task& rTask) +throw(NativeException) +{ + if(MSG_OK != MSG_task_put_with_timeout(rTask.nativeTask, nativeHost, channel , -1.0)) + { + // TODO throw NativeException + } +} + +void Host::put(int channel, const Task& rTask, double timeout) +throw(NativeException) +{ + if(MSG_OK != MSG_task_put_with_timeout(rTask.nativeTask, nativeHost, channel , timeout)) + { + // TODO throw NativeException + } +} + +void Host::putBounded(int channel, const Task& rTask, double maxRate) +throw(NativeException) +{ + MsgNative.hostPutBounded(this, channel, task, maxrate); + + if(MSG_OK != MSG_task_put_bounded(rTask.nativeTask, nativeHost, channel, maxRate)) + { + // TODO throw NativeException + } +} + + + + + + +void Host::send(const Task& rTask) +throw(NativeException) +{ + MSG_error_t rv; + + char* alias = (char*)calloc(strlen(this->getName() + strlen(Process::currentProcess().getName()) + 2); + sprintf(alias,"%s:%s", this->getName(),Process::currentProcess().getName()); + + + rv = MSG_task_send_with_timeout(rTask.nativeTask, alias, -1.0); + + free(alias); + + if(MSG_OK != rv) + { + // TODO throw NativeException + } +} + +void Host::send(const char* alias, const Task& rTask) +throw(NativeException) +{ + + if(MSG_OK != MSG_task_send_with_timeout(rTask.nativeTask, alias, -1.0)) + { + // TODO throw NativeException + } +} + +void Host::send(const Task& rTask, double timeout) +throw(NativeException) +{ + MSG_error_t rv; + + char* alias = (char*)calloc(strlen(this->getName() + strlen(Process::currentProcess().getName()) + 2); + sprintf(alias,"%s:%s", this->getName(),Process::currentProcess().getName()); + + + rv = MSG_task_send_with_timeout(rTask.nativeTask, alias, timeout); + + free(alias); + + if(MSG_OK != rv) + { + // TODO throw NativeException + } +} + +void Host::send(const char* alias, const Task& rTask, double timeout) +throw(NativeException) +{ + if(MSG_OK != MSG_task_send_with_timeout(rTask.nativeTask, alias, timeout)) + { + // TODO throw NativeException + } +} + + +void Host::sendBounded(const Task& rTask, double maxRate) +throw(NativeException) +{ + + MSG_error_t rv; + + char* alias = (char*)calloc(strlen(this->getName() + strlen(Process::currentProcess().getName()) + 2); + sprintf(alias,"%s:%s", this->getName(),Process::currentProcess().getName()); + + rv = MSG_task_send_bounded(rTask.nativeTask, alias, maxRate); + + free(alias); + + if(MSG_OK != rv) + { + // TODO throw NativeException + } +} + +void Host::sendBounded(const char* alias, const Task& rTask, double maxRate) +throw(NativeException) +{ + if(MSG_OK != MSG_task_send_bounded(rTask.nativeTask, alias, maxRate)) + { + // TODO throw NativeException + } +} + + +} \ No newline at end of file diff --git a/src/cxx/Host.hpp b/src/cxx/Host.hpp new file mode 100644 index 0000000000..03b9232724 --- /dev/null +++ b/src/cxx/Host.hpp @@ -0,0 +1,92 @@ +#ifndef MSG_HOST_HPP +#define MSG_HOST_HPP + + +// Compilation C++ recquise +#ifndef __cplusplus + #error Host.hpp requires C++ compilation (use a .cxx suffix) +#endif + +namespace msg +{ +class Host +{ + private : + // Default constructor. + Host(); + + // Copy constructor. + Host(const Host& rHost); + + // Destructor. + virtual ~Host(); + + public: + + // Operations + + static Host& getByName(const char* hostName) + throw(HostNotFoundException); + + static int getNumber(void); + + static Host& currentHost(void); + + static int all(Host** hosts); + + + const char* getName(void) const; + + void setData(void* data); + + // Getters/setters + + void* getData(void) const; + + int Host::getRunningTaskNumber(void) const; + + double getSpeed(void) const; + + bool hasData(void) const; + + bool isAvailble(void) const; + + void put(int channel, const Task& rTask) + throw(NativeException); + + void put(int channel, Task task, double timeout) + throw(NativeException); + + void Host::putBounded(int channel, const Task& rTask, double maxRate) + throw(NativeException); + + + void send(const Task& rTask) + throw(NativeException); + + void send(const char* alias, const Task& rTask) + throw(NativeException); + + void send(const Task& rTask, double timeout) + throw(NativeException); + + void send(const char* alias, const Task& rTask, double timeout) + throw(NativeException); + + void sendBounded(const Task& rTask, double maxRate) + throw(NativeException); + + void sendBounded(const char* alias, const Task& rTask, double maxRate) + throw(NativeException); + + + private: + // Attributes. + + m_host_t nativeHost; + + void* data; + }; +} + +#endif // !MSG_HOST_HPP \ No newline at end of file diff --git a/src/cxx/HostNotFoundException.cxx b/src/cxx/HostNotFoundException.cxx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/cxx/MsgException.cxx b/src/cxx/MsgException.cxx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/cxx/MsgException.hpp b/src/cxx/MsgException.hpp new file mode 100644 index 0000000000..bcc3c4491f --- /dev/null +++ b/src/cxx/MsgException.hpp @@ -0,0 +1,43 @@ +#ifndef MSG_EXCEPTION_HPP +#define MSG_EXCEPTION_HPP + +namespace msg +{ + class MsgException + { + public: + // Default constructor. + MsgException(); + + // This constructor takes as parameter the message of the + // MsgException object. + MsgException(const char* msg); + + // Copy constructor. + MsgException(const MsgException& rMsgException); + + // Destructor. + virtual ~MsgException(); + + + // Operations. + + // Returns the message of the exception. + const char* what(void) const; + + + // Getters/setters. + + // Operators. + + private: + + // Attributes. + + // The message of the exception. + const char* msg; + + }; +} + +#endif // !MSG_EXCEPTION_HPP \ No newline at end of file diff --git a/src/cxx/MsgNative.hpp b/src/cxx/MsgNative.hpp new file mode 100644 index 0000000000..9fe34234b1 --- /dev/null +++ b/src/cxx/MsgNative.hpp @@ -0,0 +1,126 @@ +#ifndef MSG_NATIVE_HPP +#define MSG_NATIVE_HPP + +// Compilation C++ recquise +#ifndef __cplusplus + #error MsgNative.hpp requires C++ compilation (use a .cxx suffix) +#endif + +namespace msg +{ +class MsgNative +{ + private: + // Default constructor. + MsgNative(){} + + // Copy constructor. + MsgNative(const MsgNative& rMsgInterface) {} + + // Destructor. + virtual ~MsgNative(){} + + public: + + + static void processCreate(const Process& rProcess, const Host& rHost); + + static int processKillAll(int resetPID); + + static void processSuspend(const Process& process); + + static void processKill(const Process& process); + + static void processResume(const Process& process); + + static bool processIsSuspended(const Process& process); + + static Host& processGetHost(const Process& process); + + static Process& processFromPID(int PID); + + static int processGetPID(const Process& process); + + static int processGetPPID(const Process& process); + + static Process& processSelf(void); + + static int processSelfPID(void); + + static int processSelfPPID(void); + + static void processChangeHost(const Process& process, const Host& host); + + static void processWaitFor(double seconds); + + static void processExit(const Process& process); + + static Host& hostGetByName(const string& name) throw(HostNotFoundException); + + static string& hostGetName(const Host& host); + + static int hostGetNumber(void); + + static Host& hostSelf(void); + + static double hostGetSpeed(const Host& host); + + static bool hostIsAvail(const Host& host); + + static Host[] allHosts(void); + + static int hostGetLoad(const Host& host); + + static void taskCreate(const Task& task, const string& name, double computeDuration, double messageSize) + throw(NullPointerException, IllegalArgumentException); + + static Process& taskGetSender(const Task& task); + + static Host& taskGetSource(const Task& task); + + static string& taskGetName(const Task& task); + + static void taskCancel(const Task& task); + + static void parallelTaskCreate(const Task& pTask, const string& name, Host[]hosts, double[]computeDurations, double[]messageSizes) + throw(NullPointerException, IllegalArgumentException); + + static double taskGetComputeDuration(const Task& task); + + static double taskGetRemainingDuration(const Task& task); + + static void taskSetPriority(const Taska task, double priority); + + static void taskDestroy(const Task& task); + + static void taskExecute(const Task& task); + + static Task& taskGet(int channel, double timeout, const Host& host); + + static void taskSend(const string& alias, const Task& task, double timeout); + + static Task& taskReceive(const string& alias, double timeout, const Host& host); + + static int taskListenFrom(const string& alias); + + static bool taskListen(const string& alias); + + static int taskListenFromHost(const string& alias, const Host& host); + + static bool taskProbe(int channel); + + static int taskGetCommunicatingProcess(int channel); + + static int taskProbeHost(int channel, const Host& host); + + static void hostPut(const Host& host, int channel, const Task& task, double timeout); + + static void hostPutBounded(const Hos&t host, int channel, const Task& task, double max_rate); + + static void taskSendBounded(const string& alias, const Task& task, double maxrate); +}; +} + + + +#endif // !MSG_NATIVE_HPP \ No newline at end of file diff --git a/src/cxx/Object.cxx b/src/cxx/Object.cxx new file mode 100644 index 0000000000..2aa26b2892 --- /dev/null +++ b/src/cxx/Object.cxx @@ -0,0 +1,149 @@ +#include +#include + + +DeclaringClasses* DeclaringClass::declaringClasses = NULL; + + +namespace msg +{ + // Generate static object constructor for class registration + void DeclareClass(Class* c) + { + MSG_DELCARING_CLASSES.lock(); + MSG_DELCARING_CLASSES.addHead(c); + MSG_DELCARING_CLASSES.unlock(); + } +} + +////////////////////////////////////////////////////////////////////////////// +// Implémentation des fonctions membre de la classe Class + +// true if the class is derived from base classe referenced +// by pBaseClass +bool Class::isDerivedFrom(const Class* baseClass) const +{ + const Class* cur = this; + + while(cur) + { + if(cur == baseClass) + return true; + + cur = cur->baseClass; + } + + return false; +} + +// Dynamic name lookup and creation +Class* Class::fromName(const char* name) +{ + Class* cur; + + MSG_DELCARING_CLASSES.lock(); + + for(cur = MSG_DELCARING_CLASSES.getHead(); cur; cur = cur->next) + { + if(!strcmp(name,cur->name)) + break; + } + + MSG_DELCARING_CLASSES.unlock(); + return cur; +} + +Object* Class::createObject(const char* name) +{ + Class* c = fromName(name); + + if(NULL == c) + return NULL; + + return c->createObject(); +} + + +////////////////////////////////////////////////////////////////////////////// +// Object members implementation + +// Special runtime-class structure for Object (no base class) +const struct Class Object::classObject = +{ + "Object", // name + sizeof(Object), // typeSize + NULL, // baseClass + NULL, // next + NULL // declaringClass +}; + + +////////////////////////////////////////////////////////////////////////////// +// DeclaringClasses members implementation +// + +DeclaringClasses::DeclaringClasses() +{ + head = NULL; + count = 0; +} + + +// Ajoute une nouvelle classe en tête de liste +void DeclaringClasses::addHead(Class* c) +{ + if(NULL != head) + c->next = head; + + head = c; + count++; +} + +// Retourne la tête de liste et la retire de la liste +Class* DeclaringClasses::removeHead(void) +{ + Class* c = NULL; + + if(NULL != head) + { + c = head; + head = head->next; + count--; + } + + return c; +} + +// Retire la classe pClasse de la liste, mais ne la détruit pas +bool DeclaringClasses::remove(Class* c) +{ + if(NULL == head) + return false; + + bool success = false; + + if(head == c) + { + head = c->next; + count--; + success = true; + } + else + { + Class* cur = head; + + while((NULL != cur) && (cur->next!= c)) + cur = cur->next; + + if(NULL != cur) + { + cur->next = c->next; + count--; + success = true; + } + } + + return success; +} + + diff --git a/src/cxx/Process.cxx b/src/cxx/Process.cxx new file mode 100644 index 0000000000..0de536e8fb --- /dev/null +++ b/src/cxx/Process.cxx @@ -0,0 +1,525 @@ +#include + +namespace msg +{ + +Process* Process::currentProcess = NULL; + +// Default constructor. +Process::Process() +{ + this->nativeProcess = NULL; +} + +Process::Process(const char* hostname, const char* name) +throw(HostNotFoundException) +{ + Host host = Host::getByName(hostname); + + create(host, name, 0, NULL); +} + +Process::Process(const char* hostname, const char* name, int argc, char** argv) +throw(HostNotFoundException) +{ + Host host = Host::getByName(hostname); + + create(host, name, argc, argv); +} + +Process::Process(const Host& rHost, const char* name) +throw(HostNotFoundException) +{ + + create(rHost, name, 0, NULL); +} + +Process::Process(const Host& rHost, const char* name, int argc, char** argv) +throw(HostNotFoundException) +{ + + create(rHost, name, argc, argv); +} + +int Process::run(int argc, char** argv) +{ + Process* process =(Process*)argv[argc]; + + return process->main(argc, argv); +} + +void Process::create(const Host& rHost, const char* name, int argc, char** argv) +throw(HostNotFoundException) +{ + smx_process_t nativeCurrentProcess = NULL; + nativeProcess = xbt_new0(s_smx_process_t, 1); + smx_simdata_process_t simdata = xbt_new0(s_smx_simdata_process_t, 1); + smx_host_t nativeHost = SIMIX_host_get_by_name(rHost.getName()); + + argv = (char**)realloc(argc + 1, sizeo(char*)); + + argv[argc] = (char*)this; + + + // TODO throw HostNotFoundException if host is NULL + + // Simulator Data + simdata->smx_host = nativeHost; + simdata->mutex = NULL; + simdata->cond = NULL; + simdata->argc = argc; + simdata->argv = argv; + simdata->context = xbt_context_new(name, Process::run, NULL, NULL, simix_global->cleanup_process_function, nativeProcess, simdata->argc, simdata->argv); + + /* Process structure */ + nativeProcess->name = xbt_strdup(name); + nativeProcess->simdata = simdata; + + // Set process data + nativeProcess->data = NULL; + + // Set process properties + simdata->properties = NULL; + + xbt_swag_insert(nativeProcess, nativeHost->simdata->process_list); + + /* fix current_process, about which xbt_context_start mocks around */ + nativeCurrentProcess = simix_global->current_process; + xbt_context_start(nativeProcess->simdata->context); + simix_global->current_process = nativeCurrentProcess; + + xbt_swag_insert(nativeProcess, simix_global->process_list); + DEBUG2("Inserting %s(%s) in the to_run list", nativeProcess->name, nativeHost->name); + xbt_swag_insert(nativeProcess, simix_global->process_to_run); +} + + +int Process::killAll(int resetPID) +{ + return MSG_process_killall(resetPID); +} + +void Process::suspend(void) +throw(NativeException) +{ + if(MSG_OK != MSG_process_suspend(nativeProcess)) + { + // TODO throw NativeException. + } +} + +void Process::resume(void) +throw(NativeException) +{ + if(MSG_OK != MSG_process_resume(nativeProcess)) + { + // TODO throw NativeException. + } +} + + +bool Process::isSuspended(void) +{ + return (bool)MSG_process_is_suspended(nativeProcess); +} + + +Host& Process::getHost(void) +throw(NativeException) +{ + m_host_t nativeHost = MSG_process_get_host(nativeProcess); + + if(!nativeHost->data) + { + // TODO throw NativeException. + return NULL; + } + + // return the reference to the Host object + return (*((Host*)nativeHost->data)); +} + +Process& Process::fromPID(int PID) +throw(ProcessNotFoundException, NativeException) +{ + Process* process = NULL; + m_process_t nativeProcess = MSG_process_from_PID(PID); + + + if(!process) + { + throw ProcessNotFoundException; + return NULL; + } + + process = Process::fromNativeProcess(nativeProcess); + + if(!process) + { + // TODO throw NativeException + return NULL; + } + + return (*process); +} + +// TODO implement this method +Process& Process::fromNativeProcess(m_process_t nativeProcess) +{ + +} + +int Process::getPID(void) +{ + return MSG_process_get_PID(nativeProcess); +} + +int Process::getPPID(void) +{ + return MSG_process_get_PPID(nativeProcess); +} + + +Process& Process::currentProcess(void) +throw(NativeException) +{ + Process* currentProcess = NULL; + m_process_t currentNativeProcess = MSG_process_self(); + + + if(!currentNativeProcess) + { + // TODO throw NativeException + } + + currentProcess = Process::fromNativeProcess(currentNativeProcess); + + if(!currentProcess) + { + // TODO throw NativeException + return NULL; + } + + 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(NativeException) +{ + if(MSG_OK != MSG_process_change_host(nativeProcess, rHost.nativeHost)) + { + // TODO throw NativeException + } + +} + +void Process::sleep(double seconds) +throw(NativeException) +{ + if(MSG_OK != MSG_process_sleep(seconds)) + { + // TODO throw NativeException + } + +} + +void Process::putTask(const Host& rHost, int channel, const Task& rTask) +throw( NativeException) +{ + if(MSG_OK != MSG_task_put_with_timeout(rTask.nativeTask, rHost.nativeHost, channel, -1.0)) + { + // TODO throw NativeException + } +} + +void Process::putTask(const Host& rHost, int channel, const Task& rTask, double timeout) +throw(NativeException) +{ + if(MSG_OK != MSG_task_put_with_timeout(rTask.nativeTask, rHost.nativeHost, channel, timeout)) + { + // TODO throw NativeException + } +} + +Task& Process::getTask(int channel) +throw(NativeException) +{ + m_task_t nativeTask = NULL; + + + if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, -1.0, NULL)) + { + // TODO throw NativeException + return NULL; + } + + return (*((Task*)(nativeTask->data))); +} + +Task& Process::getTask(int channel, double timeout) +throw(NativeException) +{ + m_task_t nativeTask = NULL; + + + if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, timeout, NULL)) + { + // TODO throw NativeException + return NULL; + } + + return (*((Task*)(nativeTask->data))); +} + +Task& Process::getTask(int channel, const Host& rHost) +throw(NativeException) +{ + m_task_t nativeTask = NULL; + + + if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, -1.0, rHost.nativeHost)) + { + // TODO throw NativeException + return NULL; + } + + return (*((Task*)(nativeTask->data))); +} + +Task& Process::getTask(int channel, double timeout, const Host& rHost) +throw(NativeException) +{ + m_task_t nativeTask = NULL; + + + if (MSG_OK != MSG_task_get_ext(&nativeTask, channel, timeout, rHost.nativeHost)) + { + // TODO throw NativeException + return NULL; + } + + return (*((Task*)(nativeTask->data))); +} + +void Process::sendTask(const char* alias, const Task& rTask, double timeout) +throw(NativeException) +{ + if(MSG_OK != MSG_task_send_with_timeout(rTask.nativeTask, alias ,timeout)) + { + // TODO throw NativeException + } + +} + +void Process::sendTask(const char* alias, const Task& rTask) +throw(NativeException) +{ + if(MSG_OK != MSG_task_send_with_timeout(rTask.nativeTask, alias ,-1.0)) + { + // TODO throw NativeException + } +} + +void Process::sendTask(const Task& rTask) +throw(NativeException) +{ + MSG_error_t rv; + + char* alias = (char*)calloc(strlen(Host::currentHost().getName() + strlen(nativeProcess->name) + 2); + sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name); + + rv = MSG_task_send_with_timeout(rTask.nativeTask, alias ,-1.0); + + free(alias); + + if(MSG_OK != rv) + { + // TODO throw NativeException + } +} + +void Process::sendTask(const Task& rTask, double timeout) +throw(NativeException) +{ + MSG_error_t rv; + + char* alias = (char*)calloc(strlen(Host::currentHost().getName() + strlen(nativeProcess->name) + 2); + sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name); + + rv = MSG_task_send_with_timeout(rTask.nativeTask, alias ,timeout); + + free(alias); + + if(MSG_OK != rv) + { + // TODO throw NativeException + } +} + +Task& Process::receiveTask(const char* alias) +throw(NativeException) +{ + + m_task_t nativeTask = NULL; + + if (MSG_OK != MSG_task_receive_ext(&nativeTask,alias, -1.0, NULL)) + { + // TODO throw NativeException + return NULL; + } + + return (*((Task*)nativeTask->data)); +} + + +Task& Process::receiveTask(void) +throw(NativeException) +{ + m_task_t nativeTask = NULL; + + char* alias = (char*)calloc(strlen(Host::currentHost().getName() + strlen(nativeProcess->name) + 2); + sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name); + + MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, -1.0, NULL); + + free(alias); + + if(MSG_OK != rv) + { + //TODO throw NativeException + return NULL; + } + + return (*((Task*)nativeTask->data)); +} + + +Task& Process::receiveTask(const char* alias, double timeout) +throw(NativeException) +{ + m_task_t nativeTask = NULL; + + if(MSG_OK != MSG_task_receive_ext(&nativeTask, alias, timeout, NULL)) + { + //TODO throw NativeException + return NULL; + } + + return (*((Task*)nativeTask->data)); +} + + +Task& Process::receiveTask(double timeout) +throw(NativeException) +{ + m_task_t nativeTask = NULL; + + char* alias = (char*)calloc(strlen(Host::currentHost().getName() + strlen(nativeProcess->name) + 2); + sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name); + + MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, timeout, NULL); + + free(alias); + + if(MSG_OK != rv) + { + //TODO throw NativeException + return NULL; + } + + return (*((Task*)nativeTask->data)); +} + + +Task& Process::receiveTask(const char* alias, double timeout, const Host& rHost) +throw(NativeException) +{ + m_task_t nativeTask = NULL; + + if(MSG_OK != MSG_task_receive_ext(&nativeTask, alias, timeout, rHost.nativeHost)) + { + //TODO throw NativeException + return NULL; + } + + return (*((Task*)nativeTask->data)); +} + + +Task& Process::receiveTask(double timeout, const Host& rHost) +throw(NativeException) +{ + m_task_t nativeTask = NULL; + + char* alias = (char*)calloc(strlen(Host::currentHost().getName() + strlen(nativeProcess->name) + 2); + sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name); + + MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, timeout, rHost.nativeHost); + + free(alias); + + if(MSG_OK != rv) + { + //TODO throw NativeException + return NULL; + } + + return (*((Task*)nativeTask->data)); +} + + +Task& Process::receiveTask(const char* alias, const Host& rHost) +throw(NativeException) +{ + + m_task_t nativeTask = NULL; + + + if(MSG_OK != MSG_task_receive_ext(&nativeTask, alias, -1.0, rHost.nativeHost)) + { + //TODO throw NativeException + return NULL; + } + + return (*((Task*)nativeTask->data)); +} + +Task& Process::receiveTask(const Host& rHost) +throw(NativeException) +{ + m_task_t nativeTask = NULL; + + char* alias = (char*)calloc(strlen(Host::currentHost().getName() + strlen(nativeProcess->name) + 2); + sprintf(alias,"%s:%s", Host::currentHost().getName() ,nativeProcess->name); + + MSG_error_t rv = MSG_task_receive_ext(&nativeTask, alias, -1.0, rHost.nativeHost); + + free(alias); + + if(MSG_OK != rv) + { + //TODO throw NativeException + return NULL; + } + + return (*((Task*)nativeTask->data)); +} + +const char* Process::getName(void) const +{ + return nativeProcess->name; +} + + +} \ No newline at end of file diff --git a/src/cxx/Process.hpp b/src/cxx/Process.hpp new file mode 100644 index 0000000000..1ee45b3872 --- /dev/null +++ b/src/cxx/Process.hpp @@ -0,0 +1,148 @@ +#ifndef MSG_PROCESS_HPP +#define MSG_PROCESS_HPP + +// Compilation C++ recquise +#ifndef __cplusplus + #error Process.hpp requires C++ compilation (use a .cxx suffix) +#endif + +namespace msg +{ + +class Process +{ + + friend ApplicationHandler; + + private; + + // Default constructor. + Process(); + + public: + + // Construct a process from the name of the host and its name. + Process(const char* hostName, const char* name) + throw(HostNotFoundException); + + Process(const Host& rHost, const char* name) + throw(HostNotFoundException); + + Process(const char* hostName, const char* name, int argc, char** argv) + throw(HostNotFoundException); + + Process(const Host& rHost, const char* name, int argc, char** argv) + throw(HostNotFoundException); + + static int killAll(int resetPID); + + void Process::suspend(void) + throw(NativeException); + + void Process::resume(void) + throw(NativeException); + + bool isSuspended(void); + + Host& getHost(void) + throw(NativeException); + + static Process& fromPID(int PID); + + + int getPID(void); + + int getPPID(void); + + const char* getName(void) const; + + static Process& currentProcess(void); + + static int currentProcessPID(void); + + static int currentProcessPPID(void); + + void migrate(const Host& rHost) + throw(NativeException); + + static void sleep(double seconds) + throw(NativeException); + + void putTask(const Host& rHost, int channel, const Task& rTask) + throw( NativeException); + + void putTask(const Host& rHost, int channel, const Task& rTask, double timeout) + throw(NativeException); + + Task& getTask(int channel) + throw(NativeException); + + Task& getTask(int channel, double timeout) + throw(NativeException); + + Task& getTask(int channel, const Host& rHost) + throw(NativeException); + + Task& getTask(int channel, double timeout, const Host& rHost) + throw(NativeException); + + void sendTask(const char* alias, const Task& rTask, double timeout) + throw(NativeException); + + void sendTask(const char* alias, const Task& rTask) + throw(NativeException); + + void sendTask(const Task& rTask) + throw(NativeException); + + void sendTask(const Task& rTask, double timeout) + throw(NativeException); + + Task& receiveTask(const char* alias) + throw(NativeException); + + Task& receiveTask(void) + throw(NativeException); + + Task& receiveTask(const char* alias, double timeout) + throw(NativeException); + + Task& receiveTask(double timeout) + throw(NativeException); + + Task& receiveTask(const char* alias, double timeout, const Host& rHost) + throw(NativeException); + + Task& Process::receiveTask(double timeout, const Host& rHost) + throw(NativeException); + + Task& receiveTask(const char* alias, const Host& rHost) + throw(NativeException); + + Task& receiveTask(const Host& rHost) + throw(NativeException); + + + private: + void create(const Host& rHost, const char* name, int argc, char** argv) + throw(HostNotFoundException); + + + static Process& fromNativeProcess(m_process_t nativeProcess); + + + public: + + static int run(int argc, char** argv); + + virtual int main(int argc, char** argv) = 0; + + private: + + // Attributes. + + m_process_t nativeProcess; // pointer to the native msg process. + +}; + +} \ No newline at end of file diff --git a/src/cxx/Task.cxx b/src/cxx/Task.cxx new file mode 100644 index 0000000000..30f2dd0532 --- /dev/null +++ b/src/cxx/Task.cxx @@ -0,0 +1,183 @@ +#include + +namespace msg +{ + +Task::Task() +{ + nativeTask = NULL; +} + + +Task::Task(const Task& rTask) +{ +} + + +Task::~Task() +throw(NativeException) +{ + if(NULL != nativeTask) + { + if(MSG_OK != MSG_task_destroy(nativeTask)) + { + // TODO throw NativeException + } + } +} + + +Task::Task(const char* name, double computeDuration, double messageSize) +{ + + if(computeDuration < 0) + { + // TODO throw exception + return; + } + + if(messageSize < 0) + { + // TODO throw exception + return; + } + + if(!name) + { + // TODO throw exception + return; + } + + // 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) +{ + // TODO parallel task create +} + + +const char* Task::getName(void) const +{ + return nativeTask->name; +} + +Process& Task::getSender(void) const +{ + m_proccess_t nativeProcess = MSG_task_get_sender(nativeTask); + + return (*((Process*)(nativeProcess->data))); +} + +Host& Task::getSource(void) const +throw(NativeException) +{ + m_host_t nativeHost = MSG_task_get_source(nativeTask); + + if(!nativeHost->data) + { + // TODO throw the exception + return NULL; + } + + 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) +{ + MSG_task_set_priority(nativeTask, priority); +} + +Task& Task::get(int channel) +throw(NativeException) +{ + m_task_t nativeTask = NULL; + + + if(MSG_OK != MSG_task_get_ext(&nativeTask, channel , -1.0, NULL)) + { + // TODO throw the NativeException + return NULL; + } + + return (*((Task*)(nativeTask->data))); +} + +Task& Task::get(int channel, const Host& rHost) +throw(NativeException) +{ + m_task_t nativeTask = NULL; + + + if(MSG_OK != MSG_task_get_ext(&nativeTask, channel , -1.0, rHost.nativeHost)) + { + // TODO throw the NativeException + return NULL; + } + + return (*((Task*)(nativeTask->data))); +} + +Task& Task::get(int channel, double timeout, const Host& rHost) +throw(NativeException) +{ + m_task_t nativeTask = NULL; + + + if(MSG_OK != MSG_task_get_ext(&nativeTask, channel , timeout, rHost.nativeHost)) + { + // TODO throw the NativeException + return NULL; + } + + return (*((Task*)(nativeTask->data))); +} + +bool static Task::probe(int channel) +{ + return (bool)MSG_task_Iprobe(channel); +} + +int Task::probe(int channel, const Host& rHost) +{ + return MSG_task_probe_from_host(chan_id,rHost.nativeHost); +} + +void Task::execute(void) +throw(NativeException) +{ + if(MSG_OK != MSG_task_execute(nativeTask)) + { + // TODO throw NativeException + } +} + +void Task::cancel(void) +throw(NativeException) +{ + if(MSG_OK != MSG_task_cancel(nativeTask)) + { + // TODO throw NativeException + } +} + +void send(void) +throw(NativeException) +{ +} + +} + diff --git a/src/cxx/Task.hpp b/src/cxx/Task.hpp new file mode 100644 index 0000000000..4b55a64b39 --- /dev/null +++ b/src/cxx/Task.hpp @@ -0,0 +1,78 @@ +#ifndef MSG_TASK_HPP +#define MSG_TASK_HPP + +// Compilation C++ recquise +#ifndef __cplusplus + #error Process.hpp requires C++ compilation (use a .cxx suffix) +#endif + +namespace msg +{ +class Task +{ + protected: + // Default constructor. + Task(); + + public: + // Copy constructor. + Task(const Task& rTask); + + // Destructor. + virtual ~Task() + throw(NativeException); + + // Other constructors. + Task(const char* name, double computeDuration, double messageSize); + + Task(const char* name, Host* hosts, double* computeDurations, double* messageSizes); + + + // Getters/setters. + const char* getName(void) const; + + + Process& getSender(void) const; + + Host& getSource(void) const + throw(NativeException); + + double getComputeDuration(void) const; + + double getRemainingDuration(void) const; + + void setPriority(double priority); + + static Task& get(int channel) + throw(NativeException); + + static Task& get(int channel, const Host& rHost) + throw(NativeException); + + static Task& get(int channel, double timeout, const Host& rHost) + throw(NativeException); + + static bool probe(int channel); + + static int probe(int channel, const Host& rHost); + + void execute(void) + throw(NativeException); + + void cancel(void) + throw(NativeException); + + + void send(void) + throw(NativeException); + + private: + + m_task_t nativeTask; + + +}; + +} + +#endif // §MSG_TASK_HPP \ No newline at end of file -- 2.20.1