BEGIN_DECL()
-/**
- * gras_if_RL:
+/** @addtogroup GRAS_cond
+ * @brief Handling code specific to the simulation or to the reality (Virtualization).
*
- * Returns true only if the program runs on real life
+ * Please note that those are real functions and not pre-processor defines. This is to ensure
+ * that the same object code can be linked against the SG library or the RL one without recompilation.
+ *
+ * @{
*/
+
+/** \brief Returns true only if the program runs on real life */
int gras_if_RL(void);
-/**
- * gras_if_SG:
- *
- * Returns true only if the program runs within the simulator
- */
+/** \brief Returns true only if the program runs within the simulator */
int gras_if_SG(void);
+/** @} */
+
END_DECL()
#endif /* GRAS_COND_H */
BEGIN_DECL()
-/** @defgroup GRAS_dd Data description
+/** @addtogroup GRAS_dd Data description
* @brief Describing data to be exchanged (Communication facility)
*
* @section Overview
* - d) Callback Persistant State: Simple push/pop mecanism
* - e) Callback Persistant State: Full featured mecanism
*/
-
+/*@{*/
+
/** @name a) basic operations
- * @ingroup GRAS_dd
*
* If you only want to send pre-existing types, simply retrieve the pre-defined description with
* the \ref gras_datadesc_by_name function. Existing types entail:
/* @} */
/** @name b) Automatic parsing
- * @ingroup GRAS_dd
*
* If you need to declare a new datatype, this is the simplest way to describe it to GRAS. Simply
* enclose its type definition into a \ref GRAS_DEFINE_TYPE macro call, and you're set. Here is
gras_datadesc_parse(const char *name, const char *C_statement);
/** @name c) Simple manual definitions
- * @ingroup GRAS_dd
*
* Here are the functions to use if you want to declare your description manually.
* The function names should be self-explanatory in most cases.
/*@}*/
/** @name d) Callback Persistant State: Simple push/pop mecanism
- * @ingroup GRAS_dd
*
* Sometimes, one of the callbacks need to leave information for the next ones. If this is a simple integer (such as
* an array size), you can use the functions described here. If not, you'll have to play with the complete cbps interface.
/*@}*/
/** @name e) Callback Persistant State: Full featured mecanism
- * @ingroup GRAS_dd
*
* Sometimes, one of the callbacks need to leave information for the next ones. If the simple push/pop mecanism
* introduced in previous section isn't enough, you can always use this full featured one.
gras_cbps_block_end(gras_cbps_t ps);
/* @} */
+/*@}*/
/*******************************
BEGIN_DECL()
-/* msgtype declaration and retrival */
+/** @addtogroup GRAS_msg
+ * @brief Defining messages and callbacks, and exchanging messages (Communication facility)
+ * @{
+ */
+
+/** @name Message declaration and retrival
+ *
+ * GRAS messages can only accept one type of payload. If you absolutely want to declare a message
+ * able to convey several datatypes, you can always say that it conveys a generic reference (see
+ * \ref gras_datadesc_ref_generic).
+ *
+ * In order to ease the upgrade of GRAS applications, it is possible to \e version the messages, ie
+ * to add a version number to the message (by default, the version is set to 0). Any messages of the
+ * wrong version will be ignored by the applications not providing any specific callback for them.
+ *
+ * This mecanism (stolen from the dynamic loader one) should ensure you to change the semantic of a given
+ * message while still understanding the old one.
+ */
+/** @{ */
+/** \brief Opaque type */
typedef struct s_gras_msgtype *gras_msgtype_t;
+/** \brief declare a new message type of the given name. It only accepts the given datadesc as payload */
void gras_msgtype_declare (const char *name,
gras_datadesc_type_t payload);
+/** \brief declare a new versionned message type of the given name and payload. */
void gras_msgtype_declare_v(const char *name,
short int version,
gras_datadesc_type_t payload);
+/** \brief retrive an existing message type from its name. */
gras_msgtype_t gras_msgtype_by_name (const char *name);
+/** \brief retrive an existing message type from its name and version number. */
gras_msgtype_t gras_msgtype_by_namev(const char *name,
short int version);
+/** @} */
-/**
- * gras_cb_t:
- * @msg: The message itself
- * @Returns: true if the message was consumed by the callback.
+/** @name Callback declaration and use */
+/** @{ */
+/** \brief Type of message callback functions.
+ * \param msg: The message itself
+ * \return true if the message was consumed by the callback, false if the message was
+ * refused by the callback (and should be passed to the next callback of the stack for
+ * this message)
*
- * Type of message callback functions. Once a such a function is registered to
- * handle messages of a given type with RegisterCallback(), it will be called
- * each time such a message incomes.
+ * Once a such a function is registered to handle messages of a given type with
+ * \ref gras_cb_register(), it will be called each time such a message arrives.
*
* If the callback accepts the message, it should free it after use.
*/
typedef int (*gras_cb_t)(gras_socket_t expeditor,
void *payload);
+/** \brief Bind the given callback to the given message type
+ *
+ * Several callbacks can be attached to a given message type. The lastly added one will get the message first, and
+ * if it returns false, the message will be passed to the second one.
+ * And so on until one of the callbacks accepts the message.
+ */
void gras_cb_register (gras_msgtype_t msgtype,
gras_cb_t cb);
+/** \brief Unbind the given callback from the given message type */
void gras_cb_unregister(gras_msgtype_t msgtype,
gras_cb_t cb);
+/** @} */
+/** @name Message exchange */
+/** @{ */
+/** \brief Send the data pointed by \a payload as a message of type \a msgtype to the peer \a sock */
xbt_error_t gras_msg_send(gras_socket_t sock,
gras_msgtype_t msgtype,
void *payload);
+/** \brief Waits for a message to come in over a given socket. */
xbt_error_t gras_msg_wait(double timeout,
gras_msgtype_t msgt_want,
gras_socket_t *expeditor,
void *payload);
xbt_error_t gras_msg_handle(double timeOut);
+/*@}*/
END_DECL()
/****************************************************************************/
/* Manipulating User Data */
/****************************************************************************/
+
+/** \addtogroup GRAS_globals
+ * \brief Handling global variables so that it works on simulator (Virtualization).
+ *
+ * In GRAS, using globals is forbidden since the "processes" will
+ * sometimes run as a thread inside the same process (namely, in
+ * simulation mode). So, you have to put all globals in a structure, and
+ * let GRAS handle it.
+ *
+ * Use the \ref gras_userdata_new macro to create a new user data (or malloc it
+ * and use \ref gras_userdata_set yourself), and \ref gras_userdata_get to
+ * retrive a reference to it.
+ */
+/*@{*/
+
/**
* \brief Get the data associated with the current process.
* \ingroup GRAS_globals
*/
void gras_userdata_set(void *ud);
-/**
- * \brief Malloc and set the data associated with the current process.
- * \ingroup GRAS_globals
- */
-
+/** \brief Malloc and set the data associated with the current process. */
#define gras_userdata_new(type) (gras_userdata_set(xbt_new0(type,1)),gras_userdata_get())
+/*@}*/
END_DECL()
#include "xbt/error.h"
+/** \addtogroup GRAS_sock
+ * \brief Socket handling (Communication facility).
+ */
+
+/** \name Socket creation functions
+ * \ingroup GRAS_sock
+ */
+/*@{*/
+/** \brief Opaque type describing a socket */
typedef struct s_gras_socket *gras_socket_t;
+/** \brief Simply create a client socket (to speak to a remote host) */
xbt_error_t gras_socket_client(const char *host,
unsigned short port,
/* OUT */ gras_socket_t *dst);
+/** \brief Simply create a server socket (to ear from remote hosts speaking to you) */
xbt_error_t gras_socket_server(unsigned short port,
/* OUT */ gras_socket_t *dst);
+/** \brief Close socket */
void gras_socket_close(gras_socket_t sd);
-/* get information about socket */
-int gras_socket_my_port (gras_socket_t sock);
-int gras_socket_peer_port(gras_socket_t sock);
-char *gras_socket_peer_name(gras_socket_t sock);
-
-/* extended interface to get all details */
+/** \brief Create a client socket, full interface to all relevant settings */
xbt_error_t gras_socket_client_ext(const char *host,
unsigned short port,
unsigned long int bufSize,
int raw,
/* OUT */ gras_socket_t *dst);
+/** \brief Create a server socket, full interface to all relevant settings */
xbt_error_t gras_socket_server_ext(unsigned short port,
unsigned long int bufSize,
int raw,
/* OUT */ gras_socket_t *dst);
+/*@}*/
+/** \name Retrieving data about sockets and peers
+ * \ingroup GRAS_sock
+ *
+ * Who are you talking to?
+ */
+/*@{*/
+
+/** Get the port number on which this socket is connected on my side */
+int gras_socket_my_port (gras_socket_t sock);
+/** Get the port number on which this socket is connected on remote side */
+int gras_socket_peer_port(gras_socket_t sock);
+/** Get the host name of the remote side */
+char *gras_socket_peer_name(gras_socket_t sock);
+/*@}*/
+
+/** \name Using raw sockets
+ * \ingroup GRAS_sock
+ *
+ * You may want to use sockets not to exchange valuable data (in messages),
+ * but to conduct some experiments such as bandwidth measurement. If so, try those raw sockets.
+ *
+ * You can only use those functions on sockets openned with the "raw" boolean set to true.
+ *
+ * \bug Raw sockets are not fully functionnal yet.
+ */
+/*@{*/
-/* using raw sockets */
xbt_error_t gras_socket_raw_send(gras_socket_t peer,
unsigned int timeout,
unsigned long int expSize,
unsigned long int expSize,
unsigned long int msgSize);
+/*@}*/
+
+/** \name Using files as sockets
+ * \ingroup GRAS_sock
+ *
+ * For debugging purpose, it is possible to deal with files as if they were sockets.
+ * It can even be useful to store stuff in a portable manner, but writing messages to a file
+ * may be strange...
+ *
+ * \bug Don't use '-' on windows. this file represents stdin or stdout, but I failed to deal with it on windows.
+ */
+/*@{*/
/* debuging functions */
xbt_error_t gras_socket_client_from_file(const char*path,
/* OUT */ gras_socket_t *dst);
xbt_error_t gras_socket_server_from_file(const char*path,
/* OUT */ gras_socket_t *dst);
+/*@}*/
#endif /* GRAS_TRANSPORT_H */
BEGIN_DECL()
-/**
- * gras_os_time:
- * @Returns: number of second since the Epoch.
- * (00:00:00 UTC, January 1, 1970 in Real Life, and begining of simulation in SG)
- *
- * Get the current time.
+/** @addtogroup GRAS_virtu
+ * @brief System call abstraction layer (Virtualization).
+ * @{
+ */
+
+/** @brief Get the current time
+ * @return number of second since the Epoch.
+ * (00:00:00 UTC, January 1, 1970 in Real Life, and begining of simulation in SG)
*/
double gras_os_time(void);
-/**
- * gras_os_sleep:
- * @Param1: number of seconds to sleep
- * @Param2: number of microseconds to sleep
- *
- * sleeps for the given amount of time.
+/** @brief sleeps for the given amount of time.
+ * @param sec: number of seconds to sleep
+ * @param usec: number of microseconds to sleep
*/
void gras_os_sleep(unsigned long sec, unsigned long usec);
-/**
- * gras_get_my_fqdn:
+/** @brief get the fully-qualified name of the current host
*
* Returns the fully-qualified name of the host machine, or NULL if the name
* cannot be determined. Always returns the same value, so multiple calls
const char *
gras_get_my_fqdn(void);
+/** @} */
END_DECL()
#endif /* GRAS_VIRTU_H */
static char GRAS_header[6];
static char *make_namev(const char *name, short int ver);
-/**
- * gras_msg_init:
- *
+/*
* Initialize this submodule.
*/
void gras_msg_init(void) {
GRAS_header[5]=(char)GRAS_THISARCH;
}
-/**
- * gras_msg_exit:
- *
+/*
* Finalize the msg module
- **/
+ */
void
gras_msg_exit(void) {
VERB0("Exiting Msg");
xbt_set_free(&_gras_msgtype_set);
}
-/**
- * gras_msgtype_free:
- *
+/*
* Reclamed memory
*/
void gras_msgtype_free(void *t) {
}
/**
- * gras_msgtype_declare:
- * @name: name as it should be used for logging messages (must be uniq)
- * @payload: datadescription of the payload
- *
- * Registers a message to the GRAS mecanism.
+ * @param name: name as it should be used for logging messages (must be uniq)
+ * @param payload: datadescription of the payload
*/
void gras_msgtype_declare(const char *name,
gras_datadesc_type_t payload) {
}
/**
- * gras_msgtype_declare_v:
- * @name: name as it should be used for logging messages (must be uniq)
- * @version: something like versionning symbol
- * @payload: datadescription of the payload
+ * @param name: name as it should be used for logging messages (must be uniq)
+ * @param version: something like versionning symbol
+ * @param payload: datadescription of the payload
*
* Registers a message to the GRAS mecanism. Use this version instead of
* gras_msgtype_declare when you change the semantic or syntax of a message and
&gras_msgtype_free);
}
-/**
- * gras_msgtype_by_name:
- *
- * Retrieve a datatype description from its name
+/*
+ * Retrieve a msgtype description from its name
*/
gras_msgtype_t gras_msgtype_by_name (const char *name) {
return gras_msgtype_by_namev(name,0);
}
-/**
- * gras_msgtype_by_namev:
- *
- * Retrieve a datatype description from its name and version
+/*
+ * Retrieve a msgtype description from its name and version
*/
gras_msgtype_t gras_msgtype_by_namev(const char *name,
short int version) {
return res;
}
-/**
- * gras_msg_send:
- *
+/*
* Send the given message on the given socket
*/
xbt_error_t
return no_error;
}
-/**
- * gras_msg_recv:
- *
+/*
* receive the next message on the given socket.
*/
xbt_error_t
}
/**
- * gras_msg_wait:
- * @timeout: How long should we wait for this message.
- * @id: id of awaited msg
- * @Returns: the error code (or no_error).
- *
- * Waits for a message to come in over a given socket.
+ * @param timeout: How long should we wait for this message.
+ * @param msgt_want: type of awaited msg
+ * @param[out] expeditor: where to create a socket to answer the incomming message
+ * @param[out] payload: where to write the payload of the incomming message
+ * @return the error code (or no_error).
*
* Every message of another type received before the one waited will be queued
* and used by subsequent call to this function or MsgHandle().
}
/**
- * gras_msg_handle:
- * @timeOut: How long to wait for incoming messages
- * @Returns: the error code (or no_error).
+ * @param timeOut: How long to wait for incoming messages
+ * @return the error code (or no_error).
*
- * Waits up to #timeOut# seconds to see if a message comes in; if so, calls the
- * registered listener for that message (see RegisterCallback()).
+ * Waits up to \a timeOut seconds to see if a message comes in; if so, calls the
+ * registered listener for that message (see \ref gras_cb_register()).
*/
xbt_error_t
gras_msg_handle(double timeOut) {
#include "gras/Virtu/virtu_sg.h"
-/**
- * gras_time:
- * @Returns: The current time
- *
- * The epoch since when the time is given is not specified. It is thus only usefull to compute intervals
+/*
+ * Time elapsed since the begining of the simulation.
*/
double gras_os_time() {
return MSG_getClock();
}
-/**
- * gras_sleep:
- * @sec: amount of sec to sleep
- * @usec: amount of micro second to sleep
- *
+/*
* Freeze the process for the specified amount of time
*/
void gras_os_sleep(unsigned long sec,unsigned long usec) {
MSG was the first distributed programming environment provided within
SimGrid. While almost realistic, it remains quite simple (simplistic?).
+ \section MSG_who Who should use this (and who shouldn't)
+
You should use this model if you want to study some heuristics for a
given problem you don't really want to implement. If you want to get a
real implementation of your solution, have a look at the \ref GRAS_API
encompassing both developer helping tools (the simulator and associated
tools) and an efficient while portable execution runtime.
+ \section GRAS_who Who should use this (and who shouldn't)
+
You should use this programming environment if you want to develop real
applications, ie if the final result of your work is a program which
may eventually be distributed.
consider implementing your own directly on top of \ref SURF_API (but you
probably want to contact us before).
- The user visibile features tend to offer several kind of functionnalities:
+ \section GRAS_funct Offered functionnalities
- <b>Communication facilities</b>: Exchanging messages between peers
+ - \ref GRAS_dd: any data which may transit on the network must be
+ described beforehand so that GRAS can handle the platform
+ heterogeneity and convert them if needed.
+ - \ref GRAS_sock: this is how to open a communication channel to
+ other processes, and retrive information about them.
+ - \ref GRAS_msg: communications are message oriented. You have to
+ describe all possible messages and their payload beforehand, and
+ can then attach callbacks to the arrival of a given kind of message.
- <b>Virtualization</b>: Running both on top of the simulator and on
top of real platforms, and portability support.
+ - \ref GRAS_globals: The use of globals is forbidden since the
+ "processes" are threads in simulation mode. \n
+ This is how to let GRAS handle your globals properly.
+ - \ref GRAS_cond: How to declare specific code for the simulation mode
+ or for the real mode.
+ - \ref GRAS_virtu: You naturally don't want to call the
+ gettimeofday(2) function in simulation mode since it would give
+ you the time on the host running the simulation, not the time in
+ the simulated world (you are belonging to).\n
+ This a system call virtualization layer, which also acts as a
+ portability layer.
+
+ @{
*/
-/** \addtogroup GRAS_implem
- \ingroup GRAS_API
-
- Internals of GRAS (forget it) */
-/** \addtogroup GRAS_dd
- \ingroup GRAS_API */
-/** \addtogroup GRAS_dd_implem
- \ingroup GRAS_implem */
-/** \defgroup GRAS_sock Sockets
- \ingroup GRAS_API
- \brief Open/close sockets, and get info on peer (Communication facility). */
-/** \defgroup GRAS_msg Messages
- \ingroup GRAS_API
- \brief Defining messages and callbacks, and sending/receiving messages (Communication facility).
- */
-/** \defgroup GRAS_globals Globals
- \ingroup GRAS_API
- \brief Handling global variables so that it works on simulator (Virtualization).
-
- In GRAS, using globals is forbidden since the "processes" will
- sometimes run as a thread inside the same process (namely, in
- simulation mode). So, you have to put all globals in a structure, and
- let GRAS handle it.
-
- Use the \ref gras_userdata_new macro to create a new user data (or malloc it
- and use \ref gras_userdata_set yourself), and \ref gras_userdata_get to
- retrive a reference to it. */
-/** \defgroup GRAS_virtu Syscalls
- \ingroup GRAS_API
- \brief System call abstraction layer (Virtualization). */
+ /** \defgroup GRAS_dd Data description */
+ /** \defgroup GRAS_sock Sockets */
+ /** \defgroup GRAS_msg Messages */
+
+ /** \defgroup GRAS_globals Globals */
+ /** \defgroup GRAS_cond Conditional execution */
+ /** \defgroup GRAS_virtu Syscalls */
+
+/** @} */
/** \defgroup SMPI_API SMPI
\ingroup SimGrid_API
for that. In other words, it will constitute an emulation solution for
parallel codes.
+ \section SMPI_who Who should use this (and who shouldn't)
+
You should use this programming environment of the SimGrid suite if you
want to study existing MPI applications.
If you want to work on a distributed application, have a look at the