diff options
author | Xinliang David Li <davidxl@google.com> | 2016-06-06 03:17:58 +0000 |
---|---|---|
committer | Xinliang David Li <davidxl@google.com> | 2016-06-06 03:17:58 +0000 |
commit | 0bdc52140c2a233fbbc227ad078bfc837246414f (patch) | |
tree | 824d273f8dfe7baa0da4d553e0b0c5949823401d /lib/profile/InstrProfilingUtil.c | |
parent | c30637134ec5d2286d80950d727db06049318e47 (diff) |
[profile] in-process mergeing support (part-2)
(Part-1 merging API is in profile runtime)
This patch implements a portable file opening API
with exclusive access for the process. In-process
profile merge requires profile file update to be
atomic/fully sychronized.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@271864 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/profile/InstrProfilingUtil.c')
-rw-r--r-- | lib/profile/InstrProfilingUtil.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/lib/profile/InstrProfilingUtil.c b/lib/profile/InstrProfilingUtil.c index eb79d4222..24e302d4a 100644 --- a/lib/profile/InstrProfilingUtil.c +++ b/lib/profile/InstrProfilingUtil.c @@ -12,9 +12,15 @@ #ifdef _WIN32 #include <direct.h> +#include <windows.h> #else #include <sys/stat.h> #include <sys/types.h> +#if defined(__linux__) +#include <unistd.h> +#endif +#include <fcntl.h> +#include <errno.h> #endif #ifdef COMPILER_RT_HAS_UNAME @@ -35,7 +41,7 @@ void __llvm_profile_recursive_mkdir(char *path) { #ifdef _WIN32 _mkdir(path); #else - mkdir(path, 0755); /* Some of these will fail, ignore it. */ + mkdir(path, 0755); /* Some of these will fail, ignore it. */ #endif path[i] = save; } @@ -70,4 +76,51 @@ int lprofGetHostName(char *Name, int Len) { } #endif +FILE *lprofOpenFileEx(const char *ProfileName) { + FILE *f; + int fd; +#ifdef COMPILER_RT_HAS_FCNTL_LCK + struct flock s_flock; + + s_flock.l_whence = SEEK_SET; + s_flock.l_start = 0; + s_flock.l_len = 0; /* Until EOF. */ + s_flock.l_pid = getpid(); + + s_flock.l_type = F_WRLCK; + fd = open(ProfileName, O_RDWR | O_CREAT, 0666); + if (fd < 0) + return 0; + + while (fcntl(fd, F_SETLKW, &s_flock) && errno == EINTR) + continue; + + f = fdopen(fd, "r+b"); +#elif defined(_WIN32) + HANDLE h = CreateFile(ProfileName, GENERIC_READ | GENERIC_WRITE, 0, 0, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + if (h == INVALID_HANDLE_VALUE) + return 0; + + fd = _open_osfhandle((intptr_t)h, 0); + if (fd == -1) { + CloseHandle(h); + return 0; + } + + f = _fdopen(fd, "r+b"); + if (f == 0) { + CloseHandle(h); + return 0; + } +#else + /* Worst case no locking applied. */ + PROF_WARN("Concurrent file access is not supported : %s\n", "lack file locking"); + fd = open(ProfileName, O_RDWR | O_CREAT, 0666); + if (fd < 0) + return 0; + f = fdopen(fd, "r+b"); +#endif + return f; +} |