Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of scm.gforge.inria.fr:/gitroot/simgrid/simgrid
authorMartin Quinson <martin.quinson@loria.fr>
Wed, 22 Jun 2016 20:32:13 +0000 (22:32 +0200)
committerMartin Quinson <martin.quinson@loria.fr>
Wed, 22 Jun 2016 20:32:13 +0000 (22:32 +0200)
30 files changed:
.clang-format [new file with mode: 0644]
examples/msg/app-bittorrent/connection.h
examples/msg/app-bittorrent/messages.c
examples/msg/app-bittorrent/peer.c
examples/msg/app-bittorrent/peer.h
examples/msg/dht-pastry/dht-pastry.c
examples/s4u/CMakeLists.txt
examples/s4u/basic/s4u_basic.cpp
examples/s4u/basic/s4u_basic.h [new file with mode: 0644]
examples/s4u/basic/s4u_basic.tesh
examples/s4u/basic/s4u_basic_function.cpp [new file with mode: 0644]
include/simgrid/msg.h
include/simgrid/s4u/actor.hpp
include/simgrid/s4u/conditionVariable.hpp
include/simgrid/s4u/engine.hpp
include/simgrid/simix.h
include/simgrid/simix.hpp
include/xbt/base.h
src/instr/instr_paje_header.cpp
src/instr/instr_paje_trace.cpp
src/mc/mc_smx.cpp
src/msg/msg_deployment.cpp
src/s4u/s4u_actor.cpp
src/s4u/s4u_conditionVariable.cpp
src/simix/smx_deployment.cpp
src/simix/smx_global.cpp
src/simix/smx_private.h
src/simix/smx_process.cpp
src/smpi/smpi_base.cpp
src/surf/sg_platf.cpp

diff --git a/.clang-format b/.clang-format
new file mode 100644 (file)
index 0000000..146daad
--- /dev/null
@@ -0,0 +1,89 @@
+---
+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
+...
+
index 057e3d8..0bfcde0 100644 (file)
@@ -16,10 +16,10 @@ typedef struct s_connection {
   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.
index ce8f93e..5c8dff5 100644 (file)
@@ -112,6 +112,8 @@ int task_message_size(e_message_type type)
   case MESSAGE_CANCEL:
     size = MESSAGE_CANCEL_SIZE;
     break;
+  default:
+    THROW_IMPOSSIBLE;
   }
   return size;
 }
index 10153cd..4aaf7c0 100644 (file)
@@ -156,7 +156,8 @@ void seed_loop(peer_t peer, double deadline)
  */
 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,
@@ -408,6 +409,8 @@ void handle_message(peer_t peer, msg_task_t task)
   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) {
@@ -431,14 +434,7 @@ void request_new_piece_to_peer(peer_t peer, connection_t 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, &current_piece);
   if (piece_index != -1)
     xbt_dynar_remove_at(peer->current_pieces, piece_index, NULL);
   remote_peer->current_piece = -1;
@@ -735,8 +731,7 @@ int get_first_block(peer_t peer, int piece)
 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;
     }
@@ -748,8 +743,7 @@ int is_interested(peer_t peer, connection_t remote_peer)
 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;
@@ -762,8 +756,7 @@ int is_interested_and_free(peer_t peer, connection_t remote_peer)
 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)
@@ -794,14 +787,7 @@ void send_request_to_peer(peer_t peer, connection_t remote_peer, int piece)
 /** 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);
 }
 
 /***********************************************************
index 009de84..4ba13ae 100644 (file)
@@ -50,7 +50,7 @@ int get_peers_data(peer_t peer);
 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);
index d782365..214e509 100644 (file)
@@ -101,6 +101,18 @@ static int shl(int a, int b) {
   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;
@@ -247,7 +259,10 @@ static void handle_task(node_t node, msg_task_t task) {
         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;
       } 
       
@@ -257,7 +272,10 @@ static void handle_task(node_t node, msg_task_t task) {
       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  */
@@ -313,7 +331,10 @@ static void handle_task(node_t node, msg_task_t task) {
             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);
+            }
           }
         }
         }
@@ -398,6 +419,7 @@ static void handle_task(node_t node, msg_task_t task) {
         }
       }
   }
+  task_free(task);
 }
 
 /** \brief Initializes the current node as the first one of the system.
@@ -422,7 +444,10 @@ static int join(node_t node){
 
   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;
 }
@@ -514,7 +539,16 @@ static int node(int argc, char *argv[])
       }
 
     }
+  //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;
 }
 
index a3a2a04..bd0ad11 100644 (file)
@@ -7,6 +7,13 @@ foreach (example basic io mutex actions-comm)
   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
index 12156f2..73cf613 100644 (file)
@@ -5,31 +5,9 @@
 
 #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);
diff --git a/examples/s4u/basic/s4u_basic.h b/examples/s4u/basic/s4u_basic.h
new file mode 100644 (file)
index 0000000..7a3f9c6
--- /dev/null
@@ -0,0 +1,35 @@
+/* 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.");
+  }
+};
index 111fea7..627fb9d 100644 (file)
@@ -6,3 +6,10 @@ $ $SG_TEST_EXENV ${bindir:=.}/s4u_basic
 > [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.
diff --git a/examples/s4u/basic/s4u_basic_function.cpp b/examples/s4u/basic/s4u_basic_function.cpp
new file mode 100644 (file)
index 0000000..dd39a93
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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;
+}
index 2759482..681572d 100644 (file)
@@ -197,7 +197,6 @@ XBT_PUBLIC(msg_error_t) MSG_main(void);
 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,
index 7f8016f..9b38309 100644 (file)
@@ -206,6 +206,13 @@ public:
     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
 
@@ -270,6 +277,11 @@ namespace this_actor {
    * 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();
 
 };
 
index 0c34c92..4d59c28 100644 (file)
@@ -84,9 +84,12 @@ public:
 
   // 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_;
 
index bee4afa..07863e1 100644 (file)
@@ -7,6 +7,9 @@
 #define SIMGRID_S4U_ENGINE_HPP
 
 #include <xbt/base.h>
+#include <xbt/functional.hpp>
+
+#include <simgrid/simix.hpp>
 
 #include <simgrid/s4u/forward.hpp>
 
@@ -58,6 +61,27 @@ public:
   /** @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_;
 };
index 9beaaf8..87ba0bc 100644 (file)
@@ -177,7 +177,6 @@ XBT_PUBLIC(void) SIMIX_create_environment(const char *file);
 
 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);
 
index 99d2410..eb92f42 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <xbt/function_types.h>
 #include <xbt/future.hpp>
+#include <xbt/functional.hpp>
 
 #include <simgrid/simix.h>
 
@@ -171,6 +172,14 @@ public:
 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);
+
 }
 }
 
index 9359d53..259c84c 100644 (file)
@@ -47,6 +47,7 @@
 
 # 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. */
index 6994075..d0b48b1 100644 (file)
@@ -164,6 +164,7 @@ static void TRACE_header_PajePushState (int basic, int size)
   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
@@ -172,6 +173,7 @@ static void TRACE_header_PajePushState (int basic, int size)
     fprintf(tracing_file, "%%       Fname string\n");
     fprintf(tracing_file, "%%       Lnumber int\n");
   }
+#endif
   fprintf(tracing_file, "%%EndEventDef\n");
 }
 
index 4ca30af..4ab7004 100644 (file)
@@ -223,12 +223,12 @@ void print_pajeSetState(paje_event_t event) {
 
   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();
 }
 
@@ -246,12 +246,12 @@ void print_pajePushState(paje_event_t event) {
       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) {
index daf6b83..09571a1 100644 (file)
@@ -84,7 +84,7 @@ void Process::refresh_simix()
   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));
 
index af82087..015d748 100644 (file)
@@ -52,18 +52,6 @@ void MSG_function_register_default(xbt_main_func_t code)
   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
  */
index 5cec45a..1a97502 100644 (file)
@@ -12,6 +12,8 @@
 #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;
@@ -25,6 +27,15 @@ s4u::Actor::Actor(const char* name, s4u::Host *host, double killTime, std::funct
     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);
 }
@@ -111,6 +122,10 @@ void send(Mailbox &chan, void *payload, size_t simulatedSize) {
   c.wait();
 }
 
+int getPid() {
+  return simcall_process_get_PID(SIMIX_process_self());
+}
+
 }
 }
 }
index 28c9fc0..02f4f82 100644 (file)
@@ -63,7 +63,7 @@ std::cv_status s4u::ConditionVariable::wait_until(std::unique_lock<Mutex>& lock,
 /**
  * Notify functions
  */
-void s4u::ConditionVariable::notify() { 
+void s4u::ConditionVariable::notify_one() {
    simcall_cond_signal(cond_);
 }
  
index 44ccbb8..a740981 100644 (file)
@@ -56,6 +56,14 @@ void SIMIX_launch_application(const char *file)
   }
 }
 
+// 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.
  *
@@ -66,11 +74,11 @@ void SIMIX_launch_application(const char *file)
  */
 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.
  *
@@ -80,8 +88,7 @@ static xbt_main_func_t default_function = nullptr;
 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);
 }
 
 /**
@@ -92,17 +99,18 @@ void SIMIX_function_register_default(xbt_main_func_t 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
  */
@@ -132,14 +140,25 @@ void SIMIX_process_set_function(const char *process_host,
   }
   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
index ab8d595..6549bdb 100644 (file)
@@ -44,7 +44,7 @@
 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 */
@@ -194,17 +194,14 @@ void SIMIX_global_init(int *argc, char **argv)
 #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;
@@ -299,7 +296,6 @@ void SIMIX_clean(void)
   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;
@@ -315,9 +311,7 @@ void SIMIX_clean(void)
 
   surf_exit();
 
-  xbt_free(simix_global);
   simix_global = nullptr;
-
   return;
 }
 
index feb9990..1808c16 100644 (file)
@@ -8,6 +8,11 @@
 #define _SIMIX_PRIVATE_H
 
 #include <functional>
+#include <memory>
+#include <unordered_map>
+
+#include <xbt/functional.hpp>
+
 
 #include "src/internal_config.h"
 #include "simgrid/simix.h"
@@ -58,26 +63,40 @@ typedef struct s_smx_context_factory *smx_context_factory_t;
 
 #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);
@@ -155,4 +174,6 @@ XBT_PRIVATE void SIMIX_process_set_cleanup_function(smx_process_t process, void_
 
 SG_END_DECL()
 
+XBT_PRIVATE simgrid::simix::ActorCodeFactory& SIMIX_get_actor_code_factory(const char *name);
+
 #endif
index ae48724..bb91a10 100644 (file)
@@ -786,13 +786,14 @@ static int SIMIX_process_join_finish(smx_process_exit_status_t status, smx_synch
     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;
 }
@@ -835,6 +836,7 @@ void SIMIX_process_sleep_destroy(smx_synchro_t synchro)
   if (sleep->surf_sleep) {
     sleep->surf_sleep->unref();
     sleep->surf_sleep = nullptr;
+    sleep->unref();
   }
 }
 
index 45e032e..0170851 100644 (file)
@@ -90,11 +90,6 @@ static simgrid::config::Flag<double> smpi_iprobe_sleep(
 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;
@@ -140,7 +135,11 @@ XBT_DEBUG("token : %s", token_iter->c_str());
     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]);
   }
index 036b9ca..7b85965 100644 (file)
@@ -570,14 +570,14 @@ void sg_platf_new_process(sg_platf_process_cbarg_t process)
     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;