)
add_subdirectory(dumb)
+add_subdirectory(io)
\ No newline at end of file
--- /dev/null
+s4u_io_test
--- /dev/null
+set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}")
+add_executable(s4u_io_test ${CMAKE_CURRENT_SOURCE_DIR}/s4u_io_test.cpp)
+target_link_libraries(s4u_io_test simgrid)
+
+set(tesh_files
+ ${tesh_files}
+ ${CMAKE_CURRENT_SOURCE_DIR}/s4u_io.tesh
+ PARENT_SCOPE)
+set(xml_files
+ ${xml_files}
+ PARENT_SCOPE)
+set(examples_src
+ ${examples_src}
+ ${CMAKE_CURRENT_SOURCE_DIR}/s4u_io_test.cpp
+ PARENT_SCOPE)
+set(bin_files
+ ${bin_files}
+ PARENT_SCOPE)
+set(txt_files
+ ${txt_files}
+ PARENT_SCOPE)
--- /dev/null
+/* Copyright (c) 2006-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. */
+
+#include <vector>
+
+#include "simgrid/s4u.h"
+
+using namespace simgrid;
+using namespace s4u;
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category");
+
+class myHost : Actor {
+public:
+ myHost(const char*procname, Host *host,int argc, char **argv)
+: s4u::Actor(procname,host,argc,argv){}
+
+ void show_info(boost::unordered_map <std::string, Storage &> &mounts) {
+ XBT_INFO("Storage info on %s:", Host::current()->name());
+
+ for (const auto&kv : mounts) {
+ const char* mountpoint = kv.first.c_str();
+ Storage &storage = kv.second;
+
+ // Retrieve disk's information
+ sg_size_t free_size = storage.size_free();
+ sg_size_t used_size = storage.size_used();
+ sg_size_t size = storage.size();
+
+ XBT_INFO(" %s (%s) Used: %llu; Free: %llu; Total: %llu.",
+ storage.name(), mountpoint, used_size, free_size, size);
+ }
+ }
+
+ int main(int argc, char **argv) {
+ boost::unordered_map <std::string, Storage &> &mounts = Host::current()->mountedStorages();
+
+ show_info(mounts);
+
+ // Open an non-existing file to create it
+ const char *filename = "/home/tmp/data.txt";
+ File *file = new File(filename, NULL);
+ sg_size_t write, read, file_size;
+
+ write = file->write(200000); // Write 200,000 bytes
+ XBT_INFO("Create a %llu bytes file named '%s' on /sd1", write, filename);
+
+ // check that sizes have changed
+ show_info(mounts);
+
+ // Now retrieve the size of created file and read it completely
+ file_size = file->size();
+ file->seek(0);
+ read = file->read(file_size);
+ XBT_INFO("Read %llu bytes on %s", read, filename);
+
+ // 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);
+
+ Storage &storage = 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->path(), newpath);
+ file->move(newpath);
+
+ // Test attaching some user data to the file
+ file->set_userdata(xbt_strdup("777"));
+ XBT_INFO("User data attached to the file: %s", (char*)file->userdata());
+
+ // Close the file
+ delete file;
+
+ // Now attach some user data to disk1
+ XBT_INFO("Get/set data for storage element: %s",storage.name());
+ XBT_INFO(" Uninitialized storage data: '%s'", (char*)storage.userdata());
+
+ storage.set_userdata(xbt_strdup("Some user data"));
+ XBT_INFO(" Set and get data: '%s'", (char*)storage.userdata());
+
+ /*
+ // Dump disks contents
+ XBT_INFO("*** Dump content of %s ***",Host::current()->name());
+ xbt_dict_t contents = NULL;
+ contents = MSG_host_get_storage_content(MSG_host_self()); // contents is a dict of dicts
+ xbt_dict_cursor_t curs, curs2 = NULL;
+ char* mountname;
+ xbt_dict_t content;
+ char* path;
+ sg_size_t *size;
+ xbt_dict_foreach(contents, curs, mountname, content){
+ XBT_INFO("Print the content of mount point: %s",mountname);
+ xbt_dict_foreach(content,curs2,path,size){
+ XBT_INFO("%s size: %llu bytes", path,*((sg_size_t*)size));
+ }
+ xbt_dict_free(&content);
+ }
+ xbt_dict_free(&contents);
+ */
+ return 0;
+ }
+};
+
+int main(int argc, char **argv) {
+ Engine *e = new Engine(&argc,argv);
+ e->loadPlatform("../../platforms/storage/storage.xml");
+
+ new myHost("host", Host::byName("denise"), 0, NULL);
+ e->run();
+ return 0;
+}
--- /dev/null
+#! ./tesh
+
+$ $SG_TEST_EXENV ./s4u_io_test
+> [denise:host:(0) 0.000000] [s4u_test/INFO] Storage info on denise:
+> [denise:host:(0) 0.000000] [s4u_test/INFO] Disk4 (/home) Used: 13221994; Free: 536857690006; Total: 536870912000.
+> [denise:host:(0) 0.000000] [s4u_test/INFO] Disk2 (c:) Used: 2391537133; Free: 534479374867; Total: 536870912000.
+> [denise:host:(0) 0.003333] [s4u_test/INFO] Create a 200000 bytes file named '/home/tmp/data.txt' on /sd1
+> [denise:host:(0) 0.003333] [s4u_test/INFO] Storage info on denise:
+> [denise:host:(0) 0.003333] [s4u_test/INFO] Disk4 (/home) Used: 13421994; Free: 536857490006; Total: 536870912000.
+> [denise:host:(0) 0.003333] [s4u_test/INFO] Disk2 (c:) Used: 2391537133; Free: 534479374867; Total: 536870912000.
+> [denise:host:(0) 0.004333] [s4u_test/INFO] Read 200000 bytes on /home/tmp/data.txt
+> [denise:host:(0) 0.006000] [s4u_test/INFO] Write 100000 bytes on /home/tmp/data.txt
+> [denise:host:(0) 0.006000] [s4u_test/INFO] Move '/home/tmp/data.txt' to '/home/tmp/simgrid.readme'
+> [denise:host:(0) 0.006000] [s4u_test/INFO] User data attached to the file: 777
+> [denise:host:(0) 0.006000] [s4u_test/INFO] Get/set data for storage element: Disk4
+> [denise:host:(0) 0.006000] [s4u_test/INFO] Uninitialized storage data: '(null)'
+> [denise:host:(0) 0.006000] [s4u_test/INFO] Set and get data: 'Some user data'
#include "s4u/async.hpp"
#include "s4u/comm.hpp"
+#include "s4u/storage.hpp"
+#include "s4u/file.hpp"
+
#endif /* SIMGRID_S4U_S4U_H */
--- /dev/null
+/* Copyright (c) 2006-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. */
+
+#ifndef SIMGRID_S4U_FILE_HPP
+#define SIMGRID_S4U_FILE_HPP
+
+#include <boost/unordered_map.hpp>
+#include <vector>
+
+#include "simgrid/simix.h"
+
+namespace simgrid {
+namespace s4u {
+
+class Actor;
+class Storage;
+
+/** @brief A simulated file
+ *
+ * Used to simulate the time it takes to access to a file, but does not really store any information.
+ *
+ * They are located on @link{simgrid::s4u::Storage}, that are accessed from a given @link{simgrid::s4u::Host} through mountpoints.
+ * For now, you cannot change the mountpoints programatically, and must declare them from your platform file.
+ */
+class File {
+public:
+ File(const char *fullpath, void* userdata);
+ ~File();
+private:
+ smx_file_t p_inferior;
+ const char *p_path;
+
+public:
+ /** Retrieves the path to the file */
+ const char *path() { return p_path;}
+public:
+ /** Simulates a read action. Returns the size of data actually read
+ *
+ * FIXME: reading from a remotely mounted disk is not implemented yet. Any storage is considered as local, and no network communication ever occur.
+ */
+ sg_size_t read(sg_size_t size);
+ /** Simulates a write action. Returns the size of data actually written.
+ *
+ * FIXME: reading from a remotely mounted disk is not implemented yet. Any storage is considered as local, and no network communication ever occur.
+ */
+ sg_size_t write(sg_size_t size);
+
+ /** Allows to store user data on that host */
+ void set_userdata(void *data) {p_userdata = data;}
+ /** Retrieves the previously stored data */
+ void* userdata() {return p_userdata;}
+private:
+ void *p_userdata=NULL;
+
+public:
+ /** Retrieve the datasize */
+ sg_size_t size();
+
+ /** Sets the file head to the given position. */
+ void seek(sg_size_t pos);
+ /** 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);
+
+ /** Remove a file from disk */
+ void unlink();
+
+ /* FIXME: add these to the S4U API:
+ XBT_PUBLIC(const char *) MSG_file_get_name(msg_file_t file);
+ XBT_PUBLIC(msg_error_t) MSG_file_rcopy(msg_file_t fd, msg_host_t host, const char* fullpath);
+ XBT_PUBLIC(msg_error_t) MSG_file_rmove(msg_file_t fd, msg_host_t host, const char* fullpath);
+ */
+
+};
+
+}} // namespace simgrid::s4u
+
+#endif /* SIMGRID_S4U_HOST_HPP */
#define SIMGRID_S4U_HOST_HPP
#include <boost/unordered_map.hpp>
+#include <vector>
#include "simgrid/simix.h"
namespace s4u {
class Actor;
+class Storage;
+class File;
/** @brief Simulated machine that can host some actors
*
* and actors can retrieve the host on which they run using @link{simgrid::s4u::Host.current()}.
*/
class Host {
+ friend Actor;
+ friend File;
private:
Host(const char *name);
+protected:
+ ~Host();
public:
/** Retrieves an host from its name. */
static s4u::Host *byName(std::string name);
/** Retrieves the host on which the current actor is running */
static s4u::Host *current();
- const char* getName();
+ const char* name();
/** Turns that host on if it was previously off
*
/** Allows to store user data on that host */
- void setData(void *data) {p_userdata = data;}
+ void set_userdata(void *data) {p_userdata = data;}
/** Retrieves the previously stored data */
- void* getData() {return p_userdata;}
+ void* userdata() {return p_userdata;}
+
+ /** Get an associative list [mount point]->[Storage] off all local mount points.
+ *
+ * This is defined in the platform file, and cannot be modified programatically (yet).
+ *
+ * Do not change the returned value in any way.
+ */
+ boost::unordered_map<std::string, Storage&> &mountedStorages();
+private:
+ boost::unordered_map<std::string, Storage&> *mounts = NULL; // caching
protected:
- friend Actor;
- sg_host_t getInferior() {return p_sghost;}
+ sg_host_t inferior() {return p_inferior;}
private:
void*p_userdata=NULL;
- sg_host_t p_sghost;
+ sg_host_t p_inferior;
static boost::unordered_map<std::string, s4u::Host *> *hosts;
};
*/
public native void setProperty(String name, String value);
- /** This methods returns the list of mount point names on an host
- * @return An array containing all mounted storages on the host
- */
- public native Storage[] getMountedStorage();
-
/** This methods returns the list of storages attached to an host
* @return An array containing all storages (name) attached to the host
*/
--- /dev/null
+/* Copyright (c) 2006-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. */
+
+#ifndef INCLUDE_SIMGRID_S4U_STORAGE_HPP_
+#define INCLUDE_SIMGRID_S4U_STORAGE_HPP_
+
+#include <boost/unordered_map.hpp>
+#include "simgrid/simix.h"
+
+namespace simgrid {
+namespace s4u {
+
+class Storage {
+private:
+ Storage(std::string name, smx_storage_t inferior);
+ virtual ~Storage();
+public:
+ /** Retrieve a Storage by its name. It must exist in the platform file */
+ static Storage &byName(const char* name);
+ const char *name();
+ sg_size_t size_free();
+ sg_size_t size_used();
+ /** Retrieve the total amount of space of this storage element */
+ sg_size_t size();
+
+ /* TODO: missing API:
+XBT_PUBLIC(xbt_dict_t) MSG_storage_get_properties(msg_storage_t storage);
+XBT_PUBLIC(void) MSG_storage_set_property_value(msg_storage_t storage, const char *name, char *value,void_f_pvoid_t free_ctn);
+XBT_PUBLIC(const char *)MSG_storage_get_property_value(msg_storage_t storage, const char *name);
+XBT_PUBLIC(xbt_dynar_t) MSG_storages_as_dynar(void);
+XBT_PUBLIC(xbt_dict_t) MSG_storage_get_content(msg_storage_t storage);
+XBT_PUBLIC(msg_error_t) MSG_storage_file_move(msg_file_t fd, msg_host_t dest, char* mount, char* fullname);
+XBT_PUBLIC(const char *) MSG_storage_get_host(msg_storage_t storage);
+ */
+protected:
+ smx_storage_t inferior();
+private:
+ static boost::unordered_map<std::string, Storage *> *storages;
+ std::string p_name;
+ smx_storage_t p_inferior;
+
+
+public:
+ void set_userdata(void *data) {p_userdata = data;}
+ void *userdata() {return p_userdata;}
+private:
+ void *p_userdata = NULL;
+
+};
+
+} /* namespace s4u */
+} /* namespace simgrid */
+
+#endif /* INCLUDE_SIMGRID_S4U_STORAGE_HPP_ */
: s4u::Actor::Actor(name,host, argc,argv, -1) {
}
s4u::Actor::Actor(const char *name, s4u::Host *host, int argc, char **argv, double killTime) {
- p_smx_process = simcall_process_create(name, s4u_actor_runner, this, host->getName(), killTime, argc, argv, NULL/*properties*/,0);
+ p_smx_process = simcall_process_create(name, s4u_actor_runner, this, host->name(), killTime, argc, argv, NULL/*properties*/,0);
xbt_assert(p_smx_process,"Cannot create the actor");
// TRACE_msg_process_create(procname, simcall_process_get_PID(p_smx_process), host->getInferior());
--- /dev/null
+/* Copyright (c) 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. */
+
+#include "xbt/log.h"
+#include "msg/msg_private.h"
+#include "msg/msg_mailbox.h"
+
+#include "simgrid/s4u/actor.hpp"
+#include "simgrid/s4u/comm.hpp"
+#include "simgrid/s4u/host.hpp"
+#include "simgrid/s4u/mailbox.hpp"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_file,"S4U files");
+
+#include "simgrid/s4u/file.hpp"
+#include "simgrid/s4u/host.hpp"
+#include "simgrid/simix.h"
+
+namespace simgrid {
+namespace s4u {
+
+File::File(const char*fullpath, void *userdata) {
+ // this cannot fail because we get a xbt_die if the mountpoint does not exist
+ p_inferior = simcall_file_open(fullpath, Host::current()->inferior());
+ p_path = fullpath;
+}
+
+File::~File() {
+ simcall_file_close(p_inferior, Host::current()->inferior());
+}
+
+sg_size_t File::read(sg_size_t size) {
+ return simcall_file_read(p_inferior, size, Host::current()->inferior());
+}
+sg_size_t File::write(sg_size_t size) {
+ return simcall_file_write(p_inferior,size, Host::current()->inferior());
+}
+sg_size_t File::size() {
+ return simcall_file_get_size(p_inferior);
+}
+
+void File::seek(sg_size_t pos) {
+ simcall_file_seek(p_inferior,pos,SEEK_SET);
+}
+sg_size_t File::tell() {
+ return simcall_file_tell(p_inferior);
+}
+void File::move(const char*fullpath) {
+ simcall_file_move(p_inferior,fullpath);
+}
+void File::unlink() {
+ sg_host_t attached = Host::current()->inferior(); // FIXME: we should check where this file is attached
+ simcall_file_unlink(p_inferior,attached);
+}
+
+}} // namespace simgrid::s4u
#include "simix/smx_process_private.h"
#include "simgrid/s4u/host.hpp"
+#include "simgrid/s4u/storage.hpp"
-using namespace simgrid;
+namespace simgrid {
+namespace s4u {
-boost::unordered_map<std::string, simgrid::s4u::Host*> *simgrid::s4u::Host::hosts
- = new boost::unordered_map<std::string, simgrid::s4u::Host*>();
+boost::unordered_map<std::string, Host*> *Host::hosts
+ = new boost::unordered_map<std::string, Host*>();
-s4u::Host::Host(const char*name) {
- p_sghost = sg_host_by_name(name);
- if (p_sghost==NULL)
+Host::Host(const char*name) {
+ p_inferior = sg_host_by_name(name);
+ if (p_inferior==NULL)
xbt_die("No such host: %s",name); //FIXME: raise an exception
}
+Host::~Host() {
+ if (mounts != NULL)
+ delete mounts;
+}
-s4u::Host *s4u::Host::byName(std::string name) {
- s4u::Host * res = NULL;
+Host *Host::byName(std::string name) {
+ Host * res = NULL;
try {
res = hosts->at(name);
} catch (std::out_of_range& e) {}
if (res==NULL) {
- res = new s4u::Host(name.c_str());
+ res = new Host(name.c_str());
hosts->insert({name,res});
}
return res;
}
-s4u::Host *s4u::Host::current(){
+Host *Host::current(){
smx_process_t smx_proc = SIMIX_process_self();
if (smx_proc == NULL)
xbt_die("Cannot call Host::current() from the maestro context");
- return s4u::Host::byName(SIMIX_host_get_name(SIMIX_process_get_host(smx_proc)));
+ return Host::byName(SIMIX_host_get_name(SIMIX_process_get_host(smx_proc)));
}
-const char* s4u::Host::getName() {
- return sg_host_name(p_sghost);
+const char* Host::name() {
+ return sg_host_name(p_inferior);
}
-void s4u::Host::turnOn() {
- simcall_host_on(p_sghost);
+void Host::turnOn() {
+ simcall_host_on(p_inferior);
}
-void s4u::Host::turnOff() {
- simcall_host_off(p_sghost);
+void Host::turnOff() {
+ simcall_host_off(p_inferior);
}
-bool s4u::Host::isOn() {
- return simcall_host_get_state(p_sghost);
+bool Host::isOn() {
+ return simcall_host_get_state(p_inferior);
}
+
+boost::unordered_map<std::string, Storage&> &Host::mountedStorages() {
+ if (mounts == NULL) {
+ mounts = new boost::unordered_map<std::string, Storage&> ();
+
+ xbt_dict_t dict = simcall_host_get_mounted_storage_list(p_inferior);
+
+ xbt_dict_cursor_t cursor;
+ char *mountname;
+ char *storagename;
+ xbt_dict_foreach(dict, cursor, mountname, storagename) {
+ mounts->insert({mountname, Storage::byName(storagename)});
+ }
+ xbt_dict_free(&dict);
+ }
+
+ return *mounts;
+}
+
+
+} // namespace simgrid
+} // namespace s4u
--- /dev/null
+/* Copyright (c) 2006-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. */
+
+#include "simgrid/s4u/storage.hpp"
+
+#include "xbt/lib.h"
+extern xbt_lib_t storage_lib;
+
+namespace simgrid {
+namespace s4u {
+
+boost::unordered_map <std::string, Storage *> *Storage::storages = new boost::unordered_map<std::string, Storage*> ();
+Storage::Storage(std::string name, smx_storage_t inferior) {
+ p_name = name;
+ p_inferior = inferior;
+
+ storages->insert({name, this});
+}
+
+Storage::~Storage() {
+ // TODO Auto-generated destructor stub
+}
+
+smx_storage_t Storage::inferior() {
+ return p_inferior;
+}
+Storage &Storage::byName(const char*name) {
+ s4u::Storage *res = NULL;
+ try {
+ res = storages->at(name);
+ } catch (std::out_of_range& e) {
+ smx_storage_t inferior = xbt_lib_get_elm_or_null(storage_lib,name);
+ if (inferior == NULL)
+ xbt_die("Storage %s does not exist. Please only use the storages that are defined in your platform.", name);
+
+ res = new Storage(name,inferior);
+ }
+ return *res;
+}
+
+const char*Storage::name() {
+ return p_name.c_str();
+}
+
+sg_size_t Storage::size_free() {
+ return simcall_storage_get_free_size(p_inferior);
+}
+sg_size_t Storage::size_used() {
+ return simcall_storage_get_used_size(p_inferior);
+}
+sg_size_t Storage::size() {
+ return SIMIX_storage_get_size(p_inferior);
+}
+
+} /* namespace s4u */
+} /* namespace simgrid */
### S4U ###
ADD_TESH_FACTORIES(s4u-dumb "thread;ucontext;raw;boost" --cd ${CMAKE_HOME_DIRECTORY}/examples/s4u/dumb s4u_test.tesh)
+ ADD_TESH_FACTORIES(s4u-io "thread;ucontext;raw;boost" --cd ${CMAKE_HOME_DIRECTORY}/examples/s4u/io s4u_io_test.tesh)
+
### SIMDAG ###
# BEGIN TESH TESTS
src/s4u/s4u_async.cpp
src/s4u/s4u_comm.cpp
src/s4u/s4u_engine.cpp
+ src/s4u/s4u_file.cpp
src/s4u/s4u_host.cpp
src/s4u/s4u_mailbox.cpp
+ src/s4u/s4u_storage.cpp
)
set(SIMGRID_SRC
include/simgrid/s4u/async.hpp
include/simgrid/s4u/comm.hpp
include/simgrid/s4u/engine.hpp
+ include/simgrid/s4u/file.hpp
include/simgrid/s4u/host.hpp
include/simgrid/s4u/mailbox.hpp
+ include/simgrid/s4u/storage.hpp
include/simgrid/s4u.h
include/smpi/mpi.h
include/smpi/smpi.h