/* 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 <dlfcn.h>
+#include <fcntl.h>
#include <spawn.h>
+#include <sys/sendfile.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
-#include <dlfcn.h>
#include "mc/mc.h"
#include "private.h"
#include "src/mc/mc_replay.h"
#include "src/msg/msg_private.h"
#include "src/simix/smx_private.h"
+#include "src/surf/surf_interface.hpp"
#include "src/smpi/SmpiHost.hpp"
#include "surf/surf.h"
#include "xbt/replay.hpp"
* configuration tools */
return 0;
}
- smpi_init_logs();
TRACE_global_init(&argc, argv);
- TRACE_add_start_function(TRACE_smpi_alloc);
- TRACE_add_end_function(TRACE_smpi_release);
SIMIX_global_init(&argc, argv);
MSG_init(&argc,argv);
SMPI_switch_data_segment = &smpi_switch_data_segment;
- smpi_init_options();
-
simgrid::s4u::Host::onCreation.connect([](simgrid::s4u::Host& host) {
host.extension_set(new simgrid::smpi::SmpiHost(&host));
});
if (smpi_privatize_global_variables == SMPI_PRIVATIZE_DLOPEN) {
std::string executable_copy = executable;
- simix_global->default_function = [executable_copy](std::vector<std::string> args) {
- return std::function<void()>([executable_copy, args] {
+
+ // Prepare the copy of the binary (open the file and get its size)
+ // (fdin will remain open for the whole process execution. That's a sort of leak but we can live with it)
+ int fdin = open(executable_copy.c_str(), O_RDONLY);
+ xbt_assert(fdin >= 0, "Cannot read from %s", executable_copy.c_str());
+ struct stat fdin_stat;
+ fstat(fdin, &fdin_stat);
+ off_t fdin_size = fdin_stat.st_size;
+
+ simix_global->default_function = [executable_copy, fdin, fdin_size](std::vector<std::string> args) {
+ return std::function<void()>([executable_copy, fdin, fdin_size, args] {
// Copy the dynamic library:
std::string target_executable = executable_copy
+ "_" + std::to_string(getpid())
+ "_" + std::to_string(rank++) + ".so";
- // TODO, execute directly instead of relying on cp
- const char* command1 [] = {
- "cp", "--reflink=auto", "--", executable_copy.c_str(), target_executable.c_str(),
- nullptr
- };
- const char* command2 [] = {
- "cp", "--", executable_copy.c_str(), target_executable.c_str(),
- nullptr
- };
- if (execute_command(command1) != 0 && execute_command(command2) != 0)
- xbt_die("copy failed");
+
+ int fdout = open(target_executable.c_str(), O_WRONLY);
+ xbt_assert(fdout >= 0, "Cannot write into %s", target_executable.c_str());
+
+ sendfile(fdout, fdin, NULL, fdin_size);
+ close(fdout);
// Load the copy and resolve the entry point:
void* handle = dlopen(target_executable.c_str(), RTLD_LAZY | RTLD_LOCAL | RTLD_DEEPBIND);
if (!entry_point)
xbt_die("Could not resolve entry point");
- smpi_run_entry_point(entry_point, args);
+ smpi_run_entry_point(entry_point, args);
});
};
SIMIX_launch_application(argv[2]);
- smpi_global_init();
-
- smpi_check_options();
-
- if(smpi_privatize_global_variables == SMPI_PRIVATIZE_MMAP)
- smpi_initialize_global_memory_segments();
+ SMPI_init();
/* Clean IO before the run */
fflush(stdout);
return ret;
}
-// This function can be called from extern file, to initialize logs, options, and processes of smpi
-// without the need of smpirun
+// Called either directly from the user code, or from the code called by smpirun
void SMPI_init(){
smpi_init_logs();
smpi_init_options();
smpi_global_init();
smpi_check_options();
- if (TRACE_is_enabled() && TRACE_is_configured())
- TRACE_smpi_alloc();
+ TRACE_smpi_alloc();
+ simgrid::surf::surfExitCallbacks.connect(TRACE_smpi_release);
if(smpi_privatize_global_variables == SMPI_PRIVATIZE_MMAP)
smpi_initialize_global_memory_segments();
}