Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of github.com:simgrid/simgrid into s_type_cleanup
authorTakishipp <toufik.boubehziz@gmail.com>
Wed, 16 Aug 2017 08:58:48 +0000 (10:58 +0200)
committerTakishipp <toufik.boubehziz@gmail.com>
Wed, 16 Aug 2017 08:58:48 +0000 (10:58 +0200)
185 files changed:
.gitignore
ChangeLog
doc/Doxyfile.in
doc/doxygen/options.doc
examples/java/app/bittorrent/Common.java
examples/msg/CMakeLists.txt
examples/msg/app-bittorrent/messages.c [deleted file]
examples/msg/app-bittorrent/tracker.h [deleted file]
examples/msg/platform-properties/platform-properties.c
examples/msg/trace-categories/trace-categories.tesh
examples/msg/trace-host-user-variables/trace-host-user-variables.tesh
examples/msg/trace-masterworker/trace-masterworker.tesh
examples/s4u/CMakeLists.txt
examples/s4u/actions-storage/s4u_actions-storage.cpp
examples/s4u/app-bittorrent/s4u_app-bittorrent.tesh [new file with mode: 0644]
examples/s4u/app-bittorrent/s4u_app-bittorrent_d.xml [moved from examples/msg/app-bittorrent/app-bittorrent_d.xml with 100% similarity]
examples/s4u/app-bittorrent/s4u_bittorrent.cpp [new file with mode: 0644]
examples/s4u/app-bittorrent/s4u_bittorrent.hpp [new file with mode: 0644]
examples/s4u/app-bittorrent/s4u_peer.cpp [new file with mode: 0644]
examples/s4u/app-bittorrent/s4u_peer.hpp [new file with mode: 0644]
examples/s4u/app-bittorrent/s4u_tracker.cpp [new file with mode: 0644]
examples/s4u/app-bittorrent/s4u_tracker.hpp [new file with mode: 0644]
examples/s4u/app-masterworker/s4u_app-masterworker.cpp
examples/s4u/app-masterworker/s4u_app-masterworker.tesh
examples/s4u/io/s4u_io.cpp
examples/simdag/daxload/sd_daxload.tesh
examples/simdag/properties/sd_properties.c
include/simgrid/msg.h
include/simgrid/s4u/Engine.hpp
include/simgrid/s4u/File.hpp
include/simgrid/s4u/Host.hpp
include/simgrid/s4u/NetZone.hpp
include/simgrid/s4u/Storage.hpp
include/simgrid/s4u/VirtualMachine.hpp
include/simgrid/simix.h
include/simgrid/simix.hpp
include/xbt/algorithm.hpp [new file with mode: 0644]
include/xbt/dynar.h
include/xbt/dynar.hpp
include/xbt/function_types.h
include/xbt/parmap.h
src/bindings/java/JavaContext.cpp
src/bindings/java/jmsg_comm.cpp
src/bindings/java/jmsg_host.cpp
src/bindings/java/jmsg_process.cpp
src/bindings/java/jmsg_storage.cpp
src/bindings/java/jmsg_task.cpp
src/bindings/java/jmsg_vm.cpp
src/bindings/lua/lua_platf.cpp
src/include/instr/instr_interface.h
src/include/surf/surf.h
src/include/xbt/parmap.hpp [new file with mode: 0644]
src/instr/instr_config.cpp
src/instr/instr_interface.cpp
src/instr/instr_paje_containers.cpp
src/instr/instr_private.h
src/instr/instr_resource_utilization.cpp
src/instr/jedule/jedule_platform.cpp
src/kernel/activity/MailboxImpl.cpp
src/kernel/context/Context.hpp
src/kernel/context/ContextBoost.cpp
src/kernel/context/ContextBoost.hpp
src/kernel/context/ContextRaw.cpp
src/kernel/context/ContextThread.cpp
src/kernel/context/ContextUnix.cpp
src/kernel/routing/ClusterZone.cpp
src/kernel/routing/ClusterZone.hpp
src/kernel/routing/DijkstraZone.cpp
src/kernel/routing/DijkstraZone.hpp
src/kernel/routing/DragonflyZone.cpp
src/kernel/routing/DragonflyZone.hpp
src/kernel/routing/EmptyZone.cpp
src/kernel/routing/EmptyZone.hpp
src/kernel/routing/FatTreeZone.cpp
src/kernel/routing/FatTreeZone.hpp
src/kernel/routing/FloydZone.cpp
src/kernel/routing/FloydZone.hpp
src/kernel/routing/FullZone.cpp
src/kernel/routing/FullZone.hpp
src/kernel/routing/NetZoneImpl.cpp
src/kernel/routing/NetZoneImpl.hpp
src/kernel/routing/RoutedZone.cpp
src/kernel/routing/RoutedZone.hpp
src/kernel/routing/TorusZone.cpp
src/kernel/routing/TorusZone.hpp
src/kernel/routing/VivaldiZone.cpp
src/kernel/routing/VivaldiZone.hpp
src/mc/LocationList.cpp
src/mc/LocationList.hpp
src/mc/mc_base.cpp
src/msg/msg_global.cpp
src/msg/msg_io.cpp
src/msg/msg_process.cpp
src/msg/msg_vm.cpp
src/plugins/vm/s4u_VirtualMachine.cpp
src/s4u/s4u_actor.cpp
src/s4u/s4u_engine.cpp
src/s4u/s4u_file.cpp
src/s4u/s4u_host.cpp
src/s4u/s4u_mailbox.cpp
src/s4u/s4u_netzone.cpp
src/s4u/s4u_storage.cpp
src/simdag/sd_daxloader.cpp
src/simdag/sd_dotloader.cpp
src/simdag/simdag_private.hpp
src/simgrid/sg_config.cpp
src/simix/ActorImpl.cpp
src/simix/libsmx.cpp
src/simix/popping.cpp
src/simix/popping_accessors.h
src/simix/popping_bodies.cpp
src/simix/popping_enum.h
src/simix/popping_generated.cpp
src/simix/simcalls.in
src/simix/smx_global.cpp
src/simix/smx_private.h
src/smpi/bindings/smpi_pmpi.cpp
src/smpi/bindings/smpi_pmpi_request.cpp
src/smpi/include/smpi_keyvals.hpp
src/smpi/internals/instr_smpi.cpp
src/smpi/internals/smpi_bench.cpp
src/smpi/internals/smpi_global.cpp
src/smpi/internals/smpi_memory.cpp
src/smpi/internals/smpi_shared.cpp
src/smpi/internals/smpi_utils.cpp
src/smpi/mpi/smpi_comm.cpp
src/smpi/mpi/smpi_f2c.cpp
src/smpi/mpi/smpi_group.cpp
src/smpi/mpi/smpi_info.cpp
src/smpi/mpi/smpi_request.cpp
src/surf/FileImpl.cpp
src/surf/FileImpl.hpp
src/surf/PropertyHolder.cpp
src/surf/StorageImpl.cpp
src/surf/StorageImpl.hpp
src/surf/cpu_interface.cpp
src/surf/cpu_interface.hpp
src/surf/instr_routing.cpp
src/surf/instr_surf.cpp
src/surf/network_cm02.cpp
src/surf/network_cm02.hpp
src/surf/network_ib.cpp
src/surf/network_interface.cpp
src/surf/network_interface.hpp
src/surf/network_ns3.cpp
src/surf/network_smpi.cpp
src/surf/network_smpi.hpp
src/surf/sg_platf.cpp
src/surf/storage_n11.cpp
src/surf/surf_interface.cpp
src/surf/surf_interface.hpp
src/surf/surf_private.h
src/surf/trace_mgr.cpp
src/surf/trace_mgr.hpp
src/surf/xml/platf.hpp
src/surf/xml/platf_private.hpp
src/surf/xml/surfxml_parseplatf.cpp
src/surf/xml/surfxml_sax_cb.cpp
src/xbt/config.cpp
src/xbt/dynar.cpp
src/xbt/parmap.cpp
src/xbt/xbt_replay.cpp
src/xbt/xbt_str.cpp
teshsuite/mc/dwarf/dwarf.cpp
teshsuite/msg/CMakeLists.txt
teshsuite/msg/app-bittorrent/app-bittorrent.tesh [moved from examples/msg/app-bittorrent/app-bittorrent.tesh with 88% similarity]
teshsuite/msg/app-bittorrent/app-bittorrent_d.xml [new file with mode: 0644]
teshsuite/msg/app-bittorrent/bittorrent.c [moved from examples/msg/app-bittorrent/bittorrent.c with 85% similarity]
teshsuite/msg/app-bittorrent/bittorrent.h [moved from examples/msg/app-bittorrent/bittorrent.h with 84% similarity]
teshsuite/msg/app-bittorrent/connection.c [moved from examples/msg/app-bittorrent/connection.c with 63% similarity]
teshsuite/msg/app-bittorrent/connection.h [moved from examples/msg/app-bittorrent/connection.h with 62% similarity]
teshsuite/msg/app-bittorrent/generate.py [moved from examples/msg/app-bittorrent/generate.py with 100% similarity]
teshsuite/msg/app-bittorrent/messages.c [new file with mode: 0644]
teshsuite/msg/app-bittorrent/messages.h [moved from examples/msg/app-bittorrent/messages.h with 74% similarity]
teshsuite/msg/app-bittorrent/peer.c [moved from examples/msg/app-bittorrent/peer.c with 64% similarity]
teshsuite/msg/app-bittorrent/peer.h [moved from examples/msg/app-bittorrent/peer.h with 57% similarity]
teshsuite/msg/app-bittorrent/tracker.c [moved from examples/msg/app-bittorrent/tracker.c with 72% similarity]
teshsuite/msg/app-bittorrent/tracker.h [new file with mode: 0644]
teshsuite/s4u/comm-pt2pt/comm-pt2pt.cpp
teshsuite/simdag/flatifier/flatifier.cpp
teshsuite/xbt/CMakeLists.txt
teshsuite/xbt/parmap_bench/parmap_bench.c [deleted file]
teshsuite/xbt/parmap_bench/parmap_bench.cpp [new file with mode: 0644]
teshsuite/xbt/parmap_test/parmap_test.cpp [moved from teshsuite/xbt/parmap_test/parmap_test.c with 51% similarity]
tools/cmake/DefinePackages.cmake

index 2b2b42b..5c80711 100644 (file)
@@ -102,6 +102,7 @@ doc/simgrid.tag
 doc/doxygen/logcategories.doc
 doc/simgrid_modules.map
 doc/javadoc
+doc/example_lists/
 ### Specific of project 
 .settings/
 .csettings/
index 9f70fdb..251ba08 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,13 @@ SimGrid (3.17) UNRELEASED (release target: September 22 2017)
   - Comm.detach(): start and forget about asynchronous emission
   - this_actor::send(mailbox) is now mailbox->put()
 
+ SURF
+  - Unused option network/sender-gap is removed.
+
+ MSG
+  - Deprecate MSG_task_isend_with_matching(): This unused feature
+    really complicates our internals. Will be removed in v3.20.
+
 SimGrid (3.16) Released June 22. 2017.
 
  The Blooming Spring Release: developments are budding.
@@ -52,7 +59,7 @@ SimGrid (3.16) Released June 22. 2017.
  SMPI
   - New algorithm to privatize globals: dlopen, with dynamic loading tricks
   - New option: smpi/keep-temps to not cleanup temp files
-  - New option : smpi/shared-malloc-blocksize . Relevant only when global shared 
+  - New option : smpi/shared-malloc-blocksize . Relevant only when global shared
     mallocs mode is used, allows to change the size of the fake file used
     (default 1MB), to potentially limit the number of mappings for large runs.
   - Support for sparse privatized malloc with SMPI_PARTIAL_SHARED_MALLOC()
@@ -93,7 +100,7 @@ SimGrid (3.15) Released March 22. 2017
 
  MSG
  - New: MSG_process_yield(). Stop and yield to other processes.
- - New: MSG_process_daemon(). Daemon processes are automatically killed 
+ - New: MSG_process_daemon(). Daemon processes are automatically killed
    when the last non-daemon process terminates
  - New: MSG_process_ref/unref(). Fiddle with the process refcounting.
  - Renamed MSG_energy_plugin_init() -> MSG_host_energy_plugin_init()
@@ -105,13 +112,13 @@ SimGrid (3.15) Released March 22. 2017
  - Kill the obscure NativeException. Nobody want to survive the issues
    it denotes, so use JniException that is a RuntimeException (not to
    be caught explicitly).
- - Partial bug fix in initialization. SimGrid flags on command line were 
-   consumed at C level but stayed in the original Java String[] args. 
+ - Partial bug fix in initialization. SimGrid flags on command line were
+   consumed at C level but stayed in the original Java String[] args.
    This could mess users' args[i] if SG flags were not put at the end of
    the command line.
-   The SimGrid flags are now removed from the Java arguments. However, 
+   The SimGrid flags are now removed from the Java arguments. However,
    the number of arguments REMAINS UNCHANGED. It is then UNSAFE to test
-   if args.length is greater than the number of YOUR OWN ARGUMENTS. 
+   if args.length is greater than the number of YOUR OWN ARGUMENTS.
    It might be if you have --log or --cfg flags in the command line.
  - Fix numerous memleaks all around the place. In particular, around VMs.
 
@@ -133,21 +140,21 @@ SimGrid (3.15) Released March 22. 2017
 
  SimDag
  - Backwards Compatibility breaks
-    - The SD_route_get_list and SD_route_get_size functions have been removed. 
-      They are replaced by the unique 
+    - The SD_route_get_list and SD_route_get_size functions have been removed.
+      They are replaced by the unique
          void sg_host_route(sg_host_t src, sg_host_t dst, xbt_dynar_t links)
-      The route from src to dst is built in the links dynar whose size can 
+      The route from src to dst is built in the links dynar whose size can
       be obtained with xbt_dynar_length.
     - The SD_route_bandwidth and SD_route_latency functions have been replaced by
-        sg_host_route_bandwidth and sg_host_route_latency. 
+        sg_host_route_bandwidth and sg_host_route_latency.
       Macros ensure the backwards compatibility, but you should fix your code
 
  SMPI
- - Major C++ rewrite ongoing (SMPI used to be C compiled in C++). 
+ - Major C++ rewrite ongoing (SMPI used to be C compiled in C++).
    This can break codes using SMPI internals (from private.h instead of the public smpi.h).
- - Bump our claim of support from MPI 1.1 to MPI 2.2. 
+ - Bump our claim of support from MPI 1.1 to MPI 2.2.
    We don't support 100% of it, but it should be enough. Contact us if not.
- - MPI_Win_lock/unlock, MPI_Get_accumulate support added (as for all RMA, implementation is 
+ - MPI_Win_lock/unlock, MPI_Get_accumulate support added (as for all RMA, implementation is
    naive and probably inaccurate)
  - New algorithm for SMPI_SHARED_MALLOC: global, where all blocks are
    mapped onto a unique small file using some system magic.
@@ -194,13 +201,13 @@ SimGrid (3.14) Released December 24. 2016
 
  SMPI
  * Privatization now works on FreeBSD
+
  * Privatization is now activated by default in smpirun
    You can turn it off with -no-privatize if something goes wrong.
 
  * Call-location tracing for SMPI.
-   You can add the exact location (filename / linenumber) of an MPI call to 
-   your trace files and slow down or speed up the simulation between two 
+   You can add the exact location (filename / linenumber) of an MPI call to
+   your trace files and slow down or speed up the simulation between two
    consecutive calls by using an adjustment file (see the documentation).
 
  * Fixed computation of timings for MPI_Send, MPI_Recv & possibly also others
@@ -212,8 +219,8 @@ SimGrid (3.14) Released December 24. 2016
  * smpi/cpu-threshold:-1 should become smpi/simulate-computation:no
    smpi/running-power    is renamed to smpi/host-speed
 
- * smpi/grow-injected-times option to enable or disable multiplication of the 
-   timings injected in MPI_Iprobe, or MPI_Test. Enabled by default, which can 
+ * smpi/grow-injected-times option to enable or disable multiplication of the
+   timings injected in MPI_Iprobe, or MPI_Test. Enabled by default, which can
    make simulation less precise (but also much faster).
 
  * smpirun script should be (much) faster for large deployments.
@@ -243,11 +250,11 @@ SimGrid (3.14) Released December 24. 2016
    - Ignored parameter of vm_create: core_nb, disk_path and disk_size.
    - Unimplemented save/restore methods
  * MSG_as_router_get_property_value() was redundent with
-   MSG_environment_as_get_property_value(). 
+   MSG_environment_as_get_property_value().
    - Removed MSG_as_router_*propert*() functions
    - Added MSG_environment_as_set_property_value() for consistency
- * xbt heterogeneous dictionnaries (created with xbt_dict_new()). 
-   Well, they are still there for now, but deprecated with a warning. 
+ * xbt heterogeneous dictionnaries (created with xbt_dict_new()).
+   Well, they are still there for now, but deprecated with a warning.
    Please switch to xbt_dict_new_homogeneous() before this is removed
    for real.
  * Task affinity. Its intended behavior (that was very badly tested
@@ -255,8 +262,8 @@ SimGrid (3.14) Released December 24. 2016
    would have hoped here.
  * xbt_os_sem_get_value: unused internally, deprecated on OS X El Capitan
  * Option network/coordinates is now useless and should be dropped.
- Storage: 
+
+ Storage:
  * Added option storage/max_file_descriptors to allow more than 1024 files opened
 
  SURF:
@@ -265,29 +272,29 @@ SimGrid (3.14) Released December 24. 2016
 
  XML:
  * Add Exa- and Peta- units such as EiB, EB, Eib, Eb for size, and
-   EiBps, EBps, Eibps, Ebps for bandwidth. 
+   EiBps, EBps, Eibps, Ebps for bandwidth.
    They may become useful to some lucky ones.
-   
+
  Java:
  * New functions: msg.Comm.waitAll() and msg.Comm.waitAny()
  * ex/app_tokenring: new example, very similar to the MSG Token Ring
  * ex/async_waitAll: new example, on asynchronous communications
 
  MSG:
- * Memory usage should be decreased for simulations with a large number 
+ * Memory usage should be decreased for simulations with a large number
    of processes. This also helps for SMPI.
 
 SimGrid (3.13) stable; urgency=low
 
  The Half Release, a.k.a. the Zealous Easter Trim.
+
  - We removed half of the lines, that were mostly experimental cruft.
    v3.12 lasted 286000 lines of code, v3.13 is only 142000 lines
    (not counting blanks and comments -- according to openhub.net)
  - The internals are now compiled in C++ (and will soon be clean C++)
- - We removed 75 klines of XML, 12 klines of Java, 5 klines of cmake, 
+ - We removed 75 klines of XML, 12 klines of Java, 5 klines of cmake,
    59 klines of C, etc. We added only 29 klines of C++ in replacement.
-   
+
  * Backwards Compatibility breaks
    - Removed Lua simulation bindings (switch to C or Java for that).
      Lua can still be used to describe platforms
@@ -299,11 +306,11 @@ SimGrid (3.13) stable; urgency=low
         way, with filter function.
           - MSG_task_listen_from_host
           - MSG_mailbox_get_count_host_waiting_tasks
-          - MSG_mailbox_put_with_timeout was removed. 
+          - MSG_mailbox_put_with_timeout was removed.
             Please use MSG_task_send_with_timeout instead.
-   - In SimDag 
-      - the SD_application_reinit function was removed. It has been a noop for a while. 
-      - The ACCESS_MODE of SD_workstation has been removed. This feature was not really usable and should soon be 
+   - In SimDag
+      - the SD_application_reinit function was removed. It has been a noop for a while.
+      - The ACCESS_MODE of SD_workstation has been removed. This feature was not really usable and should soon be
         replaced by a more flexible mechanism.
       - The following functions thus do not exist anymore
          - SD_workstation_get_access_mode
@@ -313,7 +320,7 @@ SimGrid (3.13) stable; urgency=low
         - SD_route_get_communication_time => SG_route_get_latency() + amount / SD_route_get_bandwidth()
         - SD_workstation_get_computation_time => amount / sg_host_speed()
    - In Java
-      - VM.setBound(int load) is now VM.setBound(double bound) to meet the MSG semantics. 
+      - VM.setBound(int load) is now VM.setBound(double bound) to meet the MSG semantics.
         Use VM.getSpeed()*load/100 for the legacy behavior.
    - In CMake
       - option enable_tracing was removed. It was not doing anything for a while.
@@ -352,7 +359,7 @@ SimGrid (3.13) stable; urgency=low
        And the same in bits:  'Tibps', 'Gibps', 'Mibps', 'Kibps', 'Tbps', 'Gbps', 'Mbps', 'kbps', 'bps'
      - latency. Default: 's' second. Also defined:
        'w' week, 'd' day, 'h' hour, 'm' minute, 'ms' millisecond, 'us' microsecond, 'ns' nanosecond, 'ps' picosecond
-       
+
  * bin/simgrid_update_xml can upgrade your files automatically (won't convert unit-less values)
    tools/sg_xml_unit_converter.py may help (but it's just a warning and will probably ever be).
 
@@ -363,14 +370,14 @@ SimGrid (3.13) stable; urgency=low
 
  MSG
  * The examples were completely reorganized (in C and Java), for your browsing pleasure.
- * Kill all deprecated functions (the ones you had when declaring MSG_DEPRECATED). 
+ * Kill all deprecated functions (the ones you had when declaring MSG_DEPRECATED).
    They were deprecated since a few years, and probably did not even compile anymore.
 
  SimDag
- * The API has been profoundly modified to directly use the core objects instead of redefining its own. 
+ * The API has been profoundly modified to directly use the core objects instead of redefining its own.
    SD_Workstation_t and SD_link_t are now sg_host_t and sg_link_t respectively.
-   Some functions have also been renamed for consistency. Backward compatibility is maintained, but users are 
-   encouraged to update their codes. A list of the modified functions can be found at the end of 
+   Some functions have also been renamed for consistency. Backward compatibility is maintained, but users are
+   encouraged to update their codes. A list of the modified functions can be found at the end of
    include/simgrid/simdag.h
 
  Simix
@@ -406,7 +413,7 @@ SimGrid (3.13) stable; urgency=low
  * refactoring and cleanup of the code;
  * ongoing process to cleanly separate the model-checking algorithms
    from the code model-checking support.
+
  -- Wed Apr 27 21:00:53 CEST 2016 Da SimGrid team <simgrid-devel@lists.gforge.inria.fr>
 
 SimGrid (3.12) stable; urgency=low
index 2ec75dd..500cbe4 100644 (file)
@@ -689,6 +689,7 @@ INPUT                  = doxygen/index.doc \
                          @CMAKE_HOME_DIRECTORY@/include/simgrid \
                          @CMAKE_HOME_DIRECTORY@/include/simgrid/s4u \
                          @CMAKE_HOME_DIRECTORY@/src/include/surf \
+                         @CMAKE_HOME_DIRECTORY@/src/include/xbt \
                          @CMAKE_HOME_DIRECTORY@/src/msg/ \
                          @CMAKE_HOME_DIRECTORY@/src/kernel/ \
                          @CMAKE_HOME_DIRECTORY@/src/kernel/activity/ \
index 2ec954e..98f91cc 100644 (file)
@@ -112,7 +112,6 @@ int main(int argc, char *argv[]) {
 - \c network/maxmin-selective-update: \ref options_model_optim
 - \c network/model: \ref options_model_select
 - \c network/optim: \ref options_model_optim
-- \c network/sender_gap: \ref options_model_network_sendergap
 - \c network/TCP-gamma: \ref options_model_network_gamma
 - \c network/weight-S: \ref options_model_network_coefs
 
@@ -373,15 +372,6 @@ can be set to 0 (disable this feature) or 1 (enable it).
 
 Note that with the default host model this option is activated by default.
 
-\subsubsection options_model_network_sendergap Simulating sender gap
-
-(this configuration item is experimental and may change or disapear)
-
-It is possible to specify a timing gap between consecutive emission on
-the same network card through the \b network/sender-gap item. This
-is still under investigation as of writting, and the default value is
-to wait 10 microseconds (1e-5 seconds) between emissions.
-
 \subsubsection options_model_network_asyncsend Simulating asyncronous send
 
 (this configuration item is experimental and may change or disapear)
index 0eb1eaa..b7f7718 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2006-2014, 2016. The SimGrid Team.
+/* Copyright (c) 2006-2014, 2016-2017. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
@@ -18,7 +18,7 @@ class Common {
   public static final int MESSAGE_SIZE = 1; /* Information message size */
   public static final int MAXIMUM_PEERS = 50;  /* Max number of peers sent by the tracker to clients */
   public static final int TRACKER_QUERY_INTERVAL = 1000;  /* Interval of time where the peer should send a request to the tracker */
-  public static final double TRACKER_COMM_SIZE = 0.01;  /* Communication size for a task to the tracker */
+  public static final double TRACKER_COMM_SIZE = 1;  /* Communication size for a task to the tracker */
   public static final int GET_PEERS_TIMEOUT = 10000;  /* Timeout for the get peers data */
   public static final int TIMEOUT_MESSAGE = 10;
   public static final int TRACKER_RECEIVE_TIMEOUT = 10;
index ca06ab3..fc994e3 100644 (file)
@@ -30,13 +30,6 @@ if(SIMGRID_HAVE_NS3)
   set_target_properties(network-ns3  PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/network-ns3)
 endif()
 
-add_executable       (bittorrent app-bittorrent/bittorrent.c app-bittorrent/messages.c app-bittorrent/peer.c app-bittorrent/tracker.c app-bittorrent/connection.c)
-target_link_libraries(bittorrent simgrid)
-set_target_properties(bittorrent PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/app-bittorrent)
-foreach (file bittorrent connection messages peer tracker)
-  set(examples_src  ${examples_src}  ${CMAKE_CURRENT_SOURCE_DIR}/app-bittorrent/${file}.c  ${CMAKE_CURRENT_SOURCE_DIR}/app-bittorrent/${file}.h)
-endforeach()
-
 add_executable       (chainsend app-chainsend/chainsend.c app-chainsend/iterator.c app-chainsend/common.c app-chainsend/messages.c app-chainsend/broadcaster.c app-chainsend/peer.c)
 target_link_libraries(chainsend simgrid)
 set_target_properties(chainsend PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/app-chainsend)
@@ -51,21 +44,19 @@ foreach (file answer dht-kademlia node routing_table task)
   set(examples_src  ${examples_src}  ${CMAKE_CURRENT_SOURCE_DIR}/dht-kademlia/${file}.c  ${CMAKE_CURRENT_SOURCE_DIR}/dht-kademlia/${file}.h)
 endforeach()
 
-foreach (file app-bittorrent app-chainsend app-masterworker app-pingpong async-wait
+foreach (file app-chainsend app-masterworker app-pingpong async-wait
          async-waitall async-waitany dht-kademlia dht-pastry io-remote platform-properties process-yield 
          task-priority)
   set(xml_files    ${xml_files}     ${CMAKE_CURRENT_SOURCE_DIR}/${file}/${file}_d.xml)
 endforeach()
 
 set(txt_files    ${txt_files}     ${CMAKE_CURRENT_SOURCE_DIR}/README.doc          PARENT_SCOPE)
-set(bin_files    ${bin_files}     ${CMAKE_CURRENT_SOURCE_DIR}/app-bittorrent/generate.py
-                                  ${CMAKE_CURRENT_SOURCE_DIR}/dht-kademlia/generate.py
+set(bin_files    ${bin_files}     ${CMAKE_CURRENT_SOURCE_DIR}/dht-kademlia/generate.py
                                   ${CMAKE_CURRENT_SOURCE_DIR}/dht-pastry/generate.py                       PARENT_SCOPE)
 set(examples_src ${examples_src}  ${CMAKE_CURRENT_SOURCE_DIR}/app-chainsend/chainsend.c
                                   ${CMAKE_CURRENT_SOURCE_DIR}/dht-kademlia/common.h
                                   ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3/network-ns3.c                    PARENT_SCOPE)
-set(tesh_files   ${tesh_files}    ${CMAKE_CURRENT_SOURCE_DIR}/app-bittorrent/app-bittorrent.tesh
-                                  ${CMAKE_CURRENT_SOURCE_DIR}/app-chainsend/app-chainsend.tesh
+set(tesh_files   ${tesh_files}    ${CMAKE_CURRENT_SOURCE_DIR}/app-chainsend/app-chainsend.tesh
                                   ${CMAKE_CURRENT_SOURCE_DIR}/dht-kademlia/dht-kademlia.tesh
                                   ${CMAKE_CURRENT_SOURCE_DIR}/app-masterworker/app-masterworker-multicore.tesh
                                   ${CMAKE_CURRENT_SOURCE_DIR}/app-masterworker/app-masterworker-vivaldi.tesh
@@ -89,7 +80,7 @@ set(xml_files    ${xml_files}     ${CMAKE_CURRENT_SOURCE_DIR}/app-masterworker/a
                                   ${CMAKE_CURRENT_SOURCE_DIR}/process-startkilltime/start_d.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/process-startkilltime/start_kill_d.xml       PARENT_SCOPE)
 
-foreach(x app-bittorrent app-chainsend app-masterworker app-pingpong app-token-ring
+foreach(x app-chainsend app-masterworker app-pingpong app-token-ring
           async-wait async-waitall async-waitany cloud-capping cloud-masterworker cloud-migration cloud-simple 
           cloud-two-tasks dht-pastry dht-kademlia platform-failures io-file io-remote io-storage task-priority 
           process-create process-daemon process-join process-kill process-migration process-startkilltime process-suspend process-yield
@@ -105,7 +96,6 @@ foreach (x categories route-user-variables link-user-variables masterworker plat
   ADD_TESH(msg-trace-${x} --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/trace-${x} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/trace-${x} trace-${x}.tesh)
 endforeach()
 
-ADD_TESH_FACTORIES(msg-app-bittorrent-parallel         "thread;ucontext;raw" --cfg contexts/nthreads:4 ${CONTEXTS_SYNCHRO} --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/app-bittorrent --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/app-bittorrent app-bittorrent.tesh)
 ADD_TESH_FACTORIES(msg-dht-kademlia-parallel           "thread;ucontext;raw" --cfg contexts/nthreads:4 ${CONTEXTS_SYNCHRO} --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/dht-kademlia --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/dht-kademlia dht-kademlia.tesh)
 ADD_TESH_FACTORIES(msg-energy-pstate-ptask             "thread;ucontext;raw;boost" --cfg host/model:ptask_L07 --log xbt_cfg.threshold:critical --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/msg --cd ${CMAKE_BINARY_DIR}/examples/msg ${CMAKE_HOME_DIRECTORY}/examples/msg/energy-pstate/energy-pstate.tesh)
 ADD_TESH_FACTORIES(msg-energy-consumption-ptask        "thread;ucontext;raw;boost" --cfg host/model:ptask_L07 --log xbt_cfg.threshold:critical --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/msg --cd ${CMAKE_BINARY_DIR}/examples/msg ${CMAKE_HOME_DIRECTORY}/examples/msg/energy-consumption/energy-consumption.tesh)
diff --git a/examples/msg/app-bittorrent/messages.c b/examples/msg/app-bittorrent/messages.c
deleted file mode 100644 (file)
index d4c7c2b..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Copyright (c) 2012-2014. 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 "messages.h"
-#include "bittorrent.h"
-
-XBT_LOG_NEW_DEFAULT_CATEGORY(msg_messages, "Messages specific for the message factory");
-
-#define BITS_TO_BYTES(x) ((x / 8) + (x % 8) ? 1 : 0)
-
-/** @brief Build a new empty message
- * @param type type of the message
- * @param issuer_host_name hostname of the issuer, for debugging purposes
- * @param mailbox mailbox where the peer should answer
- * @param peer_id id of the issuer
- * @param size message size in bytes
- */
-msg_task_t task_message_new(e_message_type type, const char *issuer_host_name, const char *mailbox, int peer_id,
-                            int size)
-{
-  message_t message = xbt_new(s_message_t, 1);
-  message->issuer_host_name = issuer_host_name;
-  message->peer_id = peer_id;
-  message->mailbox = mailbox;
-  message->type = type;
-  msg_task_t task = MSG_task_create(NULL, 0, size, message);
-  XBT_DEBUG("type: %d size: %d", (int) type, size);
-  return task;
-}
-
-/** Builds a message containing an index. */
-msg_task_t task_message_index_new(e_message_type type, const char *issuer_host_name, const char *mailbox, int peer_id,
-                                  int index, int varsize)
-{
-  msg_task_t task = task_message_new(type, issuer_host_name, mailbox, peer_id, task_message_size(type) + varsize);
-  message_t message = MSG_task_get_data(task);
-  message->index = index;
-  return task;
-}
-
-msg_task_t task_message_bitfield_new(const char *issuer_host_name, const char *mailbox, int peer_id,
-                                     unsigned int bitfield, int bitfield_size)
-{
-  msg_task_t task = task_message_new(MESSAGE_BITFIELD, issuer_host_name, mailbox, peer_id,
-                                     task_message_size(MESSAGE_BITFIELD) + BITS_TO_BYTES(bitfield_size));
-  message_t message = MSG_task_get_data(task);
-  message->bitfield = bitfield;
-  return task;
-}
-
-msg_task_t task_message_request_new(const char *issuer_host_name, const char *mailbox, int peer_id, int index,
-                                    int block_index, int block_length)
-{
-  msg_task_t task = task_message_index_new(MESSAGE_REQUEST, issuer_host_name, mailbox, peer_id, index, 0);
-  message_t message = MSG_task_get_data(task);
-  message->block_index = block_index;
-  message->block_length = block_length;
-  return task;
-}
-
-msg_task_t task_message_piece_new(const char *issuer_host_name, const char *mailbox, int peer_id, int index,
-                                  int block_index, int block_length, int block_size)
-{
-  msg_task_t task = task_message_index_new(MESSAGE_PIECE, issuer_host_name, mailbox, peer_id, index,
-                                           block_length * block_size);
-  message_t message = MSG_task_get_data(task);
-  message->block_index = block_index;
-  message->block_length = block_length;
-  return task;
-}
-
-void task_message_free(void *task)
-{
-  message_t message = MSG_task_get_data(task);
-  xbt_free(message);
-  MSG_task_destroy(task);
-}
-
-int task_message_size(e_message_type type)
-{
-  int size = 0;
-  switch (type) {
-  case MESSAGE_HANDSHAKE:
-    size = MESSAGE_HANDSHAKE_SIZE;
-    break;
-  case MESSAGE_CHOKE:
-    size = MESSAGE_CHOKE_SIZE;
-    break;
-  case MESSAGE_UNCHOKE:
-    size = MESSAGE_UNCHOKE_SIZE;
-    break;
-  case MESSAGE_INTERESTED:
-  case MESSAGE_NOTINTERESTED:
-    size = MESSAGE_INTERESTED_SIZE;
-    break;
-  case MESSAGE_HAVE:
-    size = MESSAGE_HAVE_SIZE;
-    break;
-  case MESSAGE_BITFIELD:
-    size = MESSAGE_BITFIELD_SIZE;
-    break;
-  case MESSAGE_REQUEST:
-    size = MESSAGE_REQUEST_SIZE;
-    break;
-  case MESSAGE_PIECE:
-    size = MESSAGE_PIECE_SIZE;
-    break;
-  case MESSAGE_CANCEL:
-    size = MESSAGE_CANCEL_SIZE;
-    break;
-  default:
-    THROW_IMPOSSIBLE;
-  }
-  return size;
-}
diff --git a/examples/msg/app-bittorrent/tracker.h b/examples/msg/app-bittorrent/tracker.h
deleted file mode 100644 (file)
index 40e7d9d..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (c) 2012-2014. 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. */
-
-#ifndef BITTORRENT_TRACKER_H_
-#define BITTORRENT_TRACKER_H_
-#include <xbt/dynar.h>
-#include "bittorrent.h"
-/**
- * Tracker main function
- */
-int tracker(int argc, char *argv[]);
-/**
- * Task types exchanged between a node and the tracker
- */
-typedef enum {
-  TRACKER_TASK_QUERY,
-  TRACKER_TASK_ANSWER
-} e_tracker_task_type_t;
-/**
- * Tasks exchanged between a tracker and peers.
- */
-typedef struct s_tracker_task_data {
-  e_tracker_task_type_t type;   //type of the task
-  const char *mailbox;          //mailbox where the tracker should answer
-  const char *issuer_host_name; //hostname, for debug purposes
-  //Query data
-  int peer_id;                  //peer id
-  int uploaded;                 //how much the peer has already uploaded
-  int downloaded;               //how much the peer has downloaded
-  int left;                     //how much the peer has left
-  //Answer data
-  int interval;                 //how often the peer should contact the tracker (unused for now)
-  xbt_dynar_t peers;            //the peer list the peer has asked for.
-} s_tracker_task_data_t;
-typedef s_tracker_task_data_t *tracker_task_data_t;
-
-tracker_task_data_t tracker_task_data_new(const char *issuer_host_name, const char *mailbox, int peer_id,
-                                          int uploaded, int downloaded, int left);
-void tracker_task_data_free(tracker_task_data_t task);
-
-int is_in_list(xbt_dynar_t peers, int id);
-#endif                          /* BITTORRENT_TRACKER_H */
index a7b4d59..5158498 100644 (file)
@@ -33,7 +33,7 @@ static void test_host(const char*hostname)
   XBT_INFO("   Property: %s old value: %s", exist, value);
 
   XBT_INFO("== Trying to modify a host property");
-  MSG_host_set_property_value(thehost, exist, xbt_strdup("250"));
+  MSG_host_set_property_value(thehost, exist, (char*)"250");
 
   /* Test if we have changed the value */
   value = MSG_host_get_property_value(thehost, exist);
@@ -42,7 +42,9 @@ static void test_host(const char*hostname)
   XBT_INFO("   Property: %s old value: %s", exist, value);
 
   /* Restore the value for the next test */
-  MSG_host_set_property_value(thehost, exist, xbt_strdup("180"));
+  MSG_host_set_property_value(thehost, exist, (char*)"180");
+
+  xbt_dict_free(&props);
 }
 
 static int alice(int argc, char *argv[]) { /* Dump what we have on the current host */
@@ -87,6 +89,7 @@ static int bob(int argc, char *argv[])
 
   value = MSG_process_get_property_value(MSG_process_self(), noexist);
   xbt_assert(!value, "The property is defined (it shouldnt)");
+  xbt_dict_free(&props);
 
   return 0;
 }
index b58419e..f2836b6 100644 (file)
@@ -12,23 +12,23 @@ $ $SG_TEST_EXENV ${bindir:=.}/trace-categories$EXEEXT --cfg=tracing:yes --cfg=tr
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/uncategorized' to 'categories.uncat.plist'
 
 $ $SG_TEST_EXENV cat categories.cat.plist
->   node = ("HOST","LINK");
->   edge = ("0-LINK4-LINK4","0-HOST1-LINK4","0-LINK4-HOST1");
+>   node = ("LINK","HOST");
+>   edge = ("0-LINK4-LINK4","0-LINK4-HOST1","0-HOST1-LINK4");
 >
 >   host = {
 >     type = "square";
 >     size = "power";
->     values = ("pdata","pcompute","pfinalize","prequest");
+>     values = ("pcompute","pdata","pfinalize","prequest");
 >   };
 >   link = {
 >     type = "rhombus";
 >     size = "bandwidth";
->     values = ("bdata","bcompute","bfinalize","brequest");
+>     values = ("bcompute","bdata","bfinalize","brequest");
 >   };
 
 $ $SG_TEST_EXENV cat categories.uncat.plist
->   node = ("HOST","LINK");
->   edge = ("0-LINK4-LINK4","0-HOST1-LINK4","0-LINK4-HOST1");
+>   node = ("LINK","HOST");
+>   edge = ("0-LINK4-LINK4","0-LINK4-HOST1","0-HOST1-LINK4");
 >
 >   host = {
 >     type = "square";
index d45d68c..431b774 100644 (file)
@@ -9,12 +9,12 @@ $ $SG_TEST_EXENV ${bindir:=.}/trace-host-user-variables$EXEEXT --cfg=tracing:yes
 > [0.004078] [msg_test/INFO] HDD_utilization
 > [0.004078] [msg_test/INFO] Declared link variables:
 > [0.004078] [msg_test/INFO] Node types in the trace:
-> [0.004078] [msg_test/INFO] LINK
 > [0.004078] [msg_test/INFO] HOST
+> [0.004078] [msg_test/INFO] LINK
 > [0.004078] [msg_test/INFO] Node types in the trace:
-> [0.004078] [msg_test/INFO] 0-LINK3-LINK3
 > [0.004078] [msg_test/INFO] 0-HOST1-LINK3
 > [0.004078] [msg_test/INFO] 0-LINK3-HOST1
+> [0.004078] [msg_test/INFO] 0-LINK3-LINK3
 
 $ rm -f viva_graph.plist
 
index 7690bfe..d17cce3 100644 (file)
@@ -10,10 +10,10 @@ $ $SG_TEST_EXENV ${bindir:=.}/trace-masterworker$EXEEXT --cfg=tracing:yes --cfg=
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/categorized' to 'trace-masterworker.cat.plist'
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/uncategorized' to 'trace-masterworker.uncat.plist'
 > [4.214821] [msg_trace_masterworker/INFO] Declared tracing categories:
-> [4.214821] [msg_trace_masterworker/INFO] request
+> [4.214821] [msg_trace_masterworker/INFO] compute
 > [4.214821] [msg_trace_masterworker/INFO] finalize
 > [4.214821] [msg_trace_masterworker/INFO] report
-> [4.214821] [msg_trace_masterworker/INFO] compute
+> [4.214821] [msg_trace_masterworker/INFO] request
 > [4.214821] [msg_trace_masterworker/INFO] Declared marks:
 > [4.214821] [msg_trace_masterworker/INFO] msmark
 
@@ -27,10 +27,10 @@ $ $SG_TEST_EXENV ${bindir:=.}/trace-masterworker$EXEEXT ${srcdir:=.}/config_trac
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/categorized' to 'trace-masterworker.cat.plist'
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/uncategorized' to 'trace-masterworker.uncat.plist'
 > [4.214821] [msg_trace_masterworker/INFO] Declared tracing categories:
-> [4.214821] [msg_trace_masterworker/INFO] request
+> [4.214821] [msg_trace_masterworker/INFO] compute
 > [4.214821] [msg_trace_masterworker/INFO] finalize
 > [4.214821] [msg_trace_masterworker/INFO] report
-> [4.214821] [msg_trace_masterworker/INFO] compute
+> [4.214821] [msg_trace_masterworker/INFO] request
 > [4.214821] [msg_trace_masterworker/INFO] Declared marks:
 > [4.214821] [msg_trace_masterworker/INFO] msmark
 
@@ -48,17 +48,17 @@ $ $SG_TEST_EXENV ${bindir:=.}/trace-masterworker$EXEEXT --cfg=tracing:yes --cfg=
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/categorized' to 'trace-masterworker.cat.plist'
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/uncategorized' to 'trace-masterworker.uncat.plist'
 > [4.214821] [msg_trace_masterworker/INFO] Declared tracing categories:
-> [4.214821] [msg_trace_masterworker/INFO] request
+> [4.214821] [msg_trace_masterworker/INFO] compute
 > [4.214821] [msg_trace_masterworker/INFO] finalize
 > [4.214821] [msg_trace_masterworker/INFO] report
-> [4.214821] [msg_trace_masterworker/INFO] compute
+> [4.214821] [msg_trace_masterworker/INFO] request
 > [4.214821] [msg_trace_masterworker/INFO] Declared marks:
 > [4.214821] [msg_trace_masterworker/INFO] msmark
 
 $ $SG_TEST_EXENV cat trace-masterworker.uncat.plist
->   node = ("HOST","LINK");
+>   node = ("LINK","HOST");
 >   edge = ("0-LINK13-LINK13","0-LINK13-HOST1","0-HOST1-LINK13");
-> 
+>
 >   host = {
 >     type = "square";
 >     size = "power";
@@ -71,18 +71,18 @@ $ $SG_TEST_EXENV cat trace-masterworker.uncat.plist
 >   };
 
 $ $SG_TEST_EXENV cat trace-masterworker.cat.plist
->   node = ("HOST","LINK");
+>   node = ("LINK","HOST");
 >   edge = ("0-LINK13-LINK13","0-LINK13-HOST1","0-HOST1-LINK13");
-> 
+>
 >   host = {
 >     type = "square";
 >     size = "power";
->     values = ("pcompute","preport","pfinalize","prequest");
+>     values = ("pcompute","pfinalize","preport","prequest");
 >   };
 >   link = {
 >     type = "rhombus";
 >     size = "bandwidth";
->     values = ("bcompute","breport","bfinalize","brequest");
+>     values = ("bcompute","bfinalize","breport","brequest");
 >   };
 
 $ rm -rf trace-masterworker.trace trace-masterworker.cat.plist trace-masterworker.uncat.plist
index 72a43da..6064c0c 100644 (file)
@@ -17,12 +17,23 @@ foreach (file s4u_dht-chord node)
 endforeach()
 set(examples_src  ${examples_src}  ${CMAKE_CURRENT_SOURCE_DIR}/dht-chord/s4u_dht-chord.hpp)
 
+add_executable       (s4u_bittorrent app-bittorrent/s4u_bittorrent.cpp app-bittorrent/s4u_peer.cpp
+                      app-bittorrent/s4u_tracker.cpp)
+target_link_libraries(s4u_bittorrent simgrid)
+set_target_properties(s4u_bittorrent PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/app-bittorrent)
+foreach (file s4u_bittorrent s4u_peer s4u_tracker)
+  set(examples_src  ${examples_src}  ${CMAKE_CURRENT_SOURCE_DIR}/app-bittorrent/${file}.cpp
+                                     ${CMAKE_CURRENT_SOURCE_DIR}/app-bittorrent/${file}.hpp)
+endforeach()
+
 set(examples_src  ${examples_src}                                                                          PARENT_SCOPE)
-set(tesh_files    ${tesh_files}   ${CMAKE_CURRENT_SOURCE_DIR}/dht-chord/s4u_dht-chord.tesh                 PARENT_SCOPE)
+set(tesh_files    ${tesh_files}   ${CMAKE_CURRENT_SOURCE_DIR}/app-bittorrent/s4u_app-bittorrent.tesh
+                                  ${CMAKE_CURRENT_SOURCE_DIR}/dht-chord/s4u_dht-chord.tesh                 PARENT_SCOPE)
 set(xml_files     ${xml_files}    ${CMAKE_CURRENT_SOURCE_DIR}/actions-comm/s4u_actions-comm_split_d.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/actions-comm/s4u_actions-comm_d.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/actions-storage/s4u_actions-storage_d.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/actor-create/s4u_actor-create_d.xml
+                                  ${CMAKE_CURRENT_SOURCE_DIR}/app-bittorrent/s4u_app-bittorrent_d.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/app-masterworker/s4u_app-masterworker_d.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/dht-chord/s4u_dht-chord_d.xml                PARENT_SCOPE)
 set(txt_files     ${txt_files}    ${CMAKE_CURRENT_SOURCE_DIR}/actions-comm/s4u_actions-comm_split_p0.txt
@@ -32,6 +43,6 @@ set(txt_files     ${txt_files}    ${CMAKE_CURRENT_SOURCE_DIR}/actions-comm/s4u_a
                                   ${CMAKE_CURRENT_SOURCE_DIR}/README.doc                                   PARENT_SCOPE)
 
 foreach(example actions-comm actions-storage actor-create actor-daemon actor-kill actor-migration actor-suspend 
-                 app-masterworker app-pingpong app-token-ring dht-chord plugin-hostload io mutex )
+                app-bittorrent app-masterworker app-pingpong app-token-ring dht-chord plugin-hostload io mutex )
   ADD_TESH_FACTORIES(s4u-${example} "thread;ucontext;raw;boost" --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/${example} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_HOME_DIRECTORY}/examples/s4u/${example} s4u_${example}.tesh)
 endforeach()
index 85e71e1..85ffb9d 100644 (file)
@@ -29,7 +29,7 @@ static void log_action(const char* const* action, double date)
   }
 }
 
-static simgrid::s4u::File* get_file_descriptor(const char* file_name)
+static simgrid::s4u::File* get_file_descriptor(std::string file_name)
 {
   std::string full_name = simgrid::s4u::this_actor::getName() + ":" + file_name;
 
@@ -60,11 +60,11 @@ public:
   /* My actions */
   static void open(const char* const* action)
   {
-    const char* file_name = action[2];
+    std::string file_name = action[2];
     double clock          = simgrid::s4u::Engine::getClock();
     std::string full_name = simgrid::s4u::this_actor::getName() + ":" + file_name;
 
-    ACT_DEBUG("Entering Open: %s (filename: %s)", NAME, file_name);
+    ACT_DEBUG("Entering Open: %s (filename: %s)", NAME, file_name.c_str());
     simgrid::s4u::File* file = new simgrid::s4u::File(file_name, NULL);
 
     opened_files.insert({full_name, file});
@@ -74,7 +74,7 @@ public:
 
   static void read(const char* const* action)
   {
-    const char* file_name = action[2];
+    std::string file_name = action[2];
     sg_size_t size        = std::stoul(action[3]);
     double clock          = simgrid::s4u::Engine::getClock();
 
@@ -88,12 +88,12 @@ public:
 
   static void close(const char* const* action)
   {
-    const char* file_name = action[2];
+    std::string file_name = action[2];
     double clock          = simgrid::s4u::Engine::getClock();
 
     simgrid::s4u::File* file = get_file_descriptor(file_name);
 
-    ACT_DEBUG("Entering Close: %s (filename: %s)", NAME, file_name);
+    ACT_DEBUG("Entering Close: %s (filename: %s)", NAME, file_name.c_str());
     delete file;
 
     log_action(action, simgrid::s4u::Engine::getClock() - clock);
diff --git a/examples/s4u/app-bittorrent/s4u_app-bittorrent.tesh b/examples/s4u/app-bittorrent/s4u_app-bittorrent.tesh
new file mode 100644 (file)
index 0000000..d309e01
--- /dev/null
@@ -0,0 +1,23 @@
+#! ./tesh
+
+p Testing the Bittorrent implementation with MSG
+
+! timeout 10
+! output sort 19
+$ $SG_TEST_EXENV ${bindir:=.}/s4u_bittorrent ${srcdir:=.}/cluster.xml ${srcdir:=.}/../s4u/app-bittorrent/s4u_app-bittorrent_d.xml "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n"
+> [    0.000000] (1:tracker@node-0.acme.org) Tracker launched.
+> [    0.000000] (2:peer@node-1.acme.org) Hi, I'm joining the network with id 2
+> [    0.000000] (3:peer@node-2.acme.org) Hi, I'm joining the network with id 3
+> [    0.000000] (4:peer@node-3.acme.org) Hi, I'm joining the network with id 4
+> [    0.000000] (5:peer@node-4.acme.org) Hi, I'm joining the network with id 5
+> [    0.000000] (6:peer@node-5.acme.org) Hi, I'm joining the network with id 6
+> [    0.000000] (7:peer@node-6.acme.org) Hi, I'm joining the network with id 7
+> [    0.000000] (8:peer@node-7.acme.org) Hi, I'm joining the network with id 8
+> [ 3000.000000] (1:tracker@node-0.acme.org) Tracker is leaving
+> [ 5000.007806] (2:peer@node-1.acme.org) Here is my current status: 1111111111
+> [ 5000.007806] (3:peer@node-2.acme.org) Here is my current status: 1111111111
+> [ 5000.007806] (4:peer@node-3.acme.org) Here is my current status: 1111111111
+> [ 5000.007806] (5:peer@node-4.acme.org) Here is my current status: 1111111111
+> [ 5000.007806] (6:peer@node-5.acme.org) Here is my current status: 1111111111
+> [ 5000.007806] (7:peer@node-6.acme.org) Here is my current status: 1111111111
+> [ 5000.007806] (8:peer@node-7.acme.org) Here is my current status: 1111111111
diff --git a/examples/s4u/app-bittorrent/s4u_bittorrent.cpp b/examples/s4u/app-bittorrent/s4u_bittorrent.cpp
new file mode 100644 (file)
index 0000000..cbc093b
--- /dev/null
@@ -0,0 +1,37 @@
+/* Copyright (c) 2012-2017. 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 "s4u_bittorrent.hpp"
+#include "s4u_peer.hpp"
+#include "s4u_tracker.hpp"
+
+simgrid::xbt::Extension<simgrid::s4u::Host, HostBittorrent> HostBittorrent::EXTENSION_ID;
+
+int main(int argc, char* argv[])
+{
+  simgrid::s4u::Engine* e = new simgrid::s4u::Engine(&argc, argv);
+
+  /* Check the arguments */
+  xbt_assert(argc > 2, "Usage: %s platform_file deployment_file", argv[0]);
+
+  e->loadPlatform(argv[1]);
+
+  HostBittorrent::EXTENSION_ID = simgrid::s4u::Host::extension_create<HostBittorrent>();
+
+  std::vector<simgrid::s4u::Host*> list;
+  simgrid::s4u::Engine::getInstance()->getHostList(&list);
+  for (auto host : list)
+    host->extension_set(new HostBittorrent(host));
+
+  e->registerFunction<Tracker>("tracker");
+  e->registerFunction<Peer>("peer");
+  e->loadDeployment(argv[2]);
+
+  e->run();
+
+  delete e;
+  return 0;
+}
diff --git a/examples/s4u/app-bittorrent/s4u_bittorrent.hpp b/examples/s4u/app-bittorrent/s4u_bittorrent.hpp
new file mode 100644 (file)
index 0000000..a3b296a
--- /dev/null
@@ -0,0 +1,104 @@
+/* Copyright (c) 2012-2014, 2016-2017. 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. */
+
+#ifndef BITTORRENT_BITTORRENT_HPP_
+#define BITTORRENT_BITTORRENT_HPP_
+
+#include <simgrid/s4u.hpp>
+#include <xbt/RngStream.h>
+
+#define MAILBOX_SIZE 40
+#define TRACKER_MAILBOX "tracker_mailbox"
+/** Max number of peers sent by the tracker to clients */
+#define MAXIMUM_PEERS 50
+/** Interval of time where the peer should send a request to the tracker */
+#define TRACKER_QUERY_INTERVAL 1000
+/** Communication size for a task to the tracker */
+#define TRACKER_COMM_SIZE 1
+#define GET_PEERS_TIMEOUT 10000
+#define TIMEOUT_MESSAGE 10
+#define TRACKER_RECEIVE_TIMEOUT 10
+/** Number of peers that can be unchocked at a given time */
+#define MAX_UNCHOKED_PEERS 4
+/** Interval between each update of the choked peers */
+#define UPDATE_CHOKED_INTERVAL 30
+/** Number of pieces the peer asks for simultaneously */
+#define MAX_PIECES 1
+
+/** Message sizes
+ * Sizes based on report by A. Legout et al, Understanding BitTorrent: An Experimental Perspective
+ * http://hal.inria.fr/inria-00000156/en
+ */
+#define MESSAGE_HANDSHAKE_SIZE 68
+#define MESSAGE_CHOKE_SIZE 5
+#define MESSAGE_UNCHOKE_SIZE 5
+#define MESSAGE_INTERESTED_SIZE 5
+#define MESSAGE_NOTINTERESTED_SIZE 5
+#define MESSAGE_HAVE_SIZE 9
+#define MESSAGE_BITFIELD_SIZE 5
+#define MESSAGE_REQUEST_SIZE 17
+#define MESSAGE_PIECE_SIZE 13
+#define MESSAGE_CANCEL_SIZE 17
+
+/** Types of messages exchanged between two peers. */
+typedef enum {
+  MESSAGE_HANDSHAKE,
+  MESSAGE_CHOKE,
+  MESSAGE_UNCHOKE,
+  MESSAGE_INTERESTED,
+  MESSAGE_NOTINTERESTED,
+  MESSAGE_HAVE,
+  MESSAGE_BITFIELD,
+  MESSAGE_REQUEST,
+  MESSAGE_PIECE,
+  MESSAGE_CANCEL
+} e_message_type;
+
+class Message {
+public:
+  e_message_type type;
+  int peer_id;
+  simgrid::s4u::MailboxPtr return_mailbox;
+  unsigned int bitfield = 0U;
+  int piece             = 0;
+  int block_index       = 0;
+  int block_length      = 0;
+  Message(e_message_type type, int peer_id, simgrid::s4u::MailboxPtr return_mailbox)
+      : type(type), peer_id(peer_id), return_mailbox(return_mailbox){};
+  Message(e_message_type type, int peer_id, unsigned int bitfield, simgrid::s4u::MailboxPtr return_mailbox)
+      : type(type), peer_id(peer_id), return_mailbox(return_mailbox), bitfield(bitfield){};
+  Message(e_message_type type, int peer_id, simgrid::s4u::MailboxPtr return_mailbox, int piece, int block_index,
+          int block_length)
+      : type(type)
+      , peer_id(peer_id)
+      , return_mailbox(return_mailbox)
+      , piece(piece)
+      , block_index(block_index)
+      , block_length(block_length){};
+  Message(e_message_type type, int peer_id, simgrid::s4u::MailboxPtr return_mailbox, int piece)
+      : type(type), peer_id(peer_id), return_mailbox(return_mailbox), piece(piece){};
+  ~Message() = default;
+};
+
+class HostBittorrent {
+  RngStream stream_;
+  simgrid::s4u::Host* host = nullptr;
+
+public:
+  static simgrid::xbt::Extension<simgrid::s4u::Host, HostBittorrent> EXTENSION_ID;
+
+  explicit HostBittorrent(simgrid::s4u::Host* ptr) : host(ptr)
+  {
+    std::string descr = std::string("RngSream<") + host->getCname() + ">";
+    stream_           = RngStream_CreateStream(descr.c_str());
+  }
+
+  ~HostBittorrent() { RngStream_DeleteStream(&stream_); };
+
+  RngStream getStream() { return stream_; };
+};
+
+#endif /* BITTORRENT_BITTORRENT_HPP_ */
diff --git a/examples/s4u/app-bittorrent/s4u_peer.cpp b/examples/s4u/app-bittorrent/s4u_peer.cpp
new file mode 100644 (file)
index 0000000..0b03bdb
--- /dev/null
@@ -0,0 +1,671 @@
+/* Copyright (c) 2012-2017. 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 <climits>
+#include <xbt/ex.hpp>
+
+#include "s4u_peer.hpp"
+#include "s4u_tracker.hpp"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_bt_peer, "Messages specific for the peers");
+
+/*
+ * User parameters for transferred file data. For the test, the default values are :
+ * File size: 10 pieces * 5 blocks/piece * 16384 bytes/block = 819200 bytes
+ */
+#define FILE_PIECES 10UL
+#define PIECES_BLOCKS 5UL
+#define BLOCK_SIZE 16384
+
+/** Number of blocks asked by each request */
+#define BLOCKS_REQUESTED 2
+
+#define ENABLE_END_GAME_MODE 1
+#define SLEEP_DURATION 1
+#define BITS_TO_BYTES(x) (((x) / 8 + (x) % 8) ? 1 : 0)
+
+Peer::Peer(std::vector<std::string> args)
+{
+  // Check arguments
+  xbt_assert(args.size() == 3 || args.size() == 4, "Wrong number of arguments");
+  try {
+    id       = std::stoi(args[1]);
+    mailbox_ = simgrid::s4u::Mailbox::byName(std::to_string(id));
+  } catch (std::invalid_argument& ia) {
+    throw std::invalid_argument(std::string("Invalid ID:") + args[1].c_str());
+  }
+
+  try {
+    deadline = std::stod(args[2]);
+  } catch (std::invalid_argument& ia) {
+    throw std::invalid_argument(std::string("Invalid deadline:") + args[2].c_str());
+  }
+  xbt_assert(deadline > 0, "Wrong deadline supplied");
+
+  stream = simgrid::s4u::this_actor::getHost()->extension<HostBittorrent>()->getStream();
+
+  if (args.size() == 4 && args[3] == "1") {
+    bitfield_       = (1U << FILE_PIECES) - 1U;
+    bitfield_blocks = (1ULL << (FILE_PIECES * PIECES_BLOCKS)) - 1ULL;
+  }
+  pieces_count = new short[FILE_PIECES]{0};
+
+  XBT_INFO("Hi, I'm joining the network with id %d", id);
+}
+
+Peer::~Peer()
+{
+  for (auto peer : connected_peers)
+    delete peer.second;
+  delete[] pieces_count;
+}
+
+/** Peer main function */
+void Peer::operator()()
+{
+  // Getting peer data from the tracker.
+  if (getPeersFromTracker()) {
+    XBT_DEBUG("Got %zu peers from the tracker. Current status is: %s", connected_peers.size(), getStatus().c_str());
+    begin_receive_time = simgrid::s4u::Engine::getClock();
+    mailbox_->setReceiver(simgrid::s4u::Actor::self());
+    if (hasFinished()) {
+      sendHandshakeToAllPeers();
+    } else {
+      leech();
+    }
+    seed();
+  } else {
+    XBT_INFO("Couldn't contact the tracker.");
+  }
+
+  XBT_INFO("Here is my current status: %s", getStatus().c_str());
+}
+
+bool Peer::getPeersFromTracker()
+{
+  simgrid::s4u::MailboxPtr tracker_mailbox = simgrid::s4u::Mailbox::byName(TRACKER_MAILBOX);
+  // Build the task to send to the tracker
+  TrackerQuery* peer_request = new TrackerQuery(id, mailbox_);
+  try {
+    XBT_DEBUG("Sending a peer request to the tracker.");
+    tracker_mailbox->put(peer_request, TRACKER_COMM_SIZE, GET_PEERS_TIMEOUT);
+  } catch (xbt_ex& e) {
+    if (e.category == timeout_error) {
+      XBT_DEBUG("Timeout expired when requesting peers to tracker");
+      delete peer_request;
+      return false;
+    }
+  }
+
+  try {
+    TrackerAnswer* answer = static_cast<TrackerAnswer*>(mailbox_->get(GET_PEERS_TIMEOUT));
+    // Add the peers the tracker gave us to our peer list.
+    for (auto peer_id : *answer->getPeers())
+      if (id != peer_id)
+        connected_peers[peer_id] = new Connection(peer_id);
+    delete answer;
+  } catch (xbt_ex& e) {
+    if (e.category == timeout_error) {
+      XBT_DEBUG("Timeout expired when requesting peers to tracker");
+      return false;
+    }
+  }
+  return true;
+}
+
+void Peer::sendHandshakeToAllPeers()
+{
+  for (auto kv : connected_peers) {
+    Connection* remote_peer = kv.second;
+    Message* handshake      = new Message(MESSAGE_HANDSHAKE, id, mailbox_);
+    remote_peer->mailbox_->put_init(handshake, MESSAGE_HANDSHAKE_SIZE)->detach();
+    XBT_DEBUG("Sending a HANDSHAKE to %d", remote_peer->id);
+  }
+}
+
+void Peer::sendMessage(simgrid::s4u::MailboxPtr mailbox, e_message_type type, uint64_t size)
+{
+  const char* type_names[6] = {"HANDSHAKE", "CHOKE", "UNCHOKE", "INTERESTED", "NOTINTERESTED", "CANCEL"};
+  XBT_DEBUG("Sending %s to %s", type_names[type], mailbox->getName());
+  mailbox->put_init(new Message(type, id, bitfield_, mailbox_), size)->detach();
+}
+
+void Peer::sendBitfield(simgrid::s4u::MailboxPtr mailbox)
+{
+  XBT_DEBUG("Sending a BITFIELD to %s", mailbox->getName());
+  mailbox
+      ->put_init(new Message(MESSAGE_BITFIELD, id, bitfield_, mailbox_),
+                 MESSAGE_BITFIELD_SIZE + BITS_TO_BYTES(FILE_PIECES))
+      ->detach();
+}
+
+void Peer::sendPiece(simgrid::s4u::MailboxPtr mailbox, unsigned int piece, int block_index, int block_length)
+{
+  xbt_assert(not hasNotPiece(piece), "Tried to send a unavailable piece.");
+  XBT_DEBUG("Sending the PIECE %u (%d,%d) to %s", piece, block_index, block_length, mailbox->getName());
+  mailbox->put_init(new Message(MESSAGE_PIECE, id, mailbox_, piece, block_index, block_length), BLOCK_SIZE)->detach();
+}
+
+void Peer::sendHaveToAllPeers(unsigned int piece)
+{
+  XBT_DEBUG("Sending HAVE message to all my peers");
+  for (auto kv : connected_peers) {
+    Connection* remote_peer = kv.second;
+    remote_peer->mailbox_->put_init(new Message(MESSAGE_HAVE, id, mailbox_, piece), MESSAGE_HAVE_SIZE)->detach();
+  }
+}
+
+void Peer::sendRequestTo(Connection* remote_peer, unsigned int piece)
+{
+  remote_peer->current_piece = piece;
+  xbt_assert(remote_peer->hasPiece(piece));
+  int block_index = getFirstMissingBlockFrom(piece);
+  if (block_index != -1) {
+    int block_length = MIN(BLOCKS_REQUESTED, PIECES_BLOCKS - block_index);
+    XBT_DEBUG("Sending a REQUEST to %s for piece %u (%d,%d)", remote_peer->mailbox_->getName(), piece, block_index,
+              block_length);
+    remote_peer->mailbox_
+        ->put_init(new Message(MESSAGE_REQUEST, id, mailbox_, piece, block_index, block_length), MESSAGE_REQUEST_SIZE)
+        ->detach();
+  }
+}
+
+std::string Peer::getStatus()
+{
+  std::string res = std::string("");
+  for (int i = FILE_PIECES - 1; i >= 0; i--)
+    res = std::string((bitfield_ & (1U << i)) ? "1" : "0") + res;
+  return res;
+}
+
+bool Peer::hasFinished()
+{
+  return bitfield_ == (1U << FILE_PIECES) - 1U;
+}
+
+/** Indicates if the remote peer has a piece not stored by the local peer */
+bool Peer::isInterestedBy(Connection* remote_peer)
+{
+  return remote_peer->bitfield & (bitfield_ ^ ((1 << FILE_PIECES) - 1));
+}
+
+bool Peer::isInterestedByFree(Connection* remote_peer)
+{
+  for (unsigned int i = 0; i < FILE_PIECES; i++)
+    if (hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i))
+      return true;
+  return false;
+}
+
+void Peer::updatePiecesCountFromBitfield(unsigned int bitfield)
+{
+  for (unsigned int i = 0; i < FILE_PIECES; i++)
+    if (bitfield & (1U << i))
+      pieces_count[i]++;
+}
+
+unsigned int Peer::countPieces(unsigned int bitfield)
+{
+  unsigned int count = 0U;
+  unsigned int n     = bitfield;
+  while (n) {
+    count += n & 1U;
+    n >>= 1U;
+  }
+  return count;
+}
+
+int Peer::nbInterestedPeers()
+{
+  int nb = 0;
+  for (auto kv : connected_peers)
+    if (kv.second->interested)
+      nb++;
+  return nb;
+}
+
+void Peer::leech()
+{
+  double next_choked_update = simgrid::s4u::Engine::getClock() + UPDATE_CHOKED_INTERVAL;
+  XBT_DEBUG("Start downloading.");
+
+  /* Send a "handshake" message to all the peers it got (since it couldn't have gotten more than 50 peers) */
+  sendHandshakeToAllPeers();
+  XBT_DEBUG("Starting main leech loop listening on mailbox: %s", mailbox_->getName());
+
+  void* data = nullptr;
+  while (simgrid::s4u::Engine::getClock() < deadline && countPieces(bitfield_) < FILE_PIECES) {
+    if (comm_received == nullptr) {
+      comm_received = mailbox_->get_async(&data);
+    }
+    if (comm_received->test()) {
+      message = static_cast<Message*>(data);
+      handleMessage();
+      delete message;
+      comm_received = nullptr;
+    } else {
+      // We don't execute the choke algorithm if we don't already have a piece
+      if (simgrid::s4u::Engine::getClock() >= next_choked_update && countPieces(bitfield_) > 0) {
+        updateChokedPeers();
+        next_choked_update += UPDATE_CHOKED_INTERVAL;
+      } else {
+        simgrid::s4u::this_actor::sleep_for(SLEEP_DURATION);
+      }
+    }
+  }
+  if (hasFinished())
+    XBT_DEBUG("%d becomes a seeder", id);
+}
+
+void Peer::seed()
+{
+  double next_choked_update = simgrid::s4u::Engine::getClock() + UPDATE_CHOKED_INTERVAL;
+  XBT_DEBUG("Start seeding.");
+  // start the main seed loop
+  void* data = nullptr;
+  while (simgrid::s4u::Engine::getClock() < deadline) {
+    if (comm_received == nullptr) {
+      comm_received = mailbox_->get_async(&data);
+    }
+    if (comm_received->test()) {
+      message = static_cast<Message*>(data);
+      handleMessage();
+      delete message;
+      comm_received = nullptr;
+    } else {
+      if (simgrid::s4u::Engine::getClock() >= next_choked_update) {
+        updateChokedPeers();
+        // TODO: Change the choked peer algorithm when seeding.
+        next_choked_update += UPDATE_CHOKED_INTERVAL;
+      } else {
+        simgrid::s4u::this_actor::sleep_for(SLEEP_DURATION);
+      }
+    }
+  }
+}
+
+void Peer::updateActivePeersSet(Connection* remote_peer)
+{
+  if (remote_peer->interested && not remote_peer->choked_upload)
+    active_peers.insert(remote_peer);
+  else
+    active_peers.erase(remote_peer);
+}
+
+void Peer::handleMessage()
+{
+  const char* type_names[10] = {"HANDSHAKE", "CHOKE",    "UNCHOKE", "INTERESTED", "NOTINTERESTED",
+                                "HAVE",      "BITFIELD", "REQUEST", "PIECE",      "CANCEL"};
+
+  XBT_DEBUG("Received a %s message from %s", type_names[message->type], message->return_mailbox->getName());
+
+  auto known_peer         = connected_peers.find(message->peer_id);
+  Connection* remote_peer = (known_peer == connected_peers.end()) ? nullptr : known_peer->second;
+  xbt_assert(remote_peer != nullptr || message->type == MESSAGE_HANDSHAKE,
+             "The impossible did happened: A not-in-our-list peer sent us a message.");
+
+  switch (message->type) {
+    case MESSAGE_HANDSHAKE:
+      // Check if the peer is in our connection list.
+      if (remote_peer == nullptr) {
+        XBT_DEBUG("This peer %d was unknown, answer to its handshake", message->peer_id);
+        connected_peers[message->peer_id] = new Connection(message->peer_id);
+        sendMessage(message->return_mailbox, MESSAGE_HANDSHAKE, MESSAGE_HANDSHAKE_SIZE);
+      }
+      // Send our bitfield to the peer
+      sendBitfield(message->return_mailbox);
+      break;
+    case MESSAGE_BITFIELD:
+      // Update the pieces list
+      updatePiecesCountFromBitfield(message->bitfield);
+      // Store the bitfield
+      remote_peer->bitfield = message->bitfield;
+      xbt_assert(not remote_peer->am_interested, "Should not be interested at first");
+      if (isInterestedBy(remote_peer)) {
+        remote_peer->am_interested = true;
+        sendMessage(message->return_mailbox, MESSAGE_INTERESTED, MESSAGE_INTERESTED_SIZE);
+      }
+      break;
+    case MESSAGE_INTERESTED:
+      // Update the interested state of the peer.
+      remote_peer->interested = true;
+      updateActivePeersSet(remote_peer);
+      break;
+    case MESSAGE_NOTINTERESTED:
+      remote_peer->interested = false;
+      updateActivePeersSet(remote_peer);
+      break;
+    case MESSAGE_UNCHOKE:
+      xbt_assert(remote_peer->choked_download);
+      remote_peer->choked_download = false;
+      // Send requests to the peer, since it has unchoked us
+      if (remote_peer->am_interested)
+        requestNewPieceTo(remote_peer);
+      break;
+    case MESSAGE_CHOKE:
+      xbt_assert(not remote_peer->choked_download);
+      remote_peer->choked_download = true;
+      if (remote_peer->current_piece != -1)
+        removeCurrentPiece(remote_peer, remote_peer->current_piece);
+      break;
+    case MESSAGE_HAVE:
+      XBT_DEBUG("\t for piece %d", message->piece);
+      xbt_assert((message->piece >= 0 && static_cast<unsigned int>(message->piece) < FILE_PIECES),
+                 "Wrong HAVE message received");
+      remote_peer->bitfield = remote_peer->bitfield | (1U << static_cast<unsigned int>(message->piece));
+      pieces_count[message->piece]++;
+      // If the piece is in our pieces, we tell the peer that we are interested.
+      if (not remote_peer->am_interested && hasNotPiece(message->piece)) {
+        remote_peer->am_interested = true;
+        sendMessage(message->return_mailbox, MESSAGE_INTERESTED, MESSAGE_INTERESTED_SIZE);
+        if (not remote_peer->choked_download)
+          requestNewPieceTo(remote_peer);
+      }
+      break;
+    case MESSAGE_REQUEST:
+      xbt_assert(remote_peer->interested);
+      xbt_assert((message->piece >= 0 && static_cast<unsigned int>(message->piece) < FILE_PIECES),
+                 "Wrong HAVE message received");
+      if (not remote_peer->choked_upload) {
+        XBT_DEBUG("\t for piece %d (%d,%d)", message->piece, message->block_index,
+                  message->block_index + message->block_length);
+        if (not hasNotPiece(message->piece)) {
+          sendPiece(message->return_mailbox, message->piece, message->block_index, message->block_length);
+        }
+      } else {
+        XBT_DEBUG("\t for piece %d but he is choked.", message->peer_id);
+      }
+      break;
+    case MESSAGE_PIECE:
+      XBT_DEBUG(" \t for piece %d (%d,%d)", message->piece, message->block_index,
+                message->block_index + message->block_length);
+      xbt_assert(not remote_peer->choked_download);
+      xbt_assert(remote_peer->am_interested || ENABLE_END_GAME_MODE,
+                 "Can't received a piece if I'm not interested without end-game mode!"
+                 "piece (%d) bitfield (%u) remote bitfield (%u)",
+                 message->piece, bitfield_, remote_peer->bitfield);
+      xbt_assert(not remote_peer->choked_download, "Can't received a piece if I'm choked !");
+      xbt_assert((message->piece >= 0 && static_cast<unsigned int>(message->piece) < FILE_PIECES),
+                 "Wrong piece received");
+      // TODO: Execute a computation.
+      if (hasNotPiece(static_cast<unsigned int>(message->piece))) {
+        updateBitfieldBlocks(message->piece, message->block_index, message->block_length);
+        if (hasCompletedPiece(static_cast<unsigned int>(message->piece))) {
+          // Removing the piece from our piece list
+          removeCurrentPiece(remote_peer, message->piece);
+          // Setting the fact that we have the piece
+          bitfield_ = bitfield_ | (1U << static_cast<unsigned int>(message->piece));
+          XBT_DEBUG("My status is now %s", getStatus().c_str());
+          // Sending the information to all the peers we are connected to
+          sendHaveToAllPeers(message->piece);
+          // sending UNINTERESTED to peers that do not have what we want.
+          updateInterestedAfterReceive();
+        } else {                                      // piece not completed
+          sendRequestTo(remote_peer, message->piece); // ask for the next block
+        }
+      } else {
+        XBT_DEBUG("However, we already have it");
+        xbt_assert(ENABLE_END_GAME_MODE, "Should not happen because we don't use end game mode !");
+        requestNewPieceTo(remote_peer);
+      }
+      break;
+    case MESSAGE_CANCEL:
+      break;
+    default:
+      THROW_IMPOSSIBLE;
+  }
+  // Update the peer speed.
+  if (remote_peer) {
+    remote_peer->addSpeedValue(1.0 / (simgrid::s4u::Engine::getClock() - begin_receive_time));
+  }
+  begin_receive_time = simgrid::s4u::Engine::getClock();
+}
+
+/** Selects the appropriate piece to download and requests it to the remote_peer */
+void Peer::requestNewPieceTo(Connection* remote_peer)
+{
+  int piece = selectPieceToDownload(remote_peer);
+  if (piece != -1) {
+    current_pieces |= (1U << (unsigned int)piece);
+    sendRequestTo(remote_peer, piece);
+  }
+}
+
+void Peer::removeCurrentPiece(Connection* remote_peer, unsigned int current_piece)
+{
+  current_pieces &= ~(1U << current_piece);
+  remote_peer->current_piece = -1;
+}
+
+/** @brief Return the piece to be downloaded
+ * There are two cases (as described in "Bittorrent Architecture Protocol", Ryan Toole :
+ * If a piece is partially downloaded, this piece will be selected prioritarily
+ * If the peer has strictly less than 4 pieces, he chooses a piece at random.
+ * If the peer has more than pieces, he downloads the pieces that are the less replicated (rarest policy).
+ * If all pieces have been downloaded or requested, we select a random requested piece (endgame mode).
+ * @param remote_peer: information about the connection
+ * @return the piece to download if possible. -1 otherwise
+ */
+int Peer::selectPieceToDownload(Connection* remote_peer)
+{
+  int piece = partiallyDownloadedPiece(remote_peer);
+  // strict priority policy
+  if (piece != -1)
+    return piece;
+
+  // end game mode
+  if (countPieces(current_pieces) >= (FILE_PIECES - countPieces(bitfield_)) && isInterestedBy(remote_peer)) {
+#if ENABLE_END_GAME_MODE == 0
+    return -1;
+#endif
+    int nb_interesting_pieces = 0;
+    // compute the number of interesting pieces
+    for (unsigned int i = 0; i < FILE_PIECES; i++)
+      if (hasNotPiece(i) && remote_peer->hasPiece(i))
+        nb_interesting_pieces++;
+
+    xbt_assert(nb_interesting_pieces != 0);
+    // get a random interesting piece
+    int random_piece_index = RngStream_RandInt(stream, 0, nb_interesting_pieces - 1);
+    int current_index      = 0;
+    for (unsigned int i = 0; i < FILE_PIECES; i++) {
+      if (hasNotPiece(i) && remote_peer->hasPiece(i)) {
+        if (random_piece_index == current_index) {
+          piece = i;
+          break;
+        }
+        current_index++;
+      }
+    }
+    xbt_assert(piece != -1);
+    return piece;
+  }
+  // Random first policy
+  if (countPieces(bitfield_) < 4 && isInterestedByFree(remote_peer)) {
+    int nb_interesting_pieces = 0;
+    // compute the number of interesting pieces
+    for (unsigned int i = 0; i < FILE_PIECES; i++)
+      if (hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i))
+        nb_interesting_pieces++;
+    xbt_assert(nb_interesting_pieces != 0);
+    // get a random interesting piece
+    int random_piece_index = RngStream_RandInt(stream, 0, nb_interesting_pieces - 1);
+    int current_index      = 0;
+    for (unsigned int i = 0; i < FILE_PIECES; i++) {
+      if (hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i)) {
+        if (random_piece_index == current_index) {
+          piece = i;
+          break;
+        }
+        current_index++;
+      }
+    }
+    xbt_assert(piece != -1);
+    return piece;
+  } else { // Rarest first policy
+    short min         = SHRT_MAX;
+    int nb_min_pieces = 0;
+    int current_index = 0;
+    // compute the smallest number of copies of available pieces
+    for (unsigned int i = 0; i < FILE_PIECES; i++) {
+      if (pieces_count[i] < min && hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i))
+        min = pieces_count[i];
+    }
+
+    xbt_assert(min != SHRT_MAX || not isInterestedByFree(remote_peer));
+    // compute the number of rarest pieces
+    for (unsigned int i = 0; i < FILE_PIECES; i++)
+      if (pieces_count[i] == min && hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i))
+        nb_min_pieces++;
+
+    xbt_assert(nb_min_pieces != 0 || not isInterestedByFree(remote_peer));
+    // get a random rarest piece
+    int random_rarest_index = RngStream_RandInt(stream, 0, nb_min_pieces - 1);
+    for (unsigned int i = 0; i < FILE_PIECES; i++)
+      if (pieces_count[i] == min && hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i)) {
+        if (random_rarest_index == current_index) {
+          piece = i;
+          break;
+        }
+        current_index++;
+      }
+
+    xbt_assert(piece != -1 || not isInterestedByFree(remote_peer));
+    return piece;
+  }
+}
+
+void Peer::updateChokedPeers()
+{
+  if (nbInterestedPeers() == 0)
+    return;
+  XBT_DEBUG("(%d) update_choked peers %zu active peers", id, active_peers.size());
+  // update the current round
+  round_                  = (round_ + 1) % 3;
+  Connection* chosen_peer = nullptr;
+  // select first active peer and remove it from the set
+  Connection* choked_peer = *(active_peers.begin());
+  active_peers.erase(choked_peer);
+
+  /**If we are currently seeding, we unchoke the peer which has been unchoked the last time.*/
+  if (hasFinished()) {
+    Connection* remote_peer;
+    double unchoke_time = simgrid::s4u::Engine::getClock() + 1;
+    for (auto kv : connected_peers) {
+      remote_peer = kv.second;
+      if (remote_peer->last_unchoke < unchoke_time && remote_peer->interested && remote_peer->choked_upload) {
+        unchoke_time = remote_peer->last_unchoke;
+        chosen_peer  = remote_peer;
+      }
+    }
+  } else {
+    // Random optimistic unchoking
+    if (round_ == 0) {
+      int j = 0;
+      do {
+        // We choose a random peer to unchoke.
+        std::unordered_map<int, Connection*>::iterator chosen_peer_it = connected_peers.begin();
+        std::advance(chosen_peer_it, RngStream_RandInt(stream, 0, connected_peers.size() - 1));
+        chosen_peer = chosen_peer_it->second;
+        if (chosen_peer == nullptr)
+          THROWF(unknown_error, 0, "A peer should have be selected at this point");
+        else if (not chosen_peer->interested || not chosen_peer->choked_upload)
+          chosen_peer = nullptr;
+        else
+          XBT_DEBUG("Nothing to do, keep going");
+        j++;
+      } while (chosen_peer == nullptr && j < MAXIMUM_PEERS);
+    } else {
+      // Use the "fastest download" policy.
+      double fastest_speed = 0.0;
+      for (auto kv : connected_peers) {
+        Connection* remote_peer = kv.second;
+        if (remote_peer->peer_speed > fastest_speed && remote_peer->choked_upload && remote_peer->interested) {
+          chosen_peer   = remote_peer;
+          fastest_speed = remote_peer->peer_speed;
+        }
+      }
+    }
+  }
+
+  if (chosen_peer != nullptr)
+    XBT_DEBUG("(%d) update_choked peers unchoked (%d) ; int (%d) ; choked (%d) ", id, chosen_peer->id,
+              chosen_peer->interested, chosen_peer->choked_upload);
+
+  if (choked_peer != chosen_peer) {
+    if (choked_peer != nullptr) {
+      xbt_assert(not choked_peer->choked_upload, "Tries to choked a choked peer");
+      choked_peer->choked_upload = true;
+      updateActivePeersSet(choked_peer);
+      XBT_DEBUG("(%d) Sending a CHOKE to %d", id, choked_peer->id);
+      sendMessage(choked_peer->mailbox_, MESSAGE_CHOKE, MESSAGE_CHOKE_SIZE);
+    }
+    if (chosen_peer != nullptr) {
+      xbt_assert((chosen_peer->choked_upload), "Tries to unchoked an unchoked peer");
+      chosen_peer->choked_upload = false;
+      active_peers.insert(chosen_peer);
+      chosen_peer->last_unchoke = simgrid::s4u::Engine::getClock();
+      XBT_DEBUG("(%d) Sending a UNCHOKE to %d", id, chosen_peer->id);
+      updateActivePeersSet(chosen_peer);
+      sendMessage(chosen_peer->mailbox_, MESSAGE_UNCHOKE, MESSAGE_UNCHOKE_SIZE);
+    }
+  }
+}
+
+/** @brief Update "interested" state of peers: send "not interested" to peers that don't have any more pieces we want.*/
+void Peer::updateInterestedAfterReceive()
+{
+  for (auto kv : connected_peers) {
+    Connection* remote_peer = kv.second;
+    if (remote_peer->am_interested) {
+      bool interested = false;
+      // Check if the peer still has a piece we want.
+      for (unsigned int i = 0; i < FILE_PIECES; i++)
+        if (hasNotPiece(i) && remote_peer->hasPiece(i)) {
+          interested = true;
+          break;
+        }
+
+      if (not interested) { // no more piece to download from connection
+        remote_peer->am_interested = false;
+        sendMessage(remote_peer->mailbox_, MESSAGE_NOTINTERESTED, MESSAGE_NOTINTERESTED_SIZE);
+      }
+    }
+  }
+}
+
+void Peer::updateBitfieldBlocks(int piece, int block_index, int block_length)
+{
+  xbt_assert((piece >= 0 && static_cast<unsigned int>(piece) <= FILE_PIECES), "Wrong piece.");
+  xbt_assert((block_index >= 0 && static_cast<unsigned int>(block_index) <= PIECES_BLOCKS), "Wrong block : %d.",
+             block_index);
+  for (int i = block_index; i < (block_index + block_length); i++)
+    bitfield_blocks |= (1ULL << static_cast<unsigned int>(piece * PIECES_BLOCKS + i));
+}
+
+bool Peer::hasCompletedPiece(unsigned int piece)
+{
+  for (unsigned int i = 0; i < PIECES_BLOCKS; i++)
+    if (not(bitfield_blocks & 1ULL << (piece * PIECES_BLOCKS + i)))
+      return false;
+  return true;
+}
+
+int Peer::getFirstMissingBlockFrom(int piece)
+{
+  for (unsigned int i = 0; i < PIECES_BLOCKS; i++)
+    if (not(bitfield_blocks & 1ULL << (piece * PIECES_BLOCKS + i)))
+      return i;
+  return -1;
+}
+
+/** Returns a piece that is partially downloaded and stored by the remote peer if any -1 otherwise. */
+int Peer::partiallyDownloadedPiece(Connection* remote_peer)
+{
+  for (unsigned int i = 0; i < FILE_PIECES; i++)
+    if (hasNotPiece(i) && remote_peer->hasPiece(i) && isNotDownloadingPiece(i) && getFirstMissingBlockFrom(i) > 0)
+      return i;
+  return -1;
+}
diff --git a/examples/s4u/app-bittorrent/s4u_peer.hpp b/examples/s4u/app-bittorrent/s4u_peer.hpp
new file mode 100644 (file)
index 0000000..bbbbcdd
--- /dev/null
@@ -0,0 +1,91 @@
+/* Copyright (c) 2012-2017. 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. */
+
+#ifndef BITTORRENT_PEER_HPP
+#define BITTORRENT_PEER_HPP
+#include "s4u_bittorrent.hpp"
+#include <set>
+#include <unordered_map>
+
+class Connection {
+public:
+  int id; // Peer id
+  simgrid::s4u::MailboxPtr mailbox_;
+  unsigned int bitfield = 0U; // Fields
+  //  int messages_count;
+  double peer_speed    = 0;
+  double last_unchoke  = 0;
+  int current_piece    = -1;
+  bool am_interested   = false; // Indicates if we are interested in something the peer has
+  bool interested      = false; // Indicates if the peer is interested in one of our pieces
+  bool choked_upload   = true;  // Indicates if the peer is choked for the current peer
+  bool choked_download = true;  // Indicates if the peer has choked the current peer
+
+  explicit Connection(int id) : id(id), mailbox_(simgrid::s4u::Mailbox::byName(std::to_string(id))){};
+  ~Connection() = default;
+  void addSpeedValue(double speed) { peer_speed = peer_speed * 0.6 + speed * 0.4; }
+  bool hasPiece(unsigned int piece) { return bitfield & 1U << piece; }
+};
+
+class Peer {
+  int id;
+  double deadline;
+  RngStream stream;
+  simgrid::s4u::MailboxPtr mailbox_;
+  std::unordered_map<int, Connection*> connected_peers;
+  std::set<Connection*> active_peers; // active peers list
+
+  unsigned int bitfield_             = 0;       // list of pieces the peer has.
+  unsigned long long bitfield_blocks = 0;       // list of blocks the peer has.
+  short* pieces_count                = nullptr; // number of peers that have each piece.
+  unsigned int current_pieces        = 0;       // current pieces the peer is downloading
+  double begin_receive_time = 0; // time when the receiving communication has begun, useful for calculating host speed.
+  int round_                = 0; // current round for the chocking algorithm.
+
+  simgrid::s4u::CommPtr comm_received = nullptr; // current comm
+  Message* message                    = nullptr; // current message being received
+public:
+  explicit Peer(std::vector<std::string> args);
+  Peer(const Peer&) = delete;
+  ~Peer();
+  void operator()();
+
+  std::string getStatus();
+  bool hasFinished();
+  int nbInterestedPeers();
+  bool isInterestedBy(Connection* remote_peer);
+  bool isInterestedByFree(Connection* remote_peer);
+  void updateActivePeersSet(Connection* remote_peer);
+  void updateInterestedAfterReceive();
+  void updateChokedPeers();
+
+  bool hasNotPiece(unsigned int piece) { return not(bitfield_ & 1U << piece); }
+  bool hasCompletedPiece(unsigned int piece);
+  unsigned int countPieces(unsigned int bitfield);
+  /** Check that a piece is not currently being download by the peer. */
+  bool isNotDownloadingPiece(unsigned int piece) { return not(current_pieces & 1U << piece); }
+  int partiallyDownloadedPiece(Connection* remote_peer);
+  void updatePiecesCountFromBitfield(unsigned int bitfield);
+  void removeCurrentPiece(Connection* remote_peer, unsigned int current_piece);
+  void updateBitfieldBlocks(int piece, int block_index, int block_length);
+  int getFirstMissingBlockFrom(int piece);
+  int selectPieceToDownload(Connection* remote_peer);
+  void requestNewPieceTo(Connection* remote_peer);
+
+  bool getPeersFromTracker();
+  void sendMessage(simgrid::s4u::MailboxPtr mailbox, e_message_type type, uint64_t size);
+  void sendBitfield(simgrid::s4u::MailboxPtr mailbox);
+  void sendPiece(simgrid::s4u::MailboxPtr mailbox, unsigned int piece, int block_index, int block_length);
+  void sendHandshakeToAllPeers();
+  void sendHaveToAllPeers(unsigned int piece);
+  void sendRequestTo(Connection* remote_peer, unsigned int piece);
+
+  void handleMessage();
+  void leech();
+  void seed();
+};
+
+#endif /* BITTORRENT_PEER_HPP */
diff --git a/examples/s4u/app-bittorrent/s4u_tracker.cpp b/examples/s4u/app-bittorrent/s4u_tracker.cpp
new file mode 100644 (file)
index 0000000..7ddd5e0
--- /dev/null
@@ -0,0 +1,70 @@
+/* Copyright (c) 2012-2017. 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 "s4u_tracker.hpp"
+#include <xbt/RngStream.h>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_bt_tracker, "Messages specific for the tracker");
+
+Tracker::Tracker(std::vector<std::string> args)
+{
+  // Checking arguments
+  xbt_assert(args.size() == 2, "Wrong number of arguments for the tracker.");
+  // Retrieving end time
+  try {
+    deadline = std::stod(args[1]);
+  } catch (std::invalid_argument& ia) {
+    throw std::invalid_argument(std::string("Invalid deadline:") + args[1].c_str());
+  }
+  xbt_assert(deadline > 0, "Wrong deadline supplied");
+
+  stream = simgrid::s4u::this_actor::getHost()->extension<HostBittorrent>()->getStream();
+
+  mailbox = simgrid::s4u::Mailbox::byName(TRACKER_MAILBOX);
+
+  XBT_INFO("Tracker launched.");
+}
+
+void Tracker::operator()()
+{
+  simgrid::s4u::CommPtr comm = nullptr;
+  while (simgrid::s4u::Engine::getClock() < deadline) {
+    void* received;
+    if (comm == nullptr)
+      comm = mailbox->get_async(&received);
+    if (comm->test()) {
+      // Retrieve the data sent by the peer.
+      TrackerQuery* tq = static_cast<TrackerQuery*>(received);
+
+      // Add the peer to our peer list, if not already known.
+      if (known_peers.find(tq->getPeerId()) == known_peers.end()) {
+        known_peers.insert(tq->getPeerId());
+      }
+
+      // Sending back peers to the requesting peer
+      TrackerAnswer* ta = new TrackerAnswer(TRACKER_QUERY_INTERVAL);
+      std::set<int>::iterator next_peer;
+      int nb_known_peers = known_peers.size();
+      int max_tries      = MIN(MAXIMUM_PEERS, nb_known_peers);
+      int tried          = 0;
+      while (tried < max_tries) {
+        do {
+          next_peer = known_peers.begin();
+          std::advance(next_peer, RngStream_RandInt(stream, 0, nb_known_peers - 1));
+        } while (ta->getPeers()->find(*next_peer) != ta->getPeers()->end());
+        ta->addPeer(*next_peer);
+        tried++;
+      }
+      tq->getReturnMailbox()->put_init(ta, TRACKER_COMM_SIZE)->detach();
+
+      delete tq;
+      comm = nullptr;
+    } else {
+      simgrid::s4u::this_actor::sleep_for(1);
+    }
+  }
+  XBT_INFO("Tracker is leaving");
+}
diff --git a/examples/s4u/app-bittorrent/s4u_tracker.hpp b/examples/s4u/app-bittorrent/s4u_tracker.hpp
new file mode 100644 (file)
index 0000000..591233f
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (c) 2012-2014, 2017. 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. */
+
+#ifndef BITTORRENT_TRACKER_HPP_
+#define BITTORRENT_TRACKER_HPP_
+
+#include "s4u_bittorrent.hpp"
+#include <set>
+
+class TrackerQuery {
+  int peer_id; // peer id
+  simgrid::s4u::MailboxPtr return_mailbox;
+public:
+  explicit TrackerQuery(int peer_id, simgrid::s4u::MailboxPtr return_mailbox)
+      : peer_id(peer_id), return_mailbox(return_mailbox){};
+  ~TrackerQuery() = default;
+  int getPeerId() { return peer_id; }
+  simgrid::s4u::MailboxPtr getReturnMailbox() { return return_mailbox; }
+};
+
+class TrackerAnswer {
+  XBT_ATTRIB_UNUSED int interval; // how often the peer should contact the tracker (unused for now)
+  std::set<int>* peers; // the peer list the peer has asked for.
+public:
+  explicit TrackerAnswer(int interval) : interval(interval) { peers = new std::set<int>; }
+  TrackerAnswer(const TrackerAnswer&)                               = delete;
+  ~TrackerAnswer() { delete peers; };
+  void addPeer(int peer) { peers->insert(peer); }
+  std::set<int>* getPeers() { return peers; }
+};
+
+class Tracker {
+  double deadline;
+  RngStream stream;
+  simgrid::s4u::MailboxPtr mailbox;
+  std::set<int> known_peers;
+
+public:
+  explicit Tracker(std::vector<std::string> args);
+  void operator()();
+};
+
+#endif /* BITTORRENT_TRACKER_HPP */
index 8e13fc5..04102b7 100644 (file)
@@ -40,17 +40,18 @@ public:
         XBT_INFO("Sending \"%s\" (of %ld) to mailbox \"%s\"", (std::string("Task_") + std::to_string(i)).c_str(),
                  number_of_tasks, mailbox->getName());
 
-      /* - Send the task to the @ref worker */
-      char* payload = bprintf("%f", comp_size);
-      mailbox->put(payload, comm_size);
+      /* - Send the computation amount to the @ref worker */
+      mailbox->put(static_cast<void*>(&comp_size), comm_size);
     }
 
     XBT_INFO("All tasks have been dispatched. Let's tell everybody the computation is over.");
     for (int i = 0; i < workers_count; i++) {
       /* - Eventually tell all the workers to stop by sending a "finalize" task */
       mailbox = simgrid::s4u::Mailbox::byName(std::string("worker-") + std::to_string(i % workers_count));
-      mailbox->put(xbt_strdup("finalize"), 0);
+      double finalize = -1;
+      mailbox->put(static_cast<void*>(&finalize), 0);
     }
+    simgrid::s4u::this_actor::sleep_for(.1); // Grace time to ensure everyone finishes.
   }
 };
 
@@ -70,19 +71,15 @@ public:
   void operator()()
   {
     while (1) { /* The worker waits in an infinite loop for tasks sent by the \ref master */
-      char* res = static_cast<char*>(mailbox->get());
-      xbt_assert(res != nullptr, "MSG_task_get failed");
-
-      if (strcmp(res, "finalize") == 0) { /* - Exit if 'finalize' is received */
-        xbt_free(res);
+      double* comp_size = static_cast<double*>(mailbox->get());
+      xbt_assert(comp_size != nullptr, "MSG_task_get failed");
+      if (*comp_size < 0) { /* - Exit if 'finalize' is received */
+        XBT_INFO("I'm done. See you!");
         break;
       }
       /*  - Otherwise, process the task */
-      double comp_size = std::stod(res);
-      xbt_free(res);
-      simgrid::s4u::this_actor::execute(comp_size);
+      simgrid::s4u::this_actor::execute(*comp_size);
     }
-    XBT_INFO("I'm done. See you!");
   }
 };
 
index f9b20df..ff2092d 100644 (file)
@@ -31,6 +31,6 @@ $ $SG_TEST_EXENV ${bindir:=.}/s4u_app-masterworker$EXEEXT ${srcdir:=.}/small_pla
 > [  4.057541] (worker@Jupiter) I'm done. See you!
 > [  4.083249] (worker@Fafard) I'm done. See you!
 > [  4.931805] (worker@Ginette) I'm done. See you!
-> [  5.094868] (maestro@) Simulation time 5.09487
 > [  5.094868] (worker@Bourassa) I'm done. See you!
+> [  5.194868] (maestro@) Simulation time 5.19487
 
index 378f271..8c60b63 100644 (file)
@@ -16,7 +16,7 @@ public:
     XBT_INFO("Storage info on %s:", simgrid::s4u::Host::current()->getCname());
 
     for (const auto&kv : mounts) {
-      const char* mountpoint = kv.first.c_str();
+      std::string mountpoint         = kv.first;
       simgrid::s4u::Storage* storage = kv.second;
 
       // Retrieve disk's information
@@ -24,8 +24,8 @@ public:
       sg_size_t used_size = storage->getSizeUsed();
       sg_size_t size      = storage->getSize();
 
-      XBT_INFO("    %s (%s) Used: %llu; Free: %llu; Total: %llu.", storage->getName(), mountpoint, used_size, free_size,
-               size);
+      XBT_INFO("    %s (%s) Used: %llu; Free: %llu; Total: %llu.", storage->getName(), mountpoint.c_str(), used_size,
+               free_size, size);
     }
   }
 
@@ -36,11 +36,11 @@ public:
     show_info(mounts);
 
     // Open an non-existing file to create it
-    const char* filename = "/home/tmp/data.txt";
+    std::string filename     = "/home/tmp/data.txt";
     simgrid::s4u::File* file = new simgrid::s4u::File(filename, nullptr);
 
     sg_size_t write = file->write(200000);  // Write 200,000 bytes
-    XBT_INFO("Create a %llu bytes file named '%s' on /sd1", write, filename);
+    XBT_INFO("Create a %llu bytes file named '%s' on /sd1", write, filename.c_str());
 
     // check that sizes have changed
     show_info(mounts);
@@ -49,22 +49,22 @@ public:
     const sg_size_t file_size = file->size();
     file->seek(0);
     const sg_size_t read = file->read(file_size);
-    XBT_INFO("Read %llu bytes on %s", read, filename);
+    XBT_INFO("Read %llu bytes on %s", read, filename.c_str());
 
     // Now write 100,000 bytes in tmp/data.txt
     write = file->write(100000);  // Write 100,000 bytes
-    XBT_INFO("Write %llu bytes on %s", write, filename);
+    XBT_INFO("Write %llu bytes on %s", write, filename.c_str());
 
     simgrid::s4u::Storage* storage = simgrid::s4u::Storage::byName("Disk4");
 
     // Now rename file from ./tmp/data.txt to ./tmp/simgrid.readme
-    const char *newpath = "/home/tmp/simgrid.readme";
-    XBT_INFO("Move '%s' to '%s'", file->getPath(), newpath);
+    std::string newpath = "/home/tmp/simgrid.readme";
+    XBT_INFO("Move '%s' to '%s'", file->getPath(), newpath.c_str());
     file->move(newpath);
 
     // Test attaching some user data to the file
     file->setUserdata(xbt_strdup("777"));
-    XBT_INFO("User data attached to the file: %s", (char*)file->getUserdata());
+    XBT_INFO("User data attached to the file: %s", static_cast<char*>(file->getUserdata()));
     xbt_free(file->getUserdata());
 
     // Close the file
@@ -72,10 +72,10 @@ public:
 
     // Now attach some user data to disk1
     XBT_INFO("Get/set data for storage element: %s", storage->getName());
-    XBT_INFO("    Uninitialized storage data: '%s'", (char*)storage->getUserdata());
+    XBT_INFO("    Uninitialized storage data: '%s'", static_cast<char*>(storage->getUserdata()));
 
     storage->setUserdata(xbt_strdup("Some user data"));
-    XBT_INFO("    Set and get data: '%s'", (char*)storage->getUserdata());
+    XBT_INFO("    Set and get data: '%s'", static_cast<char*>(storage->getUserdata()));
 
     xbt_free(storage->getUserdata());
   }
index 3417134..8caeab7 100644 (file)
@@ -109,6 +109,8 @@ $ cat ${srcdir:=.}/daxload/smalldax.trace
 > [0.016600] node-1.acme.org compute 42000000000.000000 # 1@task1
 > [0.016600] node-10.acme.org compute 42000000000.000000 # 2@task2
 > [42.033200] node-11.acme.org compute 42000000000.000000 # 3@task1
+> [0.000000] node-0.acme.org send node-1.acme.org 1000000.000000 # root_i1_1@task1
+> [0.016600] node-1.acme.org recv node-0.acme.org 1000000.000000 # root_i1_1@task1
 > [0.000000] node-0.acme.org send node-10.acme.org 1000000.000000 # root_i2_2@task2
 > [0.016600] node-10.acme.org recv node-0.acme.org 1000000.000000 # root_i2_2@task2
 > [42.016600] node-1.acme.org send node-11.acme.org 1000000.000000 # 1@task1_o1_3@task1
@@ -117,8 +119,6 @@ $ cat ${srcdir:=.}/daxload/smalldax.trace
 > [42.033200] node-11.acme.org recv node-10.acme.org 1000000.000000 # 2@task2_o2_3@task1
 > [84.033200] node-11.acme.org send node-0.acme.org 4167312.000000 # 3@task1_o3_end
 > [84.067138] node-0.acme.org recv node-11.acme.org 4167312.000000 # 3@task1_o3_end
-> [0.000000] node-0.acme.org send node-1.acme.org 1000000.000000 # root_i1_1@task1
-> [0.016600] node-1.acme.org recv node-0.acme.org 1000000.000000 # root_i1_1@task1
 > [84.067138] node-0.acme.org compute 0.000000 # end
 
 $ cmake -E remove -f ${srcdir:=.}/dax.dot ${srcdir:=.}/daxload/smalldax.trace
index 2e437de..7e8d159 100644 (file)
@@ -38,22 +38,24 @@ int main(int argc, char **argv)
 
 
   /* Print the properties of 'host1' */
-  xbt_dict_foreach(props, cursor, key, data) {
+  xbt_dict_foreach (props, cursor, key, data)
     XBT_INFO("\tProperty: %s has value: %s", key, data);
-  }
 
   /* Try to get a property that does not exist */
   value = sg_host_get_property_value(h1, noexist);
   XBT_INFO("\tProperty: %s has value: %s", noexist, value?value:"Undefined (NULL)");
 
+  xbt_dict_free(&props);
+
   /* Get the property list of 'host2' */
   XBT_INFO("Property list for host %s", name2);
   props = sg_host_get_properties(h2);
 
   /* Print the properties of 'host2' */
-  xbt_dict_foreach(props, cursor, key, data) {
+  xbt_dict_foreach (props, cursor, key, data)
     XBT_INFO("\tProperty: %s on host: %s", key, data);
-  }
+
+  xbt_dict_free(&props);
 
   /* Modify an existing property test. First check it exists */
   XBT_INFO("Modify an existing property");
index 1f9c363..c621759 100644 (file)
@@ -1,5 +1,4 @@
-/* Copyright (c) 2004-2015. The SimGrid Team.
- * All rights reserved.                                                     */
+/* Copyright (c) 2004-2017. 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. */
@@ -404,8 +403,10 @@ XBT_PUBLIC(msg_error_t) MSG_task_receive_bounded(msg_task_t * task, const char *
 XBT_PUBLIC(msg_comm_t) MSG_task_isend(msg_task_t task, const char *alias);
 XBT_PUBLIC(msg_comm_t) MSG_task_isend_bounded(msg_task_t task, const char *alias, double maxrate);
 XBT_PUBLIC(msg_comm_t)
-MSG_task_isend_with_matching(msg_task_t task, const char* alias, int (*match_fun)(void*, void*, void*),
-                             void* match_data);
+XBT_ATTRIB_DEPRECATED_v320(
+    "This function will be removed from SimGrid v3.20. If you really need this function, please speak up quickly.")
+    MSG_task_isend_with_matching(msg_task_t task, const char* alias, int (*match_fun)(void*, void*, void*),
+                                 void* match_data);
 
 XBT_PUBLIC(void) MSG_task_dsend(msg_task_t task, const char *alias, void_f_pvoid_t cleanup);
 XBT_PUBLIC(void) MSG_task_dsend_bounded(msg_task_t task, const char *alias, void_f_pvoid_t cleanup, double maxrate);
@@ -514,9 +515,6 @@ XBT_PUBLIC(void) MSG_vm_set_bound(msg_vm_t vm, double bound);
 /* Used only by the bindings -- unclean pimple, please ignore if you're not writing a binding */
 XBT_PUBLIC(smx_context_t) MSG_process_get_smx_ctx(msg_process_t process);
 
-/* Functions renamed in 3.14 */
-#define MSG_mailbox_get_head(m) MSG_mailbox_front(m)
-
 SG_END_DECL()
 
 #ifdef __cplusplus
index a42beca..e705bab 100644 (file)
@@ -75,7 +75,7 @@ public:
   simgrid::s4u::NetZone* getNetzoneByNameOrNull(const char* name);
 
   /** @brief Retrieve the netcard of the given name (or nullptr if not found) */
-  simgrid::kernel::routing::NetPoint* getNetpointByNameOrNull(const char* name);
+  simgrid::kernel::routing::NetPoint* getNetpointByNameOrNull(std::string name);
   void getNetpointList(std::vector<simgrid::kernel::routing::NetPoint*> * list);
   void netpointRegister(simgrid::kernel::routing::NetPoint * card);
   void netpointUnregister(simgrid::kernel::routing::NetPoint * card);
index 18d2926..cdc9b97 100644 (file)
@@ -25,12 +25,12 @@ namespace s4u {
 XBT_PUBLIC_CLASS File
 {
 public:
-  File(const char* fullpath, void* userdata);
-  File(const char* fullpath, sg_host_t host, void* userdata);
+  File(std::string fullpath, void* userdata);
+  File(std::string fullpath, sg_host_t host, void* userdata);
   ~File();
 
   /** Retrieves the path to the file */
-  const char* getPath() { return path_; }
+  const char* getPath() { return path_.c_str(); }
 
   /** Simulates a local read action. Returns the size of data actually read */
   sg_size_t read(sg_size_t size);
@@ -53,23 +53,21 @@ public:
   /** Retrieves the current file position */
   sg_size_t tell();
 
-  /** Rename a file
-   *
-   * WARNING: It is forbidden to move the file to another mount point */
-  void move(const char* fullpath);
+  /** Rename a file. WARNING: It is forbidden to move the file to another mount point */
+  void move(std::string fullpath);
 
   /** Remove a file from disk */
   int unlink();
 
-  const char* storage_type;
-  const char* storageId;
+  std::string storage_type;
+  std::string storageId;
   std::string mount_point;
   int desc_id = 0;
 
 private:
   surf_file_t pimpl_ = nullptr;
-  const char* path_  = nullptr;
-  void* userdata_    = nullptr;
+  std::string path_;
+  void* userdata_ = nullptr;
 };
 }
 } // namespace simgrid::s4u
index 3c8691e..30c932e 100644 (file)
@@ -11,7 +11,6 @@
 #include <unordered_map>
 
 #include "xbt/Extendable.hpp"
-#include "xbt/dict.h"
 #include "xbt/signal.hpp"
 #include "xbt/string.hpp"
 #include "xbt/swag.h"
index fa5ca04..0f50b37 100644 (file)
@@ -38,13 +38,13 @@ XBT_PUBLIC_CLASS NetZone
 protected:
   friend simgrid::kernel::routing::NetZoneImpl;
 
-  explicit NetZone(NetZone * father, const char* name);
+  explicit NetZone(NetZone * father, std::string name);
   virtual ~NetZone();
 
 public:
   /** @brief Seal your netzone once you're done adding content, and before routing stuff through it */
   virtual void seal();
-  char* getCname();
+  const char* getCname();
   NetZone* getFather();
 
   std::vector<NetZone*>* getChildren();             // Sub netzones
@@ -80,7 +80,7 @@ private:
 
   std::unordered_map<std::string, std::string> properties_;
   NetZone* father_ = nullptr;
-  char* name_      = nullptr;
+  std::string name_;
 
   bool sealed_ = false; // We cannot add more content when sealed
 
index 38e30b7..efad7b8 100644 (file)
@@ -28,7 +28,7 @@ public:
   explicit Storage(surf::StorageImpl * pimpl) : pimpl_(pimpl) {}
   virtual ~Storage() = default;
   /** Retrieve a Storage by its name. It must exist in the platform file */
-  static Storage* byName(const char* name);
+  static Storage* byName(std::string name);
   const char* getName();
   const char* getType();
   Host* getHost();
index b5dbf21..4453039 100644 (file)
@@ -45,6 +45,7 @@ private:
   virtual ~VirtualMachine();
 
 public:
+  void start();
   bool isMigrating();
 
   void getParameters(vm_params_t params);
index 44e2635..de1ac3a 100644 (file)
@@ -72,9 +72,7 @@ extern int smx_context_guard_size_was_set;
 
 SG_BEGIN_DECL()
 
-XBT_PUBLIC(xbt_dynar_t) SIMIX_process_get_runnable();
 XBT_PUBLIC(smx_actor_t) SIMIX_process_from_PID(aid_t PID);
-XBT_PUBLIC(xbt_dynar_t) SIMIX_processes_as_dynar();
 
 /* parallelism */
 XBT_PUBLIC(int) SIMIX_context_is_parallel();
@@ -201,7 +199,6 @@ XBT_PUBLIC(smx_actor_t)
 simcall_process_create(const char* name, xbt_main_func_t code, void* data, sg_host_t host, int argc, char** argv,
                        std::map<std::string, std::string>* properties);
 
-XBT_PUBLIC(void) simcall_process_kill(smx_actor_t process);
 XBT_PUBLIC(void) simcall_process_killall(int reset_pid);
 XBT_PUBLIC(void) SIMIX_process_throw(smx_actor_t process, xbt_errcat_t cat, int value, const char *msg);
 
index eb7e26b..f21fa3d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007-2010, 2012-2015. The SimGrid Team.
+/* Copyright (c) 2007-2010, 2012-2017. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
@@ -69,6 +69,7 @@ typename std::result_of<F()>::type kernelImmediate(F&& code)
   return result.get();
 }
 
+XBT_PUBLIC(const std::vector<smx_actor_t>&) process_get_runnable();
 
 XBT_PUBLIC(void) set_maestro(std::function<void()> code);
 XBT_PUBLIC(void) create_maestro(std::function<void()> code);
diff --git a/include/xbt/algorithm.hpp b/include/xbt/algorithm.hpp
new file mode 100644 (file)
index 0000000..1a91452
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (c) 2015-2017. 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. */
+
+#ifndef XBT_ALGORITHM_HPP
+#define XBT_ALGORITHM_HPP
+
+namespace simgrid {
+namespace xbt {
+
+/** @brief Sorts the elements of the sequence [first, last) according to their color assuming elements can have only
+ * three colors.  Since there are only three colors, it is linear and much faster than a classical sort.  See for
+ * example http://en.wikipedia.org/wiki/Dutch_national_flag_problem
+ *
+ * \param first forward iterators to the initial position of the sequence to partition.
+ * \param last forward iterators to the final position of the sequence to partition.
+ * \param color the color function that accepts an element in the range as argument, and returns a value of 0, 1, or 2.
+ *
+ * At the end of the call, elements with color 0 are at the beginning of the range, elements with color 2 are at the end
+ * and elements with color 1 are in the middle.
+ */
+template <class ForwardIterator, class ColorFunction>
+void three_way_partition(ForwardIterator first, ForwardIterator last, ColorFunction color)
+{
+  ForwardIterator iter = first;
+  while (iter < last) {
+    int c = color(*iter);
+    if (c == 1) {
+      ++iter;
+    } else if (c == 0) {
+      if (iter != first)
+        std::swap(*iter, *first);
+      ++iter;
+      ++first;
+    } else { // c == 2
+      --last;
+      if (iter != last)
+        std::swap(*iter, *last);
+    }
+  }
+}
+}
+}
+
+#endif
index 86751e8..5484ccd 100644 (file)
@@ -93,7 +93,6 @@ XBT_PUBLIC(signed int) xbt_dynar_search_or_negative(xbt_dynar_t const dynar, voi
 XBT_PUBLIC(int) xbt_dynar_member(xbt_dynar_t const dynar, void *elem);
 XBT_PUBLIC(void) xbt_dynar_sort(xbt_dynar_t const dynar, int_f_cpvoid_cpvoid_t compar_fn);
 XBT_PUBLIC(xbt_dynar_t) xbt_dynar_sort_strings(xbt_dynar_t dynar);
-XBT_PUBLIC(void) xbt_dynar_three_way_partition(xbt_dynar_t const dynar, int_f_pvoid_t color);
 XBT_PUBLIC(int) xbt_dynar_compare(xbt_dynar_t d1, xbt_dynar_t d2, int(*compar)(const void *, const void *));
 XBT_PUBLIC(void *) xbt_dynar_to_array (xbt_dynar_t dynar);
 
index 77bb871..d9f77b5 100644 (file)
@@ -1,11 +1,11 @@
-/* Copyright (c) 2004-2007, 2009-2015. The SimGrid Team.
+/* Copyright (c) 2004-2007, 2009-2017. 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. */
 
-#ifndef SIMGRId_XBT_DYNAR_HPP
-#define SIMGRId_XBT_DYNAR_HPP
+#ifndef SIMGRID_XBT_DYNAR_HPP
+#define SIMGRID_XBT_DYNAR_HPP
 
 #include <boost/range/iterator_range.hpp>
 #include <xbt/asserts.h>
index 03aec81..f9883a5 100644 (file)
@@ -1,7 +1,6 @@
 /* function_type.h - classical types for pointer to function                */
 
-/* Copyright (c) 2006-2007, 2009-2010, 2012-2015. The SimGrid Team.
- * All rights reserved.                                                     */
+/* Copyright (c) 2006-2017. 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. */
@@ -18,8 +17,6 @@ typedef void *(*pvoid_f_void_t) (void);
 typedef void *(*pvoid_f_pvoid_t) (void *);
 typedef void (*void_f_void_t) (void);
 
-typedef int (*int_f_pvoid_t) (void*);
-
 typedef int (*int_f_pvoid_pvoid_t) (void *, void *);
 typedef int (*int_f_cpvoid_cpvoid_t) (const void *, const void *);
 
index 905b12c..d12a2f2 100644 (file)
@@ -1,6 +1,6 @@
 /* A thread pool.                                          */
 
-/* Copyright (c) 2007, 2009-2014. The SimGrid Team.
+/* Copyright (c) 2007, 2009-2014, 2016-2017. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
@@ -9,28 +9,19 @@
 #ifndef XBT_PARMAP_H
 #define XBT_PARMAP_H
 
-#include "xbt/misc.h"           /* SG_BEGIN_DECL */
-#include "xbt/function_types.h"
-#include "xbt/dynar.h"
-
-SG_BEGIN_DECL()
-
 /** \addtogroup XBT_parmap
   * \ingroup XBT_misc
   * \brief Parallel map.
   *
-  * A function is applied to all elements of a dynar in parallel with n worker threads.
-  * The worker threads are persistent until the destruction of the parmap.
+  * A function is applied to all elements of a std::vector in parallel with n worker threads.  The worker threads are
+  * persistent until the destruction of the parmap.
   *
-  * If there are more than n elements in the dynar, the worker threads are allowed to fetch themselves remaining work
-  * with xbt_parmap_next() and execute it.
+  * If there are more than n elements in the vector, the worker threads are allowed to fetch themselves remaining work
+  * with method next() and execute it.
   *
   * \{
   */
 
-/** \brief Parallel map data type (opaque type) */
-typedef struct s_xbt_parmap *xbt_parmap_t;
-
 /** \brief Synchronization mode of the worker threads of a parmap. */
 typedef enum {
   XBT_PARMAP_POSIX,          /**< use POSIX synchronization primitives */
@@ -39,13 +30,6 @@ typedef enum {
   XBT_PARMAP_DEFAULT         /**< futex if available, posix otherwise */
 } e_xbt_parmap_mode_t;
 
-XBT_PUBLIC(xbt_parmap_t) xbt_parmap_new(unsigned int num_workers, e_xbt_parmap_mode_t mode);
-XBT_PUBLIC(void) xbt_parmap_destroy(xbt_parmap_t parmap);
-XBT_PUBLIC(void) xbt_parmap_apply(xbt_parmap_t parmap, void_f_pvoid_t fun, xbt_dynar_t data);
-XBT_PUBLIC(void*) xbt_parmap_next(xbt_parmap_t parmap);
-
 /** \} */
 
-SG_END_DECL()
-
 #endif
index e39a7b9..c796b18 100644 (file)
@@ -47,10 +47,7 @@ JavaContext* JavaContextFactory::create_context(
 
 void JavaContextFactory::run_all()
 {
-  xbt_dynar_t processes = SIMIX_process_get_runnable();
-  smx_actor_t process;
-  unsigned int cursor;
-  xbt_dynar_foreach(processes, cursor, process) {
+  for (smx_actor_t process : simgrid::simix::process_get_runnable()) {
     static_cast<JavaContext*>(process->context)->resume();
   }
 }
index 8d52bfe..47f14d6 100644 (file)
@@ -10,6 +10,8 @@
 #include "jmsg.h"
 
 #include <simgrid/msg.h>
+#include <string>
+
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(java);
 
 SG_BEGIN_DECL()
@@ -79,7 +81,7 @@ JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_Comm_test(JNIEnv *env, jobject j
   }
 
   if (not comm) {
-    jxbt_throw_null(env, bprintf("comm is null"));
+    jxbt_throw_null(env, "comm is null");
     return JNI_FALSE;
   }
 
@@ -99,7 +101,7 @@ JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_Comm_test(JNIEnv *env, jobject j
 JNIEXPORT void JNICALL Java_org_simgrid_msg_Comm_waitCompletion(JNIEnv *env, jobject jcomm, jdouble timeout) {
   msg_comm_t comm = (msg_comm_t) (uintptr_t) env->GetLongField(jcomm, jcomm_field_Comm_bind);
   if (not comm) {
-    jxbt_throw_null(env, bprintf("comm is null"));
+    jxbt_throw_null(env, "comm is null");
     return;
   }
 
@@ -130,7 +132,7 @@ static msg_comm_t* jarray_to_commArray(JNIEnv *env, jobjectArray jcomms, /* OUT
 
      comms[i] = (msg_comm_t) (uintptr_t) env->GetLongField(jcomm, jcomm_field_Comm_bind);
      if (not comms[i]) {
-       jxbt_throw_null(env, bprintf("comm at rank %d is null", i));
+       jxbt_throw_null(env, std::string("comm at rank ") + std::to_string(i) + " is null");
        return nullptr;
      }
 
index e2208b3..28804e7 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "simgrid/plugins/energy.h"
 #include "simgrid/s4u/Host.hpp"
+#include "simgrid/s4u/Storage.hpp"
 
 #include "jmsg.h"
 #include "jmsg_host.h"
@@ -55,7 +56,7 @@ JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Host_getByName(JNIEnv * env, jcla
 
   /* get the C string from the java string */
   if (jname == nullptr) {
-    jxbt_throw_null(env,bprintf("No host can have a null name"));
+    jxbt_throw_null(env, "No host can have a null name");
     return nullptr;
   }
   const char *name = env->GetStringUTFChars(jname, 0);
@@ -237,8 +238,8 @@ JNIEXPORT jobjectArray JNICALL Java_org_simgrid_msg_Host_getMountedStorage(JNIEn
 
   int index = 0;
   jobjectArray jtable;
-  xbt_dict_t dict =  MSG_host_get_mounted_storage_list(host);
-  int count = xbt_dict_length(dict);
+  std::unordered_map<std::string, msg_storage_t> mounted_storages = host->getMountedStorages();
+  int count  = mounted_storages.size();
   jclass cls = env->FindClass("org/simgrid/msg/Storage");
 
   jtable = env->NewObjectArray((jsize) count, cls, nullptr);
@@ -248,17 +249,12 @@ JNIEXPORT jobjectArray JNICALL Java_org_simgrid_msg_Host_getMountedStorage(JNIEn
     return nullptr;
   }
 
-  xbt_dict_cursor_t cursor=nullptr;
-  const char* mount_name;
-  const char* storage_name;
-
-  xbt_dict_foreach(dict,cursor,mount_name,storage_name) {
-    jname = env->NewStringUTF(storage_name);
+  for (auto elm : mounted_storages) {
+    jname    = env->NewStringUTF(elm.second->getName());
     jstorage = Java_org_simgrid_msg_Storage_getByName(env,cls,jname);
     env->SetObjectArrayElement(jtable, index, jstorage);
     index++;
   }
-  xbt_dict_free(&dict);
   return jtable;
 }
 
index 184e259..000d1d4 100644 (file)
@@ -101,7 +101,7 @@ JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_fromPID(JNIEnv * env, jcl
   msg_process_t process = MSG_process_from_PID(pid);
 
   if (not process) {
-    jxbt_throw_process_not_found(env, bprintf("PID = %d",static_cast<int>(pid)));
+    jxbt_throw_process_not_found(env, std::string("PID = ") + std::to_string(static_cast<int>(pid)));
     return nullptr;
   }
 
@@ -156,7 +156,7 @@ JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_suspend(JNIEnv * env, jobjec
   /* try to suspend the process */
   msg_error_t rv = MSG_process_suspend(process);
 
-  jxbt_check_res("MSG_process_suspend()", rv, MSG_OK, bprintf("unexpected error , please report this bug"));
+  jxbt_check_res("MSG_process_suspend()", rv, MSG_OK, "unexpected error , please report this bug");
 }
 
 JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_resume(JNIEnv * env, jobject jprocess)
@@ -170,7 +170,7 @@ JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_resume(JNIEnv * env, jobject
 
   /* try to resume the process */
   msg_error_t res = MSG_process_resume(process);
-  jxbt_check_res("MSG_process_resume()", res, MSG_OK, bprintf("unexpected error , please report this bug"));
+  jxbt_check_res("MSG_process_resume()", res, MSG_OK, "unexpected error , please report this bug");
 }
 
 JNIEXPORT void
index 2d3a029..7b5003f 100644 (file)
@@ -56,7 +56,7 @@ JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Storage_getByName(JNIEnv * env, j
 
   /* get the C string from the java string */
   if (jname == nullptr) {
-    jxbt_throw_null(env,bprintf("No host can have a null name"));
+    jxbt_throw_null(env, "No host can have a null name");
     return nullptr;
   }
   const char *name = env->GetStringUTFChars(jname, 0);
index 47dfe47..eb5ca2d 100644 (file)
@@ -112,7 +112,7 @@ JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_cancel(JNIEnv * env, jobject jt
 
   msg_error_t rv = MSG_task_cancel(ptask);
 
-  jxbt_check_res("MSG_task_cancel()", rv, MSG_OK, bprintf("unexpected error , please report this bug"));
+  jxbt_check_res("MSG_task_cancel()", rv, MSG_OK, "unexpected error , please report this bug");
 }
 
 JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_execute(JNIEnv * env, jobject jtask)
index d7e9ea1..b570d72 100644 (file)
@@ -174,7 +174,7 @@ JNIEXPORT jobject JNICALL Java_org_simgrid_msg_VM_getVMByName(JNIEnv* env, jclas
 
   /* get the C string from the java string */
   if (jname == nullptr) {
-    jxbt_throw_null(env, bprintf("No VM can have a null name"));
+    jxbt_throw_null(env, "No VM can have a null name");
     return nullptr;
   }
   const char* name = env->GetStringUTFChars(jname, 0);
index c0b812c..f0ca438 100644 (file)
@@ -1,5 +1,4 @@
-/* Copyright (c) 2010, 2012-2017. The SimGrid Team.
- * All rights reserved.                                                     */
+/* Copyright (c) 2010-2017. 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. */
@@ -20,7 +19,7 @@ extern "C" {
 #include "src/surf/surf_private.h"
 #include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/split.hpp>
-#include <simgrid/host.h>
+#include <simgrid/s4u/Host.hpp>
 #include <string>
 #include <vector>
 
@@ -102,18 +101,16 @@ int console_add_backbone(lua_State *L) {
   }
 
   sg_platf_new_link(&link);
-  routing_cluster_add_backbone(simgrid::surf::LinkImpl::byName(link.id.c_str()));
+  routing_cluster_add_backbone(simgrid::surf::LinkImpl::byName(link.id));
 
   return 0;
 }
 
 int console_add_host___link(lua_State *L) {
-  s_sg_platf_host_link_cbarg_t hostlink;
-  memset(&hostlink,0,sizeof(hostlink));
+  HostLinkCreationArgs hostlink;
   int type;
 
-  lua_ensure(lua_istable(L, -1),
-      "Bad Arguments to create host_link in Lua. Should be a table with named arguments.");
+  lua_ensure(lua_istable(L, -1), "Bad Arguments to create host_link in Lua. Should be a table with named arguments.");
 
   lua_pushstring(L, "id");
   type = lua_gettable(L, -2);
@@ -135,7 +132,7 @@ int console_add_host___link(lua_State *L) {
   hostlink.link_down = lua_tostring(L, -1);
   lua_pop(L, 1);
 
-  XBT_DEBUG("Create a host_link for host %s", hostlink.id);
+  XBT_DEBUG("Create a host_link for host %s", hostlink.id.c_str());
   sg_platf_new_hostlink(&hostlink);
 
   return 0;
@@ -285,8 +282,7 @@ int  console_add_link(lua_State *L) {
  * add Router to AS components
  */
 int console_add_router(lua_State* L) {
-  lua_ensure(lua_istable(L, -1),
-      "Bad Arguments to create router, Should be a table with named arguments");
+  lua_ensure(lua_istable(L, -1), "Bad Arguments to create router, Should be a table with named arguments");
 
   lua_pushstring(L, "id");
   int type = lua_gettable(L, -2);
@@ -343,7 +339,7 @@ int console_add_route(lua_State *L) {
     // Several names separated by , \t\r\n
     for (auto name : names) {
       if (name.length() > 0) {
-        simgrid::surf::LinkImpl* link = simgrid::surf::LinkImpl::byName(name.c_str());
+        simgrid::surf::LinkImpl* link = simgrid::surf::LinkImpl::byName(name);
         route.link_list->push_back(link);
       }
     }
@@ -424,7 +420,7 @@ int console_add_ASroute(lua_State *L) {
     // Several names separated by , \t\r\n
     for (auto name : names) {
       if (name.length() > 0) {
-        simgrid::surf::LinkImpl* link = simgrid::surf::LinkImpl::byName(name.c_str());
+        simgrid::surf::LinkImpl* link = simgrid::surf::LinkImpl::byName(name);
         ASroute.link_list->push_back(link);
       }
     }
@@ -452,23 +448,19 @@ int console_add_ASroute(lua_State *L) {
 }
 
 int console_AS_open(lua_State *L) {
- const char *id;
- const char *mode;
- int type;
-
  XBT_DEBUG("Opening AS");
 
  lua_ensure(lua_istable(L, 1), "Bad Arguments to AS_open, Should be a table with named arguments");
 
  lua_pushstring(L, "id");
- type = lua_gettable(L, -2);
int type = lua_gettable(L, -2);
  lua_ensure(type == LUA_TSTRING, "Attribute 'id' must be specified for any AS and must be a string.");
- id = lua_tostring(L, -1);
const char* id = lua_tostring(L, -1);
  lua_pop(L, 1);
 
  lua_pushstring(L, "mode");
  lua_gettable(L, -2);
- mode = lua_tostring(L, -1);
const char* mode = lua_tostring(L, -1);
  lua_pop(L, 1);
 
  int mode_int = A_surfxml_AS_routing_None;
@@ -488,10 +480,10 @@ int console_AS_open(lua_State *L) {
    mode_int = A_surfxml_AS_routing_None;
  else xbt_die("Don't have the model name '%s'",mode);
 
s_sg_platf_AS_cbarg_t AS;
ZoneCreationArgs AS;
  AS.id = id;
  AS.routing = mode_int;
- simgrid::s4u::NetZone* new_as = sg_platf_new_AS_begin(&AS);
+ simgrid::s4u::NetZone* new_as = sg_platf_new_Zone_begin(&AS);
 
  /* Build a Lua representation of the new AS on the stack */
  lua_newtable(L);
@@ -506,37 +498,33 @@ int console_AS_open(lua_State *L) {
 }
 int console_AS_seal(lua_State *L) {
   XBT_DEBUG("Sealing AS");
-  sg_platf_new_AS_seal();
+  sg_platf_new_Zone_seal();
   return 0;
 }
 
 int console_host_set_property(lua_State *L) {
-  const char* name ="";
-  const char* prop_id = "";
-  const char* prop_value = "";
   lua_ensure(lua_istable(L, -1), "Bad Arguments to create link, Should be a table with named arguments");
 
   // get Host id
   lua_pushstring(L, "host");
   lua_gettable(L, -2);
-  name = lua_tostring(L, -1);
+  const char* name = lua_tostring(L, -1);
   lua_pop(L, 1);
 
   // get prop Name
   lua_pushstring(L, "prop");
   lua_gettable(L, -2);
-  prop_id = lua_tostring(L, -1);
+  const char* prop_id = lua_tostring(L, -1);
   lua_pop(L, 1);
   //get args
   lua_pushstring(L,"value");
   lua_gettable(L, -2);
-  prop_value = lua_tostring(L,-1);
+  const char* prop_value = lua_tostring(L, -1);
   lua_pop(L, 1);
 
   sg_host_t host = sg_host_by_name(name);
   lua_ensure(host, "no host '%s' found",name);
-  xbt_dict_t props = sg_host_get_properties(host);
-  xbt_dict_set(props,prop_id,xbt_strdup(prop_value),nullptr);
+  host->setProperty(prop_id, prop_value);
 
   return 0;
 }
index 4e6ff0b..a3262e0 100644 (file)
@@ -14,8 +14,6 @@ XBT_PUBLIC(int) TRACE_start ();
 XBT_PUBLIC(int) TRACE_end ();
 XBT_PUBLIC(void) TRACE_global_init();
 XBT_PUBLIC(void) TRACE_help(int detailed);
-XBT_PUBLIC(void) TRACE_surf_resource_utilization_alloc();
-XBT_PUBLIC(void) TRACE_surf_resource_utilization_release();
 
 SG_END_DECL()
 
index f1f3ce2..532f1cf 100644 (file)
@@ -60,7 +60,6 @@ SG_BEGIN_DECL()
 
 /* user-visible parameters */
 extern XBT_PRIVATE double sg_tcp_gamma;
-extern XBT_PRIVATE double sg_sender_gap;
 extern XBT_PRIVATE double sg_latency_factor;
 extern XBT_PRIVATE double sg_bandwidth_factor;
 extern XBT_PRIVATE double sg_weight_S_parameter;
@@ -434,8 +433,6 @@ const char *__surf_get_initial_path();
 /********** Tracing **********/
 /* from surf_instr.c */
 void TRACE_surf_action(surf_action_t surf_action, const char *category);
-void TRACE_surf_alloc();
-void TRACE_surf_release();
 
 /* instr_routing.c */
 void instr_routing_define_callbacks ();
diff --git a/src/include/xbt/parmap.hpp b/src/include/xbt/parmap.hpp
new file mode 100644 (file)
index 0000000..24affcc
--- /dev/null
@@ -0,0 +1,451 @@
+/* A thread pool (C++ version).                                             */
+
+/* Copyright (c) 2004-2017 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. */
+
+#ifndef XBT_PARMAP_HPP
+#define XBT_PARMAP_HPP
+
+#include "src/internal_config.h" // HAVE_FUTEX_H
+#include "src/kernel/context/Context.hpp"
+#include <atomic>
+#include <boost/optional.hpp>
+#include <simgrid/simix.h>
+#include <vector>
+#include <xbt/log.h>
+#include <xbt/parmap.h>
+#include <xbt/xbt_os_thread.h>
+
+#if HAVE_FUTEX_H
+#include <limits>
+#include <linux/futex.h>
+#include <sys/syscall.h>
+#endif
+
+XBT_LOG_EXTERNAL_CATEGORY(xbt_parmap);
+
+namespace simgrid {
+namespace xbt {
+
+/** \addtogroup XBT_parmap
+  * \ingroup XBT_misc
+  * \brief Parallel map class
+  * \{
+  */
+template <typename T> class Parmap {
+public:
+  Parmap(unsigned num_workers, e_xbt_parmap_mode_t mode);
+  Parmap(const Parmap&) = delete;
+  ~Parmap();
+  void apply(void (*fun)(T), const std::vector<T>& data);
+  boost::optional<T> next();
+
+private:
+  enum Flag { PARMAP_WORK, PARMAP_DESTROY };
+
+  /**
+   * \brief Thread data transmission structure
+   */
+  class ThreadData {
+  public:
+    ThreadData(Parmap<T>& parmap, int id) : parmap(parmap), worker_id(id) {}
+    Parmap<T>& parmap;
+    int worker_id;
+  };
+
+  /**
+   * \brief Synchronization object (different specializations).
+   */
+  class Synchro {
+  public:
+    explicit Synchro(Parmap<T>& parmap) : parmap(parmap) {}
+    virtual ~Synchro() {}
+    /**
+     * \brief Wakes all workers and waits for them to finish the tasks.
+     *
+     * This function is called by the controller thread.
+     */
+    virtual void master_signal()       = 0;
+    /**
+     * \brief Starts the parmap: waits for all workers to be ready and returns.
+     *
+     * This function is called by the controller thread.
+     */
+    virtual void master_wait()         = 0;
+    /**
+     * \brief Ends the parmap: wakes the controller thread when all workers terminate.
+     *
+     * This function is called by all worker threads when they end (not including the controller).
+     */
+    virtual void worker_signal()       = 0;
+    /**
+     * \brief Waits for some work to process.
+     *
+     * This function is called by each worker thread (not including the controller) when it has no more work to do.
+     *
+     * \param round  the expected round number
+     */
+    virtual void worker_wait(unsigned) = 0;
+
+  protected:
+    Parmap<T>& parmap;
+  };
+
+  class PosixSynchro : public Synchro {
+  public:
+    explicit PosixSynchro(Parmap<T>& parmap);
+    ~PosixSynchro();
+    void master_signal();
+    void master_wait();
+    void worker_signal();
+    void worker_wait(unsigned round);
+
+  private:
+    xbt_os_cond_t ready_cond;
+    xbt_os_mutex_t ready_mutex;
+    xbt_os_cond_t done_cond;
+    xbt_os_mutex_t done_mutex;
+  };
+
+#if HAVE_FUTEX_H
+  class FutexSynchro : public Synchro {
+  public:
+    explicit FutexSynchro(Parmap<T>& parmap) : Synchro(parmap) {}
+    void master_signal();
+    void master_wait();
+    void worker_signal();
+    void worker_wait(unsigned);
+
+  private:
+    static void futex_wait(unsigned* uaddr, unsigned val);
+    static void futex_wake(unsigned* uaddr, unsigned val);
+  };
+#endif
+
+  class BusyWaitSynchro : public Synchro {
+  public:
+    explicit BusyWaitSynchro(Parmap<T>& parmap) : Synchro(parmap) {}
+    void master_signal();
+    void master_wait();
+    void worker_signal();
+    void worker_wait(unsigned);
+  };
+
+  static void* worker_main(void* arg);
+  Synchro* new_synchro(e_xbt_parmap_mode_t mode);
+  void work();
+
+  Flag status;              /**< is the parmap active or being destroyed? */
+  unsigned work_round;      /**< index of the current round */
+  xbt_os_thread_t* workers; /**< worker thread handlers */
+  unsigned num_workers;     /**< total number of worker threads including the controller */
+  Synchro* synchro;         /**< synchronization object */
+
+  unsigned thread_counter    = 0;       /**< number of workers that have done the work */
+  void (*fun)(const T)       = nullptr; /**< function to run in parallel on each element of data */
+  const std::vector<T>* data = nullptr; /**< parameters to pass to fun in parallel */
+  std::atomic<unsigned> index;          /**< index of the next element of data to pick */
+};
+
+/**
+ * \brief Creates a parallel map object
+ * \param num_workers number of worker threads to create
+ * \param mode how to synchronize the worker threads
+ */
+template <typename T> Parmap<T>::Parmap(unsigned num_workers, e_xbt_parmap_mode_t mode)
+{
+  XBT_CDEBUG(xbt_parmap, "Create new parmap (%u workers)", num_workers);
+
+  /* Initialize the thread pool data structure */
+  this->status      = PARMAP_WORK;
+  this->work_round  = 0;
+  this->workers     = new xbt_os_thread_t[num_workers];
+  this->num_workers = num_workers;
+  this->synchro     = new_synchro(mode);
+
+  /* Create the pool of worker threads */
+  this->workers[0] = nullptr;
+#if HAVE_PTHREAD_SETAFFINITY
+  int core_bind = 0;
+#endif
+  for (unsigned i = 1; i < num_workers; i++) {
+    ThreadData* data = new ThreadData(*this, i);
+    this->workers[i] = xbt_os_thread_create(nullptr, worker_main, data, nullptr);
+#if HAVE_PTHREAD_SETAFFINITY
+    xbt_os_thread_bind(this->workers[i], core_bind);
+    if (core_bind != xbt_os_get_numcores() - 1)
+      core_bind++;
+    else
+      core_bind = 0;
+#endif
+  }
+}
+
+/**
+ * \brief Destroys a parmap
+ */
+template <typename T> Parmap<T>::~Parmap()
+{
+  status = PARMAP_DESTROY;
+  synchro->master_signal();
+
+  for (unsigned i = 1; i < num_workers; i++)
+    xbt_os_thread_join(workers[i], nullptr);
+
+  delete[] workers;
+  delete synchro;
+}
+
+/**
+ * \brief Applies a list of tasks in parallel.
+ * \param fun the function to call in parallel
+ * \param data each element of this vector will be passed as an argument to fun
+ */
+template <typename T> void Parmap<T>::apply(void (*fun)(T), const std::vector<T>& data)
+{
+  /* Assign resources to worker threads (we are maestro here)*/
+  this->fun   = fun;
+  this->data  = &data;
+  this->index = 0;
+  this->synchro->master_signal(); // maestro runs futex_wait to wake all the minions (the working threads)
+  this->work();                   // maestro works with its minions
+  this->synchro->master_wait();   // When there is no more work to do, then maestro waits for the last minion to stop
+  XBT_CDEBUG(xbt_parmap, "Job done"); //   ... and proceeds
+}
+
+/**
+ * \brief Returns a next task to process.
+ *
+ * Worker threads call this function to get more work.
+ *
+ * \return the next task to process, or throws a std::out_of_range exception if there is no more work
+ */
+template <typename T> boost::optional<T> Parmap<T>::next()
+{
+  unsigned index = this->index++;
+  if (index < this->data->size())
+    return (*this->data)[index];
+  else
+    return boost::none;
+}
+
+/**
+ * \brief Main work loop: applies fun to elements in turn.
+ */
+template <typename T> void Parmap<T>::work()
+{
+  unsigned index = this->index++;
+  unsigned length = this->data->size();
+  while (index < length) {
+    this->fun((*this->data)[index]);
+    index = this->index++;
+  }
+}
+
+/**
+ * Get a synchronization object for given mode.
+ * \param mode the synchronization mode
+ */
+template <typename T> typename Parmap<T>::Synchro* Parmap<T>::new_synchro(e_xbt_parmap_mode_t mode)
+{
+  if (mode == XBT_PARMAP_DEFAULT) {
+#if HAVE_FUTEX_H
+    mode = XBT_PARMAP_FUTEX;
+#else
+    mode = XBT_PARMAP_POSIX;
+#endif
+  }
+  Synchro* res;
+  switch (mode) {
+    case XBT_PARMAP_POSIX:
+      res = new PosixSynchro(*this);
+      break;
+    case XBT_PARMAP_FUTEX:
+#if HAVE_FUTEX_H
+      res = new FutexSynchro(*this);
+#else
+      xbt_die("Fute is not available on this OS.");
+#endif
+      break;
+    case XBT_PARMAP_BUSY_WAIT:
+      res = new BusyWaitSynchro(*this);
+      break;
+    default:
+      THROW_IMPOSSIBLE;
+  }
+  return res;
+}
+
+/**
+ * \brief Main function of a worker thread.
+ */
+template <typename T> void* Parmap<T>::worker_main(void* arg)
+{
+  ThreadData* data      = static_cast<ThreadData*>(arg);
+  Parmap<T>& parmap     = data->parmap;
+  unsigned round        = 0;
+  smx_context_t context = SIMIX_context_new(std::function<void()>(), nullptr, nullptr);
+  SIMIX_context_set_current(context);
+
+  XBT_CDEBUG(xbt_parmap, "New worker thread created");
+
+  /* Worker's main loop */
+  while (1) {
+    round++;
+    parmap.synchro->worker_wait(round);
+    if (parmap.status == PARMAP_DESTROY)
+      break;
+
+    XBT_CDEBUG(xbt_parmap, "Worker %d got a job", data->worker_id);
+    parmap.work();
+    parmap.synchro->worker_signal();
+    XBT_CDEBUG(xbt_parmap, "Worker %d has finished", data->worker_id);
+  }
+  /* We are destroying the parmap */
+  delete context;
+  delete data;
+  return nullptr;
+}
+
+template <typename T> Parmap<T>::PosixSynchro::PosixSynchro(Parmap<T>& parmap) : Synchro(parmap)
+{
+  ready_cond  = xbt_os_cond_init();
+  ready_mutex = xbt_os_mutex_init();
+  done_cond   = xbt_os_cond_init();
+  done_mutex  = xbt_os_mutex_init();
+}
+
+template <typename T> Parmap<T>::PosixSynchro::~PosixSynchro()
+{
+  xbt_os_cond_destroy(ready_cond);
+  xbt_os_mutex_destroy(ready_mutex);
+  xbt_os_cond_destroy(done_cond);
+  xbt_os_mutex_destroy(done_mutex);
+}
+
+template <typename T> void Parmap<T>::PosixSynchro::master_signal()
+{
+  xbt_os_mutex_acquire(ready_mutex);
+  this->parmap.thread_counter = 1;
+  this->parmap.work_round++;
+  /* wake all workers */
+  xbt_os_cond_broadcast(ready_cond);
+  xbt_os_mutex_release(ready_mutex);
+}
+
+template <typename T> void Parmap<T>::PosixSynchro::master_wait()
+{
+  xbt_os_mutex_acquire(done_mutex);
+  if (this->parmap.thread_counter < this->parmap.num_workers) {
+    /* wait for all workers to be ready */
+    xbt_os_cond_wait(done_cond, done_mutex);
+  }
+  xbt_os_mutex_release(done_mutex);
+}
+
+template <typename T> void Parmap<T>::PosixSynchro::worker_signal()
+{
+  xbt_os_mutex_acquire(done_mutex);
+  this->parmap.thread_counter++;
+  if (this->parmap.thread_counter == this->parmap.num_workers) {
+    /* all workers have finished, wake the controller */
+    xbt_os_cond_signal(done_cond);
+  }
+  xbt_os_mutex_release(done_mutex);
+}
+
+template <typename T> void Parmap<T>::PosixSynchro::worker_wait(unsigned round)
+{
+  xbt_os_mutex_acquire(ready_mutex);
+  /* wait for more work */
+  if (this->parmap.work_round != round) {
+    xbt_os_cond_wait(ready_cond, ready_mutex);
+  }
+  xbt_os_mutex_release(ready_mutex);
+}
+
+#if HAVE_FUTEX_H
+template <typename T> inline void Parmap<T>::FutexSynchro::futex_wait(unsigned* uaddr, unsigned val)
+{
+  XBT_CVERB(xbt_parmap, "Waiting on futex %p", uaddr);
+  syscall(SYS_futex, uaddr, FUTEX_WAIT_PRIVATE, val, nullptr, nullptr, 0);
+}
+
+template <typename T> inline void Parmap<T>::FutexSynchro::futex_wake(unsigned* uaddr, unsigned val)
+{
+  XBT_CVERB(xbt_parmap, "Waking futex %p", uaddr);
+  syscall(SYS_futex, uaddr, FUTEX_WAKE_PRIVATE, val, nullptr, nullptr, 0);
+}
+
+template <typename T> void Parmap<T>::FutexSynchro::master_signal()
+{
+  this->parmap.thread_counter = 1;
+  __sync_add_and_fetch(&this->parmap.work_round, 1);
+  /* wake all workers */
+  futex_wake(&this->parmap.work_round, std::numeric_limits<int>::max());
+}
+
+template <typename T> void Parmap<T>::FutexSynchro::master_wait()
+{
+  unsigned count = this->parmap.thread_counter;
+  while (count < this->parmap.num_workers) {
+    /* wait for all workers to be ready */
+    futex_wait(&this->parmap.thread_counter, count);
+    count = this->parmap.thread_counter;
+  }
+}
+
+template <typename T> void Parmap<T>::FutexSynchro::worker_signal()
+{
+  unsigned count = __sync_add_and_fetch(&this->parmap.thread_counter, 1);
+  if (count == this->parmap.num_workers) {
+    /* all workers have finished, wake the controller */
+    futex_wake(&this->parmap.thread_counter, std::numeric_limits<int>::max());
+  }
+}
+
+template <typename T> void Parmap<T>::FutexSynchro::worker_wait(unsigned round)
+{
+  unsigned work_round = this->parmap.work_round;
+  /* wait for more work */
+  while (work_round != round) {
+    futex_wait(&this->parmap.work_round, work_round);
+    work_round = this->parmap.work_round;
+  }
+}
+#endif
+
+template <typename T> void Parmap<T>::BusyWaitSynchro::master_signal()
+{
+  this->parmap.thread_counter = 1;
+  __sync_add_and_fetch(&this->parmap.work_round, 1);
+}
+
+template <typename T> void Parmap<T>::BusyWaitSynchro::master_wait()
+{
+  while (this->parmap.thread_counter < this->parmap.num_workers) {
+    xbt_os_thread_yield();
+  }
+}
+
+template <typename T> void Parmap<T>::BusyWaitSynchro::worker_signal()
+{
+  __sync_add_and_fetch(&this->parmap.thread_counter, 1);
+}
+
+template <typename T> void Parmap<T>::BusyWaitSynchro::worker_wait(unsigned round)
+{
+  /* wait for more work */
+  while (this->parmap.work_round != round) {
+    xbt_os_thread_yield();
+  }
+}
+
+/** \} */
+}
+}
+
+#endif
index 8455e27..9a14d50 100644 (file)
@@ -1,11 +1,11 @@
-/* Copyright (c) 2010-2015. The SimGrid Team.
- * All rights reserved.                                                     */
+/* Copyright (c) 2010-2017. 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 "src/instr/instr_private.h"
 #include "surf/surf.h"
+#include <string>
 #include <vector>
 
 XBT_LOG_NEW_CATEGORY(instr, "Logging the behavior of the tracing system (used for Visualization/Analysis of simulations)");
@@ -122,13 +122,6 @@ int TRACE_start()
     }
     trace_active = 1;
     XBT_DEBUG("Tracing is on");
-
-    /* other trace initialization */
-    created_categories = xbt_dict_new_homogeneous(xbt_free_f);
-    declared_marks = xbt_dict_new_homogeneous(xbt_free_f);
-    user_host_variables = xbt_dict_new_homogeneous(xbt_free_f);
-    user_vm_variables = xbt_dict_new_homogeneous(xbt_free_f);
-    user_link_variables = xbt_dict_new_homogeneous(xbt_free_f);
   }
   return 0;
 }
@@ -154,12 +147,6 @@ int TRACE_end()
     PJ_container_release();
     rootType = nullptr;
 
-    xbt_dict_free(&user_link_variables);
-    xbt_dict_free(&user_host_variables);
-    xbt_dict_free(&user_vm_variables);
-    xbt_dict_free(&declared_marks);
-    xbt_dict_free(&created_categories);
-
     /* close the trace files */
     const char* format = xbt_cfg_get_string(OPT_TRACING_FORMAT);
     XBT_DEBUG("Tracing format %s\n", format);
@@ -491,20 +478,19 @@ static void output_types (const char *name, xbt_dynar_t types, FILE *file)
   xbt_dynar_free (&types);
 }
 
-static void output_categories (const char *name, xbt_dynar_t cats, FILE *file)
+static void output_categories(const char* name, FILE* file)
 {
-  unsigned int i;
+  unsigned int i = created_categories.size();
   fprintf (file, "    values = (");
-  for (i = xbt_dynar_length(cats); i > 0; i--) {
-    char *cat = *(static_cast<char**>(xbt_dynar_get_ptr(cats, i - 1)));
-    fprintf (file, "\"%s%s\"", name, cat);
-    if (i - 1 > 0){
+  for (auto cat : created_categories) {
+    --i;
+    fprintf(file, "\"%s%s\"", name, cat.c_str());
+    if (i > 0) {
       fprintf (file, ",");
     }else{
       fprintf (file, ");\n");
     }
   }
-  xbt_dynar_free (&cats);
 }
 
 static void uncat_configuration (FILE *file)
@@ -541,13 +527,13 @@ static void cat_configuration (FILE *file)
            "  host = {\n"
            "    type = \"square\";\n"
            "    size = \"power\";\n");
-  output_categories ("p", TRACE_get_categories(), file);
+  output_categories("p", file);
   fprintf (file,
            "  };\n"
            "  link = {\n"
            "    type = \"rhombus\";\n"
            "    size = \"bandwidth\";\n");
-  output_categories ("b", TRACE_get_categories(), file);
+  output_categories("b", file);
   fprintf (file, "  };\n");
   //close
 }
@@ -574,7 +560,7 @@ static void generate_cat_configuration (const char *output, const char *name, in
 {
   if (output && strlen(output) > 0){
     //check if we do have categories declared
-    if (xbt_dict_is_empty(created_categories)){
+    if (created_categories.empty()) {
       XBT_INFO("No categories declared, ignoring generation of %s graph configuration", name);
       return;
     }
index 726b68a..24b187f 100644 (file)
@@ -10,6 +10,7 @@
 #include "src/surf/network_interface.hpp"
 #include "src/surf/surf_private.h"
 #include "surf/surf.h"
+#include <algorithm>
 
 typedef enum {
   INSTR_US_DECLARE,
@@ -20,26 +21,23 @@ typedef enum {
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_api, instr, "API");
 
-xbt_dict_t created_categories = nullptr;
-xbt_dict_t declared_marks = nullptr;
-xbt_dict_t user_host_variables = nullptr;
-xbt_dict_t user_vm_variables = nullptr;
-xbt_dict_t user_link_variables = nullptr;
-extern xbt_dict_t trivaNodeTypes;
-extern xbt_dict_t trivaEdgeTypes;
+std::set<std::string> created_categories;
+std::set<std::string> declared_marks;
+std::set<std::string> user_host_variables;
+std::set<std::string> user_vm_variables;
+std::set<std::string> user_link_variables;
+extern std::set<std::string> trivaNodeTypes;
+extern std::set<std::string> trivaEdgeTypes;
 
-static xbt_dynar_t instr_dict_to_dynar (xbt_dict_t filter)
+static xbt_dynar_t instr_set_to_dynar(std::set<std::string>* filter)
 {
   if (not TRACE_is_enabled() || not TRACE_needs_platform())
     return nullptr;
 
   xbt_dynar_t ret = xbt_dynar_new (sizeof(char*), &xbt_free_ref);
-  xbt_dict_cursor_t cursor = nullptr;
-  char *name;
-  char *value;
-  xbt_dict_foreach(filter, cursor, name, value) {
-    xbt_dynar_push_as (ret, char*, xbt_strdup(name));
-  }
+  for (auto name : *filter)
+    xbt_dynar_push_as(ret, char*, xbt_strdup(name.c_str()));
+
   return ret;
 }
 
@@ -88,10 +86,10 @@ void TRACE_category_with_color (const char *category, const char *color)
     return;
 
   //check if category is already created
-  if (xbt_dict_get_or_null(created_categories, category) != nullptr)
+  if (created_categories.find(category) != created_categories.end())
     return;
-
-  xbt_dict_set (created_categories, category, xbt_strdup("1"), nullptr);
+  else
+    created_categories.insert(category);
 
   //define final_color
   char final_color[INSTR_DEFAULT_STR_SIZE];
@@ -127,8 +125,7 @@ xbt_dynar_t TRACE_get_categories ()
 {
   if (not TRACE_is_enabled() || not TRACE_categorized())
     return nullptr;
-
-  return instr_dict_to_dynar (created_categories);
+  return instr_set_to_dynar(&created_categories);
 }
 
 /** \ingroup TRACE_mark
@@ -151,13 +148,13 @@ void TRACE_declare_mark(const char *mark_type)
     THROWF (tracing_error, 1, "mark_type is nullptr");
 
   //check if mark_type is already declared
-  if (xbt_dict_get_or_null(declared_marks, mark_type) != nullptr) {
+  if (declared_marks.find(mark_type) != declared_marks.end()) {
     THROWF (tracing_error, 1, "mark_type with name (%s) is already declared", mark_type);
   }
 
   XBT_DEBUG("MARK,declare %s", mark_type);
   PJ_type_event_new(mark_type, PJ_type_get_root());
-  xbt_dict_set (declared_marks, mark_type, xbt_strdup("1"), nullptr);
+  declared_marks.insert(mark_type);
 }
 
 /** \ingroup TRACE_mark
@@ -263,25 +260,25 @@ xbt_dynar_t TRACE_get_marks ()
   if (not TRACE_is_enabled())
     return nullptr;
 
-  return instr_dict_to_dynar (declared_marks);
+  return instr_set_to_dynar(&declared_marks);
 }
 
-static void instr_user_variable(double time, const char *resource, const char *variable, const char *father_type,
-                         double value, InstrUserVariable what, const char *color, xbt_dict_t filter)
+static void instr_user_variable(double time, const char* resource, const char* variable, const char* father_type,
+                                double value, InstrUserVariable what, const char* color, std::set<std::string>* filter)
 {
   /* safe switches. tracing has to be activated and if platform is not traced, we don't allow user variables */
   if (not TRACE_is_enabled() || not TRACE_needs_platform())
     return;
 
   //check if variable is already declared
-  char *created = (char*)xbt_dict_get_or_null(filter, variable);
+  auto created = filter->find(variable);
   if (what == INSTR_US_DECLARE){
-    if (not created) { // not declared yet
-      xbt_dict_set (filter, variable, xbt_strdup("1"), nullptr);
+    if (created == filter->end()) { // not declared yet
+      filter->insert(variable);
       instr_new_user_variable_type (father_type, variable, color);
     }
   }else{
-    if (created) { // declared, let's work
+    if (created != filter->end()) { // declared, let's work
       char valuestr[100];
       snprintf(valuestr, 100, "%g", value);
       container_t container = PJ_container_get(resource);
@@ -318,7 +315,7 @@ static void instr_user_srcdst_variable(double time, const char *src, const char
   std::vector<simgrid::surf::LinkImpl*> route;
   simgrid::kernel::routing::NetZoneImpl::getGlobalRoute(src_elm, dst_elm, &route, nullptr);
   for (auto link : route)
-    instr_user_variable(time, link->cname(), variable, father_type, value, what, nullptr, user_link_variables);
+    instr_user_variable(time, link->cname(), variable, father_type, value, what, nullptr, &user_link_variables);
 }
 
 /** \ingroup TRACE_API
@@ -364,7 +361,7 @@ int TRACE_platform_graph_export_graphviz (const char *filename)
  */
 void TRACE_vm_variable_declare (const char *variable)
 {
-  instr_user_variable(0, nullptr, variable, "MSG_VM", 0, INSTR_US_DECLARE, nullptr, user_vm_variables);
+  instr_user_variable(0, nullptr, variable, "MSG_VM", 0, INSTR_US_DECLARE, nullptr, &user_vm_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -379,7 +376,7 @@ void TRACE_vm_variable_declare (const char *variable)
  */
 void TRACE_vm_variable_declare_with_color (const char *variable, const char *color)
 {
-   instr_user_variable(0, nullptr, variable, "MSG_VM", 0, INSTR_US_DECLARE, color, user_vm_variables);
+  instr_user_variable(0, nullptr, variable, "MSG_VM", 0, INSTR_US_DECLARE, color, &user_vm_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -441,7 +438,7 @@ void TRACE_vm_variable_sub (const char *vm, const char *variable, double value)
  */
 void TRACE_vm_variable_set_with_time (double time, const char *vm, const char *variable, double value)
 {
-  instr_user_variable(time, vm, variable, "MSG_VM", value, INSTR_US_SET, nullptr, user_vm_variables);
+  instr_user_variable(time, vm, variable, "MSG_VM", value, INSTR_US_SET, nullptr, &user_vm_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -461,7 +458,7 @@ void TRACE_vm_variable_set_with_time (double time, const char *vm, const char *v
  */
 void TRACE_vm_variable_add_with_time (double time, const char *vm, const char *variable, double value)
 {
-  instr_user_variable(time, vm, variable, "MSG_VM", value, INSTR_US_ADD, nullptr, user_vm_variables);
+  instr_user_variable(time, vm, variable, "MSG_VM", value, INSTR_US_ADD, nullptr, &user_vm_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -481,7 +478,7 @@ void TRACE_vm_variable_add_with_time (double time, const char *vm, const char *v
  */
 void TRACE_vm_variable_sub_with_time (double time, const char *vm, const char *variable, double value)
 {
-  instr_user_variable(time, vm, variable, "MSG_VM", value, INSTR_US_SUB, nullptr, user_vm_variables);
+  instr_user_variable(time, vm, variable, "MSG_VM", value, INSTR_US_SUB, nullptr, &user_vm_variables);
 }
 
 /* for host variables */
@@ -498,7 +495,7 @@ void TRACE_vm_variable_sub_with_time (double time, const char *vm, const char *v
  */
 void TRACE_host_variable_declare (const char *variable)
 {
-  instr_user_variable(0, nullptr, variable, "HOST", 0, INSTR_US_DECLARE, nullptr, user_host_variables);
+  instr_user_variable(0, nullptr, variable, "HOST", 0, INSTR_US_DECLARE, nullptr, &user_host_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -513,7 +510,7 @@ void TRACE_host_variable_declare (const char *variable)
  */
 void TRACE_host_variable_declare_with_color (const char *variable, const char *color)
 {
-  instr_user_variable(0, nullptr, variable, "HOST", 0, INSTR_US_DECLARE, color, user_host_variables);
+  instr_user_variable(0, nullptr, variable, "HOST", 0, INSTR_US_DECLARE, color, &user_host_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -575,7 +572,7 @@ void TRACE_host_variable_sub (const char *host, const char *variable, double val
  */
 void TRACE_host_variable_set_with_time (double time, const char *host, const char *variable, double value)
 {
-  instr_user_variable(time, host, variable, "HOST", value, INSTR_US_SET, nullptr, user_host_variables);
+  instr_user_variable(time, host, variable, "HOST", value, INSTR_US_SET, nullptr, &user_host_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -595,7 +592,7 @@ void TRACE_host_variable_set_with_time (double time, const char *host, const cha
  */
 void TRACE_host_variable_add_with_time (double time, const char *host, const char *variable, double value)
 {
-  instr_user_variable(time, host, variable, "HOST", value, INSTR_US_ADD, nullptr, user_host_variables);
+  instr_user_variable(time, host, variable, "HOST", value, INSTR_US_ADD, nullptr, &user_host_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -615,7 +612,7 @@ void TRACE_host_variable_add_with_time (double time, const char *host, const cha
  */
 void TRACE_host_variable_sub_with_time (double time, const char *host, const char *variable, double value)
 {
-  instr_user_variable(time, host, variable, "HOST", value, INSTR_US_SUB, nullptr, user_host_variables);
+  instr_user_variable(time, host, variable, "HOST", value, INSTR_US_SUB, nullptr, &user_host_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -628,7 +625,7 @@ void TRACE_host_variable_sub_with_time (double time, const char *host, const cha
  */
 xbt_dynar_t TRACE_get_host_variables ()
 {
-  return instr_dict_to_dynar (user_host_variables);
+  return instr_set_to_dynar(&user_host_variables);
 }
 
 /* for link variables */
@@ -645,7 +642,7 @@ xbt_dynar_t TRACE_get_host_variables ()
  */
 void TRACE_link_variable_declare (const char *variable)
 {
-  instr_user_variable (0, nullptr, variable, "LINK", 0, INSTR_US_DECLARE, nullptr, user_link_variables);
+  instr_user_variable(0, nullptr, variable, "LINK", 0, INSTR_US_DECLARE, nullptr, &user_link_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -660,7 +657,7 @@ void TRACE_link_variable_declare (const char *variable)
  */
 void TRACE_link_variable_declare_with_color (const char *variable, const char *color)
 {
-  instr_user_variable (0, nullptr, variable, "LINK", 0, INSTR_US_DECLARE, color, user_link_variables);
+  instr_user_variable(0, nullptr, variable, "LINK", 0, INSTR_US_DECLARE, color, &user_link_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -722,7 +719,7 @@ void TRACE_link_variable_sub (const char *link, const char *variable, double val
  */
 void TRACE_link_variable_set_with_time (double time, const char *link, const char *variable, double value)
 {
-  instr_user_variable (time, link, variable, "LINK", value, INSTR_US_SET, nullptr, user_link_variables);
+  instr_user_variable(time, link, variable, "LINK", value, INSTR_US_SET, nullptr, &user_link_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -742,7 +739,7 @@ void TRACE_link_variable_set_with_time (double time, const char *link, const cha
  */
 void TRACE_link_variable_add_with_time (double time, const char *link, const char *variable, double value)
 {
-  instr_user_variable (time, link, variable, "LINK", value, INSTR_US_ADD, nullptr, user_link_variables);
+  instr_user_variable(time, link, variable, "LINK", value, INSTR_US_ADD, nullptr, &user_link_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -762,7 +759,7 @@ void TRACE_link_variable_add_with_time (double time, const char *link, const cha
  */
 void TRACE_link_variable_sub_with_time (double time, const char *link, const char *variable, double value)
 {
-  instr_user_variable (time, link, variable, "LINK", value, INSTR_US_SUB, nullptr, user_link_variables);
+  instr_user_variable(time, link, variable, "LINK", value, INSTR_US_SUB, nullptr, &user_link_variables);
 }
 
 /* for link variables, but with src and dst used for get_route */
@@ -899,7 +896,7 @@ void TRACE_link_srcdst_variable_sub_with_time (double time, const char *src, con
  */
 xbt_dynar_t TRACE_get_link_variables ()
 {
-  return instr_dict_to_dynar (user_link_variables);
+  return instr_set_to_dynar(&user_link_variables);
 }
 
 /** \ingroup TRACE_user_variables
@@ -1001,7 +998,7 @@ void TRACE_host_pop_state (const char *host, const char *state)
  */
 xbt_dynar_t TRACE_get_node_types ()
 {
-  return instr_dict_to_dynar (trivaNodeTypes);
+  return instr_set_to_dynar(&trivaNodeTypes);
 }
 
 /** \ingroup TRACE_API
@@ -1014,5 +1011,5 @@ xbt_dynar_t TRACE_get_node_types ()
  */
 xbt_dynar_t TRACE_get_edge_types ()
 {
-  return instr_dict_to_dynar (trivaEdgeTypes);
+  return instr_set_to_dynar(&trivaEdgeTypes);
 }
index 6f2331d..d65e46c 100644 (file)
@@ -14,8 +14,8 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_paje_containers, instr, "Paje tracing eve
 
 static container_t rootContainer = nullptr;    /* the root container */
 static xbt_dict_t allContainers = nullptr;     /* all created containers indexed by name */
-xbt_dict_t trivaNodeTypes = nullptr;     /* all host types defined */
-xbt_dict_t trivaEdgeTypes = nullptr;     /* all link types defined */
+std::set<std::string> trivaNodeTypes;           /* all host types defined */
+std::set<std::string> trivaEdgeTypes;           /* all link types defined */
 
 long long int instr_new_paje_id ()
 {
@@ -26,15 +26,11 @@ long long int instr_new_paje_id ()
 void PJ_container_alloc ()
 {
   allContainers = xbt_dict_new_homogeneous(nullptr);
-  trivaNodeTypes = xbt_dict_new_homogeneous(xbt_free_f);
-  trivaEdgeTypes = xbt_dict_new_homogeneous(xbt_free_f);
 }
 
 void PJ_container_release ()
 {
   xbt_dict_free (&allContainers);
-  xbt_dict_free (&trivaNodeTypes);
-  xbt_dict_free (&trivaEdgeTypes);
 }
 
 void PJ_container_set_root (container_t root)
@@ -151,7 +147,7 @@ container_t PJ_container_new (const char *name, e_container_types kind, containe
 
   //register NODE types for triva configuration
   if (newContainer->kind == INSTR_HOST || newContainer->kind == INSTR_LINK || newContainer->kind == INSTR_ROUTER) {
-    xbt_dict_set (trivaNodeTypes, newContainer->type->name, xbt_strdup("1"), nullptr);
+    trivaNodeTypes.insert(newContainer->type->name);
   }
   return newContainer;
 }
index 9cf8031..e8e38d4 100644 (file)
@@ -8,10 +8,11 @@
 
 #include <xbt/base.h>
 
-#include "simgrid/instr.h"
 #include "instr/instr_interface.h"
-#include "src/internal_config.h"
+#include "simgrid/instr.h"
 #include "simgrid_config.h"
+#include "src/internal_config.h"
+#include <set>
 
 SG_BEGIN_DECL()
 
@@ -265,12 +266,11 @@ public:
 
 };
 
-
-extern XBT_PRIVATE xbt_dict_t created_categories;
-extern XBT_PRIVATE xbt_dict_t declared_marks;
-extern XBT_PRIVATE xbt_dict_t user_host_variables;
-extern XBT_PRIVATE xbt_dict_t user_vm_variables;
-extern XBT_PRIVATE xbt_dict_t user_link_variables;
+extern XBT_PRIVATE std::set<std::string> created_categories;
+extern XBT_PRIVATE std::set<std::string> declared_marks;
+extern XBT_PRIVATE std::set<std::string> user_host_variables;
+extern XBT_PRIVATE std::set<std::string> user_vm_variables;
+extern XBT_PRIVATE std::set<std::string> user_link_variables;
 extern XBT_PRIVATE double TRACE_last_timestamp_to_dump;
 
 /* instr_paje_header.c */
@@ -325,8 +325,8 @@ XBT_PRIVATE void TRACE_surf_link_set_utilization(const char *resource,const char
 XBT_PUBLIC(void) TRACE_surf_resource_utilization_alloc();
 
 /* instr_paje.c */
-extern XBT_PRIVATE xbt_dict_t trivaNodeTypes;
-extern XBT_PRIVATE xbt_dict_t trivaEdgeTypes;
+extern XBT_PRIVATE std::set<std::string> trivaNodeTypes;
+extern XBT_PRIVATE std::set<std::string> trivaEdgeTypes;
 XBT_PRIVATE long long int instr_new_paje_id ();
 XBT_PRIVATE void PJ_container_alloc ();
 XBT_PRIVATE void PJ_container_release ();
index 3135882..7606f22 100644 (file)
@@ -1,15 +1,17 @@
-/* Copyright (c) 2010-2015. The SimGrid Team.
+/* Copyright (c) 2010-2017. 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 "src/instr/instr_private.h"
+#include <string>
+#include <unordered_map>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_resource, instr, "tracing (un)-categorized resource utilization");
 
 //to check if variables were previously set to 0, otherwise paje won't simulate them
-static xbt_dict_t platform_variables;
+static std::unordered_map<std::string, std::string> platform_variables;
 
 //used by all methods
 static void __TRACE_surf_check_variable_set_to_zero(double now, const char *variable, const char *resource)
@@ -21,18 +23,15 @@ static void __TRACE_surf_check_variable_set_to_zero(double now, const char *vari
    */
 
   // create a key considering the resource and variable
-  int n = strlen(variable)+strlen(resource)+1;
-  char *key = (char*)xbt_malloc(n*sizeof(char));
-  snprintf (key, n, "%s%s", resource, variable);
+  std::string key = std::string(resource) + variable;
 
   // check if key exists: if it doesn't, set the variable to zero and mark this in the dict
-  if (not xbt_dict_get_or_null(platform_variables, key)) {
+  if (platform_variables.find(key) == platform_variables.end()) {
     container_t container = PJ_container_get (resource);
     type_t type = PJ_type_get (variable, container->type);
     new SetVariableEvent (now, container, type, 0);
-    xbt_dict_set(platform_variables, key, (char*)"", nullptr);
+    platform_variables[key] = std::string("");
   }
-  xbt_free(key);
 }
 
 static void instr_event (double now, double delta, type_t variable, container_t resource, double value)
@@ -100,13 +99,3 @@ void TRACE_surf_host_set_utilization(const char *resource, const char *category,
     instr_event (now, delta, type, container, value);
   }
 }
-
-void TRACE_surf_resource_utilization_alloc()
-{
-  platform_variables = xbt_dict_new_homogeneous(nullptr);
-}
-
-void TRACE_surf_resource_utilization_release()
-{
-  xbt_dict_free(&platform_variables);
-}
index 5109fd7..babb894 100644 (file)
@@ -33,7 +33,6 @@ Container::~Container()
 
 void Container::addChild(jed_container_t child)
 {
-  xbt_assert(this != nullptr);
   xbt_assert(child != nullptr);
   this->children.push_back(child);
   child->parent = this;
@@ -76,8 +75,6 @@ void Container::createHierarchy(sg_netzone_t from_as)
 
 std::vector<int> Container::getHierarchy()
 {
-  xbt_assert( this!= nullptr );
-
   if(this->parent != nullptr ) {
 
     if (not this->parent->children.empty()) {
@@ -147,7 +144,6 @@ void Container::printResources(FILE * jed_file)
 
 void Container::print(FILE* jed_file)
 {
-  xbt_assert( this != nullptr );
   fprintf(jed_file, "    <res name=\"%s\">\n", this->name.c_str());
   if (not this->children.empty()) {
     for (auto child: this->children) {
index 3f8cedc..936b249 100644 (file)
@@ -9,13 +9,13 @@
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_mailbox, simix, "Mailbox implementation");
 
-static xbt_dict_t mailboxes = xbt_dict_new_homogeneous([](void* data) {
-  delete static_cast<smx_mailbox_t>(data);
-});
+static std::map<std::string, smx_mailbox_t>* mailboxes = new std::map<std::string, smx_mailbox_t>;
 
 void SIMIX_mailbox_exit()
 {
-  xbt_dict_free(&mailboxes);
+  for (auto elm : *mailboxes)
+    delete elm.second;
+  delete mailboxes;
 }
 
 /******************************************************************************/
@@ -28,20 +28,25 @@ namespace activity {
 /** @brief Returns the mailbox of that name, or nullptr */
 MailboxImpl* MailboxImpl::byNameOrNull(const char* name)
 {
-  return static_cast<smx_mailbox_t>(xbt_dict_get_or_null(mailboxes, name));
+  auto mbox = mailboxes->find(name);
+  if (mbox != mailboxes->end())
+    return mbox->second;
+  else
+    return nullptr;
 }
 /** @brief Returns the mailbox of that name, newly created on need */
 MailboxImpl* MailboxImpl::byNameOrCreate(const char* name)
 {
   xbt_assert(name, "Mailboxes must have a name");
   /* two processes may have pushed the same mbox_create simcall at the same time */
-  smx_mailbox_t mbox = static_cast<smx_mailbox_t>(xbt_dict_get_or_null(mailboxes, name));
-  if (not mbox) {
-    mbox = new MailboxImpl(name);
+  auto m = mailboxes->find(name);
+  if (m == mailboxes->end()) {
+    smx_mailbox_t mbox = new MailboxImpl(name);
     XBT_DEBUG("Creating a mailbox at %p with name %s", mbox, name);
-    xbt_dict_set(mailboxes, mbox->name_, mbox, nullptr);
-  }
-  return mbox;
+    (*mailboxes)[mbox->name_] = mbox;
+    return mbox;
+  } else
+    return m->second;
 }
 /** @brief set the receiver of the mailbox to allow eager sends
  *  \param actor The receiving dude
index 97614a9..8102fb1 100644 (file)
@@ -147,10 +147,8 @@ SG_BEGIN_DECL()
 XBT_PRIVATE void SIMIX_context_mod_init();
 XBT_PRIVATE void SIMIX_context_mod_exit();
 
-XBT_PRIVATE smx_context_t SIMIX_context_new(
-  std::function<void()> code,
-  void_pfn_smxprocess_t cleanup_func,
-  smx_actor_t simix_process);
+XBT_PUBLIC(smx_context_t)
+SIMIX_context_new(std::function<void()> code, void_pfn_smxprocess_t cleanup_func, smx_actor_t simix_process);
 
 #ifndef WIN32
 XBT_PUBLIC_DATA(char sigsegv_stack[SIGSTKSZ]);
@@ -174,7 +172,7 @@ XBT_PUBLIC(smx_context_t) SIMIX_context_self(); // public because it's used in s
 XBT_PRIVATE void *SIMIX_context_stack_new();
 XBT_PRIVATE void SIMIX_context_stack_delete(void *stack);
 
-XBT_PRIVATE void SIMIX_context_set_current(smx_context_t context);
+XBT_PUBLIC(void) SIMIX_context_set_current(smx_context_t context);
 XBT_PRIVATE smx_context_t SIMIX_context_get_current();
 
 XBT_PUBLIC(int) SIMIX_process_get_maxpid();
index a88920d..3028445 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015. The SimGrid Team. All rights reserved.               */
+/* Copyright (c) 2015-2017. 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. */
@@ -49,12 +49,12 @@ public:
 
 // BoostContextFactory
 
-bool                BoostContext::parallel_        = false;
-xbt_parmap_t        BoostContext::parmap_          = nullptr;
-uintptr_t           BoostContext::threads_working_ = 0;
+bool BoostContext::parallel_                             = false;
+simgrid::xbt::Parmap<smx_actor_t>* BoostContext::parmap_ = nullptr;
+uintptr_t BoostContext::threads_working_                 = 0;
 xbt_os_thread_key_t BoostContext::worker_id_key_;
-unsigned long       BoostContext::process_index_   = 0;
-BoostContext*       BoostContext::maestro_context_ = nullptr;
+unsigned long BoostContext::process_index_   = 0;
+BoostContext* BoostContext::maestro_context_ = nullptr;
 std::vector<BoostContext*> BoostContext::workers_context_;
 
 BoostContextFactory::BoostContextFactory()
@@ -64,7 +64,7 @@ BoostContextFactory::BoostContextFactory()
   if (BoostContext::parallel_) {
 #if HAVE_THREAD_CONTEXTS
     int nthreads = SIMIX_context_get_nthreads();
-    BoostContext::parmap_ = xbt_parmap_new(nthreads, SIMIX_context_get_parallel_mode());
+    BoostContext::parmap_ = new simgrid::xbt::Parmap<smx_actor_t>(nthreads, SIMIX_context_get_parallel_mode());
     BoostContext::workers_context_.clear();
     BoostContext::workers_context_.resize(nthreads, nullptr);
     BoostContext::maestro_context_ = nullptr;
@@ -79,7 +79,7 @@ BoostContextFactory::~BoostContextFactory()
 {
 #if HAVE_THREAD_CONTEXTS
   if (BoostContext::parmap_) {
-    xbt_parmap_destroy(BoostContext::parmap_);
+    delete BoostContext::parmap_;
     BoostContext::parmap_ = nullptr;
   }
   BoostContext::workers_context_.clear();
@@ -106,19 +106,18 @@ void BoostContextFactory::run_all()
 #if HAVE_THREAD_CONTEXTS
   if (BoostContext::parallel_) {
     BoostContext::threads_working_ = 0;
-    xbt_parmap_apply(BoostContext::parmap_,
-      [](void* arg) {
-        smx_actor_t process = static_cast<smx_actor_t>(arg);
-        BoostContext* context  = static_cast<BoostContext*>(process->context);
-        return context->resume();
-      },
-      simix_global->process_to_run);
+    BoostContext::parmap_->apply(
+        [](smx_actor_t process) {
+          BoostContext* context = static_cast<BoostContext*>(process->context);
+          return context->resume();
+        },
+        simix_global->process_to_run);
   } else
 #endif
   {
-    if (xbt_dynar_is_empty(simix_global->process_to_run))
+    if (simix_global->process_to_run.empty())
       return;
-    smx_actor_t first_process = xbt_dynar_get_as(simix_global->process_to_run, 0, smx_actor_t);
+    smx_actor_t first_process    = simix_global->process_to_run.front();
     BoostContext::process_index_ = 1;
     /* execute the first process */
     static_cast<BoostContext*>(first_process->context)->resume();
@@ -193,11 +192,10 @@ void BoostSerialContext::suspend()
   unsigned long int i              = process_index_;
   process_index_++;
 
-  if (i < xbt_dynar_length(simix_global->process_to_run)) {
+  if (i < simix_global->process_to_run.size()) {
     /* execute the next process */
     XBT_DEBUG("Run next process");
-    next_context =
-        static_cast<BoostSerialContext*>(xbt_dynar_get_as(simix_global->process_to_run, i, smx_actor_t)->context);
+    next_context = static_cast<BoostSerialContext*>(simix_global->process_to_run[i]->context);
   } else {
     /* all processes were run, return to maestro */
     XBT_DEBUG("No more process to run");
@@ -223,12 +221,11 @@ void BoostSerialContext::stop()
 
 void BoostParallelContext::suspend()
 {
-  smx_actor_t next_work = static_cast<smx_actor_t>(xbt_parmap_next(parmap_));
-  BoostParallelContext* next_context = nullptr;
-
-  if (next_work != nullptr) {
+  boost::optional<smx_actor_t> next_work = parmap_->next();
+  BoostParallelContext* next_context;
+  if (next_work) {
     XBT_DEBUG("Run next process");
-    next_context = static_cast<BoostParallelContext*>(next_work->context);
+    next_context = static_cast<BoostParallelContext*>(next_work.get()->context);
   } else {
     XBT_DEBUG("No more processes to run");
     uintptr_t worker_id = (uintptr_t)xbt_os_thread_get_specific(worker_id_key_);
index 578fe10..e8a34c2 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015. The SimGrid Team. All rights reserved.               */
+/* Copyright (c) 2015-2017. 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. */
@@ -9,7 +9,7 @@
 #include <functional>
 #include <vector>
 
-#include <xbt/parmap.h>
+#include <xbt/parmap.hpp>
 
 #include <simgrid/simix.hpp>
 
@@ -27,7 +27,7 @@ class BoostContextFactory;
 class BoostContext : public Context {
 protected: // static
   static bool parallel_;
-  static xbt_parmap_t parmap_;
+  static simgrid::xbt::Parmap<smx_actor_t>* parmap_;
   static std::vector<BoostContext*> workers_context_;
   static uintptr_t threads_working_;
   static xbt_os_thread_key_t worker_id_key_;
index 057d46e..53726aa 100644 (file)
@@ -5,7 +5,7 @@
 
 #include "src/internal_config.h"
 
-#include "xbt/parmap.h"
+#include "xbt/parmap.hpp"
 
 #include "src/simix/smx_private.h"
 #include "mc/mc.h"
@@ -73,7 +73,7 @@ ContextFactory* raw_factory()
 // ***** Loads of static stuff
 
 #if HAVE_THREAD_CONTEXTS
-static xbt_parmap_t raw_parmap;
+static simgrid::xbt::Parmap<smx_actor_t>* raw_parmap;
 static simgrid::kernel::context::RawContext** raw_workers_context;    /* space to save the worker context in each thread */
 static uintptr_t raw_threads_working;     /* number of threads that have started their work */
 static xbt_os_thread_key_t raw_worker_id_key; /* thread-specific storage for the thread id */
@@ -277,8 +277,7 @@ RawContextFactory::RawContextFactory()
 RawContextFactory::~RawContextFactory()
 {
 #if HAVE_THREAD_CONTEXTS
-  if (raw_parmap)
-    xbt_parmap_destroy(raw_parmap);
+  delete raw_parmap;
   xbt_free(raw_workers_context);
 #endif
 }
@@ -337,11 +336,10 @@ void RawContextFactory::run_all()
 
 void RawContextFactory::run_all_serial()
 {
-  if (xbt_dynar_is_empty(simix_global->process_to_run))
+  if (simix_global->process_to_run.empty())
     return;
 
-  smx_actor_t first_process =
-      xbt_dynar_get_as(simix_global->process_to_run, 0, smx_actor_t);
+  smx_actor_t first_process = simix_global->process_to_run.front();
   raw_process_index = 1;
   static_cast<RawContext*>(first_process->context)->resume_serial();
 }
@@ -351,11 +349,9 @@ void RawContextFactory::run_all_parallel()
 #if HAVE_THREAD_CONTEXTS
   raw_threads_working = 0;
   if (raw_parmap == nullptr)
-    raw_parmap = xbt_parmap_new(
-      SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode());
-  xbt_parmap_apply(raw_parmap,
-      [](void* arg) {
-        smx_actor_t process = static_cast<smx_actor_t>(arg);
+    raw_parmap = new simgrid::xbt::Parmap<smx_actor_t>(SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode());
+  raw_parmap->apply(
+      [](smx_actor_t process) {
         RawContext* context = static_cast<RawContext*>(process->context);
         context->resume_parallel();
       },
@@ -379,10 +375,10 @@ void RawContext::suspend_serial()
   RawContext* next_context = nullptr;
   unsigned long int i      = raw_process_index;
   raw_process_index++;
-  if (i < xbt_dynar_length(simix_global->process_to_run)) {
+  if (i < simix_global->process_to_run.size()) {
     /* execute the next process */
     XBT_DEBUG("Run next process");
-    next_context = static_cast<RawContext*>(xbt_dynar_get_as(simix_global->process_to_run, i, smx_actor_t)->context);
+    next_context = static_cast<RawContext*>(simix_global->process_to_run[i]->context);
   } else {
     /* all processes were run, return to maestro */
     XBT_DEBUG("No more process to run");
@@ -396,13 +392,12 @@ void RawContext::suspend_parallel()
 {
 #if HAVE_THREAD_CONTEXTS
   /* determine the next context */
-  smx_actor_t next_work    = static_cast<smx_actor_t>(xbt_parmap_next(raw_parmap));
-  RawContext* next_context = nullptr;
-
-  if (next_work != nullptr) {
+  boost::optional<smx_actor_t> next_work = raw_parmap->next();
+  RawContext* next_context;
+  if (next_work) {
     /* there is a next process to resume */
     XBT_DEBUG("Run next process");
-    next_context = static_cast<RawContext*>(next_work->context);
+    next_context = static_cast<RawContext*>(next_work.get()->context);
   } else {
     /* all processes were run, go to the barrier */
     XBT_DEBUG("No more processes to run");
@@ -450,7 +445,7 @@ void RawContext::resume_parallel()
 /** @brief Resumes all processes ready to run. */
 void RawContextFactory::run_all_adaptative()
 {
-  unsigned long nb_processes = xbt_dynar_length(simix_global->process_to_run);
+  unsigned long nb_processes = simix_global->process_to_run.size();
   if (SIMIX_context_is_parallel() &&
       static_cast<unsigned long>(SIMIX_context_get_parallel_threshold()) < nb_processes) {
     raw_context_parallel = true;
index 85ac35a..4ed2f29 100644 (file)
@@ -58,9 +58,7 @@ void ThreadContextFactory::run_all()
 {
   if (smx_ctx_thread_sem == nullptr) {
     // Serial execution
-    smx_actor_t process;
-    unsigned int cursor;
-    xbt_dynar_foreach(simix_global->process_to_run, cursor, process) {
+    for (smx_actor_t process : simix_global->process_to_run) {
       XBT_DEBUG("Handling %p",process);
       ThreadContext* context = static_cast<ThreadContext*>(process->context);
       xbt_os_sem_release(context->begin_);
@@ -68,12 +66,10 @@ void ThreadContextFactory::run_all()
     }
   } else {
     // Parallel execution
-    unsigned int index;
-    smx_actor_t process;
-    xbt_dynar_foreach(simix_global->process_to_run, index, process)
+    for (smx_actor_t process : simix_global->process_to_run)
       xbt_os_sem_release(static_cast<ThreadContext*>(process->context)->begin_);
-    xbt_dynar_foreach(simix_global->process_to_run, index, process)
-       xbt_os_sem_acquire(static_cast<ThreadContext*>(process->context)->end_);
+    for (smx_actor_t process : simix_global->process_to_run)
+      xbt_os_sem_acquire(static_cast<ThreadContext*>(process->context)->end_);
   }
 }
 
index ac2a4b5..ec26e43 100644 (file)
@@ -7,12 +7,11 @@
 
 #include <ucontext.h>           /* context relative declarations */
 
-#include "src/simix/ActorImpl.hpp"
-#include "src/simix/smx_private.h"
-#include "xbt/parmap.h"
 #include "mc/mc.h"
 #include "src/mc/mc_ignore.h"
-
+#include "src/simix/ActorImpl.hpp"
+#include "src/simix/smx_private.h"
+#include "xbt/parmap.hpp"
 
 /** Many integers are needed to store a pointer
  *
@@ -55,7 +54,7 @@ namespace context {
 }}}
 
 #if HAVE_THREAD_CONTEXTS
-static xbt_parmap_t sysv_parmap;
+static simgrid::xbt::Parmap<smx_actor_t>* sysv_parmap;
 static simgrid::kernel::context::ParallelUContext** sysv_workers_context;   /* space to save the worker's context in each thread */
 static uintptr_t sysv_threads_working;     /* number of threads that have started their work */
 static xbt_os_thread_key_t sysv_worker_id_key; /* thread-specific storage for the thread id */
@@ -146,8 +145,7 @@ UContextFactory::UContextFactory() : ContextFactory("UContextFactory")
 UContextFactory::~UContextFactory()
 {
 #if HAVE_THREAD_CONTEXTS
-  if (sysv_parmap)
-    xbt_parmap_destroy(sysv_parmap);
+  delete sysv_parmap;
   xbt_free(sysv_workers_context);
 #endif
 }
@@ -169,25 +167,24 @@ void UContextFactory::run_all()
       // with simix_global->context_factory (which might not be initialized
       // when bootstrapping):
       if (sysv_parmap == nullptr)
-        sysv_parmap = xbt_parmap_new(
-          SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode());
-
-      xbt_parmap_apply(sysv_parmap,
-        [](void* arg) {
-          smx_actor_t process = (smx_actor_t) arg;
-          ParallelUContext* context = static_cast<ParallelUContext*>(process->context);
-          context->resume();
-        },
-        simix_global->process_to_run);
+        sysv_parmap =
+            new simgrid::xbt::Parmap<smx_actor_t>(SIMIX_context_get_nthreads(), SIMIX_context_get_parallel_mode());
+
+      sysv_parmap->apply(
+          [](smx_actor_t process) {
+            ParallelUContext* context = static_cast<ParallelUContext*>(process->context);
+            context->resume();
+          },
+          simix_global->process_to_run);
 #else
       xbt_die("You asked for a parallel execution, but you don't have any threads.");
 #endif
   } else {
     // Serial:
-    if (xbt_dynar_is_empty(simix_global->process_to_run))
+    if (simix_global->process_to_run.empty())
       return;
 
-    smx_actor_t first_process = xbt_dynar_get_as(simix_global->process_to_run, 0, smx_actor_t);
+    smx_actor_t first_process = simix_global->process_to_run.front();
     sysv_process_index = 1;
     SerialUContext* context = static_cast<SerialUContext*>(first_process->context);
     context->resume();
@@ -270,15 +267,14 @@ void SerialUContext::suspend()
   SerialUContext* next_context = nullptr;
   unsigned long int i = sysv_process_index++;
 
-  if (i < xbt_dynar_length(simix_global->process_to_run)) {
+  if (i < simix_global->process_to_run.size()) {
     /* execute the next process */
     XBT_DEBUG("Run next process");
-    next_context = (SerialUContext*) xbt_dynar_get_as(
-        simix_global->process_to_run,i, smx_actor_t)->context;
+    next_context = static_cast<SerialUContext*>(simix_global->process_to_run[i]->context);
   } else {
     /* all processes were run, return to maestro */
     XBT_DEBUG("No more process to run");
-    next_context = (SerialUContext*) sysv_maestro_context;
+    next_context = static_cast<SerialUContext*>(sysv_maestro_context);
   }
   SIMIX_context_set_current(next_context);
   swapcontext(&this->uc_, &next_context->uc_);
@@ -289,7 +285,7 @@ void SerialUContext::suspend()
 void SerialUContext::resume()
 {
   SIMIX_context_set_current(this);
-  swapcontext(&((SerialUContext*)sysv_maestro_context)->uc_, &this->uc_);
+  swapcontext(&static_cast<SerialUContext*>(sysv_maestro_context)->uc_, &this->uc_);
 }
 
 void ParallelUContext::stop()
@@ -307,11 +303,11 @@ void ParallelUContext::resume()
   // Store the number of my containing body in os-thread-specific area :
   xbt_os_thread_set_specific(sysv_worker_id_key, (void*) worker_id);
   // Get my current soul:
-  ParallelUContext* worker_context = (ParallelUContext*) SIMIX_context_self();
+  ParallelUContext* worker_context = static_cast<ParallelUContext*>(SIMIX_context_self());
   // Write down that this soul is hosted in that body (for now)
   sysv_workers_context[worker_id] = worker_context;
   // Retrieve the system-level info that fuels this soul:
-  ucontext_t* worker_stack = &((ParallelUContext*) worker_context)->uc_;
+  ucontext_t* worker_stack = &worker_context->uc_;
   // Write in simix that I switched my soul
   SIMIX_context_set_current(this);
    // Actually do that using the relevant library call:
@@ -345,15 +341,12 @@ void ParallelUContext::suspend()
 #if HAVE_THREAD_CONTEXTS
   /* determine the next context */
   // Get the next soul to embody now:
-  smx_actor_t next_work = (smx_actor_t) xbt_parmap_next(sysv_parmap);
-  ParallelUContext* next_context = nullptr;
-  // Will contain the next soul to run, either simulated or initial minion's one
-  ucontext_t* next_stack;
-
-  if (next_work != nullptr) {
+  boost::optional<smx_actor_t> next_work = sysv_parmap->next();
+  ParallelUContext* next_context;
+  if (next_work) {
     // There is a next soul to embody (ie, a next process to resume)
     XBT_DEBUG("Run next process");
-    next_context = (ParallelUContext*) next_work->context;
+    next_context = static_cast<ParallelUContext*>(next_work.get()->context);
   } else {
     // All processes were run, go to the barrier
     XBT_DEBUG("No more processes to run");
@@ -362,11 +355,12 @@ void ParallelUContext::suspend()
     uintptr_t worker_id =
         (uintptr_t) xbt_os_thread_get_specific(sysv_worker_id_key);
     // Deduce the initial soul of that body
-    next_context = (ParallelUContext*) sysv_workers_context[worker_id];
+    next_context = sysv_workers_context[worker_id];
     // When given that soul, the body will wait for the next scheduling round
   }
 
-  next_stack = &next_context->uc_;
+  // Will contain the next soul to run, either simulated or initial minion's one
+  ucontext_t* next_stack = &next_context->uc_;
 
   SIMIX_context_set_current(next_context);
   // Get that next soul:
index 52f8bb1..296f3f8 100644 (file)
@@ -16,7 +16,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_cluster, surf, "Routing part of surf"
 namespace simgrid {
 namespace kernel {
 namespace routing {
-ClusterZone::ClusterZone(NetZone* father, const char* name) : NetZoneImpl(father, name)
+ClusterZone::ClusterZone(NetZone* father, std::string name) : NetZoneImpl(father, name)
 {
 }
 
@@ -119,9 +119,9 @@ void ClusterZone::getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges
   }
 }
 
-void ClusterZone::create_links_for_node(sg_platf_cluster_cbarg_t cluster, int id, int /*rank*/, int position)
+void ClusterZone::create_links_for_node(ClusterCreationArgs* cluster, int id, int /*rank*/, int position)
 {
-  char* link_id = bprintf("%s_link_%d", cluster->id, id);
+  std::string link_id = cluster->id + "_link_" + std::to_string(id);
 
   LinkCreationArgs link;
   link.id        = link_id;
@@ -133,17 +133,12 @@ void ClusterZone::create_links_for_node(sg_platf_cluster_cbarg_t cluster, int id
   surf::LinkImpl *linkUp;
   surf::LinkImpl *linkDown;
   if (link.policy == SURF_LINK_FULLDUPLEX) {
-    char* tmp_link = bprintf("%s_UP", link_id);
-    linkUp         = surf::LinkImpl::byName(tmp_link);
-    xbt_free(tmp_link);
-    tmp_link = bprintf("%s_DOWN", link_id);
-    linkDown = surf::LinkImpl::byName(tmp_link);
-    xbt_free(tmp_link);
+    linkUp   = surf::LinkImpl::byName(link_id + "_UP");
+    linkDown = surf::LinkImpl::byName(link_id + "_DOWN");
   } else {
     linkUp   = surf::LinkImpl::byName(link_id);
     linkDown = linkUp;
   }
-  xbt_free(link_id);
   privateLinks_.insert({position, {linkUp, linkDown}});
 }
 }
index 7a347a8..9fe1653 100644 (file)
@@ -67,13 +67,13 @@ namespace routing {
 
 class XBT_PRIVATE ClusterZone : public NetZoneImpl {
 public:
-  explicit ClusterZone(NetZone* father, const char* name);
+  explicit ClusterZone(NetZone* father, std::string name);
 
   void getLocalRoute(NetPoint* src, NetPoint* dst, sg_platf_route_cbarg_t into, double* latency) override;
   void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges) override;
 
-  virtual void create_links_for_node(sg_platf_cluster_cbarg_t cluster, int id, int rank, int position);
-  virtual void parse_specific_arguments(sg_platf_cluster_cbarg_t cluster)
+  virtual void create_links_for_node(ClusterCreationArgs* cluster, int id, int rank, int position);
+  virtual void parse_specific_arguments(ClusterCreationArgs* cluster)
   {
     /* this routing method does not require any specific argument */
   }
index b5c5313..a76b617 100644 (file)
@@ -307,7 +307,7 @@ DijkstraZone::~DijkstraZone()
 
 /* Creation routing model functions */
 
-DijkstraZone::DijkstraZone(NetZone* father, const char* name, bool cached) : RoutedZone(father, name)
+DijkstraZone::DijkstraZone(NetZone* father, std::string name, bool cached) : RoutedZone(father, name)
 {
   if (cached)
     routeCache_ = xbt_dict_new_homogeneous(&route_cache_elem_free);
index 2e089ed..29e8b90 100644 (file)
@@ -43,7 +43,7 @@ namespace routing {
  */
 class XBT_PRIVATE DijkstraZone : public RoutedZone {
 public:
-  DijkstraZone(NetZone* father, const char* name, bool cached);
+  DijkstraZone(NetZone* father, std::string name, bool cached);
   void seal() override;
 
   ~DijkstraZone() override;
index 4975caf..2b76d0b 100644 (file)
@@ -17,7 +17,7 @@ namespace simgrid {
 namespace kernel {
 namespace routing {
 
-DragonflyZone::DragonflyZone(NetZone* father, const char* name) : ClusterZone(father, name)
+DragonflyZone::DragonflyZone(NetZone* father, std::string name) : ClusterZone(father, name)
 {
 }
 
@@ -41,7 +41,7 @@ void DragonflyZone::rankId_to_coords(int rankId, unsigned int (*coords)[4])
   (*coords)[3]         = rankId % numNodesPerBlade_;
 }
 
-void DragonflyZone::parse_specific_arguments(sg_platf_cluster_cbarg_t cluster)
+void DragonflyZone::parse_specific_arguments(ClusterCreationArgs* cluster)
 {
   std::vector<std::string> parameters;
   std::vector<std::string> tmp;
@@ -176,13 +176,13 @@ void DragonflyZone::createLink(std::string id, int numlinks, surf::LinkImpl** li
   std::string tmpID;
   if (this->cluster_->sharing_policy == SURF_LINK_FULLDUPLEX) {
     tmpID     = linkTemplate.id + "_UP";
-    link      = surf::LinkImpl::byName(tmpID.c_str());
+    link      = surf::LinkImpl::byName(tmpID);
     *linkup   = link; // check link?
     tmpID     = linkTemplate.id + "_DOWN";
-    link      = surf::LinkImpl::byName(tmpID.c_str());
+    link      = surf::LinkImpl::byName(tmpID);
     *linkdown = link; // check link ?
   } else {
-    link      = surf::LinkImpl::byName(linkTemplate.id.c_str());
+    link      = surf::LinkImpl::byName(linkTemplate.id);
     *linkup   = link;
     *linkdown = link;
   }
index b974803..ceeeda3 100644 (file)
@@ -60,11 +60,11 @@ public:
  */
 class XBT_PRIVATE DragonflyZone : public ClusterZone {
 public:
-  explicit DragonflyZone(NetZone* father, const char* name);
+  explicit DragonflyZone(NetZone* father, std::string name);
   ~DragonflyZone() override;
   //      void create_links_for_node(sg_platf_cluster_cbarg_t cluster, int id, int rank, int position) override;
   void getLocalRoute(NetPoint* src, NetPoint* dst, sg_platf_route_cbarg_t into, double* latency) override;
-  void parse_specific_arguments(sg_platf_cluster_cbarg_t cluster) override;
+  void parse_specific_arguments(ClusterCreationArgs* cluster) override;
   void seal() override;
   void generateRouters();
   void generateLinks();
@@ -72,7 +72,7 @@ public:
 
 private:
   void rankId_to_coords(int rankId, unsigned int (*coords)[4]);
-  sg_platf_cluster_cbarg_t cluster_;
+  ClusterCreationArgs* cluster_;
   unsigned int numNodesPerBlade_    = 0;
   unsigned int numBladesPerChassis_ = 0;
   unsigned int numChassisPerGroup_  = 0;
index 732cab8..3ef2736 100644 (file)
@@ -15,7 +15,7 @@ namespace simgrid {
 namespace kernel {
 namespace routing {
 
-EmptyZone::EmptyZone(NetZone* father, const char* name) : NetZoneImpl(father, name)
+EmptyZone::EmptyZone(NetZone* father, std::string name) : NetZoneImpl(father, name)
 {
 }
 
index a63d75f..888d744 100644 (file)
@@ -21,7 +21,7 @@ namespace routing {
 
 class XBT_PRIVATE EmptyZone : public NetZoneImpl {
 public:
-  explicit EmptyZone(NetZone* father, const char* name);
+  explicit EmptyZone(NetZone* father, std::string name);
   ~EmptyZone() override;
 
   void getLocalRoute(NetPoint* src, NetPoint* dst, sg_platf_route_cbarg_t into, double* latency) override
index 49f8b8b..c6485c8 100644 (file)
@@ -20,7 +20,7 @@ namespace simgrid {
 namespace kernel {
 namespace routing {
 
-FatTreeZone::FatTreeZone(NetZone* father, const char* name) : ClusterZone(father, name)
+FatTreeZone::FatTreeZone(NetZone* father, std::string name) : ClusterZone(father, name)
 {
   XBT_DEBUG("Creating a new fat tree.");
 }
@@ -241,9 +241,9 @@ void FatTreeZone::generateSwitches()
     this->nodesByLevel_[0] *= this->lowerLevelNodesNumber_[i];
 
   if (this->nodesByLevel_[0] != this->nodes_.size()) {
-    surf_parse_error("The number of provided nodes does not fit with the wanted topology."
-                     " Please check your platform description (We need %u nodes, we got %zu)",
-                     this->nodesByLevel_[0], this->nodes_.size());
+    surf_parse_error(std::string("The number of provided nodes does not fit with the wanted topology.") +
+                     " Please check your platform description (We need " + std::to_string(this->nodesByLevel_[0]) +
+                     "nodes, we got " + std::to_string(this->nodes_.size()));
     return;
   }
 
@@ -356,7 +356,7 @@ void FatTreeZone::addLink(FatTreeNode* parent, unsigned int parentPort, FatTreeN
   this->links_.push_back(newLink);
 }
 
-void FatTreeZone::parse_specific_arguments(sg_platf_cluster_cbarg_t cluster)
+void FatTreeZone::parse_specific_arguments(ClusterCreationArgs* cluster)
 {
   std::vector<std::string> parameters;
   std::vector<std::string> tmp;
@@ -441,7 +441,7 @@ void FatTreeZone::generateDotFile(const std::string& filename) const
   file.close();
 }
 
-FatTreeNode::FatTreeNode(sg_platf_cluster_cbarg_t cluster, int id, int level, int position)
+FatTreeNode::FatTreeNode(ClusterCreationArgs* cluster, int id, int level, int position)
     : id(id), level(level), position(position)
 {
   LinkCreationArgs linkTemplate;
@@ -451,7 +451,7 @@ FatTreeNode::FatTreeNode(sg_platf_cluster_cbarg_t cluster, int id, int level, in
     linkTemplate.policy    = SURF_LINK_SHARED;
     linkTemplate.id        = "limiter_"+std::to_string(id);
     sg_platf_new_link(&linkTemplate);
-    this->limiterLink = surf::LinkImpl::byName(linkTemplate.id.c_str());
+    this->limiterLink = surf::LinkImpl::byName(linkTemplate.id);
   }
   if (cluster->loopback_bw || cluster->loopback_lat) {
     linkTemplate.bandwidth = cluster->loopback_bw;
@@ -459,11 +459,11 @@ FatTreeNode::FatTreeNode(sg_platf_cluster_cbarg_t cluster, int id, int level, in
     linkTemplate.policy    = SURF_LINK_FATPIPE;
     linkTemplate.id        = "loopback_"+ std::to_string(id);
     sg_platf_new_link(&linkTemplate);
-    this->loopback = surf::LinkImpl::byName(linkTemplate.id.c_str());
+    this->loopback = surf::LinkImpl::byName(linkTemplate.id);
   }
 }
 
-FatTreeLink::FatTreeLink(sg_platf_cluster_cbarg_t cluster, FatTreeNode* downNode, FatTreeNode* upNode)
+FatTreeLink::FatTreeLink(ClusterCreationArgs* cluster, FatTreeNode* downNode, FatTreeNode* upNode)
     : upNode(upNode), downNode(downNode)
 {
   static int uniqueId = 0;
@@ -477,11 +477,11 @@ FatTreeLink::FatTreeLink(sg_platf_cluster_cbarg_t cluster, FatTreeNode* downNode
 
   if (cluster->sharing_policy == SURF_LINK_FULLDUPLEX) {
     std::string tmpID = std::string(linkTemplate.id) + "_UP";
-    this->upLink      = surf::LinkImpl::byName(tmpID.c_str()); // check link?
+    this->upLink      = surf::LinkImpl::byName(tmpID); // check link?
     tmpID          = std::string(linkTemplate.id) + "_DOWN";
-    this->downLink    = surf::LinkImpl::byName(tmpID.c_str()); // check link ?
+    this->downLink    = surf::LinkImpl::byName(tmpID); // check link ?
   } else {
-    this->upLink   = surf::LinkImpl::byName(linkTemplate.id.c_str());
+    this->upLink   = surf::LinkImpl::byName(linkTemplate.id);
     this->downLink = this->upLink;
   }
   uniqueId++;
index 40b439a..c08e69e 100644 (file)
@@ -51,7 +51,7 @@ public:
    * instead of passing by an upper level switch.
    */
   surf::LinkImpl* loopback;
-  FatTreeNode(sg_platf_cluster_cbarg_t cluster, int id, int level, int position);
+  FatTreeNode(ClusterCreationArgs* cluster, int id, int level, int position);
 };
 
 /** \brief Link in a fat tree (@ref FatTreeZone).
@@ -61,7 +61,7 @@ public:
  */
 class FatTreeLink {
 public:
-  FatTreeLink(sg_platf_cluster_cbarg_t cluster, FatTreeNode* source, FatTreeNode* destination);
+  FatTreeLink(ClusterCreationArgs* cluster, FatTreeNode* source, FatTreeNode* destination);
   /** Link going up in the tree */
   surf::LinkImpl* upLink;
   /** Link going down in the tree */
@@ -98,7 +98,7 @@ public:
  */
 class XBT_PRIVATE FatTreeZone : public ClusterZone {
 public:
-  explicit FatTreeZone(NetZone* father, const char* name);
+  explicit FatTreeZone(NetZone* father, std::string name);
   ~FatTreeZone() override;
   void getLocalRoute(NetPoint* src, NetPoint* dst, sg_platf_route_cbarg_t into, double* latency) override;
 
@@ -113,7 +113,7 @@ public:
    *
    * It will also store the cluster for future use.
    */
-  void parse_specific_arguments(sg_platf_cluster_cbarg_t cluster) override;
+  void parse_specific_arguments(ClusterCreationArgs* cluster) override;
   void addProcessingNode(int id);
   void generateDotFile(const std::string& filename = "fatTree.dot") const;
 
@@ -129,7 +129,7 @@ private:
   std::vector<FatTreeLink*> links_;
   std::vector<unsigned int> nodesByLevel_;
 
-  sg_platf_cluster_cbarg_t cluster_ = nullptr;
+  ClusterCreationArgs* cluster_ = nullptr;
 
   void addLink(FatTreeNode* parent, unsigned int parentPort, FatTreeNode* child, unsigned int childPort);
   int getLevelPosition(const unsigned int level);
index 863c876..329eff9 100644 (file)
@@ -21,7 +21,7 @@ namespace simgrid {
 namespace kernel {
 namespace routing {
 
-FloydZone::FloydZone(NetZone* father, const char* name) : RoutedZone(father, name)
+FloydZone::FloydZone(NetZone* father, std::string name) : RoutedZone(father, name)
 {
   predecessorTable_ = nullptr;
   costTable_        = nullptr;
index f1cb156..a612425 100644 (file)
@@ -23,7 +23,7 @@ namespace routing {
  */
 class XBT_PRIVATE FloydZone : public RoutedZone {
 public:
-  explicit FloydZone(NetZone* father, const char* name);
+  explicit FloydZone(NetZone* father, std::string name);
   ~FloydZone() override;
 
   void getLocalRoute(NetPoint* src, NetPoint* dst, sg_platf_route_cbarg_t into, double* latency) override;
index 9bae539..dbb5a80 100644 (file)
@@ -14,7 +14,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_full, surf, "Routing part of surf");
 namespace simgrid {
 namespace kernel {
 namespace routing {
-FullZone::FullZone(NetZone* father, const char* name) : RoutedZone(father, name)
+FullZone::FullZone(NetZone* father, std::string name) : RoutedZone(father, name)
 {
 }
 
index f13764f..ab13bc5 100644 (file)
@@ -15,13 +15,12 @@ namespace routing {
 /** @ingroup ROUTING_API
  *  @brief NetZone with an explicit routing provided by the user
  *
- *  The full communication matrix is provided at creation, so this model
- *  has the highest expressive power and the lowest computational requirements,
- *  but also the highest memory requirements (both in platform file and in memory).
+ *  The full communication matrix is provided at creation, so this model has the highest expressive power and the lowest
+ *  computational requirements, but also the highest memory requirements (both in platform file and in memory).
  */
 class XBT_PRIVATE FullZone : public RoutedZone {
 public:
-  explicit FullZone(NetZone* father, const char* name);
+  explicit FullZone(NetZone* father, std::string name);
   void seal() override;
   ~FullZone() override;
 
index 5f846b1..e128d57 100644 (file)
@@ -26,14 +26,15 @@ public:
   std::vector<surf::LinkImpl*> links;
 };
 
-NetZoneImpl::NetZoneImpl(NetZone* father, const char* name) : NetZone(father, name)
+NetZoneImpl::NetZoneImpl(NetZone* father, std::string name) : NetZone(father, name)
 {
-  xbt_assert(nullptr == simgrid::s4u::Engine::getInstance()->getNetpointByNameOrNull(name),
-             "Refusing to create a second NetZone called '%s'.", name);
+  xbt_assert(nullptr == simgrid::s4u::Engine::getInstance()->getNetpointByNameOrNull(name.c_str()),
+             "Refusing to create a second NetZone called '%s'.", name.c_str());
 
   netpoint_ = new NetPoint(name, NetPoint::Type::NetZone, static_cast<NetZoneImpl*>(father));
-  XBT_DEBUG("NetZone '%s' created with the id '%u'", name, netpoint_->id());
+  XBT_DEBUG("NetZone '%s' created with the id '%u'", name.c_str(), netpoint_->id());
 }
+
 NetZoneImpl::~NetZoneImpl()
 {
   for (auto& kv : bypassRoutes_)
@@ -260,20 +261,18 @@ bool NetZoneImpl::getBypassRoute(routing::NetPoint* src, routing::NetPoint* dst,
     for (int i = 0; i < max; i++) {
       if (i <= max_index_src && max <= max_index_dst) {
         key = {path_src.at(i)->netpoint_, path_dst.at(max)->netpoint_};
-        try {
-          bypassedRoute = bypassRoutes_.at(key);
+        auto bpr = bypassRoutes_.find(key);
+        if (bpr != bypassRoutes_.end()) {
+          bypassedRoute = bpr->second;
           break;
-        } catch (std::out_of_range& unfound) {
-          // Do nothing
         }
       }
       if (max <= max_index_src && i <= max_index_dst) {
         key = {path_src.at(max)->netpoint_, path_dst.at(i)->netpoint_};
-        try {
-          bypassedRoute = bypassRoutes_.at(key);
+        auto bpr = bypassRoutes_.find(key);
+        if (bpr != bypassRoutes_.end()) {
+          bypassedRoute = bpr->second;
           break;
-        } catch (std::out_of_range& unfound) {
-          // Do nothing
         }
       }
     }
@@ -283,11 +282,10 @@ bool NetZoneImpl::getBypassRoute(routing::NetPoint* src, routing::NetPoint* dst,
 
     if (max <= max_index_src && max <= max_index_dst) {
       key = {path_src.at(max)->netpoint_, path_dst.at(max)->netpoint_};
-      try {
-        bypassedRoute = bypassRoutes_.at(key);
+      auto bpr = bypassRoutes_.find(key);
+      if (bpr != bypassRoutes_.end()) {
+        bypassedRoute = bpr->second;
         break;
-      } catch (std::out_of_range& unfound) {
-        // Do nothing
       }
     }
   }
index e4a297c..98296b5 100644 (file)
@@ -53,7 +53,7 @@ XBT_PUBLIC_CLASS NetZoneImpl : public s4u::NetZone
   friend simgrid::kernel::EngineImpl; // it destroys netRoot_
 
 protected:
-  explicit NetZoneImpl(NetZone * father, const char* name);
+  explicit NetZoneImpl(NetZone * father, std::string name);
   virtual ~NetZoneImpl();
 
 public:
index 2647781..cd223f1 100644 (file)
@@ -65,7 +65,7 @@ namespace simgrid {
 namespace kernel {
 namespace routing {
 
-RoutedZone::RoutedZone(NetZone* father, const char* name) : NetZoneImpl(father, name)
+RoutedZone::RoutedZone(NetZone* father, std::string name) : NetZoneImpl(father, name)
 {
 }
 
index 25be9b4..3904232 100644 (file)
@@ -50,7 +50,7 @@ namespace routing {
 
 class XBT_PRIVATE RoutedZone : public NetZoneImpl {
 public:
-  explicit RoutedZone(NetZone* father, const char* name);
+  explicit RoutedZone(NetZone* father, std::string name);
 
   void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges) override;
   virtual sg_platf_route_cbarg_t newExtendedRoute(RoutingMode hierarchy, sg_platf_route_cbarg_t routearg,
index 399ac2e..945fa9e 100644 (file)
@@ -27,11 +27,11 @@ inline void rankId_to_coords(int rankId, std::vector<unsigned int> dimensions, u
 namespace simgrid {
 namespace kernel {
 namespace routing {
-TorusZone::TorusZone(NetZone* father, const char* name) : ClusterZone(father, name)
+TorusZone::TorusZone(NetZone* father, std::string name) : ClusterZone(father, name)
 {
 }
 
-void TorusZone::create_links_for_node(sg_platf_cluster_cbarg_t cluster, int id, int rank, int position)
+void TorusZone::create_links_for_node(ClusterCreationArgs* cluster, int id, int rank, int position)
 {
   /* Create all links that exist in the torus. Each rank creates @a dimensions-1 links */
   int dim_product = 1; // Needed to calculate the next neighbor_id
@@ -45,7 +45,8 @@ void TorusZone::create_links_for_node(sg_platf_cluster_cbarg_t cluster, int id,
                                ? rank - (current_dimension - 1) * dim_product
                                : rank + dim_product;
     // name of neighbor is not right for non contiguous cluster radicals (as id != rank in this case)
-    char* link_id  = bprintf("%s_link_from_%i_to_%i", cluster->id, id, neighbor_rank_id);
+    std::string link_id =
+        std::string(cluster->id) + "_link_from_" + std::to_string(id) + "_to_" + std::to_string(neighbor_rank_id);
     link.id        = link_id;
     link.bandwidth = cluster->bw;
     link.latency   = cluster->lat;
@@ -54,12 +55,10 @@ void TorusZone::create_links_for_node(sg_platf_cluster_cbarg_t cluster, int id,
     surf::LinkImpl* linkUp;
     surf::LinkImpl* linkDown;
     if (link.policy == SURF_LINK_FULLDUPLEX) {
-      char* tmp_link = bprintf("%s_UP", link_id);
+      std::string tmp_link = link_id + "_UP";
       linkUp         = surf::LinkImpl::byName(tmp_link);
-      free(tmp_link);
-      tmp_link = bprintf("%s_DOWN", link_id);
+      tmp_link             = link_id + "_DOWN";
       linkDown = surf::LinkImpl::byName(tmp_link);
-      free(tmp_link);
     } else {
       linkUp   = surf::LinkImpl::byName(link_id);
       linkDown = linkUp;
@@ -71,24 +70,22 @@ void TorusZone::create_links_for_node(sg_platf_cluster_cbarg_t cluster, int id,
      */
     privateLinks_.insert({position + j, {linkUp, linkDown}});
     dim_product *= current_dimension;
-    xbt_free(link_id);
   }
   rank++;
 }
 
-void TorusZone::parse_specific_arguments(sg_platf_cluster_cbarg_t cluster)
+void TorusZone::parse_specific_arguments(ClusterCreationArgs* cluster)
 {
   std::vector<std::string> dimensions;
   boost::split(dimensions, cluster->topo_parameters, boost::is_any_of(","));
 
   if (not dimensions.empty()) {
     /* We are in a torus cluster
-     * Parse attribute dimensions="dim1,dim2,dim3,...,dimN" and safe it in a vector.
+     * Parse attribute dimensions="dim1,dim2,dim3,...,dimN" and save them into a vector.
      * Additionally, we need to know how many ranks we have in total
      */
-    for (auto group : dimensions) {
-      dimensions_.push_back(surf_parse_get_int(group.c_str()));
-    }
+    for (auto group : dimensions)
+      dimensions_.push_back(surf_parse_get_int(group));
 
     linkCountPerNode_ = dimensions_.size();
   }
@@ -119,21 +116,16 @@ void TorusZone::getLocalRoute(NetPoint* src, NetPoint* dst, sg_platf_route_cbarg
   unsigned int current_node = src->id();
   unsigned int next_node    = 0;
   /*
-   * Arrays that hold the coordinates of the current node and
-   * the target; comparing the values at the i-th position of
-   * both arrays, we can easily assess whether we need to route
-   * into this dimension or not.
+   * Arrays that hold the coordinates of the current node andthe target; comparing the values at the i-th position of
+   * both arrays, we can easily assess whether we need to route into this dimension or not.
    */
   unsigned int myCoords[4];
   rankId_to_coords(src->id(), dimensions_, &myCoords);
   unsigned int targetCoords[4];
   rankId_to_coords(dst->id(), dimensions_, &targetCoords);
   /*
-   * linkOffset describes the offset where the link
-   * we want to use is stored
-   * (+1 is added because each node has a link from itself to itself,
-   * which can only be the case if src->m_id == dst->m_id -- see above
-   * for this special case)
+   * linkOffset describes the offset where the link we want to use is stored(+1 is added because each node has a link
+   * from itself to itself, which can only be the case if src->m_id == dst->m_id -- see above for this special case)
    */
   int nodeOffset = (dimensions_.size() + 1) * src->id();
 
index bf0c845..56d4c70 100644 (file)
@@ -20,10 +20,10 @@ namespace routing {
 
 class XBT_PRIVATE TorusZone : public ClusterZone {
 public:
-  explicit TorusZone(NetZone* father, const char* name);
-  void create_links_for_node(sg_platf_cluster_cbarg_t cluster, int id, int rank, int position) override;
+  explicit TorusZone(NetZone* father, std::string name);
+  void create_links_for_node(ClusterCreationArgs* cluster, int id, int rank, int position) override;
   void getLocalRoute(NetPoint* src, NetPoint* dst, sg_platf_route_cbarg_t into, double* latency) override;
-  void parse_specific_arguments(sg_platf_cluster_cbarg_t cluster) override;
+  void parse_specific_arguments(ClusterCreationArgs* cluster) override;
 
 private:
   std::vector<unsigned int> dimensions_;
index 8ebb7fa..9901722 100644 (file)
@@ -57,7 +57,8 @@ static std::vector<double>* getCoordsFromNetpoint(NetPoint* np)
              (np->isNetZone() ? "Netzone" : (np->isHost() ? "Host" : "Router")), np->cname(), np);
   return &coords->coords;
 }
-VivaldiZone::VivaldiZone(NetZone* father, const char* name) : ClusterZone(father, name)
+
+VivaldiZone::VivaldiZone(NetZone* father, std::string name) : ClusterZone(father, name)
 {
 }
 
@@ -86,25 +87,27 @@ void VivaldiZone::getLocalRoute(NetPoint* src, NetPoint* dst, sg_platf_route_cba
   }
 
   /* Retrieve the private links */
-  try {
-    std::pair<surf::LinkImpl*, surf::LinkImpl*> info = privateLinks_.at(src->id());
+  auto src_link = privateLinks_.find(src->id());
+  if (src_link != privateLinks_.end()) {
+    std::pair<surf::LinkImpl*, surf::LinkImpl*> info = src_link->second;
     if (info.first) {
       route->link_list->push_back(info.first);
       if (lat)
         *lat += info.first->latency();
     }
-  } catch (std::out_of_range& unfound) {
+  } else {
     XBT_DEBUG("Source of private link (%u) doesn't exist", src->id());
   }
 
-  try {
-    std::pair<surf::LinkImpl*, surf::LinkImpl*> info = privateLinks_.at(dst->id());
+  auto dst_link = privateLinks_.find(dst->id());
+  if (dst_link != privateLinks_.end()) {
+    std::pair<surf::LinkImpl*, surf::LinkImpl*> info = dst_link->second;
     if (info.second) {
       route->link_list->push_back(info.second);
       if (lat)
         *lat += info.second->latency();
     }
-  } catch (std::out_of_range& unfound) {
+  } else {
     XBT_DEBUG("Destination of private link (%u) doesn't exist", dst->id());
   }
 
index 83fc6b2..64ea9bd 100644 (file)
@@ -45,7 +45,7 @@ namespace routing {
 
 class XBT_PRIVATE VivaldiZone : public ClusterZone {
 public:
-  explicit VivaldiZone(NetZone* father, const char* name);
+  explicit VivaldiZone(NetZone* father, std::string name);
 
   void setPeerLink(NetPoint* netpoint, double bw_in, double bw_out, std::string coord);
   void getLocalRoute(NetPoint* src, NetPoint* dst, sg_platf_route_cbarg_t into, double* latency) override;
index 0ad9375..8bb4661 100644 (file)
@@ -1,5 +1,4 @@
-/* Copyright (c) 2004-2015. The SimGrid Team.
- * All rights reserved.                                                     */
+/* Copyright (c) 2004-2017. 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. */
index 58b9fe2..5fa74b3 100644 (file)
@@ -1,5 +1,4 @@
-/* Copyright (c) 2004-2015. The SimGrid Team.
- * All rights reserved.                                                     */
+/* Copyright (c) 2004-2015. 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. */
@@ -63,7 +62,8 @@ typedef std::vector<LocationListEntry> LocationList;
 class Location {
 private:
   void* memory_;
-  int register_id_;
+  int register_id_ = 0;
+
 public:
   explicit Location(void* x) : memory_(x) {}
   explicit Location(int register_id) : memory_(nullptr), register_id_(register_id) {}
index f3bc7d9..a12f15c 100644 (file)
@@ -35,13 +35,9 @@ void wait_for_requests()
 #if SIMGRID_HAVE_MC
   xbt_assert(mc_model_checker == nullptr, "This must be called from the client");
 #endif
-
-  smx_actor_t process;
-  unsigned int iter;
-
-  while (not xbt_dynar_is_empty(simix_global->process_to_run)) {
+  while (not simix_global->process_to_run.empty()) {
     SIMIX_process_runall();
-    xbt_dynar_foreach(simix_global->process_that_ran, iter, process) {
+    for (smx_actor_t process : simix_global->process_that_ran) {
       smx_simcall_t req = &process->simcall;
       if (req->call != SIMCALL_NONE && not simgrid::mc::request_is_visible(req))
         SIMIX_simcall_handle(req, 0);
index 4a0509d..f2f926b 100644 (file)
@@ -113,7 +113,6 @@ static void MSG_exit() {
   if (msg_global==nullptr)
     return;
 
-  TRACE_surf_resource_utilization_release();
   TRACE_end();
   delete msg_global;
   msg_global = nullptr;
index 776adfe..3b06983 100644 (file)
@@ -73,7 +73,8 @@ void MSG_file_dump (msg_file_t fd){
            "\t\tStorage Id: '%s'\n"
            "\t\tStorage Type: '%s'\n"
            "\t\tFile Descriptor Id: %d",
-           fd->getPath(), fd->size(), fd->mount_point.c_str(), fd->storageId, fd->storage_type, fd->desc_id);
+           fd->getPath(), fd->size(), fd->mount_point.c_str(), fd->storageId.c_str(), fd->storage_type.c_str(),
+           fd->desc_id);
 }
 
 /** \ingroup msg_file
index 18878b0..d26778e 100644 (file)
@@ -6,6 +6,7 @@
 #include "msg_private.h"
 #include "simgrid/s4u/Host.hpp"
 #include "src/simix/ActorImpl.hpp"
+#include "src/simix/smx_private.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_process, msg, "Logging specific to MSG (process)");
 
@@ -304,7 +305,12 @@ msg_process_t MSG_process_from_PID(int PID)
 
 /** @brief returns a list of all currently existing processes */
 xbt_dynar_t MSG_processes_as_dynar() {
-  return SIMIX_processes_as_dynar();
+  xbt_dynar_t res = xbt_dynar_new(sizeof(smx_actor_t), nullptr);
+  for (auto kv : simix_global->process_list) {
+    smx_actor_t actor = kv.second;
+    xbt_dynar_push(res, &actor);
+  }
+  return res;
 }
 
 /** @brief Return the current number MSG processes. */
index 99a3c5d..1b3829c 100644 (file)
@@ -184,34 +184,7 @@ void MSG_vm_destroy(msg_vm_t vm)
  */
 void MSG_vm_start(msg_vm_t vm)
 {
-  simgrid::simix::kernelImmediate([vm]() {
-    simgrid::vm::VmHostExt::ensureVmExtInstalled();
-
-    simgrid::s4u::Host* pm = vm->pimpl_vm_->getPm();
-    if (pm->extension<simgrid::vm::VmHostExt>() == nullptr)
-      pm->extension_set(new simgrid::vm::VmHostExt());
-
-    long pm_ramsize   = pm->extension<simgrid::vm::VmHostExt>()->ramsize;
-    int pm_overcommit = pm->extension<simgrid::vm::VmHostExt>()->overcommit;
-    long vm_ramsize   = vm->getRamsize();
-
-    if (pm_ramsize && not pm_overcommit) { /* Only verify that we don't overcommit on need */
-      /* Retrieve the memory occupied by the VMs on that host. Yep, we have to traverse all VMs of all hosts for that */
-      long total_ramsize_of_vms = 0;
-      for (simgrid::s4u::VirtualMachine* ws_vm : simgrid::vm::VirtualMachineImpl::allVms_)
-        if (pm == ws_vm->pimpl_vm_->getPm())
-          total_ramsize_of_vms += ws_vm->pimpl_vm_->getRamsize();
-
-      if (vm_ramsize > pm_ramsize - total_ramsize_of_vms) {
-        XBT_WARN("cannnot start %s@%s due to memory shortage: vm_ramsize %ld, free %ld, pm_ramsize %ld (bytes).",
-                 vm->getCname(), pm->getCname(), vm_ramsize, pm_ramsize - total_ramsize_of_vms, pm_ramsize);
-        THROWF(vm_error, 0, "Memory shortage on host '%s', VM '%s' cannot be started", pm->getCname(), vm->getCname());
-      }
-    }
-
-    vm->pimpl_vm_->setState(SURF_VM_STATE_RUNNING);
-  });
-
+  vm->start();
   if (TRACE_msg_vm_is_enabled()) {
     container_t vm_container = PJ_container_get(vm->getCname());
     type_t type              = PJ_type_get("MSG_VM_STATE", vm_container->type);
@@ -229,27 +202,27 @@ void MSG_vm_start(msg_vm_t vm)
  */
 void MSG_vm_shutdown(msg_vm_t vm)
 {
-  smx_actor_t issuer=SIMIX_process_self();
+  smx_actor_t issuer = SIMIX_process_self();
   simgrid::simix::kernelImmediate([vm, issuer]() { vm->pimpl_vm_->shutdown(issuer); });
 
-  // Make sure that the processes in the VM are killed in this scheduling round before processing
-  // (eg with the VM destroy)
+  // Make sure that processes in the VM are killed in this scheduling round before processing (eg with the VM destroy)
   MSG_process_sleep(0.);
 }
 
-static inline char *get_mig_process_tx_name(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm)
+static std::string get_mig_process_tx_name(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm)
 {
-  return bprintf("__pr_mig_tx:%s(%s-%s)", vm->getCname(), src_pm->getCname(), dst_pm->getCname());
+  return std::string("__pr_mig_tx:") + vm->getCname() + "(" + src_pm->getCname() + "-" + dst_pm->getCname() + ")";
 }
 
-static inline char *get_mig_process_rx_name(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm)
+static std::string get_mig_process_rx_name(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm)
 {
-  return bprintf("__pr_mig_rx:%s(%s-%s)", vm->getCname(), src_pm->getCname(), dst_pm->getCname());
+  return std::string("__pr_mig_rx:") + vm->getCname() + "(" + src_pm->getCname() + "-" + dst_pm->getCname() + ")";
 }
 
-static inline char *get_mig_task_name(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm, int stage)
+static std::string get_mig_task_name(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm, int stage)
 {
-  return bprintf("__task_mig_stage%d:%s(%s-%s)", stage, vm->getCname(), src_pm->getCname(), dst_pm->getCname());
+  return std::string("__task_mig_stage") + std::to_string(stage) + ":" + vm->getCname() + "(" + src_pm->getCname() +
+         "-" + dst_pm->getCname() + ")";
 }
 
 struct migration_session {
@@ -273,7 +246,7 @@ static int migration_rx_fun(int argc, char *argv[])
 
   bool received_finalize = false;
 
-  char *finalize_task_name = get_mig_task_name(ms->vm, ms->src_pm, ms->dst_pm, 3);
+  std::string finalize_task_name = get_mig_task_name(ms->vm, ms->src_pm, ms->dst_pm, 3);
   while (not received_finalize) {
     msg_task_t task = nullptr;
     int ret         = MSG_task_recv(&task, ms->mbox);
@@ -281,16 +254,14 @@ static int migration_rx_fun(int argc, char *argv[])
     if (ret != MSG_OK) {
       // An error occurred, clean the code and return
       // The owner did not change, hence the task should be only destroyed on the other side
-      xbt_free(finalize_task_name);
       return 0;
     }
 
-    if (strcmp(task->name, finalize_task_name) == 0)
+    if (finalize_task_name == task->name)
       received_finalize = 1;
 
     MSG_task_destroy(task);
   }
-  xbt_free(finalize_task_name);
 
   // Here Stage 1, 2  and 3 have been performed.
   // Hence complete the migration
@@ -343,8 +314,8 @@ static int migration_rx_fun(int argc, char *argv[])
   }
 
   // Inform the SRC that the migration has been correctly performed
-  char *task_name = get_mig_task_name(ms->vm, ms->src_pm, ms->dst_pm, 4);
-  msg_task_t task = MSG_task_create(task_name, 0, 0, nullptr);
+  std::string task_name = get_mig_task_name(ms->vm, ms->src_pm, ms->dst_pm, 4);
+  msg_task_t task       = MSG_task_create(task_name.c_str(), 0, 0, nullptr);
   msg_error_t ret = MSG_task_send(task, ms->mbox_ctl);
   // xbt_assert(ret == MSG_OK);
   if(ret == MSG_HOST_FAILURE){
@@ -356,7 +327,6 @@ static int migration_rx_fun(int argc, char *argv[])
     // The SRC has crashed, this is not a problem has the VM has been correctly migrated on the DST node
     MSG_task_destroy(task);
   }
-  xbt_free(task_name);
 
   XBT_DEBUG("mig: rx_done");
   return 0;
@@ -479,8 +449,8 @@ static sg_size_t send_migration_data(msg_vm_t vm, msg_host_t src_pm, msg_host_t
                                      int stage, int stage2_round, double mig_speed, double timeout)
 {
   sg_size_t sent = 0;
-  char *task_name = get_mig_task_name(vm, src_pm, dst_pm, stage);
-  msg_task_t task = MSG_task_create(task_name, 0, static_cast<double>(size), nullptr);
+  std::string task_name = get_mig_task_name(vm, src_pm, dst_pm, stage);
+  msg_task_t task       = MSG_task_create(task_name.c_str(), 0, static_cast<double>(size), nullptr);
 
   double clock_sta = MSG_get_clock();
 
@@ -490,8 +460,6 @@ static sg_size_t send_migration_data(msg_vm_t vm, msg_host_t src_pm, msg_host_t
   else
     ret = MSG_task_send(task, mbox);
 
-  xbt_free(task_name);
-
   if (ret == MSG_OK) {
     sent = size;
   } else if (ret == MSG_TIMEOUT) {
@@ -752,18 +720,12 @@ void MSG_vm_migrate(msg_vm_t vm, msg_host_t dst_pm)
   ms->mbox_ctl = bprintf("__mbox_mig_ctl:%s(%s-%s)", vm->getCname(), src_pm->getCname(), dst_pm->getCname());
   ms->mbox     = bprintf("__mbox_mig_src_dst:%s(%s-%s)", vm->getCname(), src_pm->getCname(), dst_pm->getCname());
 
-  char *pr_rx_name = get_mig_process_rx_name(vm, src_pm, dst_pm);
-  char *pr_tx_name = get_mig_process_tx_name(vm, src_pm, dst_pm);
+  std::string pr_rx_name = get_mig_process_rx_name(vm, src_pm, dst_pm);
+  std::string pr_tx_name = get_mig_process_tx_name(vm, src_pm, dst_pm);
 
-  char** argv = xbt_new(char*, 2);
-  argv[0]     = pr_rx_name;
-  argv[1]     = nullptr;
-  MSG_process_create_with_arguments(pr_rx_name, migration_rx_fun, ms, dst_pm, 1, argv);
+  MSG_process_create(pr_rx_name.c_str(), migration_rx_fun, ms, dst_pm);
 
-  argv        = xbt_new(char*, 2);
-  argv[0]     = pr_tx_name;
-  argv[1]     = nullptr;
-  MSG_process_create_with_arguments(pr_tx_name, migration_tx_fun, ms, src_pm, 1, argv);
+  MSG_process_create(pr_tx_name.c_str(), migration_tx_fun, ms, src_pm);
 
   /* wait until the migration have finished or on error has occurred */
   XBT_DEBUG("wait for reception of the final ACK (i.e. migration has been correctly performed");
@@ -791,9 +753,7 @@ void MSG_vm_migrate(msg_vm_t vm, msg_host_t dst_pm)
            vm->getCname());
   }
 
-  char* expected_task_name = get_mig_task_name(vm, src_pm, dst_pm, 4);
-  xbt_assert(strcmp(task->name, expected_task_name) == 0);
-  xbt_free(expected_task_name);
+  xbt_assert(get_mig_task_name(vm, src_pm, dst_pm, 4) == task->name);
   MSG_task_destroy(task);
 }
 
index c874d48..7c4f791 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "src/instr/instr_private.h"
 #include "src/plugins/vm/VirtualMachineImpl.hpp"
+#include "src/plugins/vm/VmHostExt.hpp"
 #include "src/simix/smx_host_private.h"
 #include "src/surf/cpu_cas01.hpp"
 
@@ -54,6 +55,38 @@ VirtualMachine::~VirtualMachine()
   pimpl_netpoint = nullptr;
 }
 
+void VirtualMachine::start()
+{
+  simgrid::simix::kernelImmediate([this]() {
+    simgrid::vm::VmHostExt::ensureVmExtInstalled();
+
+    simgrid::s4u::Host* pm = this->pimpl_vm_->getPm();
+    if (pm->extension<simgrid::vm::VmHostExt>() == nullptr)
+      pm->extension_set(new simgrid::vm::VmHostExt());
+
+    long pm_ramsize   = pm->extension<simgrid::vm::VmHostExt>()->ramsize;
+    int pm_overcommit = pm->extension<simgrid::vm::VmHostExt>()->overcommit;
+    long vm_ramsize   = this->getRamsize();
+
+    if (pm_ramsize && not pm_overcommit) { /* Only verify that we don't overcommit on need */
+      /* Retrieve the memory occupied by the VMs on that host. Yep, we have to traverse all VMs of all hosts for that */
+      long total_ramsize_of_vms = 0;
+      for (simgrid::s4u::VirtualMachine* ws_vm : simgrid::vm::VirtualMachineImpl::allVms_)
+        if (pm == ws_vm->pimpl_vm_->getPm())
+          total_ramsize_of_vms += ws_vm->pimpl_vm_->getRamsize();
+
+      if (vm_ramsize > pm_ramsize - total_ramsize_of_vms) {
+        XBT_WARN("cannnot start %s@%s due to memory shortage: vm_ramsize %ld, free %ld, pm_ramsize %ld (bytes).",
+                 this->getCname(), pm->getCname(), vm_ramsize, pm_ramsize - total_ramsize_of_vms, pm_ramsize);
+        THROWF(vm_error, 0, "Memory shortage on host '%s', VM '%s' cannot be started", pm->getCname(),
+               this->getCname());
+      }
+    }
+
+    this->pimpl_vm_->setState(SURF_VM_STATE_RUNNING);
+  });
+}
+
 bool VirtualMachine::isMigrating()
 {
   return pimpl_vm_ && pimpl_vm_->isMigrating;
@@ -80,7 +113,7 @@ void VirtualMachine::getParameters(vm_params_t params)
 /** @brief Sets the params of that VM/PM */
 void VirtualMachine::setParameters(vm_params_t params)
 {
-  simgrid::simix::kernelImmediate([&]() { pimpl_vm_->setParams(params); });
+  simgrid::simix::kernelImmediate([this, params] { pimpl_vm_->setParams(params); });
 }
 
 } // namespace simgrid
index 7dcef8f..f3f5ab0 100644 (file)
@@ -134,7 +134,7 @@ void Actor::kill(aid_t pid)
 {
   smx_actor_t process = SIMIX_process_from_PID(pid);
   if(process != nullptr) {
-    simcall_process_kill(process);
+    simgrid::simix::kernelImmediate([process] { SIMIX_process_kill(process, process); });
   } else {
     std::ostringstream oss;
     oss << "kill: ("<< pid <<") - No such process" << std::endl;
@@ -147,7 +147,9 @@ smx_actor_t Actor::getImpl() {
 }
 
 void Actor::kill() {
-  simcall_process_kill(pimpl_);
+  smx_actor_t process = SIMIX_process_self();
+  simgrid::simix::kernelImmediate(
+      [this, process] { SIMIX_process_kill(pimpl_, (pimpl_ == simix_global->maestro_process) ? pimpl_ : process); });
 }
 
 // ***** Static functions *****
@@ -294,7 +296,8 @@ bool isSuspended()
 
 void kill()
 {
-  simcall_process_kill(SIMIX_process_self());
+  smx_actor_t process = SIMIX_process_self();
+  simgrid::simix::kernelImmediate([process] { SIMIX_process_kill(process, process); });
 }
 
 void onExit(int_f_pvoid_pvoid_t fun, void* data)
index e061713..50d287e 100644 (file)
@@ -126,14 +126,12 @@ NetZone* Engine::getNetzoneByNameOrNull(const char* name)
 }
 
 /** @brief Retrieve the netpoint of the given name (or nullptr if not found) */
-simgrid::kernel::routing::NetPoint* Engine::getNetpointByNameOrNull(const char* name)
+simgrid::kernel::routing::NetPoint* Engine::getNetpointByNameOrNull(std::string name)
 {
-  try {
-    return pimpl->netpoints_.at(name);
-  } catch (std::out_of_range& unfound) {
-    return nullptr;
-  }
+  auto netp = pimpl->netpoints_.find(name);
+  return netp == pimpl->netpoints_.end() ? nullptr : netp->second;
 }
+
 /** @brief Fill the provided vector with all existing netpoints */
 void Engine::getNetpointList(std::vector<simgrid::kernel::routing::NetPoint*>* list)
 {
index 043f6d5..35f59e7 100644 (file)
@@ -17,19 +17,19 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_file,"S4U files");
 namespace simgrid {
 namespace s4u {
 
-File::File(const char* fullpath, void* userdata) : File(fullpath, Host::current(), userdata){};
+File::File(std::string fullpath, void* userdata) : File(fullpath, Host::current(), userdata){};
 
-File::File(const char* fullpath, sg_host_t host, void* userdata) : path_(fullpath), userdata_(userdata)
+File::File(std::string fullpath, sg_host_t host, void* userdata) : path_(fullpath), userdata_(userdata)
 {
   // this cannot fail because we get a xbt_die if the mountpoint does not exist
   Storage* st                  = nullptr;
   size_t longest_prefix_length = 0;
   std::string path;
-  XBT_DEBUG("Search for storage name for '%s' on '%s'", fullpath, host->getCname());
+  XBT_DEBUG("Search for storage name for '%s' on '%s'", fullpath.c_str(), host->getCname());
 
   for (auto mnt : host->getMountedStorages()) {
     XBT_DEBUG("See '%s'", mnt.first.c_str());
-    mount_point = std::string(fullpath).substr(0, mnt.first.size());
+    mount_point = fullpath.substr(0, mnt.first.length());
 
     if (mount_point == mnt.first && mnt.first.length() > longest_prefix_length) {
       /* The current mount name is found in the full path and is bigger than the previous*/
@@ -38,10 +38,10 @@ File::File(const char* fullpath, sg_host_t host, void* userdata) : path_(fullpat
     }
   }
   if (longest_prefix_length > 0) { /* Mount point found, split fullpath into mount_name and path+filename*/
-    mount_point = std::string(fullpath).substr(0, longest_prefix_length);
-    path        = std::string(fullpath).substr(longest_prefix_length, strlen(fullpath));
+    mount_point = fullpath.substr(0, longest_prefix_length);
+    path        = fullpath.substr(longest_prefix_length, fullpath.length());
   } else
-    xbt_die("Can't find mount point for '%s' on '%s'", fullpath, host->getCname());
+    xbt_die("Can't find mount point for '%s' on '%s'", fullpath.c_str(), host->getCname());
 
   pimpl_ =
       simgrid::simix::kernelImmediate([this, st, path] { return new simgrid::surf::FileImpl(st, path, mount_point); });
@@ -84,7 +84,7 @@ sg_size_t File::tell()
   return simgrid::simix::kernelImmediate([this] { return pimpl_->tell(); });
 }
 
-void File::move(const char* fullpath)
+void File::move(std::string fullpath)
 {
   simgrid::simix::kernelImmediate([this, fullpath] { pimpl_->move(fullpath); });
 }
index cd08364..5439ce8 100644 (file)
@@ -87,11 +87,8 @@ Host* Host::by_name_or_null(const char* name)
 }
 Host* Host::by_name_or_null(std::string name)
 {
-  try {
-    return host_list.at(name);
-  } catch (std::out_of_range& unfound) {
-    return nullptr;
-  }
+  auto host = host_list.find(name);
+  return host == host_list.end() ? nullptr : host->second;
 }
 
 Host *Host::current(){
index b53d652..245bd53 100644 (file)
@@ -53,9 +53,7 @@ smx_activity_t Mailbox::front()
 }
 
 void Mailbox::setReceiver(ActorPtr actor) {
-  simix::kernelImmediate([this, actor]() {
-    this->pimpl_->setReceiver(actor);
-  });
+  simix::kernelImmediate([this, actor]() { this->pimpl_->setReceiver(actor); });
 }
 
 /** @brief get the receiver (process associated to the mailbox) */
index 33dbf91..1490c8f 100644 (file)
@@ -23,7 +23,7 @@ simgrid::xbt::signal<void(bool symmetrical, kernel::routing::NetPoint* src, kern
 simgrid::xbt::signal<void(NetZone&)> NetZone::onCreation;
 simgrid::xbt::signal<void(NetZone&)> NetZone::onSeal;
 
-NetZone::NetZone(NetZone* father, const char* name) : father_(father), name_(xbt_strdup(name))
+NetZone::NetZone(NetZone* father, std::string name) : father_(father), name_(name)
 {
   children_ = new std::vector<NetZone*>();
 }
@@ -38,7 +38,6 @@ NetZone::~NetZone()
   for (auto nz : *children_)
     delete nz;
   delete children_;
-  xbt_free(name_);
 }
 
 std::unordered_map<std::string, std::string>* NetZone::getProperties()
@@ -64,9 +63,9 @@ std::vector<NetZone*>* NetZone::getChildren()
 {
   return children_;
 }
-char* NetZone::getCname()
+const char* NetZone::getCname()
 {
-  return name_;
+  return name_.c_str();
 }
 NetZone* NetZone::getFather()
 {
@@ -90,7 +89,7 @@ int NetZone::addComponent(kernel::routing::NetPoint* elm)
 
 void NetZone::addRoute(sg_platf_route_cbarg_t /*route*/)
 {
-  xbt_die("NetZone '%s' does not accept new routes (wrong class).", name_);
+  xbt_die("NetZone '%s' does not accept new routes (wrong class).", name_.c_str());
 }
 }
 }; // namespace simgrid::s4u
index 38be665..3890ce3 100644 (file)
@@ -22,7 +22,7 @@ std::map<std::string, Storage*>* allStorages()
   return res;
 }
 
-Storage* Storage::byName(const char* name)
+Storage* Storage::byName(std::string name)
 {
   surf::StorageImpl* res = surf::StorageImpl::byName(name);
   if (res == nullptr)
index 843e43e..17ce94e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2016. The SimGrid Team.
+/* Copyright (c) 2009-2017. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
@@ -10,7 +10,7 @@
 #include "xbt/log.h"
 #include "xbt/misc.h"
 #include "xbt/str.h"
-#include <unordered_map>
+#include <map>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(sd_daxparse, sd, "Parsing DAX files");
 
@@ -141,8 +141,8 @@ bool acyclic_graph_detail(xbt_dynar_t dag){
 static YY_BUFFER_STATE input_buffer;
 
 static xbt_dynar_t result;
-static std::unordered_map<std::string, SD_task_t> jobs;
-static xbt_dict_t files;
+static std::map<std::string, SD_task_t> jobs;
+static std::map<std::string, SD_task_t> files;
 static SD_task_t current_job;
 static SD_task_t root_task;
 static SD_task_t end_task;
@@ -158,9 +158,7 @@ static void dax_task_free(void *task)
  */
 xbt_dynar_t SD_daxload(const char *filename)
 {
-  xbt_dict_cursor_t cursor;
   SD_task_t file;
-  char* name;
   FILE* in_file = fopen(filename, "r");
   xbt_assert(in_file, "Unable to open \"%s\"\n", filename);
   input_buffer = dax__create_buffer(in_file, 10);
@@ -168,7 +166,6 @@ xbt_dynar_t SD_daxload(const char *filename)
   dax_lineno = 1;
 
   result = xbt_dynar_new(sizeof(SD_task_t), dax_task_free);
-  files = xbt_dict_new_homogeneous(&dax_task_free);
   root_task = SD_task_create_comp_seq("root", nullptr, 0);
   /* by design the root task is always SCHEDULABLE */
   SD_task_set_state(root_task, SD_SCHEDULABLE);
@@ -189,7 +186,8 @@ xbt_dynar_t SD_daxload(const char *filename)
    * Files not consumed in the system are said to be consumed by end task (bottom of DAG).
    */
 
-  xbt_dict_foreach(files, cursor, name, file) {
+  for (auto elm : files) {
+    file = elm.second;
     SD_task_t newfile;
     if (file->predecessors->empty()) {
       for (SD_task_t it : *file->successors) {
@@ -225,7 +223,8 @@ xbt_dynar_t SD_daxload(const char *filename)
   xbt_dynar_push(result, &end_task);
 
   /* Free previous copy of the files */
-  xbt_dict_free(&files);
+  for (auto elm : files)
+    SD_task_destroy(elm.second);
   unsigned int cpt;
   xbt_dynar_foreach(result, cpt, file) {
     if (SD_task_get_kind(file) == SD_TASK_COMM_E2E) {
@@ -295,12 +294,14 @@ void STag_dax__uses()
   bool is_input = (A_dax__uses_link == A_dax__uses_link_input);
 
   XBT_DEBUG("See <uses file=%s %s>",A_dax__uses_file,(is_input?"in":"out"));
-  SD_task_t file = static_cast<SD_task_t>(xbt_dict_get_or_null(files, A_dax__uses_file));
-  if (file == nullptr) {
+  auto it = files.find(A_dax__uses_file);
+  SD_task_t file;
+  if (it == files.end()) {
     file = SD_task_create_comm_e2e(A_dax__uses_file, nullptr, size);
     sd_global->initial_tasks->erase(file);
-    xbt_dict_set(files, A_dax__uses_file, file, nullptr);
+    files[A_dax__uses_file] = file;
   } else {
+    file = it->second;
     if (file->amount < size || file->amount > size) {
       XBT_WARN("Ignore file %s size redefinition from %.0f to %.0f", A_dax__uses_file, SD_task_get_amount(file), size);
     }
@@ -318,9 +319,10 @@ void STag_dax__uses()
 static SD_task_t current_child;
 void STag_dax__child()
 {
-  try {
-    current_child = jobs.at(A_dax__child_ref);
-  } catch (std::out_of_range& unfound) {
+  auto job = jobs.find(A_dax__child_ref);
+  if (job != jobs.end()) {
+    current_child = job->second;
+  } else {
     throw std::out_of_range(std::string("Parse error on line ") + std::to_string(dax_lineno) +
                             ": Asked to add dependencies to the non-existent " + A_dax__child_ref + "task");
   }
@@ -333,11 +335,12 @@ void ETag_dax__child()
 
 void STag_dax__parent()
 {
-  try {
-    SD_task_t parent = jobs.at(A_dax__parent_ref);
+  auto job = jobs.find(A_dax__parent_ref);
+  if (job != jobs.end()) {
+    SD_task_t parent = job->second;
     SD_task_dependency_add(nullptr, nullptr, parent, current_child);
     XBT_DEBUG("Control-flow dependency from %s to %s", current_child->name, parent->name);
-  } catch (std::out_of_range& unfound) {
+  } else {
     throw std::out_of_range(std::string("Parse error on line ") + std::to_string(dax_lineno) +
                             ": Asked to add a dependency from " + current_child->name + " to " + A_dax__parent_ref +
                             ", but " + A_dax__parent_ref + " does not exist");
index b200887..0960689 100644 (file)
@@ -103,9 +103,10 @@ xbt_dynar_t SD_dotload_generic(const char* filename, bool sequential, bool sched
         if ((performer != -1 && order != -1) && performer < static_cast<int>(sg_host_count())) {
           /* required parameters are given and less performers than hosts are required */
           XBT_DEBUG ("Task '%s' is scheduled on workstation '%d' in position '%d'", task->name, performer, order);
-          try {
-            computer = computers.at(char_performer);
-          } catch (std::out_of_range& unfound) {
+          auto comp = computers.find(char_performer);
+          if (comp != computers.end()) {
+            computer = comp->second;
+          } else {
             computer = new std::vector<SD_task_t>;
             computers.insert({char_performer, computer});
           }
index 58d88e7..b5e52f0 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2006-2015. The SimGrid Team.
+/* Copyright (c) 2006-2017. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@ namespace sd{
 class Global {
 public:
   explicit Global();
+  Global(const Global&) = delete;
   ~Global();
   bool watch_point_reached;      /* has a task just reached a watch point? */
   std::set<SD_task_t> *initial_tasks;
index 5bc246a..0da6263 100644 (file)
@@ -341,11 +341,6 @@ void sg_config_init(int *argc, char **argv)
 
   /* The parameters of network models */
 
-  // real default for "network/sender-gap" is set in network_smpi.cpp:
-  sg_sender_gap = NAN;
-  simgrid::config::bindFlag(sg_sender_gap, {"network/sender-gap", "network/sender_gap"},
-                            "Minimum gap between two overlapping sends");
-
   sg_latency_factor = 13.01; // comes from the default LV08 network model
   simgrid::config::bindFlag(sg_latency_factor, {"network/latency-factor", "network/latency_factor"},
                             "Correction factor to apply to the provided latency (default value set by network model)");
index 6bd02ca..610678f 100644 (file)
@@ -79,8 +79,9 @@ void SIMIX_process_cleanup(smx_actor_t process)
   xbt_os_mutex_acquire(simix_global->mutex);
 
   /* cancel non-blocking communications */
-  smx_activity_t synchro = process->comms.front();
   while (not process->comms.empty()) {
+    smx_activity_t synchro = process->comms.front();
+    process->comms.pop_front();
     simgrid::kernel::activity::CommImplPtr comm =
         boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro);
 
@@ -104,8 +105,6 @@ void SIMIX_process_cleanup(smx_actor_t process)
     } else {
       xbt_die("Communication synchro %p is in my list but I'm not the sender nor the receiver", synchro.get());
     }
-    process->comms.pop_front();
-    synchro = process->comms.front();
     comm->cancel();
   }
 
@@ -346,7 +345,7 @@ smx_actor_t SIMIX_process_create(const char* name, std::function<void()> code, v
   /* Now insert it in the global process list and in the process to run list */
   simix_global->process_list[process->pid] = process;
   XBT_DEBUG("Inserting %s(%s) in the to_run list", process->cname(), host->getCname());
-  xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process);
+  simix_global->process_to_run.push_back(process);
   intrusive_ptr_add_ref(process);
 
   /* Tracing the process creation */
@@ -410,7 +409,7 @@ smx_actor_t SIMIX_process_attach(const char* name, void* data, const char* hostn
   /* Now insert it in the global process list and in the process to run list */
   simix_global->process_list[process->pid] = process;
   XBT_DEBUG("Inserting %s(%s) in the to_run list", process->cname(), host->getCname());
-  xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process);
+  simix_global->process_to_run.push_back(process);
 
   /* Tracing the process creation */
   TRACE_msg_process_create(process->cname(), process->pid, process->host);
@@ -454,15 +453,10 @@ void SIMIX_process_runall()
 {
   SIMIX_context_runall();
 
-  xbt_dynar_t tmp = simix_global->process_that_ran;
-  simix_global->process_that_ran = simix_global->process_to_run;
-  simix_global->process_to_run = tmp;
-  xbt_dynar_reset(simix_global->process_to_run);
+  simix_global->process_to_run.swap(simix_global->process_that_ran);
+  simix_global->process_to_run.clear();
 }
 
-void simcall_HANDLER_process_kill(smx_simcall_t simcall, smx_actor_t process) {
-  SIMIX_process_kill(process, simcall->issuer);
-}
 /**
  * \brief Internal function to kill a SIMIX process.
  *
@@ -525,9 +519,11 @@ void SIMIX_process_kill(smx_actor_t process, smx_actor_t issuer) {
 
     process->waiting_synchro = nullptr;
   }
-  if (not xbt_dynar_member(simix_global->process_to_run, &(process)) && process != issuer) {
+  if (std::find(begin(simix_global->process_to_run), end(simix_global->process_to_run), process) ==
+          end(simix_global->process_to_run) &&
+      process != issuer) {
     XBT_DEBUG("Inserting %s in the to_run list", process->name.c_str());
-    xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process);
+    simix_global->process_to_run.push_back(process);
   }
 }
 
@@ -564,9 +560,11 @@ void SIMIX_process_throw(smx_actor_t process, xbt_errcat_t cat, int value, const
         boost::dynamic_pointer_cast<simgrid::kernel::activity::SleepImpl>(process->waiting_synchro);
     if (sleep != nullptr) {
       SIMIX_process_sleep_destroy(process->waiting_synchro);
-      if (not xbt_dynar_member(simix_global->process_to_run, &(process)) && process != SIMIX_process_self()) {
+      if (std::find(begin(simix_global->process_to_run), end(simix_global->process_to_run), process) ==
+              end(simix_global->process_to_run) &&
+          process != SIMIX_process_self()) {
         XBT_DEBUG("Inserting %s in the to_run list", process->name.c_str());
-        xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process);
+        simix_global->process_to_run.push_back(process);
       }
     }
 
@@ -821,7 +819,7 @@ void SIMIX_process_exception_terminate(xbt_ex_t * e)
 }
 
 /** @brief Returns the list of processes to run. */
-xbt_dynar_t SIMIX_process_get_runnable()
+const std::vector<smx_actor_t>& simgrid::simix::process_get_runnable()
 {
   return simix_global->process_to_run;
 }
@@ -829,21 +827,8 @@ xbt_dynar_t SIMIX_process_get_runnable()
 /** @brief Returns the process from PID. */
 smx_actor_t SIMIX_process_from_PID(aid_t PID)
 {
-  try {
-    return simix_global->process_list.at(PID);
-  } catch (std::out_of_range& unfound) {
-    return nullptr;
-  }
-}
-
-/** @brief returns a dynar containing all currently existing processes */
-xbt_dynar_t SIMIX_processes_as_dynar() {
-  xbt_dynar_t res = xbt_dynar_new(sizeof(smx_actor_t),nullptr);
-  for (auto kv : simix_global->process_list) {
-    smx_actor_t proc = kv.second;
-    xbt_dynar_push(res,&proc);
-  }
-  return res;
+  auto process = simix_global->process_list.find(PID);
+  return process == simix_global->process_list.end() ? nullptr : process->second;
 }
 
 void SIMIX_process_on_exit_runall(smx_actor_t process) {
index 045f851..d8a0a0f 100644 (file)
@@ -154,19 +154,6 @@ e_smx_state_t simcall_execution_wait(smx_activity_t execution)
   return (e_smx_state_t) simcall_BODY_execution_wait(execution);
 }
 
-/**
- * \ingroup simix_process_management
- * \brief Kills a SIMIX process.
- *
- * This function simply kills a  process.
- *
- * \param process poor victim
- */
-void simcall_process_kill(smx_actor_t process)
-{
-  simcall_BODY_process_kill(process);
-}
-
 /**
  * \ingroup simix_process_management
  * \brief Kills all SIMIX processes.
@@ -239,7 +226,7 @@ void simcall_process_set_kill_time(smx_actor_t process, double kill_time)
   if (kill_time <= SIMIX_get_clock() || simix_global->kill_process_function == nullptr)
     return;
   XBT_DEBUG("Set kill time %f for process %s@%s", kill_time, process->cname(), process->host->getCname());
-  process->kill_timer = SIMIX_timer_set(kill_time, [=] {
+  process->kill_timer = SIMIX_timer_set(kill_time, [process] {
     simix_global->kill_process_function(process);
     process->kill_timer=nullptr;
   });
index 2cefef9..91a79b1 100644 (file)
@@ -24,12 +24,11 @@ void SIMIX_simcall_answer(smx_simcall_t simcall)
     XBT_DEBUG("Answer simcall %s (%d) issued by %s (%p)", SIMIX_simcall_name(simcall->call), (int)simcall->call,
         simcall->issuer->name.c_str(), simcall->issuer);
     simcall->issuer->simcall.call = SIMCALL_NONE;
-    xbt_assert(SIMIX_is_maestro(), "Ugh! This code path is reserved for maestro, but I'm '%s' on '%s'",
-               SIMIX_process_self()->cname(), sg_host_get_name(SIMIX_process_self()->host));
     /* This check should be useless and slows everyone. Reactivate if you see something weird in process scheduling. */
-    // if (xbt_dynar_member(simix_global->process_to_run, &(simcall->issuer)))
+    // if (std::find(begin(simix_global->process_to_run), end(simix_global->process_to_run), simcall->issuer) !=
+    //         end(simix_global->process_to_run))
     //   DIE_IMPOSSIBLE;
-    xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, simcall->issuer);
+    simix_global->process_to_run.push_back(simcall->issuer);
   }
 }
 
index d16dc06..eb130f4 100644 (file)
  */
 
 #include "src/simix/popping_private.h"
-static inline smx_actor_t simcall_process_kill__get__process(smx_simcall_t simcall)
-{
-  return simgrid::simix::unmarshal<smx_actor_t>(simcall->args[0]);
-}
-static inline smx_actor_t simcall_process_kill__getraw__process(smx_simcall_t simcall)
-{
-  return simgrid::simix::unmarshal_raw<smx_actor_t>(simcall->args[0]);
-}
-static inline void simcall_process_kill__set__process(smx_simcall_t simcall, smx_actor_t arg)
-{
-  simgrid::simix::marshal<smx_actor_t>(simcall->args[0], arg);
-}
-
 static inline int simcall_process_killall__get__reset_pid(smx_simcall_t simcall)
 {
   return simgrid::simix::unmarshal<int>(simcall->args[0]);
@@ -1461,7 +1448,6 @@ static inline void simcall_run_blocking__set__code(smx_simcall_t simcall, std::f
 
 /* The prototype of all simcall handlers, automatically generated for you */
 
-XBT_PRIVATE void simcall_HANDLER_process_kill(smx_simcall_t simcall, smx_actor_t process);
 XBT_PRIVATE void simcall_HANDLER_process_killall(smx_simcall_t simcall, int reset_pid);
 XBT_PRIVATE void simcall_HANDLER_process_suspend(smx_simcall_t simcall, smx_actor_t process);
 XBT_PRIVATE void simcall_HANDLER_process_join(smx_simcall_t simcall, smx_actor_t process, double timeout);
index c2c83cc..3a1bd5e 100644 (file)
@@ -36,12 +36,6 @@ inline static R simcall(e_smx_simcall_t call, T const&... t)
   return simgrid::simix::unmarshal<R>(self->simcall.result);
 }
 
-inline static void simcall_BODY_process_kill(smx_actor_t process) {
-    /* Go to that function to follow the code flow through the simcall barrier */
-    if (0) simcall_HANDLER_process_kill(&SIMIX_process_self()->simcall, process);
-    return simcall<void, smx_actor_t>(SIMCALL_PROCESS_KILL, process);
-  }
-
 inline static void simcall_BODY_process_killall(int reset_pid) {
     /* Go to that function to follow the code flow through the simcall barrier */
     if (0) simcall_HANDLER_process_killall(&SIMIX_process_self()->simcall, reset_pid);
index 8c5c937..a2f3155 100644 (file)
@@ -19,7 +19,6 @@
  */
 typedef enum {
   SIMCALL_NONE,
-  SIMCALL_PROCESS_KILL,
   SIMCALL_PROCESS_KILLALL,
   SIMCALL_PROCESS_CLEANUP,
   SIMCALL_PROCESS_SUSPEND,
index d388546..e52c41f 100644 (file)
@@ -25,7 +25,6 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_popping);
 /** @brief Simcalls' names (generated from src/simix/simcalls.in) */
 const char* simcall_names[] = {
     "SIMCALL_NONE",
-    "SIMCALL_PROCESS_KILL",
     "SIMCALL_PROCESS_KILLALL",
     "SIMCALL_PROCESS_CLEANUP",
     "SIMCALL_PROCESS_SUSPEND",
@@ -76,11 +75,6 @@ void SIMIX_simcall_handle(smx_simcall_t simcall, int value) {
   if (simcall->issuer->context->iwannadie && simcall->call != SIMCALL_PROCESS_CLEANUP)
     return;
   switch (simcall->call) {
-case SIMCALL_PROCESS_KILL:
-      simcall_HANDLER_process_kill(simcall, simgrid::simix::unmarshal<smx_actor_t>(simcall->args[0]));
-      SIMIX_simcall_answer(simcall);
-      break;
-
 case SIMCALL_PROCESS_KILLALL:
       simcall_HANDLER_process_killall(simcall, simgrid::simix::unmarshal<int>(simcall->args[0]));
       SIMIX_simcall_answer(simcall);
index 3a6cc0f..c13413f 100644 (file)
@@ -35,7 +35,6 @@
 # Last but not the least, you should declare the new simix call in
 # ./include/simgrid/simix.h (otherwise you will get a warning at compile time)
 
-void process_kill(smx_actor_t process);
 void process_killall(int reset_pid);
 void process_cleanup(smx_actor_t process) [[nohandler]];
 void process_suspend(smx_actor_t process) [[block]];
index d00955b..0e69735 100644 (file)
@@ -10,6 +10,7 @@
 #include <csignal> /* Signal handling */
 #include <cstdlib>
 
+#include <xbt/algorithm.hpp>
 #include <xbt/functional.hpp>
 
 #include "simgrid/s4u/Engine.hpp"
@@ -204,8 +205,6 @@ void SIMIX_global_init(int *argc, char **argv)
     simix_global = std::unique_ptr<simgrid::simix::Global>(new simgrid::simix::Global());
 
     simgrid::simix::ActorImpl proc;
-    simix_global->process_to_run = xbt_dynar_new(sizeof(smx_actor_t), nullptr);
-    simix_global->process_that_ran = xbt_dynar_new(sizeof(smx_actor_t), nullptr);
     simix_global->process_to_destroy = xbt_swag_new(xbt_swag_offset(proc, destroy_hookup));
     simix_global->maestro_process = nullptr;
     simix_global->create_process_function = &SIMIX_process_create;
@@ -277,7 +276,7 @@ void SIMIX_clean()
 
   smx_cleaned = 1;
   XBT_DEBUG("SIMIX_clean called. Simulation's over.");
-  if (not xbt_dynar_is_empty(simix_global->process_to_run) && SIMIX_get_clock() <= 0.0) {
+  if (not simix_global->process_to_run.empty() && SIMIX_get_clock() <= 0.0) {
     XBT_CRITICAL("   ");
     XBT_CRITICAL("The time is still 0, and you still have processes ready to run.");
     XBT_CRITICAL("It seems that you forgot to run the simulation that you setup.");
@@ -292,8 +291,8 @@ void SIMIX_clean()
   xbt_heap_free(simix_timers);
   simix_timers = nullptr;
   /* Free the remaining data structures */
-  xbt_dynar_free(&simix_global->process_to_run);
-  xbt_dynar_free(&simix_global->process_that_ran);
+  simix_global->process_to_run.clear();
+  simix_global->process_that_ran.clear();
   xbt_swag_free(simix_global->process_to_destroy);
   simix_global->process_list.clear();
   simix_global->process_to_destroy = nullptr;
@@ -334,19 +333,6 @@ double SIMIX_get_clock()
   }
 }
 
-static int process_syscall_color(void *p)
-{
-  switch ((*(smx_actor_t *)p)->simcall.call) {
-  case SIMCALL_NONE:
-  case SIMCALL_PROCESS_KILL:
-    return 2;
-  //  case SIMCALL_PROCESS_RESUME:
-  //    return 1;
-  default:
-    return 0;
-  }
-}
-
 /** Wake up all processes waiting for a Surf action to finish */
 static void SIMIX_wake_processes()
 {
@@ -429,19 +415,16 @@ void SIMIX_run()
   double time = 0;
 
   do {
-    XBT_DEBUG("New Schedule Round; size(queue)=%lu", xbt_dynar_length(simix_global->process_to_run));
+    XBT_DEBUG("New Schedule Round; size(queue)=%zu", simix_global->process_to_run.size());
 
     SIMIX_execute_tasks();
 
-    while (not xbt_dynar_is_empty(simix_global->process_to_run)) {
-      XBT_DEBUG("New Sub-Schedule Round; size(queue)=%lu", xbt_dynar_length(simix_global->process_to_run));
+    while (not simix_global->process_to_run.empty()) {
+      XBT_DEBUG("New Sub-Schedule Round; size(queue)=%zu", simix_global->process_to_run.size());
 
       /* Run all processes that are ready to run, possibly in parallel */
       SIMIX_process_runall();
 
-      /* Move all killer processes to the end of the list, because killing a process that have an ongoing simcall is a bad idea */
-      xbt_dynar_three_way_partition(simix_global->process_that_ran, process_syscall_color);
-
       /* answer sequentially and in a fixed arbitrary order all the simcalls that were issued during that sub-round */
 
       /* WARNING, the order *must* be fixed or you'll jeopardize the simulation reproducibility (see RR-7653) */
@@ -497,9 +480,7 @@ void SIMIX_run()
        *   That would thus be a pure waste of time.
        */
 
-      unsigned int iter;
-      smx_actor_t process;
-      xbt_dynar_foreach(simix_global->process_that_ran, iter, process) {
+      for (smx_actor_t process : simix_global->process_that_ran) {
         if (process->simcall.call != SIMCALL_NONE) {
           SIMIX_simcall_handle(&process->simcall, 0);
         }
@@ -548,13 +529,13 @@ void SIMIX_run()
     /* Clean processes to destroy */
     SIMIX_process_empty_trash();
 
-    XBT_DEBUG("### time %f, #processes %zu, #to_run %lu", time, simix_global->process_list.size(),
-              xbt_dynar_length(simix_global->process_to_run));
+    XBT_DEBUG("### time %f, #processes %zu, #to_run %zu", time, simix_global->process_list.size(),
+              simix_global->process_to_run.size());
 
-    if (xbt_dynar_is_empty(simix_global->process_to_run) && not simix_global->process_list.empty())
+    if (simix_global->process_to_run.empty() && not simix_global->process_list.empty())
       simgrid::simix::onDeadlock();
 
-  } while (time > -1.0 || not xbt_dynar_is_empty(simix_global->process_to_run));
+  } while (time > -1.0 || not simix_global->process_to_run.empty());
 
   if (simix_global->process_list.size() != 0) {
 
index a0c713e..f10bf4d 100644 (file)
@@ -11,6 +11,7 @@
 #include <signal.h>
 
 #include <map>
+#include <vector>
 
 /********************************** Simix Global ******************************/
 
@@ -22,8 +23,8 @@ class Global {
 
 public:
   smx_context_factory_t context_factory = nullptr;
-  xbt_dynar_t process_to_run = nullptr;
-  xbt_dynar_t process_that_ran = nullptr;
+  std::vector<smx_actor_t> process_to_run;
+  std::vector<smx_actor_t> process_that_ran;
   std::map<aid_t, smx_actor_t> process_list;
 #if SIMGRID_HAVE_MC
   /* MCer cannot read the std::map above in the remote process, so we copy the info it needs in a dynar.
index ff6a248..59561a4 100644 (file)
@@ -3,13 +3,14 @@
 /* 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 "private.h"
 #include "simgrid/s4u/Engine.hpp"
 #include "simgrid/s4u/Host.hpp"
-#include "private.h"
 #include "smpi_comm.hpp"
 #include "smpi_datatype_derived.hpp"
 #include "smpi_process.hpp"
 #include "smpi_status.hpp"
+#include "src/simix/ActorImpl.hpp"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_pmpi, smpi, "Logging specific to SMPI (pmpi)");
 
@@ -119,7 +120,8 @@ int PMPI_Abort(MPI_Comm comm, int errorcode)
 {
   smpi_bench_end();
   // FIXME: should kill all processes in comm instead
-  simcall_process_kill(SIMIX_process_self());
+  smx_actor_t process = SIMIX_process_self();
+  simgrid::simix::kernelImmediate([process] { SIMIX_process_kill(process, process); });
   return MPI_SUCCESS;
 }
 
index 40cc76e..926b55c 100644 (file)
@@ -20,16 +20,16 @@ int PMPI_Send_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag
 
   smpi_bench_end();
   if (request == nullptr) {
-      retval = MPI_ERR_ARG;
+    retval = MPI_ERR_ARG;
   } else if (comm == MPI_COMM_NULL) {
-      retval = MPI_ERR_COMM;
+    retval = MPI_ERR_COMM;
   } else if (not datatype->is_valid()) {
     retval = MPI_ERR_TYPE;
   } else if (dst == MPI_PROC_NULL) {
-      retval = MPI_SUCCESS;
+    retval = MPI_SUCCESS;
   } else {
-      *request = simgrid::smpi::Request::send_init(buf, count, datatype, dst, tag, comm);
-      retval = MPI_SUCCESS;
+    *request = simgrid::smpi::Request::send_init(buf, count, datatype, dst, tag, comm);
+    retval   = MPI_SUCCESS;
   }
   smpi_bench_begin();
   if (retval != MPI_SUCCESS && request != nullptr)
@@ -423,8 +423,8 @@ int PMPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MP
   return retval;
 }
 
-int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void *recvbuf,
-                 int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status * status)
+int PMPI_Sendrecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void* recvbuf,
+                  int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status* status)
 {
   int retval = 0;
 
@@ -448,34 +448,34 @@ int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, int dst,
     retval = MPI_ERR_TAG;
   } else {
 
-  int rank = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
-  int dst_traced = comm->group()->index(dst);
-  int src_traced = comm->group()->index(src);
-  instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
-  extra->type = TRACING_SENDRECV;
-  extra->src = src_traced;
-  extra->dst = dst_traced;
-  int known=0;
-  extra->datatype1 = encode_datatype(sendtype, &known);
-  int dt_size_send = 1;
-  if(known==0)
-    dt_size_send = sendtype->size();
-  extra->send_size = sendcount*dt_size_send;
-  extra->datatype2 = encode_datatype(recvtype, &known);
-  int dt_size_recv = 1;
-  if(known==0)
-    dt_size_recv = recvtype->size();
-  extra->recv_size = recvcount*dt_size_recv;
-
-  TRACE_smpi_ptp_in(rank, __FUNCTION__, extra);
-  TRACE_smpi_send(rank, rank, dst_traced, sendtag,sendcount*sendtype->size());
-
-  simgrid::smpi::Request::sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf, recvcount, recvtype, src, recvtag, comm,
-                    status);
-  retval = MPI_SUCCESS;
-
-  TRACE_smpi_ptp_out(rank, dst_traced, __FUNCTION__);
-  TRACE_smpi_recv(src_traced, rank, recvtag);
+    int rank               = comm != MPI_COMM_NULL ? smpi_process()->index() : -1;
+    int dst_traced         = comm->group()->index(dst);
+    int src_traced         = comm->group()->index(src);
+    instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
+    extra->type            = TRACING_SENDRECV;
+    extra->src             = src_traced;
+    extra->dst             = dst_traced;
+    int known              = 0;
+    extra->datatype1       = encode_datatype(sendtype, &known);
+    int dt_size_send       = 1;
+    if (known == 0)
+      dt_size_send   = sendtype->size();
+    extra->send_size = sendcount * dt_size_send;
+    extra->datatype2 = encode_datatype(recvtype, &known);
+    int dt_size_recv = 1;
+    if (known == 0)
+      dt_size_recv   = recvtype->size();
+    extra->recv_size = recvcount * dt_size_recv;
+
+    TRACE_smpi_ptp_in(rank, __FUNCTION__, extra);
+    TRACE_smpi_send(rank, rank, dst_traced, sendtag, sendcount * sendtype->size());
+
+    simgrid::smpi::Request::sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf, recvcount, recvtype, src,
+                                     recvtag, comm, status);
+    retval = MPI_SUCCESS;
+
+    TRACE_smpi_ptp_out(rank, dst_traced, __FUNCTION__);
+    TRACE_smpi_recv(src_traced, rank, recvtag);
   }
 
   smpi_bench_begin();
@@ -495,7 +495,7 @@ int PMPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst,
     void* recvbuf = xbt_new0(char, size);
     retval = MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count, datatype, src, recvtag, comm, status);
     if(retval==MPI_SUCCESS){
-        simgrid::smpi::Datatype::copy(recvbuf, count, datatype, buf, count, datatype);
+      simgrid::smpi::Datatype::copy(recvbuf, count, datatype, buf, count, datatype);
     }
     xbt_free(recvbuf);
 
@@ -632,9 +632,7 @@ int PMPI_Wait(MPI_Request * request, MPI_Status * status)
     TRACE_smpi_ptp_out(rank, dst_traced, __FUNCTION__);
     if (is_wait_for_receive) {
       if(src_traced==MPI_ANY_SOURCE)
-        src_traced = (status!=MPI_STATUS_IGNORE) ?
-          comm->group()->rank(status->MPI_SOURCE) :
-          src_traced;
+        src_traced = (status != MPI_STATUS_IGNORE) ? comm->group()->rank(status->MPI_SOURCE) : src_traced;
       TRACE_smpi_recv(src_traced, dst_traced, tag_traced);
     }
   }
@@ -682,9 +680,8 @@ int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * sta
     int is_wait_for_receive = savedvals[*index].recv;
     if (is_wait_for_receive) {
       if(savedvals[*index].src==MPI_ANY_SOURCE)
-        src_traced = (status != MPI_STATUSES_IGNORE)
-                         ? savedvals[*index].comm->group()->rank(status->MPI_SOURCE)
-                         : savedvals[*index].src;
+        src_traced = (status != MPI_STATUSES_IGNORE) ? savedvals[*index].comm->group()->rank(status->MPI_SOURCE)
+                                                     : savedvals[*index].src;
       TRACE_smpi_recv(src_traced, dst_traced, savedvals[*index].tag);
     }
     TRACE_smpi_ptp_out(rank_traced, dst_traced, __FUNCTION__);
@@ -727,14 +724,14 @@ int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
 
   for (int i = 0; i < count; i++) {
     if(savedvals[i].valid){
-    //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
+      // the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
       int src_traced = savedvals[i].src;
       int dst_traced = savedvals[i].dst;
       int is_wait_for_receive = savedvals[i].recv;
       if (is_wait_for_receive) {
         if(src_traced==MPI_ANY_SOURCE)
-        src_traced = (status!=MPI_STATUSES_IGNORE) ?
-                          savedvals[i].comm->group()->rank(status[i].MPI_SOURCE) : savedvals[i].src;
+          src_traced = (status != MPI_STATUSES_IGNORE) ? savedvals[i].comm->group()->rank(status[i].MPI_SOURCE)
+                                                       : savedvals[i].src;
         TRACE_smpi_recv(src_traced, dst_traced,savedvals[i].tag);
       }
     }
index bc3e2af..986540f 100644 (file)
@@ -109,11 +109,12 @@ template <typename T> int Keyval::attr_get(int keyval, void* attr_value, int* fl
     *flag=0;
     return MPI_SUCCESS;
   }
-  try {
-    *static_cast<void**>(attr_value) = attributes()->at(keyval);
+  const auto& attribs = attributes();
+  auto attr           = attribs->find(keyval);
+  if (attr != attribs->end()) {
+    *static_cast<void**>(attr_value) = attr->second;
     *flag=1;
-  }
-  catch (const std::out_of_range& oor) {
+  } else {
     *flag=0;
   }
   return MPI_SUCCESS;
@@ -140,12 +141,13 @@ template <typename T> void Keyval::cleanup_attr(){
   if (not attributes()->empty()) {
     int flag=0;
     for(auto it : attributes_){
-      try{
-        smpi_key_elem elem = T::keyvals_.at(it.first);
+      auto elm = T::keyvals_.find(it.first);
+      if (elm != T::keyvals_.end()) {
+        smpi_key_elem elem = elm->second;
         if(elem != nullptr){
           call_deleter<T>((T*)this, elem, it.first,it.second,&flag);
         }
-      }catch(const std::out_of_range& oor) {
+      } else {
         //already deleted, not a problem;
         flag=0;
       }
index ec33a27..9318b35 100644 (file)
@@ -9,11 +9,12 @@
 #include <cctype>
 #include <cstdarg>
 #include <cwchar>
+#include <deque>
 #include <simgrid/sg_config.h>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_smpi, instr, "Tracing SMPI");
 
-static xbt_dict_t keys;
+static std::unordered_map<char*, std::deque<std::string>*> keys;
 
 static const char *smpi_colors[] ={
     "recv",     "1 0 0",
@@ -100,12 +101,14 @@ static char *TRACE_smpi_put_key(int src, int dst, int tag, char *key, int n, int
   //get the dynar for src#dst
   char aux[INSTR_DEFAULT_STR_SIZE];
   snprintf(aux, INSTR_DEFAULT_STR_SIZE, "%d#%d#%d#%d", src, dst, tag, send);
-  xbt_dynar_t d = static_cast<xbt_dynar_t>(xbt_dict_get_or_null(keys, aux));
+  auto it = keys.find(aux);
+  std::deque<std::string>* d;
 
-  if (d == nullptr) {
-    d = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
-    xbt_dict_set(keys, aux, d, nullptr);
-  }
+  if (it == keys.end()) {
+    d         = new std::deque<std::string>;
+    keys[aux] = d;
+  } else
+    d = it->second;
 
   //generate the key
   static unsigned long long counter = 0;
@@ -113,8 +116,7 @@ static char *TRACE_smpi_put_key(int src, int dst, int tag, char *key, int n, int
   snprintf(key, n, "%d_%d_%d_%llu", src, dst, tag, counter);
 
   //push it
-  char *a = static_cast<char*> (xbt_strdup(key));
-  xbt_dynar_push_as(d, char *, a);
+  d->push_back(key);
 
   return key;
 }
@@ -123,21 +125,18 @@ static char *TRACE_smpi_get_key(int src, int dst, int tag, char *key, int n, int
 {
   char aux[INSTR_DEFAULT_STR_SIZE];
   snprintf(aux, INSTR_DEFAULT_STR_SIZE, "%d#%d#%d#%d", src, dst, tag, send==1?0:1);
-  xbt_dynar_t d = static_cast<xbt_dynar_t>(xbt_dict_get_or_null(keys, aux));
-
-  // first posted
-  if(xbt_dynar_is_empty(d)){
-      TRACE_smpi_put_key(src, dst, tag, key, n, send);
-      return key;
+  auto it = keys.find(aux);
+  if (it == keys.end()) {
+    // first posted
+    TRACE_smpi_put_key(src, dst, tag, key, n, send);
+  } else {
+    snprintf(key, n, "%s", it->second->front().c_str());
+    it->second->pop_front();
   }
-
-  char *s = xbt_dynar_get_as (d, 0, char *);
-  snprintf (key, n, "%s", s);
-  xbt_dynar_remove_at (d, 0, nullptr);
   return key;
 }
 
-static xbt_dict_t process_category;
+static std::unordered_map<smx_actor_t, std::string> process_category;
 
 static void cleanup_extra_data (instr_extra_data extra){
   if(extra!=nullptr){
@@ -157,12 +156,8 @@ void TRACE_internal_smpi_set_category (const char *category)
   //declare category
   TRACE_category (category);
 
-  char processid[INSTR_DEFAULT_STR_SIZE];
-  snprintf (processid, INSTR_DEFAULT_STR_SIZE, "%p", SIMIX_process_self());
-  if (xbt_dict_get_or_null (process_category, processid))
-    xbt_dict_remove (process_category, processid);
   if (category != nullptr)
-    xbt_dict_set (process_category, processid, xbt_strdup(category), nullptr);
+    process_category[SIMIX_process_self()] = category;
 }
 
 const char *TRACE_internal_smpi_get_category ()
@@ -170,21 +165,19 @@ const char *TRACE_internal_smpi_get_category ()
   if (not TRACE_smpi_is_enabled())
     return nullptr;
 
-  char processid[INSTR_DEFAULT_STR_SIZE];
-  snprintf (processid, INSTR_DEFAULT_STR_SIZE, "%p", SIMIX_process_self());
-  return static_cast<char*>(xbt_dict_get_or_null (process_category, processid));
+  auto it = process_category.find(SIMIX_process_self());
+  return (it == process_category.end()) ? nullptr : it->second.c_str();
 }
 
 void TRACE_smpi_alloc()
 {
-  keys = xbt_dict_new_homogeneous(xbt_dynar_free_voidp);
-  process_category = xbt_dict_new_homogeneous(xbt_free_f);
+  // for symmetry
 }
 
 void TRACE_smpi_release()
 {
-  xbt_dict_free(&keys);
-  xbt_dict_free(&process_category);
+  for (auto elm : keys)
+    delete elm.second;
 }
 
 void TRACE_smpi_init(int rank)
index 44fdedf..8e17376 100644 (file)
@@ -3,13 +3,14 @@
 /* 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 "src/internal_config.h"
 #include "private.h"
 #include "private.hpp"
 #include "simgrid/modelchecker.h"
-#include "src/mc/mc_replay.h"
-#include "smpi_process.hpp"
 #include "smpi_comm.hpp"
+#include "smpi_process.hpp"
+#include "src/internal_config.h"
+#include "src/mc/mc_replay.h"
+#include <unordered_map>
 
 #ifndef WIN32
 #include <sys/mman.h>
@@ -22,9 +23,6 @@
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_bench, smpi, "Logging specific to SMPI (benchmarking)");
 
-
-xbt_dict_t samples = nullptr;         /* Allocated on first use */
-
 double smpi_cpu_threshold = -1;
 double smpi_host_speed;
 
@@ -32,11 +30,6 @@ shared_malloc_type smpi_cfg_shared_malloc = shmalloc_global;
 double smpi_total_benched_time = 0;
 smpi_privatization_region_t smpi_privatization_regions;
 
-void smpi_bench_destroy()
-{
-  xbt_dict_free(&samples);
-}
-
 extern "C" XBT_PUBLIC(void) smpi_execute_flops_(double *flops);
 void smpi_execute_flops_(double *flops)
 {
@@ -282,11 +275,14 @@ typedef struct {
   int benching;     /* 1: we are benchmarking; 0: we have enough data, no bench anymore */
 } local_data_t;
 
-static char *sample_location(int global, const char *file, int line) {
+std::unordered_map<std::string, local_data_t*> samples; /* Allocated on first use */
+
+static std::string sample_location(int global, const char* file, int line)
+{
   if (global) {
-    return bprintf("%s:%d", file, line);
+    return std::string(file) + ":" + std::to_string(line);
   } else {
-    return bprintf("%s:%d:%d", file, line, smpi_process()->index());
+    return std::string(file) + ":" + std::to_string(line) + ":" + std::to_string(smpi_process()->index());
   }
 }
 
@@ -305,19 +301,17 @@ static int sample_enough_benchs(local_data_t *data) {
 
 void smpi_sample_1(int global, const char *file, int line, int iters, double threshold)
 {
-  char *loc = sample_location(global, file, line);
+  std::string loc = sample_location(global, file, line);
 
   smpi_bench_end();     /* Take time from previous, unrelated computation into account */
   smpi_process()->set_sampling(1);
 
-  if (samples==nullptr)
-    samples = xbt_dict_new_homogeneous(free);
-
-  local_data_t *data = static_cast<local_data_t *>(xbt_dict_get_or_null(samples, loc));
-  if (data==nullptr) {
+  auto ld = samples.find(loc);
+  local_data_t* data;
+  if (ld == samples.end()) {
     xbt_assert(threshold>0 || iters>0,
         "You should provide either a positive amount of iterations to bench, or a positive maximal stderr (or both)");
-    data = static_cast<local_data_t *>( xbt_new(local_data_t, 1));
+    data            = static_cast<local_data_t*>(xbt_new(local_data_t, 1));
     data->count = 0;
     data->sum = 0.0;
     data->sum_pow2 = 0.0;
@@ -325,34 +319,34 @@ void smpi_sample_1(int global, const char *file, int line, int iters, double thr
     data->threshold = threshold;
     data->benching = 1; // If we have no data, we need at least one
     data->mean = 0;
-    xbt_dict_set(samples, loc, data, nullptr);
-    XBT_DEBUG("XXXXX First time ever on benched nest %s.",loc);
+    samples[loc]    = data;
+    XBT_DEBUG("XXXXX First time ever on benched nest %s.", loc.c_str());
   } else {
+    data = ld->second;
     if (data->iters != iters || data->threshold != threshold) {
       XBT_ERROR("Asked to bench block %s with different settings %d, %f is not %d, %f. "
                 "How did you manage to give two numbers at the same line??",
-                loc, data->iters, data->threshold, iters, threshold);
+                loc.c_str(), data->iters, data->threshold, iters, threshold);
       THROW_IMPOSSIBLE;
     }
 
     // if we already have some data, check whether sample_2 should get one more bench or whether it should emulate
     // the computation instead
     data->benching = (sample_enough_benchs(data) == 0);
-    XBT_DEBUG("XXXX Re-entering the benched nest %s. %s", loc,
+    XBT_DEBUG("XXXX Re-entering the benched nest %s. %s", loc.c_str(),
               (data->benching ? "more benching needed" : "we have enough data, skip computes"));
   }
-  xbt_free(loc);
 }
 
 int smpi_sample_2(int global, const char *file, int line)
 {
-  char *loc = sample_location(global, file, line);
+  std::string loc = sample_location(global, file, line);
   int res;
 
-  xbt_assert(samples, "Y U NO use SMPI_SAMPLE_* macros? Stop messing directly with smpi_sample_* functions!");
-  local_data_t *data = static_cast<local_data_t *>(xbt_dict_get(samples, loc));
-  XBT_DEBUG("sample2 %s",loc);
-  xbt_free(loc);
+  xbt_assert(not samples.empty(),
+             "Y U NO use SMPI_SAMPLE_* macros? Stop messing directly with smpi_sample_* functions!");
+  local_data_t* data = samples.at(loc);
+  XBT_DEBUG("sample2 %s", loc.c_str());
 
   if (data->benching==1) {
     // we need to run a new bench
@@ -375,12 +369,12 @@ int smpi_sample_2(int global, const char *file, int line)
 
 void smpi_sample_3(int global, const char *file, int line)
 {
-  char *loc = sample_location(global, file, line);
+  std::string loc = sample_location(global, file, line);
 
-  xbt_assert(samples, "Y U NO use SMPI_SAMPLE_* macros? Stop messing directly with smpi_sample_* functions!");
-  local_data_t *data = static_cast<local_data_t *>(xbt_dict_get(samples, loc));
-  XBT_DEBUG("sample3 %s",loc);
-  xbt_free(loc);
+  xbt_assert(not samples.empty(),
+             "Y U NO use SMPI_SAMPLE_* macros? Stop messing directly with smpi_sample_* functions!");
+  local_data_t* data = samples.at(loc);
+  XBT_DEBUG("sample3 %s", loc.c_str());
 
   if (data->benching==0)
     THROW_IMPOSSIBLE;
@@ -408,30 +402,36 @@ void smpi_sample_3(int global, const char *file, int line)
 }
 
 extern "C" { /** These functions will be called from the user code **/
-  smpi_trace_call_location_t* smpi_trace_get_call_location() {
-    return smpi_process()->call_location();
-  }
+smpi_trace_call_location_t* smpi_trace_get_call_location()
+{
+  return smpi_process()->call_location();
+}
 
-  void smpi_trace_set_call_location(const char* file, const int line) {
-    smpi_trace_call_location_t* loc = smpi_process()->call_location();
+void smpi_trace_set_call_location(const char* file, const int line)
+{
+  smpi_trace_call_location_t* loc = smpi_process()->call_location();
 
-    loc->previous_filename   = loc->filename;
-    loc->previous_linenumber = loc->linenumber;
-    loc->filename            = file;
-    loc->linenumber          = line;
-  }
+  loc->previous_filename   = loc->filename;
+  loc->previous_linenumber = loc->linenumber;
+  loc->filename            = file;
+  loc->linenumber          = line;
+}
 
-  /**
-   * Required for Fortran bindings
-   */
-  void smpi_trace_set_call_location_(const char* file, int* line) {
-    smpi_trace_set_call_location(file, *line);
-  }
+/** Required for Fortran bindings */
+void smpi_trace_set_call_location_(const char* file, int* line)
+{
+  smpi_trace_set_call_location(file, *line);
+}
 
-  /**
-   * Required for Fortran if -fsecond-underscore is activated
-   */
-  void smpi_trace_set_call_location__(const char* file, int* line) {
-    smpi_trace_set_call_location(file, *line);
-  }
+/** Required for Fortran if -fsecond-underscore is activated */
+void smpi_trace_set_call_location__(const char* file, int* line)
+{
+  smpi_trace_set_call_location(file, *line);
+}
+}
+
+void smpi_bench_destroy()
+{
+  for (auto elm : samples)
+    xbt_free(elm.second);
 }
index e864e81..f1226a2 100644 (file)
@@ -127,20 +127,18 @@ static void print(std::vector<std::pair<size_t, size_t>> vec) {
   std::fprintf(stderr, "{");
   for (auto elt : vec) {
     std::fprintf(stderr, "(0x%zx, 0x%zx),", elt.first, elt.second);
-    }
-    std::fprintf(stderr, "}\n");
+  }
+  std::fprintf(stderr, "}\n");
 }
 static void memcpy_private(void* dest, const void* src, std::vector<std::pair<size_t, size_t>>& private_blocks)
 {
-  for(auto block : private_blocks) {
+  for (auto block : private_blocks)
     memcpy((uint8_t*)dest+block.first, (uint8_t*)src+block.first, block.second-block.first);
-  }
 }
 
 static void check_blocks(std::vector<std::pair<size_t, size_t>> &private_blocks, size_t buff_size) {
-  for(auto block : private_blocks) {
+  for (auto block : private_blocks)
     xbt_assert(block.first <= block.second && block.second <= buff_size, "Oops, bug in shared malloc.");
-  }
 }
 
 void smpi_comm_copy_buffer_callback(smx_activity_t synchro, void *buff, size_t buff_size)
@@ -205,8 +203,8 @@ void smpi_comm_copy_buffer_callback(smx_activity_t synchro, void *buff, size_t b
     //xbt_free(comm->comm.src_data);// inside SMPI the request is kept inside the user data and should be free
     comm->src_buff = nullptr;
   }
-  if(tmpbuff!=buff)xbt_free(tmpbuff);
-
+  if (tmpbuff != buff)
+    xbt_free(tmpbuff);
 }
 
 void smpi_comm_null_copy_buffer_callback(smx_activity_t comm, void *buff, size_t buff_size)
@@ -282,10 +280,8 @@ void smpi_global_init()
     std::string str = std::string(xbt_cfg_get_string("smpi/papi-events"));
     Tokenizer tokens(str, separator_units);
 
-    // Iterate over all the computational units. This could be
-    // processes, hosts, threads, ranks... You name it. I'm not exactly
-    // sure what we will support eventually, so I'll leave it at the
-    // general term "units".
+    // Iterate over all the computational units. This could be processes, hosts, threads, ranks... You name it.
+    // I'm not exactly sure what we will support eventually, so I'll leave it at the general term "units".
     for (auto& unit_it : tokens) {
       boost::char_separator<char> separator_events(":");
       Tokenizer event_tokens(unit_it, separator_events);
@@ -306,7 +302,7 @@ void smpi_global_init()
       // Note that we need to remove the name of the unit
       // (that could also be the "default" value), which always comes first.
       // Hence, we start at ++(events.begin())!
-      for (Tokenizer::iterator events_it = ++(event_tokens.begin()); events_it != event_tokens.end(); events_it++) {
+      for (Tokenizer::iterator events_it = ++(event_tokens.begin()); events_it != event_tokens.end(); ++events_it) {
 
         int event_code   = PAPI_NULL;
         char* event_name = const_cast<char*>((*events_it).c_str());
index 9a1147f..4fce186 100644 (file)
@@ -108,7 +108,8 @@ void smpi_really_switch_data_segment(int dest)
 
 int smpi_is_privatization_file(char* file)
 {
-  return strncmp("/dev/shm/my-buffer-", file, std::strlen("/dev/shm/my-buffer-")) == 0;
+  const std::string buffer_path {"/dev/shm/my-buffer-"};
+  return buffer_path.compare(file) == 0;
 }
 
 void smpi_initialize_global_memory_segments()
index a213733..27bd066 100644 (file)
@@ -7,7 +7,7 @@
  * Associated data and metadata are used as follows:
  *
  *                                                                    mmap #1
- *    `allocs' dict                                                     ---- -.
+ *    `allocs' map                                                      ---- -.
  *    ----------      shared_data_t               shared_metadata_t   / |  |  |
  * .->| <name> | ---> -------------------- <--.   -----------------   | |  |  |
  * |  ----------      | fd of <name>     |    |   | size of mmap  | --| |  |  |
@@ -15,7 +15,7 @@
  * `----------------- | <name>           |    |   -----------------     ----  |
  *                    --------------------    |   ^                           |
  *                                            |   |                           |
- *                                            |   |   `allocs_metadata' dict  |
+ *                                            |   |   `allocs_metadata' map   |
  *                                            |   |   ----------------------  |
  *                                            |   `-- | <addr of mmap #1>  |<-'
  *                                            |   .-- | <addr of mmap #2>  |<-.
@@ -38,8 +38,6 @@
 
 #include "private.h"
 #include "private.hpp"
-#include "xbt/dict.h"
-#include "xbt/ex.hpp"
 #include <cerrno>
 
 #include <sys/types.h>
@@ -122,7 +120,8 @@ typedef struct {
 } shared_metadata_t;
 
 std::map<void*, shared_metadata_t> allocs_metadata;
-xbt_dict_t calls = nullptr;           /* Allocated on first use */
+std::map<std::string, void*> calls;
+
 #ifndef WIN32
 static int smpi_shared_malloc_bogusfile           = -1;
 static int smpi_shared_malloc_bogusfile_huge_page  = -1;
@@ -135,7 +134,7 @@ void smpi_shared_destroy()
 {
   allocs.clear();
   allocs_metadata.clear();
-  xbt_dict_free(&calls);
+  calls.clear();
 }
 
 static size_t shm_size(int fd) {
@@ -487,46 +486,18 @@ void smpi_shared_free(void *ptr)
 
 int smpi_shared_known_call(const char* func, const char* input)
 {
-  char* loc = bprintf("%s:%s", func, input);
-  int known = 0;
-
-  if (calls==nullptr) {
-    calls = xbt_dict_new_homogeneous(nullptr);
-  }
-  try {
-    xbt_dict_get(calls, loc); /* Succeed or throw */
-    known = 1;
-    xbt_free(loc);
-  }
-  catch (xbt_ex& ex) {
-    xbt_free(loc);
-    if (ex.category != not_found_error)
-      throw;
-  }
-  catch(...) {
-    xbt_free(loc);
-    throw;
-  }
-  return known;
+  std::string loc = std::string(func) + ":" + input;
+  return calls.find(loc) != calls.end();
 }
 
 void* smpi_shared_get_call(const char* func, const char* input) {
-  char* loc = bprintf("%s:%s", func, input);
+  std::string loc = std::string(func) + ":" + input;
 
-  if (calls == nullptr)
-    calls    = xbt_dict_new_homogeneous(nullptr);
-  void* data = xbt_dict_get(calls, loc);
-  xbt_free(loc);
-  return data;
+  return calls.at(loc);
 }
 
 void* smpi_shared_set_call(const char* func, const char* input, void* data) {
-  char* loc = bprintf("%s:%s", func, input);
-
-  if (calls == nullptr)
-    calls = xbt_dict_new_homogeneous(nullptr);
-  xbt_dict_set(calls, loc, data, nullptr);
-  xbt_free(loc);
+  std::string loc = std::string(func) + ":" + input;
+  calls[loc]      = data;
   return data;
 }
-