- @ref msg_ex_ns3
- @ref msg_ex_io
- @ref msg_ex_actions
- - @ref msg_ex_full_apps
+ - @ref msg_ex_apps
- @ref msg_ex_misc
@section msg_ex_basic Basic examples and features
I/O operations can also be done in a remote, i.e. when the
accessed disk is not mounted on the caller's host.
- - @ref examples/msg/actions-comm/actions-comm.c \n
- - @ref examples/msg/actions-storage/actions-storage.c \n
- - @ref examples/msg/app-pmm/app-pmm.c \n
- - @ref examples/msg/dht-chord \n
+@section msg_ex_actions Following Workload Traces
+
+This section details how to run trace-driven simulations. It is very
+handy when you want to test an algorithm or protocol that only react
+to external events. For example, many P2P protocols react to user
+requests, but do nothing if there is no such event.
+
+In such situations, you should write your protocol in C, and separate
+the workload that you want to play onto your protocol in a separate
+text file. Declare a function handling each type of the events in your
+trace, register them using @ref xbt_replay_action_register in your
+main, and then use @ref MSG_action_trace_run to launch the simulation.
+
+Then, you can either have one trace file containing all your events,
+or a file per simulated process: the former may be easier to work
+with, but the second is more efficient on very large traces. Check
+also the tesh files in the example directories for details.
+
+ - <b>Communication replay</b>.
+ @ref examples/msg/actions-comm/actions-comm.c \n
+ Presents a set of event handlers reproducing classical communication
+ primitives (synchronous and asynchronous send/receive, broadcast,
+ barrier, etc).
+
+ - <b>I/O replay</b>.
+ @ref examples/msg/actions-storage/actions-storage.c \n
+ Presents a set of event handlers reproducing classical I/O
+ primitives (open, read, write, close, etc).
+
+@section msg_ex_apps Examples of Full Applications
+
+ - <b>Parallel Matrix Multiplication</b>.
+ @ref examples/msg/app-pmm/app-pmm.c \n
+ This little application multiplies two matrices in parallel. Each
+ of the 9 processes computes a sub-block of the result, with the
+ sub-blocks of the input matrices exchanged between the processes. \n
+ This is a classical assignment in MPI lectures, here implemented
+ in MSG.
+
+ - <b>Chord P2P protocol</b>.
+ @ref examples/msg/dht-chord/dht-chord.c \n
+ This example implements the well known Chord protocol,
+ constituting a fully working non-trivial example. This
+ implementation is also very efficient, as demonstrated in
+ http://hal.inria.fr/inria-00602216/
+
- @ref examples/msg/task-priority/task-priority.c \n
- @ref examples/msg/properties/properties.c \n
@example examples/msg/io-storage/io-storage.c
@example examples/msg/io-file/io-file.c
@example examples/msg/io-remote/io-remote.c
+
@example examples/msg/actions-comm/actions-comm.c
@example examples/msg/actions-storage/actions-storage.c
+
@example examples/msg/app-pmm/app-pmm.c
@example examples/msg/dht-chord
+
@example examples/msg/task-priority/task-priority.c
@example examples/msg/properties/properties.c
MSG_task_set_priority() to change the computation priority of a
given task.
-Trace driven simulations
-========================
-
-The actions/actions.c example demonstrates how to run trace-driven
-simulations. It is very handy when you want to test an algorithm or
-protocol that does nothing unless it receives some events from
-outside. For example, a P2P protocol reacts to requests from the user,
-but does nothing if there is no such event.
-
-In such situations, SimGrid allows to write your protocol in your C
-file, and the events to react to in a separate text file. Declare a
-function handling each of the events that you want to accept in your
-trace files, register them using MSG_action_register in your main, and
-then use MSG_action_trace_run to launch the simulation. You can either
-have one trace file containing all your events, or a file per
-simulated process. Check the tesh files in the example directory for
-details on how to do it.
-
-This example uses this approach to replay MPI-like traces. It comes
-with a set of event handlers reproducing MPI events. This is somehow
-similar to SMPI, yet differently implemented. This code should
-probably be changed to use SMPI internals instead, but wasn't, so far.
-
Examples of full applications
=============================
-/* Copyright (c) 2009-2015. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2009-2016. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/simix.h" /* semaphores for the barrier */
#include <xbt/replay.h>
-/** @addtogroup MSG_examples
- *
- * @section msg_ex_actions Trace driven simulations
- *
- * This section details how to run trace-driven simulations. It is very handy when you want to test an algorithm or
- * protocol that does nothing unless it receives some events from outside. For example, a P2P protocol reacts to
- * requests from the user, but does nothing if there is no such event.
- *
- * In such situations, SimGrid allows you to write your protocol in a C file, and the events to react to in a separate
- * text file. Declare a function handling each of the events that you want to accept in your trace files, register
- * them using \ref xbt_replay_action_register in your main, and then use \ref MSG_action_trace_run to launch the
- * simulation. You can either have one trace file containing all your events, or a file per simulated process. Check
- * the tesh files in the example directories for details on how to do it.
- *
- * - <b>Communication: actions-comm/actions-comm.c</b>. This example comes with a set of event handlers reproducing
- * some classical communication primitives (synchronous and asynchronous send/receive, broadcast, barrier, ...).
- */
-
XBT_LOG_NEW_DEFAULT_CATEGORY(actions, "Messages specific for this msg example");
int communicator_size = 0;
static void action_bcast(const char *const *action)
{
- int i;
- char *bcast_identifier;
char mailbox[80];
double comm_size = parse_double(action[2]);
msg_task_t task = NULL;
- const char *process_name;
double clock = MSG_get_clock();
process_globals_t counters = (process_globals_t) MSG_process_get_data(MSG_process_self());
xbt_assert(communicator_size, "Size of Communicator is not defined, can't use collective operations");
- process_name = MSG_process_get_name(MSG_process_self());
+ const char * process_name = MSG_process_get_name(MSG_process_self());
- bcast_identifier = bprintf("bcast_%d", counters->bcast_counter++);
+ char *bcast_identifier = bprintf("bcast_%d", counters->bcast_counter++);
if (!strcmp(process_name, "p0")) {
XBT_DEBUG("%s: %s is the Root", bcast_identifier, process_name);
msg_comm_t *comms = xbt_new0(msg_comm_t, communicator_size - 1);
- for (i = 1; i < communicator_size; i++) {
+ for (int i = 1; i < communicator_size; i++) {
sprintf(mailbox, "%s_p0_p%d", bcast_identifier, i);
comms[i - 1] = MSG_task_isend(MSG_task_create(mailbox, 0, comm_size, NULL), mailbox);
}
MSG_comm_waitall(comms, communicator_size - 1, -1);
- for (i = 1; i < communicator_size; i++)
+ for (int i = 1; i < communicator_size; i++)
MSG_comm_destroy(comms[i - 1]);
xbt_free(comms);
}
}
-/** Main function */
int main(int argc, char *argv[])
{
msg_error_t res = MSG_OK;
XBT_INFO("Simulation time %g", MSG_get_clock());
- /* Explicit finalization of the action module is required now*/
- MSG_action_exit();
+ MSG_action_exit(); /* Explicit finalization of the action module */
return res != MSG_OK;
}
-/* Copyright (c) 2015. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2015-2016. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include <xbt/replay.h>
XBT_LOG_NEW_DEFAULT_CATEGORY(storage_actions, "Messages specific for this example");
-/** @addtogroup MSG_examples
- *
- * - <b>I/O: actions-comm/actions-comm.c</b>. This example comes with a set of event handlers reproducing
- * some classical I/O primitives (open, read, write, close, ...).
- */
static xbt_dict_t opened_files = NULL;
-/* pmm - parallel matrix multiplication "double diffusion" */
+/* pmm - double broadcast parallel matrix multiplication */
-/* Copyright (c) 2006-2015. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2006-2016. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "xbt/matrix.h"
#include "xbt/xbt_os_time.h"
-/** @addtogroup MSG_examples
- * @section msg_ex_full_apps Examples of full applications
- *
- * - <b>Parallel Matrix Multiplication: app-pmm/app-pmm.c</b>. This little application is something that most MPI
- * developers have written during their studies. Here it is implemented in MSG.
- */
-
XBT_LOG_NEW_DEFAULT_CATEGORY(msg_pmm, "Messages specific for this msg example");
/* This example should always be executed using a deployment of GRID_SIZE * GRID_SIZE nodes. */
-/* Copyright (c) 2010-2015. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2010-2016. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include <xbt/RngStream.h>
#include "src/mc/mc_replay.h" // FIXME: this is an internal header
-/** @addtogroup MSG_examples
- *
- * - <b>Chord P2P protocol dht-chord/dht-chord.c:</b>. This example implements the well known Chord P2P protocol. Its
- * main advantage is that it constitutes a fully working non-trivial example. In addition, its implementation is
- * rather efficient, as demonstrated in http://hal.inria.fr/inria-00602216/
- */
-
-
XBT_LOG_NEW_DEFAULT_CATEGORY(msg_chord, "Messages specific for this msg example");
#define COMM_SIZE 10
static void random_lookup(node_t);
static void quit_notify(node_t node);
-/* \brief Global initialization of the Chord simulation. */
+/* Global initialization of the Chord simulation. */
static void chord_initialize(void)
{
// compute the powers of 2 once for all
xbt_free(powers2);
}
-/**
- * \brief Turns an id into an equivalent id in [0, nb_keys).
- * \param id an id
- * \return the corresponding normalized id
- */
+/* Turns an id into an equivalent id in [0, nb_keys). */
static int normalize(int id)
{
// like id % nb_keys, but works with negatives numbers (and faster)
return id & (nb_keys - 1);
}
-/**
- * \brief Returns whether an id belongs to the interval [start, end].
+/* Returns whether an id belongs to the interval [start, end].
*
* The parameters are noramlized to make sure they are between 0 and nb_keys - 1).
* 1 belongs to [62, 3]
return id <= end;
}
-/**
- * \brief Gets the mailbox name of a host given its chord id.
+/* Gets the mailbox name of a host given its chord id.
* \param node_id id of a node
* \param mailbox pointer to where the mailbox name should be written
* (there must be enough space)
snprintf(mailbox, MAILBOX_NAME_SIZE - 1, "%d", node_id);
}
-/**
- * \brief Frees the memory used by a task.
- * \param task the MSG task to destroy
- */
+/* Frees the memory used by a task and destroy it */
static void task_free(void* task)
{
// TODO add a parameter data_free_function to MSG_task_create?
}
}
-/**
- * \brief Displays the finger table of a node.
- * \param node a node
- */
+/* Displays the finger table of a node. */
static void print_finger_table(node_t node)
{
if (XBT_LOG_ISENABLED(msg_chord, xbt_log_priority_verbose)) {
}
}
-/**
- * \brief Sets a finger of the current node.
+/* Sets a finger of the current node.
+ *
* \param node the current node
* \param finger_index index of the finger to set (0 to nb_bits - 1)
* \param id the id to set for this finger
}
}
-/**
- * \brief Sets the predecessor of the current node.
+/* Sets the predecessor of the current node.
+ *
* \param node the current node
* \param id the id to predecessor, or -1 to unset the predecessor
*/
}
}
-/**
- * \brief Node Function
+/* Node main Function
+ *
* Arguments:
* - my id
* - the id of a guy I know in the system (except for the first node)
return 0;
}
-/**
- * \brief This function is called when the current node receives a task.
+/* This function is called when the current node receives a task.
+ *
* \param node the current node
- * \param task the task to handle (don't touch it then:
- * it will be destroyed, reused or forwarded)
+ * \param task the task to handle (don't touch it afterward: it will be destroyed, reused or forwarded)
*/
static void handle_task(node_t node, msg_task_t task) {
}
}
-/**
- * \brief Initializes the current node as the first one of the system.
- * \param node the current node
- */
+/* Initializes the current node as the first one of the system */
static void create(node_t node)
{
XBT_DEBUG("Create a new Chord ring...");
print_finger_table(node);
}
-/**
- * \brief Makes the current node join the ring, knowing the id of a node
- * already in the ring
+/* Makes the current node join the ring, knowing the id of a node already in the ring
+ *
* \param node the current node
* \param known_id id of a node already in the ring
* \return 1 if the join operation succeeded, 0 otherwise
set_predecessor(node, -1); // no predecessor (yet)
/*
- int i;
- for (i = 0; i < nb_bits; i++) {
+ for (int i = 0; i < nb_bits; i++)
set_finger(node, i, known_id);
- }
*/
int successor_id = remote_find_successor(node, known_id, node->id);
return successor_id != -1;
}
-/**
- * \brief Makes the current node quit the system
- * \param node the current node
- */
+/* Makes the current node quit the system */
static void leave(node_t node)
{
XBT_DEBUG("Well Guys! I Think it's time for me to quit ;)");
quit_notify(node);
}
-/**
- * \brief Notifies the successor and the predecessor of the current node
- * of the departure
- * \param node the current node
- */
+/* Notifies the successor and the predecessor of the current node before leaving */
static void quit_notify(node_t node)
{
char mailbox[MAILBOX_NAME_SIZE];
}
-/**
- * \brief Makes the current node find the successor node of an id.
+/* Makes the current node find the successor node of an id.
+ *
* \param node the current node
* \param id the id to find
* \return the id of the successor node, or -1 if the request failed
return remote_find_successor(node, closest, id);
}
-/**
- * \brief Asks another node the successor node of an id.
+/* \brief Asks another node the successor node of an id.
+ *
* \param node the current node
* \param ask_to the node to ask to
* \param id the id to find
return successor;
}
-/**
- * \brief Asks another node its predecessor.
+/* Asks its predecessor to a remote node
+ *
* \param node the current node
* \param ask_to the node to ask to
* \return the id of its predecessor node, or -1 if the request failed
return predecessor_id;
}
-/**
- * \brief Returns the closest preceding finger of an id
- * with respect to the finger table of the current node.
+/* Returns the closest preceding finger of an id with respect to the finger table of the current node.
+ *
* \param node the current node
* \param id the id to find
* \return the closest preceding finger of that id
return node->id;
}
-/**
- * \brief This function is called periodically. It checks the immediate
- * successor of the current node.
- * \param node the current node
- */
+/* This function is called periodically. It checks the immediate successor of the current node. */
static void stabilize(node_t node)
{
XBT_DEBUG("Stabilizing node");
}
}
-/**
- * \brief Notifies the current node that its predecessor may have changed.
- * \param node the current node
- * \param candidate_id the possible new predecessor
- */
+/* Notifies the current node that its predecessor may have changed. */
static void notify(node_t node, int predecessor_candidate_id) {
if (node->pred_id == -1
}
}
-/**
- * \brief Notifies a remote node that its predecessor may have changed.
- * \param node the current node
- * \param notify_id id of the node to notify
- * \param candidate_id the possible new predecessor
- */
+/* Notifies a remote node that its predecessor may have changed. */
static void remote_notify(node_t node, int notify_id, int predecessor_candidate_id) {
task_data_t req_data = xbt_new0(s_task_data_t, 1);
MSG_task_dsend(task, mailbox, task_free);
}
-/**
- * \brief This function is called periodically.
- * It refreshes the finger table of the current node.
- * \param node the current node
- */
+/* refreshes the finger table of the current node (called periodically) */
static void fix_fingers(node_t node) {
XBT_DEBUG("Fixing fingers");
}
}
-/**
- * \brief This function is called periodically.
- * It checks whether the predecessor has failed
- * \param node the current node
- */
+/* checks whether the predecessor has failed (called periodically) */
static void check_predecessor(node_t node)
{
XBT_DEBUG("Checking whether my predecessor is alive");
}
}
-/**
- * \brief Performs a find successor request to a random id.
- * \param node the current node
- */
+/* Performs a find successor request to a random id */
static void random_lookup(node_t node)
{
int random_index = RngStream_RandInt (node->stream, 0, nb_bits - 1);