AMPI: Add fsglobals (filesystem) and pipglobals (Process-in-Process) privatization...
[charm.git] / src / libs / ck-libs / ampi / ampi_funcptr_fsglobals.C
1
2 #include "ampi_funcptr_loader.h"
3
4 #if defined _WIN32
5 # ifndef WIN32_LEAN_AND_MEAN
6 #  define WIN32_LEAN_AND_MEAN
7 # endif
8 # ifndef NOMINMAX
9 #  define NOMINMAX
10 # endif
11 # include <windows.h>
12 # include <io.h>
13 # define access _access
14 #elif defined __APPLE__
15 # include <unistd.h>
16 # include <copyfile.h>
17 # include <errno.h>
18 #else
19 # include <unistd.h>
20 # include <sys/types.h>
21 # include <sys/wait.h>
22 # include <errno.h>
23 #endif
24
25 #include <string>
26 #include <atomic>
27
28 static void fs_copy(const char * src, const char * dst)
29 {
30   static const char abortmsg[] = "Could not copy fsglobals user program!";
31
32 #if defined _WIN32
33   BOOL ret = CopyFile(src, dst, true);
34   if (ret == 0)
35   {
36     CkError("ERROR> CopyFile(): %d\n", (int)GetLastError());
37     CkAbort(abortmsg);
38   }
39 #elif defined __APPLE__
40   int ret = copyfile(src, dst, 0, COPYFILE_ALL);
41   if (ret < 0)
42   {
43     CkError("ERROR> copyfile(): %d %s\n", ret, strerror(errno));
44     CkAbort(abortmsg);
45   }
46 #else
47   pid_t pid = fork();
48   if (pid == 0)
49   {
50     execl("/bin/cp", "/bin/cp", src, dst, NULL);
51     CkError("ERROR> execl(): %s\n", strerror(errno));
52     CkAbort(abortmsg);
53   }
54   else if (pid < 0)
55   {
56     CkError("ERROR> fork(): %s\n", strerror(errno));
57     CkAbort(abortmsg);
58   }
59   else
60   {
61     int status;
62     pid_t ws = waitpid(pid, &status, 0);
63     if (ws == -1)
64       CkError("ERROR> waitpid(): %s\n", strerror(errno));
65   }
66 #endif
67 }
68
69 static std::atomic<size_t> rank_count{};
70
71 int main(int argc, char ** argv)
72 {
73   SharedObject myexe;
74
75   // copy the user binary for this rank on the filesystem and open it
76   {
77     static const char FUNCPTR_SHIM_SUFFIX[] = ".user";
78
79     std::string src{ampi_binary_path};
80     src += FUNCPTR_SHIM_SUFFIX;
81
82     std::string dst{src};
83     dst += '.';
84     dst += std::to_string(rank_count++);
85     const char * dststr = dst.c_str();
86
87     if (access(dststr, R_OK) != 0)
88       fs_copy(src.c_str(), dststr);
89
90     myexe = dlopen(dststr, RTLD_NOW|RTLD_LOCAL);
91   }
92
93   if (myexe == nullptr)
94   {
95     CkError("dlopen error: %s\n", dlerror());
96     CkAbort("Could not open fsglobals user program!");
97   }
98
99   return AMPI_FuncPtr_Loader(myexe, argc, argv);
100 }