Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of scm.gforge.inria.fr:/gitroot/simgrid/simgrid
authorMartin Quinson <martin.quinson@loria.fr>
Fri, 17 Jun 2016 09:39:43 +0000 (11:39 +0200)
committerMartin Quinson <martin.quinson@loria.fr>
Fri, 17 Jun 2016 09:39:43 +0000 (11:39 +0200)
36 files changed:
examples/java/app/bittorrent/Main.java
examples/java/app/centralizedmutex/Main.java
examples/java/app/masterworker/Main.java
examples/java/app/pingpong/Receiver.java
examples/java/cloud/migration/Daemon.java
examples/java/cloud/migration/Main.java
examples/java/cloud/migration/Test.java
examples/java/dht/chord/Main.java
examples/java/dht/kademlia/Common.java
examples/java/dht/kademlia/Main.java
examples/java/energy/consumption/Main.java
examples/java/io/file/Main.java
examples/java/io/storage/Main.java
examples/java/process/kill/Main.java
examples/java/process/migration/Main.java
examples/java/process/startkilltime/Main.java
examples/java/process/suspend/Main.java
examples/java/task/priority/Main.java
examples/java/trace/pingpong/Main.java
examples/java/trace/pingpong/Receiver.java
examples/s4u/basic/s4u_basic.cpp
examples/s4u/mutex/s4u_mutex.cpp
include/simgrid/s4u/actor.hpp
include/smpi/smpi.h
include/xbt/functional.hpp
include/xbt/utility.hpp [new file with mode: 0644]
src/bindings/java/org/simgrid/NativeLib.java
src/bindings/java/org/simgrid/msg/Msg.java
src/bindings/java/org/simgrid/msg/Process.java
src/mc/mc_checkpoint.cpp
src/smpi/private.hpp
src/smpi/smpi_bench.cpp
src/smpi/smpi_memory.cpp
src/smpi/smpi_static_variables.cpp [moved from src/smpi/smpi_c99.cpp with 100% similarity]
src/xbt/memory_map.cpp
tools/cmake/DefinePackages.cmake

index 7443a7e..021b1c5 100644 (file)
@@ -9,7 +9,11 @@ package app.bittorrent;
 import org.simgrid.msg.Msg;
 import org.simgrid.msg.MsgException;
 
-public class Main{
+class Main{
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
+
   public static void main(String[] args) throws MsgException {
     Msg.init(args);
     if(args.length < 2) {
index 6d8c6d1..32a584d 100644 (file)
@@ -10,6 +10,10 @@ import org.simgrid.msg.Msg;
 import org.simgrid.msg.NativeException;
 
 class Main {
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
+
   public static void main(String[] args) throws NativeException {
     Msg.init(args);
 
index cc24eed..c1e905c 100644 (file)
@@ -14,9 +14,9 @@ import org.simgrid.msg.NativeException;
 class Main {
   public static final int TASK_COMP_SIZE = 10000000;
   public static final int TASK_COMM_SIZE = 10000000;
-  /* This only contains the launcher. If you do nothing more than than you can run java simgrid.msg.Msg
-   * which also contains such a launcher
-   */
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
 
   public static void main(String[] args) throws NativeException {
     /* initialize the MSG simulation. Must be done before anything else (even logging). */
index 80d832e..2617455 100644 (file)
@@ -21,8 +21,6 @@ public class Receiver extends Process {
   public void main(String[] args) throws MsgException {
     Msg.info("hello!");
 
-    double time = Msg.getClock();
-
     Msg.info("try to get a task");
 
     PingPongTask task = (PingPongTask)Task.receive(getHost().getName());
@@ -31,7 +29,7 @@ public class Receiver extends Process {
 
     Msg.info("Got at time "+ timeGot);
     Msg.info("Was sent at time "+timeSent);
-    time = timeSent;
+    double time = timeSent;
 
     double communicationTime = timeGot - time;
     Msg.info("Communication time : " + communicationTime);
index 68a31f3..d03d09a 100644 (file)
@@ -10,29 +10,28 @@ import org.simgrid.msg.*;
 import org.simgrid.msg.Process;
 
 public class Daemon extends Process {
-       private Task currentTask;
-    public Daemon(VM vm, int load) {
-               super((Host)vm,"Daemon");
-       currentTask = new Task(this.getHost().getName()+"-daemon-0", this.getHost().getSpeed()*100, 0);
-    }
-    public void main(String[] args) throws MsgException {
-        int i = 1;
-        while(!Main.isEndOfTest()) {
-            // TODO the binding is not yet available
-            try {
-                currentTask.execute();
-            } catch (HostFailureException e) {
-                e.printStackTrace();
-            } catch (TaskCancelledException e) {
-                System.out.println("task cancelled");
-                suspend(); // Suspend the process
-            }
-            currentTask = new Task(this.getHost().getName()+"-daemon-"+(i++), this.getHost().getSpeed()*100, 0);
-//            Msg.info(currentTask.getName());
-        }
+  private Task currentTask;
+  public Daemon(VM vm, int load) {
+    super((Host)vm,"Daemon");
+    currentTask = new Task(this.getHost().getName()+"-daemon-0", this.getHost().getSpeed()*100, 0);
+  }
+  public void main(String[] args) throws MsgException {
+    int i = 1;
+    while(!Main.isEndOfTest()) {
+      // TODO the binding is not yet available
+    try {
+      currentTask.execute();
+    } catch (HostFailureException e) {
+      e.printStackTrace();
+    } catch (TaskCancelledException e) {
+      System.out.println("task cancelled");
+      suspend(); // Suspend the process
     }
+    currentTask = new Task(this.getHost().getName()+"-daemon-"+(i++), this.getHost().getSpeed()*100, 0);
+  }
+}
 
-    public double getRemaining(){
-        return this.currentTask.getFlopsAmount();
-    }
+  public double getRemaining(){
+    return this.currentTask.getFlopsAmount();
+  }
 }
index af1aa25..2ae9be0 100644 (file)
@@ -14,6 +14,10 @@ import org.simgrid.msg.MsgException;
 public class Main {
   private static boolean endOfTest = false;
 
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
+
   public static void setEndOfTest(){
     endOfTest=true;
   }
index 2e59f4b..279917e 100644 (file)
@@ -18,22 +18,27 @@ public class Test extends Process{
     super(hostname, name);
   }
 
-  public void main(String[] strings) throws MsgException {
-    double startTime = 0;
-    double endTime = 0;
+  public void doMigration(VM vm, Host src, Host dst) throws HostFailureException{
+    Msg.info("     - Launch migration from "+ src.getName() +" to " + dst.getName());
+    double startTime = Msg.getClock();
+    vm.migrate(dst);
+    double endTime = Msg.getClock();
+    Msg.info("     - End of Migration from "+ src.getName() +" to " + dst.getName()+ " (duration:" +
+             (endTime-startTime)+")");
+  }
 
-    /* get hosts 1 and 2*/
+  public void main(String[] strings) throws MsgException {
     Host host0 = null;
     Host host1 = null;
-
     try {
+    /* get hosts 1 and 2*/
       host0 = Host.getByName("PM0");
       host1 = Host.getByName("PM1");
     }catch (HostNotFoundException e) {
-      e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+      e.printStackTrace();
     }
 
-    List<VM> vms = new ArrayList<VM>();
+    List<VM> vms = new ArrayList<>();
 
     /* Create VM1 */
     int dpRate = 70;
@@ -47,8 +52,7 @@ public class Test extends Process{
 
     Msg.info("Load of collocated VMs fluctuate between 0 and 90% in order to create a starvation issue and see "
              + "whether it impacts or not the migration time");
-    XVM vm1 = null;
-    vm1 = new XVM(host0, "vm0",
+    XVM vm1 = new XVM(host0, "vm0",
         1, // Nb of vcpu
         2048, // Ramsize,
         125, // Net Bandwidth
@@ -62,7 +66,7 @@ public class Test extends Process{
 
     /* Collocated VMs */
     int collocatedSrc = 6;
-    int vmSrcLoad[] = {
+    int[] vmSrcLoad = {
         80,
         0,
         90,
@@ -71,7 +75,7 @@ public class Test extends Process{
         90,
     };
 
-    XVM tmp = null;
+    XVM tmp;
     for (int i=1 ; i<= collocatedSrc ; i++){
       tmp = new XVM(host0, "vm"+i,
           1, // Nb of vcpu
@@ -88,7 +92,7 @@ public class Test extends Process{
     }
 
     int collocatedDst = 6;
-    int vmDstLoad[] = {
+    int[] vmDstLoad = {
         0,
         40,
         90,
@@ -114,31 +118,14 @@ public class Test extends Process{
 
     Msg.info("Round trip of VM1 (load "+load1+"%)");
     vm1.setLoad(load1);
-    Msg.info("     - Launch migration from PM0 to PM1");
-    startTime = Msg.getClock();
-    vm1.migrate(host1);
-    endTime = Msg.getClock();
-    Msg.info("     - End of Migration from PM0 to PM1 (duration:"+(endTime-startTime)+")");
-    Msg.info("     - Launch migration from PM1 to PM0");
-    startTime = Msg.getClock();
-    vm1.migrate(host0);
-    endTime = Msg.getClock();
-    Msg.info("     - End of Migration from PM1 to PM0 (duration:"+(endTime-startTime)+")");
-
+    doMigration(vm1, host0, host1);
+    doMigration(vm1, host1, host0);
     Msg.info("");
     Msg.info("");
     Msg.info("Round trip of VM1 (load "+load2+"%)");
     vm1.setLoad(load2);
-    Msg.info("     - Launch migration from PM0 to PM1");
-    startTime = Msg.getClock();
-    vm1.migrate(host1);
-    endTime = Msg.getClock();
-    Msg.info("     - End of Migration from PM0 to PM1 (duration:"+(endTime-startTime)+")");
-    Msg.info("     - Launch migration from PM1 to PM0");
-    startTime = Msg.getClock();
-    vm1.migrate(host0);
-    endTime = Msg.getClock();
-    Msg.info("     - End of Migration from PM1 to PM0 (duration:"+(endTime-startTime)+")");
+    doMigration(vm1, host0, host1);
+    doMigration(vm1, host1, host0);
 
     Main.setEndOfTest();
     Msg.info("Forcefully destroy VMs");
index 44e2425..0128a89 100644 (file)
@@ -8,7 +8,11 @@ package dht.chord;
 
 import org.simgrid.msg.Msg;
 
-public class Main {
+class Main {
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
+
   public static void main(String[] args) {
     Msg.init(args);
     if(args.length < 2) {
index 9ec3d57..890899f 100644 (file)
@@ -29,4 +29,7 @@ public class Common {
 
   public final static int MAX_STEPS = 10;
   public final static int JOIN_BUCKETS_QUERIES = 1;
+  private Common() {
+    throw new IllegalAccessError("Utility class");
+  }
 }
index ffb9dd4..dacbfae 100644 (file)
@@ -8,7 +8,11 @@ package dht.kademlia;
 import org.simgrid.msg.Msg;
 import org.simgrid.msg.MsgException;
 
-public class Main {
+class Main {
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
+
   public static void main(String[] args) throws MsgException {
     Msg.init(args);
     if(args.length < 2) {
index 1297b9a..f403e0d 100644 (file)
@@ -14,6 +14,9 @@ public class Main {
   public static final double task_comp_size = 10;
   public static final double task_comm_size = 10;
   public static final int hostNB = 2 ; 
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
 
   public static void main(String[] args) throws MsgException {  
     Msg.energyInit(); 
index 998f911..c1b72dd 100644 (file)
@@ -11,6 +11,10 @@ import org.simgrid.msg.Host;
 import org.simgrid.msg.MsgException;
 
 public class Main {
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
+
   public static void main(String[] args) throws MsgException {
     Msg.init(args);
     if(args.length < 1) {
index 9b77b8d..b81a143 100644 (file)
@@ -10,6 +10,10 @@ import org.simgrid.msg.Host;
 import org.simgrid.msg.MsgException;
 
 public class Main {
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
+
   public static void main(String[] args) throws MsgException {
     Msg.init(args);
     if(args.length < 1) {
index 8a1065a..f62b469 100644 (file)
@@ -11,6 +11,10 @@ import org.simgrid.msg.MsgException;
 import org.simgrid.msg.NativeException;
 
 public class Main {
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
+
   public static void main(String[] args) throws NativeException {
     /* initialize the MSG simulation. Must be done before anything else (even logging). */
     Msg.init(args);
index 66eb2b1..9498dbc 100644 (file)
@@ -15,6 +15,10 @@ class Main {
   protected static Mutex mutex;
   protected static Process processToMigrate = null;
 
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
+
   public static void main(String[] args) throws NativeException {
     Msg.init(args);
     if(args.length < 1) {
index e24ecd1..2168b16 100644 (file)
@@ -9,6 +9,10 @@ import org.simgrid.msg.Msg;
 import org.simgrid.msg.NativeException;
 
 public class Main {
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
+
   public static void main(String[] args) throws NativeException {
     Msg.init(args);
     if(args.length < 2) {
index 22af113..04510e8 100644 (file)
@@ -9,6 +9,10 @@ import org.simgrid.msg.Msg;
 import org.simgrid.msg.MsgException;
 
 public class Main {
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
+
   public static void main(String[] args) {
     Msg.init(args);
     if(args.length < 1) {
index adf7fc2..29133c1 100644 (file)
@@ -10,6 +10,10 @@ import org.simgrid.msg.NativeException;
 
 /* Demonstrates the use of Task.setPriority to change the computation priority of a task */ 
 public class Main {
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
+
   public static void main(String[] args) throws NativeException {
     Msg.init(args);
     if(args.length < 2) {
index bd43e17..da7d657 100644 (file)
@@ -11,6 +11,10 @@ import org.simgrid.msg.MsgException;
 import org.simgrid.msg.NativeException;
 
 public class Main  {
+  private Main() {
+    throw new IllegalAccessError("Utility class");
+  }
+
   public static void main(String[] args) throws MsgException, NativeException {
     Msg.init(args);
     if(args.length < 1) {
index 0a57d52..2771655 100644 (file)
@@ -25,9 +25,6 @@ public class Receiver extends Process {
   public void main(String[] args) throws MsgException {
     Msg.info("hello!");
     Trace.hostPushState (getHost().getName(), "PM_STATE", "waitingPing");
-    double communicationTime=0;
-
-    double time = Msg.getClock();
 
     /* Wait for the ping */ 
     Msg.info("try to get a task");
@@ -38,9 +35,9 @@ public class Receiver extends Process {
 
     Msg.info("Got at time "+ timeGot);
     Msg.info("Was sent at time "+timeSent);
-    time=timeSent;
+    double time=timeSent;
 
-    communicationTime=timeGot - time;
+    double communicationTime=timeGot - time;
     Msg.info("Communication time : " + communicationTime);
 
     Msg.info(" --- bw "+ commSizeBw/communicationTime + " ----");
index c08cd6d..12156f2 100644 (file)
@@ -35,7 +35,7 @@ int main(int argc, char **argv) {
   simgrid::s4u::Engine *e = new simgrid::s4u::Engine(&argc,argv);
   e->loadPlatform("../../platforms/two_hosts.xml");
   simgrid::s4u::Actor("worker", simgrid::s4u::Host::by_name("Tremblay"), Worker());
-  simgrid::s4u::Actor("master", simgrid::s4u::Host::by_name("Jupiter"), 0, Master());
+  simgrid::s4u::Actor("master", simgrid::s4u::Host::by_name("Jupiter"), Master());
   e->run();
   return 0;
 }
index 3d0ba54..f1c0eb7 100644 (file)
@@ -3,90 +3,72 @@
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
-#include <xbt/sysdep.h>
+#include <functional>
 #include <mutex>
 
+#include <xbt/sysdep.h>
+
 #include "simgrid/s4u.h"
 
 #define NB_ACTOR 2
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category");
 
-// simgrid::s4u::Mutex mtx; //FIXME generate error -> You must run MSG_init before using MSG
-
-//Create an actor as a c++ functor
-class Worker {
-  simgrid::s4u::Mutex mutex_;
-  int *results_;
-public:
-  Worker(int  *res, simgrid::s4u::Mutex mutex) :
-    mutex_(std::move(mutex)),  results_(res) {};
-  // Define the code of the actor
-  void operator()() {
-    // Do the calculation
-    simgrid::s4u::this_actor::execute(1000);
-
-    // lock the mutex before enter in the critical section
-    std::lock_guard<simgrid::s4u::Mutex> lock(mutex_);
-    XBT_INFO("Hello s4u, I'm ready to compute");
-
-    // And finaly add it to the results
-    *results_ += 1;
-    XBT_INFO("I'm done, good bye");
-  }
-};
-
-// This class is an example of how to use lock_guard with simgrid mutex
-class WorkerLockGuard {
-  simgrid::s4u::Mutex mutex_;
-  int *results_;
-public:
-  WorkerLockGuard(int  *res, simgrid::s4u::Mutex mutex) :
-    mutex_(std::move(mutex)),  results_(res) {};
-  void operator()() {
-
-    simgrid::s4u::this_actor::execute(1000);
-
-    // Simply use the std::lock_guard like this
-    std::lock_guard<simgrid::s4u::Mutex> lock(mutex_);
-
-    // then you are in a safe zone
-    XBT_INFO("Hello s4u, I'm ready to compute");
-    // update the results
-    *results_ += 1;
-    XBT_INFO("I'm done, good bye");
-  }
-};
-
-class MainActor {
-public:
-  void operator()() {
-    int res = 0;
-    simgrid::s4u::Mutex mutex;
-    simgrid::s4u::Actor workers[NB_ACTOR*2];
-
-    for (int i = 0; i < NB_ACTOR * 2 ; i++) {
-      // To create a worker use the static method simgrid::s4u::Actor.
-      if((i % 2) == 0 )
-        workers[i] = simgrid::s4u::Actor("worker",
-          simgrid::s4u::Host::by_name("Jupiter"),
-          WorkerLockGuard(&res, mutex));
-      else
-        workers[i] = simgrid::s4u::Actor("worker",
-          simgrid::s4u::Host::by_name("Tremblay"),
-          Worker(&res, mutex));
-    }
-
-    simgrid::s4u::this_actor::sleep(10);
-    XBT_INFO("Results is -> %d", res);
+static void worker(simgrid::s4u::Mutex mutex, int& result)
+{
+  // Do the calculation
+  simgrid::s4u::this_actor::execute(1000);
+
+  // lock the mutex before enter in the critical section
+  std::lock_guard<simgrid::s4u::Mutex> lock(mutex);
+  XBT_INFO("Hello s4u, I'm ready to compute");
+
+  // And finaly add it to the results
+  result += 1;
+  XBT_INFO("I'm done, good bye");
+}
+
+static void workerLockGuard(simgrid::s4u::Mutex mutex, int& result)
+{
+  simgrid::s4u::this_actor::execute(1000);
+
+  // Simply use the std::lock_guard like this
+  std::lock_guard<simgrid::s4u::Mutex> lock(mutex);
+
+  // then you are in a safe zone
+  XBT_INFO("Hello s4u, I'm ready to compute");
+  // update the results
+  result += 1;
+  XBT_INFO("I'm done, good bye");
+}
+
+static void master()
+{
+  int result = 0;
+  simgrid::s4u::Mutex mutex;
+  simgrid::s4u::Actor workers[NB_ACTOR*2];
+
+  for (int i = 0; i < NB_ACTOR * 2 ; i++) {
+    // To create a worker use the static method simgrid::s4u::Actor.
+    if((i % 2) == 0 )
+      workers[i] = simgrid::s4u::Actor("worker",
+        simgrid::s4u::Host::by_name("Jupiter"),
+        workerLockGuard, mutex, std::ref(result));
+    else
+      workers[i] = simgrid::s4u::Actor("worker",
+        simgrid::s4u::Host::by_name("Tremblay"),
+        worker, mutex, std::ref(result));
   }
-};
 
+  simgrid::s4u::this_actor::sleep(10);
+  XBT_INFO("Results is -> %d", result);
+}
 
-int main(int argc, char **argv) {
+int main(int argc, char **argv)
+{
   simgrid::s4u::Engine *e = new simgrid::s4u::Engine(&argc,argv);
   e->loadPlatform("../../platforms/two_hosts.xml");
-  simgrid::s4u::Actor("main", simgrid::s4u::Host::by_name("Tremblay"), 0, MainActor());
+  simgrid::s4u::Actor("main", simgrid::s4u::Host::by_name("Tremblay"), master);
   e->run();
   return 0;
 }
index 092d14b..89a752e 100644 (file)
@@ -6,8 +6,16 @@
 #ifndef SIMGRID_S4U_ACTOR_HPP
 #define SIMGRID_S4U_ACTOR_HPP
 
+#include <atomic>
+#include <functional>
+#include <future>
+#include <memory>
 #include <stdexcept>
+#include <type_traits>
+
 #include <xbt/base.h>
+#include <xbt/functional.hpp>
+
 #include <simgrid/simix.h>
 #include <simgrid/s4u/forward.hpp>
 
@@ -113,9 +121,39 @@ namespace s4u {
  * 
  *  @{
  */
-   
+
 /** @brief Simulation Agent (see \ref s4u_actor)*/
 XBT_PUBLIC_CLASS Actor {
+private:
+  /** Wrap a (possibly non-copyable) single-use task into a `std::function` */
+  template<class F, class... Args>
+  class Task {
+  public:
+    Task(F&& code, Args&&... args) :
+      code_(std::forward<F>(code)),
+      args_(std::forward<Args>(args)...)
+    {}
+    void operator()()
+    {
+      if (done_.test_and_set())
+        throw std::logic_error("Actor task already executed");
+      simgrid::xbt::apply(std::move(code_), std::move(args_));
+    }
+  private:
+    std::atomic_flag done_ = ATOMIC_FLAG_INIT;
+    F code_;
+    std::tuple<Args...> args_;
+  };
+  /** Wrap a (possibly non-copyable) single-use task into a `std::function` */
+  template<class F, class... Args>
+  static std::function<void()> wrap_task(F f, Args... args)
+  {
+    std::shared_ptr<Task<F, Args...>> task(
+      new Task<F, Args...>(std::move(f), std::move(args)...));
+    return [=] {
+      (*task)();
+    };
+  }
 public:
   Actor() : pimpl_(nullptr) {}
   Actor(smx_process_t smx_proc) :
@@ -142,12 +180,29 @@ public:
     swap(*this, actor);
   }
 
+  /** Create an actor using a function
+   *
+   *  If the actor is restarted, the actor has a fresh copy of the function.
+   */
   Actor(const char* name, s4u::Host *host, double killTime, std::function<void()> code);
+
   Actor(const char* name, s4u::Host *host, std::function<void()> code)
-    : Actor(name, host, -1, std::move(code)) {};
-  template<class C>
-  Actor(const char* name, s4u::Host *host, C code)
-    : Actor(name, host, -1, std::function<void()>(std::move(code))) {}
+    : Actor(name, host, -1.0d, std::move(code)) {};
+
+  /** Create an actor using code
+   *
+   *  Using this constructor, move-only type can be used. The consequence is
+   *  that we cannot copy the value and restart the process in its initial
+   *  state. In order to use auto-restart, an explicit `function` must be passed
+   *  instead.
+   */
+  template<class F, class... Args,
+    // This constructor is enabled only if the call code(args...) is valid:
+    typename = typename std::result_of<F(Args...)>::type
+    >
+  Actor(const char* name, s4u::Host *host, F code, Args... args) :
+    Actor(name, host, wrap_task(std::move(code), std::move(args)...))
+  {}
 
   /** Retrieves the actor that have the given PID (or NULL if not existing) */
   //static Actor *byPid(int pid); not implemented
index a06de05..3f7245b 100644 (file)
@@ -897,6 +897,10 @@ static void __attribute__((destructor)) __postfini_##name(void) { \
 
 #define SMPI_VARGET_GLOBAL(name) name[smpi_process_index()]
 
+/** 
+ * This is used for the old privatization method, i.e., on old
+ * machines that do not yet support privatization via mmap
+ */
 #define SMPI_VARINIT_STATIC(name,type)                      \
 static type *name = NULL;                                   \
 if(!name) {                                                 \
index 31f9430..537ba8f 100644 (file)
@@ -15,6 +15,7 @@
 #include <utility>
 
 #include <xbt/sysdep.h>
+#include <xbt/utility.hpp>
 
 namespace simgrid {
 namespace xbt {
@@ -117,6 +118,41 @@ std::function<void()> wrapMain(F code, int argc, const char*const* argv)
   return wrapMain(std::move(code), args(argc, argv));
 }
 
+namespace bits {
+template <class F, class Tuple, std::size_t... I>
+constexpr auto apply(F&& f, Tuple&& t, simgrid::xbt::index_sequence<I...>)
+  -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...))
+{
+  return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
+}
+}
+
+/** Call a functional object with the values in the given tuple (from C++17)
+ *
+ *  @code{.cpp}
+ *  int foo(int a, bool b);
+ *
+ *  auto args = std::make_tuple(1, false);
+ *  int res = apply(foo, args);
+ *  @encode
+ **/
+template <class F, class Tuple>
+constexpr auto apply(F&& f, Tuple&& t)
+  -> decltype(simgrid::xbt::bits::apply(
+    std::forward<F>(f),
+    std::forward<Tuple>(t),
+    simgrid::xbt::make_index_sequence<
+      std::tuple_size<typename std::decay<Tuple>::type>::value
+    >()))
+{
+  return simgrid::xbt::bits::apply(
+    std::forward<F>(f),
+    std::forward<Tuple>(t),
+    simgrid::xbt::make_index_sequence<
+      std::tuple_size<typename std::decay<Tuple>::type>::value
+    >());
+}
+
 }
 }
 
diff --git a/include/xbt/utility.hpp b/include/xbt/utility.hpp
new file mode 100644 (file)
index 0000000..09d8db4
--- /dev/null
@@ -0,0 +1,80 @@
+/* Copyright (c) 2016. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include <tuple>
+
+namespace simgrid {
+namespace xbt {
+
+// integer_sequence and friends from C++14
+// We need them to implement `apply` from C++17.
+
+/** A compile-time sequence of integers (from C++14)
+ *
+ * `index_sequence<std::size_t,1,5,7,9>` represents the sequence `(1,5,7,9)`.
+ *
+ * @code{.cpp}
+ * template<class T, std::size_t... I>
+ * auto extract_tuple(T&& t, integer_sequence<std::size_t, I...>)
+ *   -> decltype(std::make_tuple(std::get<I>(std::forward<T>(t))...))
+ * {
+ *  return std::make_tuple(std::get<I>(std::forward<T>(t))...);
+ * }
+ *
+ * int main()
+ * {
+ *   integer_sequence<std::size_t, 1, 3> seq;
+ *   auto a = std::make_tuple(1, 2.0, false, 'a');
+ *   auto b = extract_tuple(a, seq);
+ *   std::cout << std::get<0>(b) << '\n'; // 2
+ *   std::cout << std::get<1>(b) << '\n'; // a
+ *   return 0;
+ * }
+ * @endcode
+ */
+template<class T, T... N>
+class integer_sequence {
+  static constexpr std::size_t size()
+  {
+    return std::tuple_size<decltype(std::make_tuple(N...))>::value;
+  }
+};
+
+namespace bits {
+  template<class T, long long N, long long... M>
+  struct make_integer_sequence :
+    public make_integer_sequence<T, N-1, N-1, M...>
+  {};
+  template<class T, long long... M>
+  struct make_integer_sequence<T, 0, M...> {
+    typedef integer_sequence<T, (T) M...> type;
+  };
+}
+
+/** A compile-time sequence of integers of the form `(0,1,2,3,...,N-1)` (from C++14) */
+template<class T, T N>
+using make_integer_sequence = typename simgrid::xbt::bits::make_integer_sequence<T,N>::type;
+
+/** A compile-time sequence of indices (from C++14) */
+template<std::size_t... Ints>
+using index_sequence = integer_sequence<std::size_t, Ints...>;
+
+/** A compile-time sequence of indices of the form `(0,1,2,3,...,N-1)` (from C++14) */
+template<std::size_t N>
+using make_index_sequence = make_integer_sequence<std::size_t, N>;
+
+/** Convert a type parameter pack into a index_sequence (from C++14) */
+template<class... T>
+using index_sequence_for = make_index_sequence<sizeof...(T)>;
+
+static_assert(std::is_same< make_index_sequence<0>, index_sequence<> >::value, "seq0");
+static_assert(std::is_same< make_index_sequence<1>, index_sequence<0> >::value, "seq1");
+static_assert(std::is_same< make_index_sequence<2>, index_sequence<0, 1> >::value, "seq2");
+static_assert(std::is_same< make_index_sequence<3>, index_sequence<0, 1, 2> >::value, "seq3");
+static_assert(std::is_same< index_sequence_for<int,double,float>, make_index_sequence<3> >::value, "seq4");
+
+}
+}
index 35527c0..150b0cc 100644 (file)
@@ -16,7 +16,13 @@ import java.nio.file.Path;
 
 public final class NativeLib {
        /* Statically load the library which contains all native functions used in here */
-       static private boolean isNativeInited = false;
+       private static boolean isNativeInited = false;
+       static Path tempDir = null;
+
+       private NativeLib() {
+               throw new IllegalAccessError("Utility class");
+       }
+
        public static void nativeInit() {
                if (isNativeInited)
                        return;
@@ -25,7 +31,7 @@ public final class NativeLib {
                        NativeLib.nativeInit("winpthread-1");
 
                NativeLib.nativeInit("simgrid");
-               NativeLib.nativeInit("simgrid-java");      
+               NativeLib.nativeInit("simgrid-java");
                isNativeInited = true;
        }
 
@@ -38,7 +44,7 @@ public final class NativeLib {
                        try {
                                System.loadLibrary(name);
                        } catch (UnsatisfiedLinkError systemException) {
-                               if (! name.equals("boost_context")) { // Ignore when we cannot load boost_context
+                               if (! "boost_context".equals(name)) { // Ignore when we cannot load boost_context
                                        
                                        System.err.println("\nCannot load the bindings to the "+name+" library in path "+getPath());
                                        Throwable cause = embeededException.getCause();
@@ -48,7 +54,7 @@ public final class NativeLib {
                                                else if (cause.getMessage().matches(".*libboost_context.so.*"))
                                                        System.err.println("HINT: Try to install the boost-context package (sudo apt-get install libboost-context-dev).");
                                                else
-                                                       System.err.println("Try to install the missing dependencies, which name should appear above.");                                                 
+                                                       System.err.println("Try to install the missing dependencies, which name should appear above.");
                                        } else {
                                                System.err.println("This jar file does not seem to fit your system, and no usable SimGrid installation found on disk.");
                                        }
@@ -68,9 +74,9 @@ public final class NativeLib {
 
                if (arch.matches("^i[3-6]86$"))
                        arch = "x86";
-               else if (arch.equalsIgnoreCase("x86_64"))
+               else if ("x86_64".equalsIgnoreCase(arch))
                        arch = "amd64";
-               else if (arch.equalsIgnoreCase("AMD64"))
+               else if ("AMD64".equalsIgnoreCase(arch))
                        arch = "amd64";
 
                if (os.toLowerCase().startsWith("win")){
@@ -83,31 +89,31 @@ public final class NativeLib {
 
                return prefix + "/" + os + "/" + arch + "/";
        }
-       static Path tempDir = null;
+
        private static void loadLib (String name) throws LinkageException {
-               String Path = NativeLib.getPath();
+               String path = NativeLib.getPath();
 
                String filename=name;
-               InputStream in = NativeLib.class.getClassLoader().getResourceAsStream(Path+filename);
+               InputStream in = NativeLib.class.getClassLoader().getResourceAsStream(path+filename);
 
                if (in == null) {
                        filename = "lib"+name+".so";
-                       in = NativeLib.class.getClassLoader().getResourceAsStream(Path+filename);
+                       in = NativeLib.class.getClassLoader().getResourceAsStream(path+filename);
                }
                if (in == null) {
                        filename = name+".dll";
-                       in =  NativeLib.class.getClassLoader().getResourceAsStream(Path+filename);
+                       in =  NativeLib.class.getClassLoader().getResourceAsStream(path+filename);
                }
                if (in == null) {
                        filename = "lib"+name+".dll";
-                       in =  NativeLib.class.getClassLoader().getResourceAsStream(Path+filename);
+                       in =  NativeLib.class.getClassLoader().getResourceAsStream(path+filename);
                }
                if (in == null) {
                        filename = "lib"+name+".dylib";
-                       in =  NativeLib.class.getClassLoader().getResourceAsStream(Path+filename);
+                       in =  NativeLib.class.getClassLoader().getResourceAsStream(path+filename);
                }
                if (in == null) {
-                       throw new LinkageException("Cannot find library "+name+" in path "+Path+". Sorry, but this jar does not seem to be usable on your machine.");
+                       throw new LinkageException("Cannot find library "+name+" in path "+path+". Sorry, but this jar does not seem to be usable on your machine.");
                }
                try {
                        // We must write the lib onto the disk before loading it -- stupid operating systems
@@ -121,9 +127,9 @@ public final class NativeLib {
                        /* copy the library in position */  
                        OutputStream out = new FileOutputStream(fileOut);
                        byte[] buffer = new byte[4096]; 
-                       int bytes_read; 
-                       while ((bytes_read = in.read(buffer)) != -1)     // Read until EOF
-                               out.write(buffer, 0, bytes_read); 
+                       int bytesRead; 
+                       while ((bytesRead = in.read(buffer)) != -1)     // Read until EOF
+                               out.write(buffer, 0, bytesRead); 
 
                        /* close all file descriptors, and load that shit */
                        in.close();
@@ -146,13 +152,13 @@ public final class NativeLib {
                                for (File f : dir.listFiles())
                                        if (! f.delete() )
                                                System.err.println("Unable to clean temporary file "+f.getAbsolutePath()+" during shutdown.");
-                           if (! dir.delete() )
+                               if (! dir.delete() )
                                        System.err.println("Unable to clean temporary file "+dir.getAbsolutePath()+" during shutdown.");                                
                        } catch(Exception e) {
                                System.err.println("Unable to clean temporary file "+dir.getAbsolutePath()+" during shutdown: "+e.getCause());
                                e.printStackTrace();
                        }
-               }    
+               }
        }
 
 
index f4cb975..bd49fd2 100644 (file)
@@ -13,19 +13,23 @@ import org.simgrid.NativeLib;
 public final class Msg {
 
        /** Retrieves the simulation time */
-       public final static native double getClock();
+       public static final native double getClock();
        /** Issue a debug logging message. */
-       public final static native void debug(String msg);
+       public static final native void debug(String msg);
        /** Issue a verbose logging message. */
-       public final static native void verb(String msg);
+       public static final native void verb(String msg);
        /** Issue an information logging message */
-       public final static native void info(String msg);
+       public static final native void info(String msg);
        /** Issue a warning logging message. */
-       public final static native void warn(String msg);
+       public static final native void warn(String msg);
        /** Issue an error logging message. */
-       public final static native void error(String msg);
+       public static final native void error(String msg);
        /** Issue a critical logging message. */
-       public final static native void critical(String s);
+       public static final native void critical(String s);
+
+       private Msg() {
+               throw new IllegalAccessError("Utility class");
+       }
 
        /*********************************************************************************
         * Deployment and initialization related functions                               *
@@ -35,10 +39,10 @@ public final class Msg {
         *
         * @param args            The arguments of the command line of the simulation.
         */
-       public final static native void init(String[]args);
+       public static final native void init(String[]args);
        
        /** Tell the kernel that you want to use the energy plugin */
-       public final static native void energyInit();
+       public static final native void energyInit();
 
        /** Run the MSG simulation.
         *
@@ -47,19 +51,15 @@ public final class Msg {
         * retrieve the information that you want from the simulation. In particular, retrieving the status 
         * of a process or the current date is perfectly ok. 
         */
-       public final static native void run() ;
-
-       /** This function is useless nowadays, just stop calling it. */
-       @Deprecated
-       public final static void clean(){}
+       public static final native void run() ;
 
        /** Create the simulation environment by parsing a platform file. */
-       public final static native void createEnvironment(String platformFile);
+       public static final native void createEnvironment(String platformFile);
 
-       public final static native As environmentGetRoutingRoot();
+       public static final native As environmentGetRoutingRoot();
 
        /** Starts your processes by parsing a deployment file. */
-       public final static native void deployApplication(String deploymentFile);
+       public static final native void deployApplication(String deploymentFile);
 
        /** Example launcher. You can use it or provide your own launcher, as you wish
         * @param args
index 291ab60..d9b3b6e 100644 (file)
@@ -7,7 +7,7 @@
 package org.simgrid.msg;
 
 import java.util.Arrays;
-import java.util.Vector;
+import java.util.ArrayList;
 
 /**
  * A process may be defined as a code, with some private data, executing 
@@ -53,7 +53,7 @@ public abstract class Process implements Runnable {
         * Even if this attribute is public you must never access to it.
         * It is used to compute the id of an MSG process.
         */
-       public static long nextProcessId = 0;
+       private static long nextProcessId = 0;
 
        /**
         * Even if this attribute is public you must never access to it.
@@ -77,7 +77,7 @@ public abstract class Process implements Runnable {
        private Host host = null;
 
        /** The arguments of the method function of the process. */     
-       public Vector<String> args;
+       public ArrayList<String> args;
 
 
        /**  Default constructor */
@@ -85,7 +85,7 @@ public abstract class Process implements Runnable {
                this.id = nextProcessId++;
                this.name = null;
                this.bind = 0;
-               this.args = new Vector<String>();
+               this.args = new ArrayList<>();
        }
 
 
@@ -116,7 +116,7 @@ public abstract class Process implements Runnable {
         * @throws NativeException
         *
         */ 
-       public Process(String hostname, String name, String args[]) throws HostNotFoundException, NativeException {
+       public Process(String hostname, String name, String[] args) throws HostNotFoundException, NativeException {
                this(Host.getByName(hostname), name, args);
        }
        /**
@@ -142,15 +142,15 @@ public abstract class Process implements Runnable {
                this();
                this.host = host;
                if (host == null)
-                       throw new NullPointerException("Process name cannot be NULL");
+                       throw new NullPointerException("Host cannot be NULL");
                if (name == null)
                        throw new NullPointerException("Process name cannot be NULL");
                this.name = name;
 
-               this.args = new Vector<String>();
+               this.args = new ArrayList<>();
                if (null != args)
                        this.args.addAll(Arrays.asList(args));
-       }       
+       }
        /**
         * Constructs a new process from a host and his name, the arguments of here method function are
         * specified by the parameter args.
@@ -171,12 +171,12 @@ public abstract class Process implements Runnable {
                        throw new NullPointerException("Process name cannot be NULL");
                this.name = name;
 
-               this.args = new Vector<String>();
+               this.args = new ArrayList<>();
                if (null != args)
                        this.args.addAll(Arrays.asList(args));
 
                this.startTime = startTime;
-               this.killTime = killTime;               
+               this.killTime = killTime;
        }
        /**
         * The natively implemented method to create an MSG process.
@@ -305,7 +305,7 @@ public abstract class Process implements Runnable {
         * @param millis the length of time to sleep in milliseconds.
         * @param nanos additionnal nanoseconds to sleep.
         */
-       public native static void sleep(long millis, int nanos) throws HostFailureException;
+       public static native void sleep(long millis, int nanos) throws HostFailureException;
        /**
         * Makes the current process sleep until time seconds have elapsed.
         * @param seconds               The time the current process must sleep.
@@ -331,7 +331,7 @@ public abstract class Process implements Runnable {
 
                try {
                        args = new String[this.args.size()];
-                       if (this.args.size() > 0) {
+                       if (!this.args.isEmpty()) {
                                this.args.toArray(args);
                        }
 
index 20754d3..d6e234c 100644 (file)
@@ -527,7 +527,7 @@ static std::vector<s_fd_infos_t> get_current_fds(pid_t pid)
 
     // We don't handle them.
     // It does not mean we should silently ignore them however.
-    if (strncmp(link, "pipe:", 5) == 0 || strncmp(link, "socket:", 7) == 0)
+    if (strncmp(link, "pipe:", std::strlen("pipe:")) == 0 || strncmp(link, "socket:", std::strlen("socket:")) == 0)
       continue;
 
     // If dot_output enabled, do not handle the corresponding file
@@ -541,7 +541,7 @@ static std::vector<s_fd_infos_t> get_current_fds(pid_t pid)
     }
 
     // This is probably a shared memory used by lttng-ust:
-    if(strncmp("/dev/shm/ust-shm-tmp-", link, 21)==0)
+    if(strncmp("/dev/shm/ust-shm-tmp-", link, std::strlen("/dev/shm/ust-shm-tmp-"))==0)
       continue;
 
     // Add an entry for this FD in the snapshot:
index a384ac7..b05de0c 100644 (file)
@@ -9,6 +9,14 @@
 #include <unordered_map>
 #include "src/instr/instr_smpi.h"
 
+/**
+ * Get the address of the beginning of the memory page where addr is located.
+ * Note that we use an integer division here, so (a/b)*b is not a, unless a%b == 0
+ *
+ * This is used when privatizing.
+ */
+#define TOPAGE(addr) (void *)(((unsigned long)(addr) / xbt_pagesize) * xbt_pagesize)
+
 #ifdef HAVE_PAPI
 typedef 
     std::vector<std::pair</* counter name */std::string, /* counter value */long long>> papi_counter_t;
@@ -24,3 +32,4 @@ XBT_PUBLIC(smpi_trace_call_location_t*) smpi_process_get_call_location(void);
 XBT_PUBLIC(smpi_trace_call_location_t*) smpi_trace_get_call_location();
 }
 #endif
+
index e6998c3..dfc02f1 100644 (file)
@@ -230,8 +230,6 @@ void smpi_execute(double duration)
   }
 }
 
-void smpi_switch_data_segment(int dest);
-
 void smpi_bench_begin(void)
 {
   if (smpi_privatize_global_variables) {
@@ -606,12 +604,11 @@ void* smpi_shared_set_call(const char* func, const char* input, void* data) {
    return data;
 }
 
-#define TOPAGE(addr) (void *)(((unsigned long)(addr) / xbt_pagesize) * xbt_pagesize)
 
 /** Map a given SMPI privatization segment (make a SMPI process active) */
-void smpi_switch_data_segment(int dest){
-  if (smpi_loaded_page==dest)//no need to switch either
-   return;
+void smpi_switch_data_segment(int dest) {
+  if (smpi_loaded_page == dest)//no need to switch, we've already loaded the one we want
+    return;
 
   // So the job:
   smpi_really_switch_data_segment(dest);
@@ -646,7 +643,7 @@ void smpi_really_switch_data_segment(int dest) {
 
 int smpi_is_privatisation_file(char* file)
 {
-  return strncmp("/dev/shm/my-buffer-", file, 19) == 0;
+  return strncmp("/dev/shm/my-buffer-", file, std::strlen("/dev/shm/my-buffer-")) == 0;
 }
 
 void smpi_initialize_global_memory_segments(){
index 0c29b39..7963476 100644 (file)
 #include "../xbt/memory_map.hpp"
 
 #include "private.h"
+#include "private.hpp"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_memory, smpi, "Memory layout support for SMPI");
 
-#define TOPAGE(addr) (void *)(((unsigned long)(addr) / xbt_pagesize) * xbt_pagesize)
-
-#define PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC)
-#define PROT_RW (PROT_READ | PROT_WRITE )
-#define PROT_RX (PROT_READ | PROT_EXEC )
+static const int PROT_RWX = (PROT_READ | PROT_WRITE | PROT_EXEC);
+static const int PROT_RW  = (PROT_READ | PROT_WRITE );
+static const int PROT_RX  = (PROT_READ | PROT_EXEC );
 
 void smpi_get_executable_global_size(void)
 {
index 56349c4..9babc54 100644 (file)
@@ -27,6 +27,12 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_memory_map, xbt, "Logging specific to algori
 namespace simgrid {
 namespace xbt {
 
+/**
+ * \todo This function contains many cases that do not allow for a
+ *       recovery. Currently, xbt_abort() is called but we should
+ *       much rather die with the specific reason so that it's easier
+ *       to find out what's going on.
+ */
 XBT_PRIVATE std::vector<VmMap> get_memory_map(pid_t pid)
 {
 #ifdef __linux__
@@ -34,9 +40,10 @@ XBT_PRIVATE std::vector<VmMap> get_memory_map(pid_t pid)
   /* to be returned. */
   char* path = bprintf("/proc/%i/maps", (int) pid);
   FILE *fp = std::fopen(path, "r");
-  if(fp == nullptr)
+  if (fp == nullptr) {
     std::perror("fopen failed");
-  xbt_assert(fp, "Cannot open %s to investigate the memory map of the process.", path);
+    xbt_die("Cannot open %s to investigate the memory map of the process.", path);
+  }
   free(path);
   setbuf(fp, nullptr);
 
@@ -47,13 +54,17 @@ XBT_PRIVATE std::vector<VmMap> get_memory_map(pid_t pid)
   char* line = nullptr;
   std::size_t n = 0; /* Amount of bytes to read by xbt_getline */
   while ((read = xbt_getline(&line, &n, fp)) != -1) {
+    /**
+     * The lines that we read have this format: (This is just an example)
+     * 00602000-00603000 rw-p 00002000 00:28 1837264                            <complete-path-to-file>
+     */
 
     //fprintf(stderr,"%s", line);
 
     /* Wipeout the new line character */
     line[read - 1] = '\0';
 
-    /* Tokenize the line using spaces as delimiters and store each token in lfields array. We expect 5 tokens/fields */
+    /* Tokenize the line using spaces as delimiters and store each token in lfields array. We expect 5 tokens for 6 fields */
     char* lfields[6];
     lfields[0] = strtok(line, " ");
 
@@ -64,13 +75,13 @@ XBT_PRIVATE std::vector<VmMap> get_memory_map(pid_t pid)
 
     /* Check to see if we got the expected amount of columns */
     if (i < 6)
-      xbt_abort();
+      xbt_die("The memory map apparently only supplied less than 6 columns. Recovery impossible.");
 
     /* Ok we are good enough to try to get the info we need */
     /* First get the start and the end address of the map   */
     char *tok = std::strtok(lfields[0], "-");
     if (tok == nullptr)
-      xbt_abort();
+      xbt_die("Start and end address of the map are not concatenated by a hyphen (-). Recovery impossible.");
 
     VmMap memreg;
     char *endptr;
@@ -112,10 +123,14 @@ XBT_PRIVATE std::vector<VmMap> get_memory_map(pid_t pid)
     if (memreg.prot == 0)
       memreg.prot |= PROT_NONE;
 
-    if (lfields[1][4] == 'p')
+    if (lfields[1][3] == 'p')
       memreg.flags |= MAP_PRIVATE;
-    else if (lfields[1][4] == 's')
+    else if (lfields[1][3] == 's')
       memreg.flags |= MAP_SHARED;
+    else {
+      //fprintf(stderr,"%s", line);
+      xbt_die("Flag was neither 'p' (private) nor 's' (shared). This should have never happened! Instead, the permissions column was set to: %s", lfields[1]);
+    }
 
     /* Get the offset value */
     memreg.offset = std::strtoull(lfields[2], &endptr, 16);
index 2bd4041..1416671 100644 (file)
@@ -224,7 +224,7 @@ set(SMPI_SRC
   src/smpi/smpi_base.cpp
   src/smpi/smpi_bench.cpp
   src/smpi/smpi_memory.cpp
-  src/smpi/smpi_c99.cpp
+  src/smpi/smpi_static_variables.cpp
   src/smpi/smpi_coll.cpp
   src/smpi/smpi_comm.cpp
   src/smpi/smpi_deployment.cpp
@@ -699,6 +699,7 @@ set(headers_to_install
   include/xbt/synchro_core.h
   include/xbt/sysdep.h
   include/xbt/system_error.hpp
+  include/xbt/utility.hpp
   include/xbt/virtu.h
   include/xbt/xbt_os_thread.h
   include/xbt/xbt_os_time.h