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>
Thu, 11 Oct 2018 21:18:35 +0000 (23:18 +0200)
committerMartin Quinson <martin.quinson@loria.fr>
Thu, 11 Oct 2018 21:18:35 +0000 (23:18 +0200)
21 files changed:
ChangeLog
README.md
docs/source/app_s4u.rst
examples/java/CMakeLists.txt
examples/java/cloud/migration/XVM.java
examples/java/hostload/LoadRunner.java [new file with mode: 0644]
examples/java/hostload/Main.java [new file with mode: 0644]
examples/java/hostload/hostload.tesh [new file with mode: 0644]
include/simgrid/host.h
include/simgrid/msg.h
include/simgrid/plugins/load.h
src/bindings/java/jmsg.cpp
src/bindings/java/jmsg.hpp
src/bindings/java/jmsg_host.cpp
src/bindings/java/jmsg_host.h
src/bindings/java/org/simgrid/msg/Host.java
src/bindings/java/org/simgrid/msg/Msg.java
src/msg/msg_legacy.cpp
src/msg/msg_process.cpp
src/plugins/host_load.cpp
src/s4u/s4u_Host.cpp

index 622c291..def6922 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 SimGrid (3.22) NOT RELEASED (Release Target: December 21. 2018, 22:23 UTC)
 
+Java:
+ - Expose host load plugin: loadInit, getCurrentLoad, getComputedFlops, getAvgLoad
+
 Fixed bugs:
  - #261: Document the parameters of parallel execution's constructor
 
index e5e0f1b..8966151 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com)
-[![Travis Status](https://travis-ci.org/simgrid/simgrid.svg?branch=master)](https://travis-ci.org/simgrid/simgrid)
+[![Travis Status](https://img.shields.io/travis/simgrid/simgrid/master.svg?logo=travis)](https://travis-ci.org/simgrid/simgrid)
 [![AppVeyor Status](https://ci.appveyor.com/api/projects/status/gvcssh340fwtoc35?svg=true)](https://ci.appveyor.com/project/mquinson/simgrid)
 [![SonarCloud Status](https://sonarcloud.io/api/project_badges/measure?project=simgrid&metric=alert_status)](https://sonarcloud.io/dashboard/?id=simgrid)
 [![Codacy Badge](https://api.codacy.com/project/badge/Grade/bf1bdba50440485fbda2ac19f462ccc7)](https://www.codacy.com/app/mquinson/simgrid?utm_source=github.com&amp)
index 46cc216..7fb6664 100644 (file)
@@ -20,7 +20,7 @@ with the full power of C++. This is the preferred interface to describe
 abstract algorithms in the domains of Cloud, P2P, HPC, IoT, and similar
 settings.
 
-Currently (v3.21), S4U is definitely the way to go for long-term
+Since v3.20 (June 2018), S4U is definitely the way to go for long-term
 projects. It is feature complete, but may still evolve slightly in the
 future releases. It can already be used to do everything that can be
 done in SimGrid, but you may have to adapt your code in future
index 768f22c..3b0ba59 100644 (file)
@@ -23,6 +23,7 @@ set(process-migration_files     Main  Emigrant  Policeman)
 set(process-startkilltime_files Main  Sleeper)
 set(process-suspend_files       Main  DreamMaster  LazyGuy)
 set(task-priority_files         Main  Test)
+set(hostload_files              Main  LoadRunner)
 
 if(enable_java)
   add_custom_target(java-all
@@ -31,7 +32,7 @@ if(enable_java)
 endif()
 
 foreach (example app-bittorrent app-centralizedmutex app-masterworker app-pingpong app-tokenring async-yield async-waitall async-dsend
-         cloud-migration cloud-masterworker dht-chord dht-kademlia energy-consumption energy-pstate energy-vm io-file io-storage
+         cloud-migration cloud-masterworker dht-chord dht-kademlia energy-consumption energy-pstate energy-vm hostload io-file io-storage
          process-kill process-migration process-startkilltime process-suspend task-priority trace-pingpong)
   string (REPLACE "-" "/" example_dir ${example})
   set (srcdir ${CMAKE_CURRENT_SOURCE_DIR}/${example_dir})
@@ -71,7 +72,7 @@ set(xml_files     ${xml_files}     ${CMAKE_CURRENT_SOURCE_DIR}/app/bittorrent/bi
 
 if(enable_java)
   foreach (example app-bittorrent app-centralizedmutex app-masterworker app-pingpong app-tokenring async-yield async-waitall async-dsend
-           cloud-migration cloud-masterworker dht-chord dht-kademlia energy-consumption energy-pstate energy-vm io-file io-storage
+           cloud-migration cloud-masterworker dht-chord dht-kademlia energy-consumption energy-pstate energy-vm hostload io-file io-storage
            process-kill process-migration process-startkilltime process-suspend task-priority trace-pingpong)
     string (REPLACE "-" "/" example_dir ${example})
     ADD_TESH(java-${example}  --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/java --setenv LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/lib --setenv classpath=${TESH_CLASSPATH} --cd ${CMAKE_BINARY_DIR}/examples/java/${example_dir} ${CMAKE_HOME_DIRECTORY}/examples/java/${example_dir}/${example}.tesh)
index 563475f..6c24b50 100644 (file)
@@ -46,7 +46,7 @@ public class XVM extends VM {
     return this.daemon;
   }
 
-  public int getLoad(){
+  public double getLoad(){
     Msg.info("Remaining comp:" + this.daemon.getRemaining());
     return this.currentLoad;
   }
diff --git a/examples/java/hostload/LoadRunner.java b/examples/java/hostload/LoadRunner.java
new file mode 100644 (file)
index 0000000..b382353
--- /dev/null
@@ -0,0 +1,48 @@
+/* Copyright (c) 2016-2018. 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. */
+
+package hostload;
+
+import org.simgrid.msg.*;
+import org.simgrid.msg.Process;
+
+
+public class LoadRunner extends Process {
+
+    public LoadRunner(Host host, String s) {
+        super(host, s);
+    }
+
+    public void display(){
+        Msg.info("Speed="+getHost().getSpeed()+" flop/s");
+        Msg.info("Computed Flops "+            getHost().getComputedFlops());
+        Msg.info("AvgLoad "+           getHost().getAvgLoad());
+    }
+    @Override
+    public void main(String[] strings) throws MsgException {
+        Host host = getHost();
+        display();
+        Msg.info("Sleep for 10 seconds");
+        waitFor(10);
+        display();
+
+        // Run a task
+        Task task1 = new Task("t1", 200E6, 0);
+        task1.execute();
+        display();
+        double taskTime = Msg.getClock();
+        Msg.info("Task1 simulation time: "+ taskTime);
+
+        // Run a second task
+        new Task("t1", 200E6, 0).execute();
+
+        taskTime = Msg.getClock() - taskTime;
+        Msg.info("Task2 simulation time: "+ taskTime);
+        display();
+
+    }
+
+
+}
\ No newline at end of file
diff --git a/examples/java/hostload/Main.java b/examples/java/hostload/Main.java
new file mode 100644 (file)
index 0000000..785cc39
--- /dev/null
@@ -0,0 +1,34 @@
+/* Copyright (c) 2012-2018. 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. */
+
+package hostload;
+
+import org.simgrid.msg.Host;
+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) throws MsgException {
+    Msg.loadInit();
+    Msg.init(args); 
+
+    if (args.length < 1) {
+      Msg.info("Usage   : Load platform_file");
+      Msg.info("Usage  : Load ../platforms/small_platform.xml");
+      System.exit(1);
+    }
+    /* Construct the platform */
+    Msg.createEnvironment(args[0]);
+    new LoadRunner(Host.all()[0], "").start();
+
+    Msg.run();
+
+  }
+}
diff --git a/examples/java/hostload/hostload.tesh b/examples/java/hostload/hostload.tesh
new file mode 100644 (file)
index 0000000..19c0a22
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/env tesh
+
+$ java -classpath ${classpath:=.} hostload/Main ${srcdir:=.}/../platforms/small_platform.xml
+> [0.000000] [java/INFO] Using regular java threads.
+> [Boivin::(1) 0.000000] [java/INFO] Speed=9.8095E7 flop/s
+> [Boivin::(1) 0.000000] [java/INFO] Computed Flops 0.0
+> [Boivin::(1) 0.000000] [java/INFO] AvgLoad 0.0
+> [Boivin::(1) 0.000000] [java/INFO] Sleep for 10 seconds
+> [Boivin::(1) 10.000000] [java/INFO] Speed=9.8095E7 flop/s
+> [Boivin::(1) 10.000000] [java/INFO] Computed Flops 0.0
+> [Boivin::(1) 10.000000] [java/INFO] AvgLoad 0.0
+> [Boivin::(1) 12.038840] [java/INFO] Speed=9.8095E7 flop/s
+> [Boivin::(1) 12.038840] [java/INFO] Computed Flops 2.0E8
+> [Boivin::(1) 12.038840] [java/INFO] AvgLoad 0.1693551801515729
+> [Boivin::(1) 12.038840] [java/INFO] Task1 simulation time: 12.038839900096844
+> [Boivin::(1) 14.077680] [java/INFO] Task2 simulation time: 2.0388399000968445
+> [Boivin::(1) 14.077680] [java/INFO] Speed=9.8095E7 flop/s
+> [Boivin::(1) 14.077680] [java/INFO] Computed Flops 4.0E8
+> [Boivin::(1) 14.077680] [java/INFO] AvgLoad 0.2896556718201238
+> [14.077680] [java/INFO] MSG_main finished; Terminating the simulation...
\ No newline at end of file
index 4a72056..d65ace3 100644 (file)
 
 SG_BEGIN_DECL()
 /** @brief Host datatype.
-    @ingroup m_host_management
-
-    A <em>location</em> (or <em>host</em>) is any possible place where an actor may run. Thus it is represented as a
-    <em>physical resource with computing capabilities</em>, some <em>mailboxes</em> to enable running actors to
-    communicate with remote ones, and some <em>private data</em> that can be only accessed by local actors.
+ *
+ *   A <em>location</em> (or <em>host</em>) is any possible place where an actor may run. Thus it is represented as a
+ *   <em>physical resource with computing capabilities</em>, some <em>mailboxes</em> to enable running actors to
+ *   communicate with remote ones, and some <em>private data</em> that can be only accessed by local actors.
  */
 
 XBT_PUBLIC sg_host_t* sg_host_list();
 
-/** @ingroup m_host_management
- * @brief Return the current number of hosts.
- */
+/** @brief Return the current number of hosts. */
 XBT_PUBLIC size_t sg_host_count();
 
-/** @ingroup m_host_management
+/**
  * @brief Return a dynar containing all the hosts declared at a given point of time (including VMs)
  * @remark The host order in the returned array is generally different from the host creation/declaration order in the
  *         XML platform (we use a hash table internally)
@@ -36,8 +33,7 @@ XBT_PUBLIC xbt_dynar_t sg_hosts_as_dynar();
 XBT_PUBLIC size_t sg_host_extension_create(void (*deleter)(void*));
 XBT_PUBLIC void* sg_host_extension_get(sg_host_t host, size_t rank);
 
-/** @ingroup m_host_management
- * @brief Finds a sg_host_t using its name.
+/** @brief Finds a sg_host_t using its name.
  *
  * This is a name directory service
  * @param name the name of an host.
@@ -45,22 +41,16 @@ XBT_PUBLIC void* sg_host_extension_get(sg_host_t host, size_t rank);
  */
 XBT_PUBLIC sg_host_t sg_host_by_name(const char* name);
 
-/** @ingroup m_host_management
- *
- * @brief Return the name of the #sg_host_t. */
+/** @brief Return the name of the #sg_host_t. */
 XBT_PUBLIC const char* sg_host_get_name(sg_host_t host);
 
 // ========== User Data ==============
-/** @ingroup m_host_management
- *
- * @brief Return the user data of a #sg_host_t.
+/** @brief Return the user data of a #sg_host_t.
  *
  * This functions returns the user data associated to @a host if it is possible.
  */
 XBT_PUBLIC void* sg_host_user(sg_host_t host);
-/** @ingroup m_host_management
- *
- * @brief Set the user data of a #sg_host_t.
+/** @brief Set the user data of a #sg_host_t.
  *
  * This functions attach @a data to @a host if it is possible.
  */
@@ -68,24 +58,20 @@ XBT_PUBLIC void sg_host_user_set(sg_host_t host, void* userdata);
 XBT_PUBLIC void sg_host_user_destroy(sg_host_t host);
 
 // ========= storage related functions ============
-/** @ingroup m_host_management
- * @brief Return the list of mount point names on an host.
+/** @brief Return the list of mount point names on an host.
  * @param host a host
  * @return a dict containing all mount point on the host (mount_name => sg_storage_t)
  */
 XBT_PUBLIC xbt_dict_t sg_host_get_mounted_storage_list(sg_host_t host);
 
-/** @ingroup m_host_management
- * @brief Return the list of storages attached to an host.
+/** @brief Return the list of storages attached to an host.
  * @param host a host
  * @return a dynar containing all storages (name) attached to the host
  */
 XBT_PUBLIC xbt_dynar_t sg_host_get_attached_storage_list(sg_host_t host);
 
 // =========== user-level functions ===============
-/** @ingroup m_host_management
- * @brief Return the speed of the processor (in flop/s), regardless of the current load on the machine.
- */
+/** @brief Return the speed of the processor (in flop/s), regardless of the current load on the machine. */
 XBT_PUBLIC double sg_host_speed(sg_host_t host);
 XBT_PUBLIC double sg_host_get_pstate_speed(sg_host_t host, int pstate_index);
 
@@ -93,16 +79,17 @@ XBT_PUBLIC double sg_host_get_available_speed(sg_host_t host);
 
 XBT_PUBLIC int sg_host_core_count(sg_host_t host);
 
-/** @ingroup m_process_management
- * @brief Return the location on which a process is running.
- * @return the sg_host_t corresponding to the location on which @a process is running.
+/** @brief Returns the current computation load (in flops per second).
+ * @param host a host
  */
+XBT_PUBLIC double sg_host_load(sg_host_t host);
+
+/** @brief Return the location on which the current process is running. */
 XBT_PUBLIC sg_host_t sg_host_self();
 
 XBT_PUBLIC const char* sg_host_self_get_name();
 
-/** @ingroup m_host_management
- * @brief Return the total count of pstates defined for a host. See also @ref plugin_energy.
+/** @brief Return the total count of pstates defined for a host. See also @ref plugin_energy.
  *
  * @param  host host to test
  */
index a62ed6f..87b46fc 100644 (file)
@@ -115,6 +115,7 @@ XBT_PUBLIC void MSG_host_get_process_list(sg_host_t host, xbt_dynar_t whereto);
 
 /** @brief Return the location on which the current process is executed */
 XBT_PUBLIC sg_host_t MSG_host_self();
+XBT_PUBLIC double MSG_host_get_load(sg_host_t host);
 
 /* ******************************** VMs ************************************* */
 typedef sg_vm_t msg_vm_t;
@@ -154,6 +155,14 @@ XBT_PUBLIC sg_size_t MSG_storage_read(msg_storage_t storage, sg_size_t size);
 XBT_PUBLIC sg_size_t MSG_storage_write(msg_storage_t storage, sg_size_t size);
 
 /* ******************************** Actor/process *************************** */
+/** Processes are independent agents that can do stuff on their own.
+ *  They are in charge of executing your code interacting with the simulated world.
+ *  A process may be defined as a <em>code</em> with some <em>private data</em>.
+ *  Processes must be located on <em>hosts</em> (#msg_host_t), and they exchange data by sending tasks (#msg_task_t)
+ *  that are similar to envelops containing data.
+ *
+ *  @hideinitializer
+ */
 typedef sg_actor_t msg_process_t;
 
 XBT_PUBLIC int MSG_process_get_PID(msg_process_t process);
@@ -260,8 +269,7 @@ typedef enum {
  * MSG_config("host/model","ptask_L07");
  */
 XBT_PUBLIC void MSG_config(const char* key, const char* value);
-/** @ingroup msg_simulation
- *  @brief Initialize the MSG internal data.
+/** @brief Initialize the MSG internal data.
  *  @hideinitializer
  *
  *  It also check that the link-time and compile-time versions of SimGrid do
@@ -424,7 +432,6 @@ XBT_PUBLIC const char* MSG_task_get_category(msg_task_t task);
 XBT_PUBLIC void MSG_mailbox_set_async(const char* alias);
 
 /** @brief Opaque type representing a semaphore
- *  @ingroup msg_synchro
  *  @hideinitializer
  */
 typedef struct s_smx_sem_t* msg_sem_t; // Yeah that's a rename of the smx_sem_t which doesnt require smx_sem_t to be
index eedabd4..a343091 100644 (file)
@@ -20,8 +20,13 @@ XBT_PUBLIC double sg_host_get_computed_flops(sg_host_t host);
 XBT_PUBLIC void sg_host_load_reset(sg_host_t host);
 
 #define MSG_host_load_plugin_init() sg_host_load_plugin_init()
+/** @brief Returns the current load of that host, as a ratio = achieved_flops / (core_current_speed * core_amount)
+ *
+ *  See simgrid::plugin::HostLoad::get_current_load() for the full documentation.
+ */
 #define MSG_host_get_current_load(host) sg_host_get_current_load(host)
 #define MSG_host_get_computed_flops(host) sg_host_get_computed_flops(host)
+#define MSG_host_get_avg_load(host) sg_host_get_avg_load(host)
 
 SG_END_DECL()
 
index 143a28b..5ff074a 100644 (file)
@@ -14,6 +14,7 @@
 #include "simgrid/plugins/energy.h"
 #include "simgrid/plugins/file_system.h"
 #include "simgrid/plugins/live_migration.h"
+#include "simgrid/plugins/load.h"
 #include "simgrid/simix.h"
 
 #include "simgrid/s4u/Host.hpp"
@@ -241,6 +242,9 @@ JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_fileSystemInit()
   sg_storage_file_system_init();
 }
 
+JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_loadInit() {
+    sg_host_load_plugin_init();
+}
 /** Run a Java org.simgrid.msg.Process
  *
  *  If needed, this waits for the process starting time.
index c76fb11..6028080 100644 (file)
@@ -38,6 +38,7 @@ JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_init(JNIEnv* env, jclass cls, jo
 JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_energyInit();
 JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_liveMigrationInit();
 JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_fileSystemInit();
+JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_loadInit();
 
 JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_debug(JNIEnv* env, jclass cls, jstring jargs);
 JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_verb(JNIEnv* env, jclass cls, jstring jargs);
index 32c513f..d889f51 100644 (file)
@@ -6,6 +6,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "simgrid/plugins/energy.h"
+#include "simgrid/plugins/load.h"
 #include "simgrid/s4u/Host.hpp"
 #include "simgrid/s4u/Storage.hpp"
 
@@ -372,3 +373,45 @@ JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getPowerPeakAt(JNIEnv* env,
   msg_host_t host = jhost_get_native(env, jhost);
   return MSG_host_get_power_peak_at(host, pstate);
 }
+
+JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getLoad(JNIEnv* env, jobject jhost)
+{
+  msg_host_t host = jhost_get_native(env, jhost);
+  return MSG_host_get_load(host);
+}
+
+JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCurrentLoad (JNIEnv *env, jobject jhost)
+{
+  msg_host_t host = jhost_get_native(env, jhost);
+
+  if (not host) {
+    jxbt_throw_notbound(env, "host", jhost);
+    return 0;
+  }
+
+  return MSG_host_get_current_load(host);
+}
+
+JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getComputedFlops (JNIEnv *env, jobject jhost)
+{
+  msg_host_t host = jhost_get_native(env, jhost);
+
+  if (not host) {
+    jxbt_throw_notbound(env, "host", jhost);
+    return 0;
+  }
+
+  return MSG_host_get_computed_flops(host);
+}
+
+JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getAvgLoad (JNIEnv *env, jobject jhost)
+{
+  msg_host_t host = jhost_get_native(env, jhost);
+
+  if (not host) {
+    jxbt_throw_notbound(env, "host", jhost);
+    return 0;
+  }
+
+  return MSG_host_get_avg_load(host);
+}
\ No newline at end of file
index cc9ee4a..9f6ac0d 100644 (file)
@@ -68,6 +68,10 @@ JNIEXPORT jint JNICALL Java_org_simgrid_msg_Host_getPstate(JNIEnv* env, jobject
 JNIEXPORT jint JNICALL Java_org_simgrid_msg_Host_getPstatesCount(JNIEnv* env, jobject jhost);
 JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCurrentPowerPeak(JNIEnv* env, jobject jhost);
 JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getPowerPeakAt(JNIEnv* env, jobject jhost, jint pstate);
+JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getLoad(JNIEnv* env, jobject jhost);
 
+JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCurrentLoad(JNIEnv *env, jobject jhost);
+JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getAvgLoad(JNIEnv *env, jobject jhost);
+JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getComputedFlops (JNIEnv *env, jobject jhost);
 SG_END_DECL()
 #endif
index 0476da4..53ccd99 100644 (file)
@@ -143,7 +143,17 @@ public class Host {
         * the value will be updated in kernel mode before returning the control to the requesting actor.
         */
        public native double getConsumedEnergy();
-       
+
+       /** Returns the current load of the host, as a ratio = achieved_flops / (core_current_speed * core_amount)
+        *      
+        * See simgrid::plugin::HostLoad::get_current_load() for the full documentation.
+        */
+       public native double getCurrentLoad();
+       /** Returns the number of flops computed of the host since the beginning of the simulation */
+       public native double getComputedFlops();
+       /** Returns the average load of the host as a ratio since the beginning of the simulation*/
+       public native double getAvgLoad();
+   
        /** Returns the current pstate */
        public native int getPstate();
        /** Changes the current pstate */
@@ -153,7 +163,9 @@ public class Host {
        public native double getCurrentPowerPeak();
        /** Returns the speed of the processor (in flop/s) at a given pstate. See also @ref plugin_energy. */
        public native double getPowerPeakAt(int pstate);
-       
+
+       /** Returns the current computation load (in flops per second) */
+       public native double getLoad();
 
        /** Class initializer, to initialize various JNI stuff */
        private static native void nativeInit();
index b103d2f..b4becc9 100644 (file)
@@ -40,8 +40,16 @@ public final class Msg {
        
        /** Tell the kernel that you want to use the energy plugin */
        public static final native void energyInit();
+
+    /** Tell the kernel that you want to use the filesystem plugin. */
        public static final native void fileSystemInit();
 
+    /** Initializes the HostLoad plugin.
+     *
+        * The HostLoad plugin provides an API to get the current load of each host.
+     */
+       public static final native void loadInit();
+
        /** Run the MSG simulation.
         *
         * After the simulation, you can freely retrieve the information that you want..
index 297c8f4..733a70a 100644 (file)
@@ -297,6 +297,11 @@ sg_host_t MSG_host_self()
 {
   return sg_host_self();
 }
+
+double MSG_host_get_load(sg_host_t host)
+{
+  return sg_host_load(host);
+}
 /* ************************** Virtual Machines *************************** */
 sg_vm_t MSG_vm_create_core(sg_host_t pm, const char* name)
 {
index 643e190..e7c6961 100644 (file)
@@ -16,15 +16,6 @@ std::string instr_pid(msg_process_t proc)
   return std::string(proc->get_cname()) + "-" + std::to_string(proc->get_pid());
 }
 
-/** @addtogroup m_process_management
- *
- *  Processes (#msg_process_t) are independent agents that can do stuff on their own. They are in charge of executing
- *  your code interacting with the simulated world.
- *  A process may be defined as a <em>code</em> with some <em>private data</em>.
- *  Processes must be located on <em>hosts</em> (#msg_host_t), and they exchange data by sending tasks (#msg_task_t)
- *  that are similar to envelops containing data.
- */
-
 /******************************** Process ************************************/
 /**
  * @brief Cleans the MSG data of an actor
@@ -60,16 +51,12 @@ msg_process_t MSG_process_create(const char *name, xbt_main_func_t code, void *d
   return MSG_process_create_with_environment(name == nullptr ? "" : name, code, data, host, 0, nullptr, nullptr);
 }
 
-/** @brief Creates and runs a new #msg_process_t.
+/** @brief Creates and runs a new process.
 
  * A constructor for #msg_process_t taking four arguments and returning the corresponding object. The structure (and
  * the corresponding thread) is created, and put in the list of ready process.
  * @param name a name for the object. It is for user-level information and can be nullptr.
- * @param code is a function describing the behavior of the process. It should then only use functions described
- * in @ref m_process_management (to create a new #msg_process_t for example),
-   in @ref m_host_management (only the read-only functions i.e. whose name contains the word get),
-   in @ref m_task_management (to create or destroy some #msg_task_t for example) and
-   in @ref msg_task_usage (to handle file transfers and task processing).
+ * @param code is a function describing the behavior of the process.
  * @param data a pointer to any data one may want to attach to the new object.  It is for user-level information and
  *        can be nullptr. It can be retrieved with the function @ref MSG_process_get_data.
  * @param host the location where the new process is executed.
@@ -83,17 +70,13 @@ msg_process_t MSG_process_create_with_arguments(const char *name, xbt_main_func_
   return MSG_process_create_with_environment(name, code, data, host, argc, argv, nullptr);
 }
 
-/** @ingroup m_process_management
+/**
  * @brief Creates and runs a new #msg_process_t.
 
  * A constructor for #msg_process_t taking four arguments and returning the corresponding object. The structure (and
  * the corresponding thread) is created, and put in the list of ready process.
  * @param name a name for the object. It is for user-level information and can be nullptr.
- * @param code is a function describing the behavior of the process. It should then only use functions described
- * in @ref m_process_management (to create a new #msg_process_t for example),
-   in @ref m_host_management (only the read-only functions i.e. whose name contains the word get),
-   in @ref m_task_management (to create or destroy some #msg_task_t for example) and
-   in @ref msg_task_usage (to handle file transfers and task processing).
+ * @param code is a function describing the behavior of the process.
  * @param data a pointer to any data one may want to attach to the new object.  It is for user-level information and
  *        can be nullptr. It can be retrieved with the function @ref MSG_process_get_data.
  * @param host the location where the new process is executed.
@@ -166,7 +149,7 @@ msg_process_t MSG_process_attach(const char *name, void *data, msg_host_t host,
   return process->ciface();
 }
 
-/** Detach a process attached with `MSG_process_attach()`
+/** @brief Detach a process attached with `MSG_process_attach()`
  *
  *  This is called when the current process has finished its job.
  *  Used in the main thread, it waits for the simulation to finish before  returning. When it returns, the other
@@ -177,8 +160,7 @@ void MSG_process_detach()
   SIMIX_process_detach();
 }
 
-/** @ingroup m_process_management
- * @brief Returns the user data of a process.
+/** @brief Returns the user data of a process.
  *
  * This function checks whether @a process is a valid pointer and returns the user data associated to this process.
  */
@@ -190,8 +172,7 @@ void* MSG_process_get_data(msg_process_t process)
   return process->get_impl()->get_user_data();
 }
 
-/** @ingroup m_process_management
- * @brief Sets the user data of a process.
+/** @brief Sets the user data of a process.
  *
  * This function checks whether @a process is a valid pointer and sets the user data associated to this process.
  */
@@ -204,8 +185,7 @@ msg_error_t MSG_process_set_data(msg_process_t process, void *data)
   return MSG_OK;
 }
 
-/** @ingroup m_process_management
- * @brief Sets a cleanup function to be called to free the userdata of a process when a process is destroyed.
+/** @brief Sets a cleanup function to be called to free the userdata of a process when a process is destroyed.
  * @param data_cleanup a cleanup function for the userdata of a process, or nullptr to call no function
  */
 XBT_PUBLIC void MSG_process_set_data_cleanup(void_f_pvoid_t data_cleanup)
@@ -229,8 +209,7 @@ int MSG_process_get_number()
   return SIMIX_process_count();
 }
 
-/** @ingroup m_process_management
- * @brief Return the PID of the current process.
+/** @brief Return the PID of the current process.
  *
  * This function returns the PID of the currently running #msg_process_t.
  */
@@ -240,8 +219,7 @@ int MSG_process_self_PID()
   return self == nullptr ? 0 : self->pid_;
 }
 
-/** @ingroup m_process_management
- * @brief Return the PPID of the current process.
+/** @brief Return the PPID of the current process.
  *
  * This function returns the PID of the parent of the currently running #msg_process_t.
  */
@@ -250,16 +228,13 @@ int MSG_process_self_PPID()
   return MSG_process_get_PPID(MSG_process_self());
 }
 
-/** @ingroup m_process_management
- * @brief Return the name of the current process.
- */
+/** @brief Return the name of the current process. */
 const char* MSG_process_self_name()
 {
   return SIMIX_process_self_get_name();
 }
 
-/** @ingroup m_process_management
- * @brief Return the current process.
+/** @brief Return the current process.
  *
  * This function returns the currently running #msg_process_t.
  */
@@ -271,26 +246,20 @@ msg_process_t MSG_process_self()
 smx_context_t MSG_process_get_smx_ctx(msg_process_t process) { // deprecated -- smx_context_t should die afterward
   return process->get_impl()->context_;
 }
-/**
- * @ingroup m_process_management
- * @brief Add a function to the list of "on_exit" functions for the current process.
- * The on_exit functions are the functions executed when your process is killed.
- * You should use them to free the data used by your process.
+/** @brief Add a function to the list of "on_exit" functions for the current process.
+ *  The on_exit functions are the functions executed when your process is killed.
+ *  You should use them to free the data used by your process.
  */
 void MSG_process_on_exit(int_f_pvoid_pvoid_t fun, void *data) {
   simgrid::s4u::this_actor::on_exit([fun](int a, void* b) { fun((void*)(intptr_t)a, b); }, data);
 }
 
-/** @ingroup m_process_management
- * @brief Take an extra reference on that process to prevent it to be garbage-collected
- */
+/** @brief Take an extra reference on that process to prevent it to be garbage-collected */
 XBT_PUBLIC void MSG_process_ref(msg_process_t process)
 {
   intrusive_ptr_add_ref(process);
 }
-/** @ingroup m_process_management
- * @brief Release a reference on that process so that it can get be garbage-collected
- */
+/** @brief Release a reference on that process so that it can get be garbage-collected */
 XBT_PUBLIC void MSG_process_unref(msg_process_t process)
 {
   intrusive_ptr_release(process);
index ad42f71..f0605a8 100644 (file)
@@ -43,10 +43,17 @@ public:
   explicit HostLoad(simgrid::s4u::Host&& ptr) = delete;
 
   double get_current_load();
+  /** Get the the average load since last reset(), as a ratio
+   *
+   * That's the ratio (amount of flops that were actually computed) / (amount of flops that could have been computed at full speed)
+   */
   double get_average_load() { update(); return (theor_max_flops_ == 0) ? 0 : computed_flops_ / theor_max_flops_; };
+  /** Amount of flops computed since last reset() */
   double get_computed_flops() { update(); return computed_flops_; }
-  double get_idle_time() { update(); return idle_time_; } /** Return idle time since last reset */
-  double get_total_idle_time() { update(); return total_idle_time_; } /** Return idle time over the whole simulation */
+  /** Return idle time since last reset() */
+  double get_idle_time() { update(); return idle_time_; }
+  /** Return idle time over the whole simulation */
+  double get_total_idle_time() { update(); return total_idle_time_; }
   void update();
   void add_activity(simgrid::kernel::activity::ExecImplPtr activity);
   void reset();
@@ -121,18 +128,22 @@ void HostLoad::update()
   last_updated_  = now;
 }
 
-/**
- * WARNING: This function does not guarantee that you have the real load at any time imagine all actions on your CPU
- * terminate at time t. Your load is then 0. Then you query the load (still 0) and then another action starts (still at
- * time t!). This means that the load was never really 0 (because the time didn't advance) but it will still be reported
- * as 0.
+/** @brief Get the current load as a ratio = achieved_flops / (core_current_speed * core_amount)
+ *
+ * You may also want to check simgrid::s4u::Host::get_load() that simply returns
+ * the achieved flop rate (in flops per seconds), ie the load that a new action arriving on
+ * that host would suffer.
  *
- * So, use at your own risk.
+ * Please note that this function only returns an instantaneous load that may be deceiving
+ * in some scenarios. For example, imagine that an activity terminates at time t, and that
+ * another activity is created on the same host at the exact same timestamp. The load was
+ * never 0 on the simulated machine since the time did not advance between the two events.
+ * But still, if you call this function between the two events (in the simulator course), it
+ * returns 0 although there is no time (in the simulated time) where this value is valid.
  */
 double HostLoad::get_current_load()
 {
   // We don't need to call update() here because it is called every time an action terminates or starts
-  // FIXME: Can this happen at the same time? stop -> call to getCurrentLoad, load = 0 -> next action starts?
   return current_flops_ / static_cast<double>(host_->get_speed() * host_->get_core_count());
 }
 
@@ -182,8 +193,7 @@ static void on_action_state_change(simgrid::surf::CpuAction* action, simgrid::ke
 
 /* **************************** Public interface *************************** */
 
-/** @ingroup plugin_load
- * @brief Initializes the HostLoad plugin
+/** @brief Initializes the HostLoad plugin
  * @details The HostLoad plugin provides an API to get the current load of each host.
  */
 void sg_host_load_plugin_init()
@@ -240,9 +250,9 @@ void sg_host_load_plugin_init()
   simgrid::s4u::Host::on_speed_change.connect(&on_host_change);
 }
 
-/** @brief Returns the current load of the host passed as argument
+/** @brief Returns the current load of that host, as a ratio = achieved_flops / (core_current_speed * core_amount)
  *
- *  See also @ref plugin_load
+ *  See simgrid::plugin::HostLoad::get_current_load() for the full documentation.
  */
 double sg_host_get_current_load(sg_host_t host)
 {
index 27d5e96..b44b000 100644 (file)
@@ -223,7 +223,9 @@ double Host::get_speed() const
   return this->pimpl_cpu->get_speed(1.0);
 }
 /** @brief Returns the current computation load (in flops per second)
+ *
  * The external load (coming from an availability trace) is not taken in account.
+ * You may also be interested in the load plugin.
  */
 double Host::get_load() const
 {
@@ -626,3 +628,8 @@ sg_host_t sg_host_self()
   smx_actor_t process = SIMIX_process_self();
   return (process == nullptr) ? nullptr : process->host_;
 }
+
+double sg_host_load(sg_host_t host)
+{
+  return host->get_load();
+}