--- /dev/null
+---
+Language: Cpp
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: true
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: false
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterClass: false
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: true
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+ColumnLimit: 120
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+ForEachMacros: [ xbt_dynar_foreach ]
+IncludeCategories:
+ - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
+ Priority: 2
+ - Regex: '^(<|"(gtest|isl|json)/)'
+ Priority: 3
+ - Regex: '.*'
+ Priority: 1
+IndentCaseLabels: true
+IndentWidth: 2
+IndentWrappedFunctionNames: false
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Left
+ReflowComments: true
+SortIncludes: true
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp11
+TabWidth: 8
+UseTab: Never
+...
+
double peer_speed;
double last_unchoke;
int current_piece;
- int am_interested:1; //Indicates if we are interested in something the peer has
- int interested:1; //Indicates if the peer is interested in one of our pieces
- int choked_upload:1; //Indicates if the peer is choked for the current peer
- int choked_download:1; //Indicates if the peer has choked the current peer
+ unsigned int am_interested:1; //Indicates if we are interested in something the peer has
+ unsigned int interested:1; //Indicates if the peer is interested in one of our pieces
+ unsigned int choked_upload:1; //Indicates if the peer is choked for the current peer
+ unsigned int choked_download:1; //Indicates if the peer has choked the current peer
} s_connection_t, *connection_t;
/** @brief Build a new connection object from the peer id.
case MESSAGE_CANCEL:
size = MESSAGE_CANCEL_SIZE;
break;
+ default:
+ THROW_IMPOSSIBLE;
}
return size;
}
*/
int get_peers_data(peer_t peer)
{
- int success = 0, send_success = 0;
+ int success = 0;
+ int send_success = 0;
double timeout = MSG_get_clock() + GET_PEERS_TIMEOUT;
//Build the task to send to the tracker
tracker_task_data_t data = tracker_task_data_new(MSG_host_get_name(MSG_host_self()), peer->mailbox_tracker,
case MESSAGE_CANCEL:
XBT_DEBUG("The received CANCEL from %s (%s)", message->mailbox, message->issuer_host_name);
break;
+ default:
+ THROW_IMPOSSIBLE;
}
//Update the peer speed.
if (remote_peer) {
/** remove current_piece from the list of currently downloaded pieces. */
void remove_current_piece(peer_t peer, connection_t remote_peer, int current_piece)
{
- int piece_index = -1, piece;
- unsigned int i;
- xbt_dynar_foreach(peer->current_pieces, i, piece) {
- if (piece == current_piece) {
- piece_index = i;
- break;
- }
- }
+ int piece_index = xbt_dynar_search_or_negative(peer->current_pieces, ¤t_piece);
if (piece_index != -1)
xbt_dynar_remove_at(peer->current_pieces, piece_index, NULL);
remote_peer->current_piece = -1;
int is_interested(peer_t peer, connection_t remote_peer)
{
xbt_assert(remote_peer->bitfield, "Bitfield not received");
- int i;
- for (i = 0; i < FILE_PIECES; i++) {
+ for (int i = 0; i < FILE_PIECES; i++) {
if (remote_peer->bitfield[i] == '1' && peer->bitfield[i] == '0') {
return 1;
}
int is_interested_and_free(peer_t peer, connection_t remote_peer)
{
xbt_assert(remote_peer->bitfield, "Bitfield not received");
- int i;
- for (i = 0; i < FILE_PIECES; i++) {
+ for (int i = 0; i < FILE_PIECES; i++) {
if (remote_peer->bitfield[i] == '1' && peer->bitfield[i] == '0' &&
(in_current_pieces(peer, i) == 0)) {
return 1;
int partially_downloaded_piece(peer_t peer, connection_t remote_peer)
{
xbt_assert(remote_peer->bitfield, "Bitfield not received");
- int i;
- for (i = 0; i < FILE_PIECES; i++) {
+ for (int i = 0; i < FILE_PIECES; i++) {
if (remote_peer->bitfield[i] == '1' && peer->bitfield[i] == '0' &&
(in_current_pieces(peer, i) == 0)) {
if (get_first_block(peer, i) > 0)
/** Indicates if a piece is currently being downloaded by the peer. */
int in_current_pieces(peer_t peer, int piece)
{
- unsigned i;
- int peer_piece;
- xbt_dynar_foreach(peer->current_pieces, i, peer_piece) {
- if (peer_piece == piece) {
- return 1;
- }
- }
- return 0;
+ return xbt_dynar_member(peer->current_pieces, &piece);
}
/***********************************************************
void leech_loop(peer_t peer, double deadline);
void seed_loop(peer_t peer, double deadline);
-void peer_init(peer_t, int id, int seed);
+void peer_init(peer_t peer, int id, int seed);
void peer_free(peer_t peer);
int has_finished(char *bitfield);
return l;
}
+/* 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?
+ if(task != NULL){
+ s_task_data_t* data = (s_task_data_t*)MSG_task_get_data(task);
+ xbt_free(data->state);
+ xbt_free(data);
+ MSG_task_destroy(task);
+ }
+}
+
/* Get the closest id to the dest in the node namespace_set */
static int closest_in_namespace_set(node_t node, int dest) {
int best_dist;
task_data->sender_id = node->id;
task_data->steps++;
task_sent = MSG_task_create(NULL, COMP_SIZE, COMM_SIZE, task_data);
- MSG_task_send_with_timeout(task_sent, mailbox, timeout);
+ if (MSG_task_send_with_timeout(task_sent, mailbox, timeout)== MSG_TIMEOUT) {
+ XBT_DEBUG("Timeout expired when forwarding join to next %d", next);
+ task_free(task_sent);
+ }
type = TASK_JOIN_REPLY;
}
get_mailbox(node->id, req_data->answer_to);
req_data->state = node_get_state(node);
task_sent = MSG_task_create(NULL, COMP_SIZE, COMM_SIZE, req_data);
- MSG_task_send_with_timeout(task_sent, task_data->answer_to, timeout);
+ if (MSG_task_send_with_timeout(task_sent, task_data->answer_to, timeout)== MSG_TIMEOUT) {
+ XBT_DEBUG("Timeout expired when sending back the current node state to the joining node to %d", node->id);
+ task_free(task_sent);
+ }
break;
}
/* Join reply from all the node touched by the join */
get_mailbox(node->id, req_data->answer_to);
req_data->state = node_get_state(node);
task_sent = MSG_task_create(NULL, COMP_SIZE, COMM_SIZE, req_data);
- MSG_task_send_with_timeout(task_sent, mailbox, timeout);
+ if (MSG_task_send_with_timeout(task_sent, mailbox, timeout)== MSG_TIMEOUT) {
+ XBT_DEBUG("Timeout expired when sending update to %d", j);
+ task_free(task_sent);
+ }
}
}
}
}
}
}
+ task_free(task);
}
/** \brief Initializes the current node as the first one of the system.
msg_task_t task_sent = MSG_task_create(NULL, COMP_SIZE, COMM_SIZE, req_data);
XBT_DEBUG("Trying to join Pastry ring... (with node %s)", mailbox);
- MSG_task_send_with_timeout(task_sent, mailbox, timeout);
+ if (MSG_task_send_with_timeout(task_sent, mailbox, timeout)== MSG_TIMEOUT) {
+ XBT_DEBUG("Timeout expired when joining ring with node %d", node->known_id);
+ task_free(task_sent);
+ }
return 1;
}
}
}
+ //Cleanup the receiving communication.
+ if (node.comm_receive != NULL) {
+ if (MSG_comm_test(node.comm_receive) && MSG_comm_get_status(node.comm_receive) == MSG_OK) {
+ task_free(MSG_comm_get_task(node.comm_receive));
+ }
+ MSG_comm_destroy(node.comm_receive);
+ }
+
}
+ xbt_free(node.pending_tasks);
return 1;
}
set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/s4u_${example}.cpp)
endforeach()
+add_executable (s4u_basic_function basic/s4u_basic_function.cpp)
+target_link_libraries(s4u_basic_function simgrid)
+set_target_properties(s4u_basic_function PROPERTIES RUNTIME_OUTPUT_DIRECTORY
+ ${CMAKE_CURRENT_BINARY_DIR}/basic)
+set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/basic/s4u_basic_function.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/basic/s4u_basic.h)
+
set(examples_src ${examples_src} PARENT_SCOPE)
set(tesh_files ${tesh_files} PARENT_SCOPE)
set(xml_files ${xml_files} ${CMAKE_CURRENT_SOURCE_DIR}/actions-comm/s4u_actions-comm_split_d.xml
#include <xbt/sysdep.h>
-#include "simgrid/s4u.h"
-
-XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category");
-
-class Worker {
-public:
- void operator()() {
- XBT_INFO("Hello s4u, I'm ready to serve");
- char *msg = static_cast<char*>(simgrid::s4u::this_actor::recv(
- *simgrid::s4u::Mailbox::byName("worker")));
- XBT_INFO("I received '%s'",msg);
- XBT_INFO("I'm done. See you.");
- }
-};
-
-class Master {
-public:
- void operator()() {
- const char *msg = "GaBuZoMeu";
- XBT_INFO("Hello s4u, I have something to send");
- simgrid::s4u::this_actor::send(*simgrid::s4u::Mailbox::byName("worker"), xbt_strdup(msg), strlen(msg));
- XBT_INFO("I'm done. See you.");
- }
-};
+#include <simgrid/s4u.h>
+#include "s4u_basic.h"
int main(int argc, char **argv) {
simgrid::s4u::Engine *e = new simgrid::s4u::Engine(&argc,argv);
--- /dev/null
+/* 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/sysdep.h>
+
+#include "simgrid/s4u.h"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category");
+
+class Worker {
+public:
+ Worker() {};
+ Worker(simgrid::xbt::args args) {}
+ void operator()() {
+ XBT_INFO("Hello s4u, I'm ready to serve");
+ char *msg = static_cast<char*>(simgrid::s4u::this_actor::recv(
+ *simgrid::s4u::Mailbox::byName("worker")));
+ XBT_INFO("I received '%s'",msg);
+ XBT_INFO("I'm done. See you.");
+ }
+};
+
+class Master {
+public:
+ Master() {};
+ Master(simgrid::xbt::args args) {}
+ void operator()() {
+ const char *msg = "GaBuZoMeu";
+ XBT_INFO("Hello s4u, I have something to send");
+ simgrid::s4u::this_actor::send(*simgrid::s4u::Mailbox::byName("worker"), xbt_strdup(msg), strlen(msg));
+ XBT_INFO("I'm done. See you.");
+ }
+};
> [Tremblay:worker:(0) 0.001301] [s4u_test/INFO] I received 'GaBuZoMeu'
> [Tremblay:worker:(0) 0.001301] [s4u_test/INFO] I'm done. See you.
> [Jupiter:master:(0) 0.001301] [s4u_test/INFO] I'm done. See you.
+
+$ $SG_TEST_EXENV ${bindir:=.}/s4u_basic_function
+> [Tremblay:worker:(0) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to serve
+> [Jupiter:master:(0) 0.000000] [s4u_test/INFO] Hello s4u, I have something to send
+> [Tremblay:worker:(0) 0.001301] [s4u_test/INFO] I received 'GaBuZoMeu'
+> [Tremblay:worker:(0) 0.001301] [s4u_test/INFO] I'm done. See you.
+> [Jupiter:master:(0) 0.001301] [s4u_test/INFO] I'm done. See you.
--- /dev/null
+/* 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/sysdep.h>
+
+#include <simgrid/s4u.h>
+
+#include "s4u_basic.h"
+
+int main(int argc, char **argv) {
+ simgrid::s4u::Engine *e = new simgrid::s4u::Engine(&argc,argv);
+ e->loadPlatform("../../platforms/two_hosts.xml");
+ e->registerFunction<Worker>("worker");
+ e->registerFunction<Master>("master");
+ simgrid::xbt::args args;
+ simgrid::s4u::Actor("worker", simgrid::s4u::Host::by_name("Tremblay"), "worker", args);
+ simgrid::s4u::Actor("master", simgrid::s4u::Host::by_name("Jupiter"), "master", args);
+ e->run();
+ return 0;
+}
XBT_PUBLIC(void) MSG_function_register(const char *name,
xbt_main_func_t code);
XBT_PUBLIC(void) MSG_function_register_default(xbt_main_func_t code);
-XBT_PUBLIC(xbt_main_func_t) MSG_get_registered_function(const char *name);
XBT_PUBLIC(void) MSG_launch_application(const char *file);
/*Bypass the parser */
XBT_PUBLIC(void) MSG_set_function(const char *host_id,
Actor(name, host, wrap_task(std::move(code), std::move(args)...))
{}
+ // Create actor from function name:
+
+ Actor(const char* name, s4u::Host *host, double killTime, const char* function, simgrid::xbt::args args);
+
+ Actor(const char* name, s4u::Host *host, const char* function, simgrid::xbt::args args) :
+ Actor(name, host, -1.0, function, std::move(args)) {}
+
/** Retrieves the actor that have the given PID (or NULL if not existing) */
//static Actor *byPid(int pid); not implemented
* See \ref Comm for the full communication API (including non blocking communications).
*/
XBT_PUBLIC(void) send(Mailbox &chan, void*payload, size_t simulatedSize);
+
+ /**
+ * Return the PID of the current actor.
+ */
+ XBT_PUBLIC(int) getPid();
};
// Notify functions
- void notify();
+ void notify_one();
void notify_all();
+ XBT_ATTRIB_DEPRECATED("Use notify_one() instead")
+ void notify() { notify_one(); }
+
private:
smx_cond_t cond_;
#define SIMGRID_S4U_ENGINE_HPP
#include <xbt/base.h>
+#include <xbt/functional.hpp>
+
+#include <simgrid/simix.hpp>
#include <simgrid/s4u/forward.hpp>
/** @brief Retrieve the AS of the given name (or nullptr if not found) */
simgrid::s4u::As *asByNameOrNull(const char *name);
+ template<class F>
+ void registerFunction(const char* name)
+ {
+ simgrid::simix::registerFunction(name, [](simgrid::xbt::args args){
+ return simgrid::simix::ActorCode([args] {
+ F code(std::move(args));
+ code();
+ });
+ });
+ }
+
+ template<class F>
+ void registerFunction(const char* name, F code)
+ {
+ simgrid::simix::registerFunction(name, [code](simgrid::xbt::args args){
+ return simgrid::simix::ActorCode([code,args] {
+ code(std::move(args));
+ });
+ });
+ }
+
private:
static s4u::Engine *instance_;
};
XBT_PUBLIC(void) SIMIX_function_register(const char *name, xbt_main_func_t code);
XBT_PUBLIC(void) SIMIX_function_register_default(xbt_main_func_t code);
-XBT_PUBLIC(xbt_main_func_t) SIMIX_get_registered_function(const char *name);
XBT_PUBLIC(void) SIMIX_init_application(void);
XBT_PUBLIC(void) SIMIX_launch_application(const char *file);
#include <xbt/function_types.h>
#include <xbt/future.hpp>
+#include <xbt/functional.hpp>
#include <simgrid/simix.h>
XBT_PUBLIC(void) set_maestro(std::function<void()> code);
XBT_PUBLIC(void) create_maestro(std::function<void()> code);
+// What's executed as SIMIX actor code:
+typedef std::function<void()> ActorCode;
+
+// Create ActorCode based on argv:
+typedef std::function<ActorCode(simgrid::xbt::args args)> ActorCodeFactory;
+
+XBT_PUBLIC(void) registerFunction(const char* name, ActorCodeFactory factory);
+
}
}
# define XBT_ATTRIB_NORETURN __attribute__((__noreturn__))
# define XBT_ATTRIB_UNUSED __attribute__((__unused__))
+# define XBT_ATTRIB_DEPRECATED(m) __attribute__((__deprecated__(m)))
/* Constructor priorities exist since gcc 4.3. Apparently, they are however not
* supported on Macs. */
fprintf(tracing_file, "%% Container string\n");
fprintf(tracing_file, "%% Value string\n");
if (size) fprintf(tracing_file, "%% Size int\n");
+#if HAVE_SMPI
if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
/**
* paje currently (May 2016) uses "Filename" and "Linenumber" as
fprintf(tracing_file, "%% Fname string\n");
fprintf(tracing_file, "%% Lnumber int\n");
}
+#endif
fprintf(tracing_file, "%%EndEventDef\n");
}
print_default_pajeState_row<setState_t>(event);
stream << " " << static_cast<setState_t>(event->data)->value->id;
-
+#if HAVE_SMPI
if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
stream << " \"" << static_cast<setState_t>(event->data)->filename
<< "\" " << static_cast<setState_t>(event->data)->linenumber;
}
-
+#endif
print_row();
}
stream << 0;
}
}
-
+#if HAVE_SMPI
if (xbt_cfg_get_boolean("smpi/trace-call-location")) {
stream << " \"" << static_cast<pushState_t>(event->data)->filename
<< "\" " << static_cast<pushState_t>(event->data)->linenumber;
}
-
+#endif
print_row();
if (static_cast<pushState_t>(event->data)->extra != nullptr) {
this->read_variable("simix_global", &simix_global_p, sizeof(simix_global_p));
// simix_global = REMOTE(*simix_global)
- s_smx_global_t simix_global;
+ union { simgrid::simix::Global simix_global };
this->read_bytes(&simix_global, sizeof(simix_global),
remote(simix_global_p));
SIMIX_function_register_default(code);
}
-/** \ingroup msg_simulation
- * \brief Retrieves a registered main function
- *
- * Registers a code function in a global table.
- * This table is then used by #MSG_launch_application.
- * \param name the reference name of the function.
- */
-xbt_main_func_t MSG_get_registered_function(const char *name)
-{
- return SIMIX_get_registered_function(name);
-}
-
/**
* \brief register functions bypassing the parser
*/
#include "simgrid/s4u/host.hpp"
#include "simgrid/s4u/mailbox.hpp"
+#include "src/simix/smx_private.h"
+
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_actor,"S4U actors");
using namespace simgrid;
killTime, nullptr, 0));
}
+s4u::Actor::Actor(const char* name, s4u::Host *host, double killTime, const char* function, simgrid::xbt::args args)
+{
+ simgrid::simix::ActorCodeFactory& factory = SIMIX_get_actor_code_factory(function);
+ simgrid::simix::ActorCode code = factory(std::move(args));
+ this->pimpl_ = SIMIX_process_ref(simcall_process_create(
+ name, std::move(code), nullptr, host->name().c_str(),
+ killTime, nullptr, 0));
+}
+
void s4u::Actor::join() {
simcall_process_join(pimpl_, -1);
}
c.wait();
}
+int getPid() {
+ return simcall_process_get_PID(SIMIX_process_self());
+}
+
}
}
}
/**
* Notify functions
*/
-void s4u::ConditionVariable::notify() {
+void s4u::ConditionVariable::notify_one() {
simcall_cond_signal(cond_);
}
}
}
+// Wrap a main() function into a ActorCodeFactory:
+static simgrid::simix::ActorCodeFactory toActorCodeFactory(xbt_main_func_t code)
+{
+ return [code](simgrid::xbt::args args) {
+ return simgrid::xbt::wrapMain(code, std::move(args));
+ };
+}
+
/**
* \brief Registers a #xbt_main_func_t code in a global table.
*
*/
void SIMIX_function_register(const char *name, xbt_main_func_t code)
{
- xbt_assert(simix_global, "SIMIX_global_init has to be called before SIMIX_function_register.");
- xbt_dict_set(simix_global->registered_functions, name, (void*) code, nullptr);
+ xbt_assert(simix_global,
+ "SIMIX_global_init has to be called before SIMIX_function_register.");
+ simix_global->registered_functions[name] = toActorCodeFactory(code);
}
-static xbt_main_func_t default_function = nullptr;
/**
* \brief Registers a #xbt_main_func_t code as default value.
*
void SIMIX_function_register_default(xbt_main_func_t code)
{
xbt_assert(simix_global, "SIMIX_global_init has to be called before SIMIX_function_register.");
-
- default_function = code;
+ simix_global->default_function = toActorCodeFactory(code);
}
/**
* \param name the reference name of the function.
* \return The #smx_process_t or nullptr.
*/
-xbt_main_func_t SIMIX_get_registered_function(const char *name)
+simgrid::simix::ActorCodeFactory& SIMIX_get_actor_code_factory(const char *name)
{
- xbt_main_func_t res = nullptr;
xbt_assert(simix_global,
- "SIMIX_global_init has to be called before SIMIX_get_registered_function.");
+ "SIMIX_global_init has to be called before SIMIX_get_actor_code_factory.");
- res = (xbt_main_func_t)xbt_dict_get_or_null(simix_global->registered_functions, name);
- return res ? res : default_function;
+ auto i = simix_global->registered_functions.find(name);
+ if (i == simix_global->registered_functions.end())
+ return simix_global->default_function;
+ else
+ return i->second;
}
-
/**
* \brief Bypass the parser, get arguments, and set function to each process
*/
}
process.argv[process.argc] = nullptr;
- xbt_main_func_t parse_code = SIMIX_get_registered_function(process_function);
+ // Check we know how to handle this function name:
+ simgrid::simix::ActorCodeFactory& parse_code = SIMIX_get_actor_code_factory(process_function);
xbt_assert(parse_code, "Function '%s' unknown", process_function);
- process.function = process_function;
+ process.function = process_function;
process.host = process_host;
process.kill_time = process_kill_time;
process.start_time = process_start_time;
process.on_failure = SURF_PROCESS_ON_FAILURE_DIE;
-
sg_platf_new_process(&process);
}
+
+namespace simgrid {
+namespace simix {
+
+void registerFunction(const char* name, ActorCodeFactory factory)
+{
+ simix_global->registered_functions[name] = std::move(factory);
+}
+
+}
+}
\ No newline at end of file
XBT_LOG_NEW_CATEGORY(simix, "All SIMIX categories");
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_kernel, simix, "Logging specific to SIMIX (kernel)");
-smx_global_t simix_global = nullptr;
+std::unique_ptr<simgrid::simix::Global> simix_global;
static xbt_heap_t simix_timers = nullptr;
/** @brief Timer datatype */
#endif
if (!simix_global) {
- simix_global = xbt_new0(s_smx_global_t, 1);
+ simix_global = std::unique_ptr<simgrid::simix::Global>(new simgrid::simix::Global());
simgrid::simix::Process proc;
simix_global->process_to_run = xbt_dynar_new(sizeof(smx_process_t), nullptr);
simix_global->process_that_ran = xbt_dynar_new(sizeof(smx_process_t), nullptr);
simix_global->process_list = xbt_swag_new(xbt_swag_offset(proc, process_hookup));
simix_global->process_to_destroy = xbt_swag_new(xbt_swag_offset(proc, destroy_hookup));
-
simix_global->maestro_process = nullptr;
- simix_global->registered_functions = xbt_dict_new_homogeneous(nullptr);
-
simix_global->create_process_function = &SIMIX_process_create;
simix_global->kill_process_function = &kill_process;
simix_global->cleanup_process_function = &SIMIX_process_cleanup;
xbt_swag_free(simix_global->process_list);
simix_global->process_list = nullptr;
simix_global->process_to_destroy = nullptr;
- xbt_dict_free(&(simix_global->registered_functions));
xbt_os_mutex_destroy(simix_global->mutex);
simix_global->mutex = nullptr;
surf_exit();
- xbt_free(simix_global);
simix_global = nullptr;
-
return;
}
#define _SIMIX_PRIVATE_H
#include <functional>
+#include <memory>
+#include <unordered_map>
+
+#include <xbt/functional.hpp>
+
#include "src/internal_config.h"
#include "simgrid/simix.h"
#endif
-SG_BEGIN_DECL()
-
/********************************** Simix Global ******************************/
-typedef struct s_smx_global {
- smx_context_factory_t context_factory;
- xbt_dynar_t process_to_run;
- xbt_dynar_t process_that_ran;
- xbt_swag_t process_list;
- xbt_swag_t process_to_destroy;
- smx_process_t maestro_process;
- xbt_dict_t registered_functions;
- smx_creation_func_t create_process_function;
- void_pfn_smxprocess_t kill_process_function;
+
+namespace simgrid {
+namespace simix {
+
+class Global {
+public:
+ smx_context_factory_t context_factory = nullptr;
+ xbt_dynar_t process_to_run = nullptr;
+ xbt_dynar_t process_that_ran = nullptr;
+ xbt_swag_t process_list = nullptr;
+ xbt_swag_t process_to_destroy = nullptr;
+ smx_process_t maestro_process = nullptr;
+
+ // Maps function names to actor code:
+ std::unordered_map<std::string, simgrid::simix::ActorCodeFactory> registered_functions;
+
+ // This might be used when no corresponding function name is registered:
+ simgrid::simix::ActorCodeFactory default_function;
+
+ smx_creation_func_t create_process_function = nullptr;
+ void_pfn_smxprocess_t kill_process_function = nullptr;
/** Callback used when killing a SMX_process */
- void_pfn_smxprocess_t cleanup_process_function;
+ void_pfn_smxprocess_t cleanup_process_function = nullptr;
+ xbt_os_mutex_t mutex = nullptr;
+};
+
+}
+}
+
+SG_BEGIN_DECL()
- xbt_os_mutex_t mutex;
-} s_smx_global_t, *smx_global_t;
+XBT_PUBLIC_DATA(std::unique_ptr<simgrid::simix::Global>) simix_global;
-XBT_PUBLIC_DATA(smx_global_t) simix_global;
extern XBT_PRIVATE unsigned long simix_process_maxpid;
XBT_PUBLIC(void) SIMIX_clean(void);
SG_END_DECL()
+XBT_PRIVATE simgrid::simix::ActorCodeFactory& SIMIX_get_actor_code_factory(const char *name);
+
#endif
sleep->surf_sleep->unref();
sleep->surf_sleep = nullptr;
}
- delete sleep;
+ sleep->unref();
return 0;
}
smx_synchro_t SIMIX_process_join(smx_process_t issuer, smx_process_t process, double timeout)
{
smx_synchro_t res = SIMIX_process_sleep(issuer, timeout);
+ static_cast<simgrid::simix::Synchro*>(res)->ref();
SIMIX_process_on_exit(process, (int_f_pvoid_pvoid_t)SIMIX_process_join_finish, res);
return res;
}
if (sleep->surf_sleep) {
sleep->surf_sleep->unref();
sleep->surf_sleep = nullptr;
+ sleep->unref();
}
}
static simgrid::config::Flag<double> smpi_test_sleep(
"smpi/test", "Minimum time to inject inside a call to MPI_Test", 1e-4);
-static bool factor_cmp(const s_smpi_factor_multival_t& pa, const s_smpi_factor_multival_t& pb)
-{
- return (pa.factor < pb.factor);
-}
-
static std::vector<s_smpi_factor_multival_t> parse_factor(const char *smpi_coef_string)
{
std::vector<s_smpi_factor_multival_t> smpi_factor;
smpi_factor.push_back(fact);
XBT_DEBUG("smpi_factor:\t%zu : %zu values, first: %f", fact.factor, smpi_factor.size(), fact.values[0]);
}
- std::sort(smpi_factor.begin(), smpi_factor.end(), &factor_cmp);
+ std::sort(smpi_factor.begin(), smpi_factor.end(),
+ [](const s_smpi_factor_multival_t &pa,
+ const s_smpi_factor_multival_t &pb) {
+ return (pa.factor < pb.factor);
+ });
for (auto& fact : smpi_factor) {
XBT_DEBUG("smpi_factor:\t%zu : %zu values, first: %f", fact.factor, smpi_factor.size() ,fact.values[0]);
}
msg->data[msg->used-3]='\0';
xbt_die("%s", msg->data);
}
- xbt_main_func_t parse_code = SIMIX_get_registered_function(process->function);
- xbt_assert(parse_code, "Function '%s' unknown", process->function);
+ simgrid::simix::ActorCodeFactory& factory = SIMIX_get_actor_code_factory(process->function);
+ xbt_assert(factory, "Function '%s' unknown", process->function);
double start_time = process->start_time;
double kill_time = process->kill_time;
int auto_restart = process->on_failure == SURF_PROCESS_ON_FAILURE_DIE ? 0 : 1;
- std::function<void()> code = simgrid::xbt::wrapMain(parse_code, process->argc, process->argv);
+ std::function<void()> code = factory(simgrid::xbt::args(process->argc, process->argv));
smx_process_arg_t arg = nullptr;
smx_process_t process_created = nullptr;