Index: cmake/config-ix.cmake =================================================================== --- cmake/config-ix.cmake +++ cmake/config-ix.cmake @@ -532,7 +532,7 @@ endif() if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND - OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android") + OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|SunOS") set(COMPILER_RT_HAS_PROFILE TRUE) else() set(COMPILER_RT_HAS_PROFILE FALSE) Index: lib/profile/GCDAProfiling.c =================================================================== --- lib/profile/GCDAProfiling.c +++ lib/profile/GCDAProfiling.c @@ -34,9 +34,6 @@ #else #include #include -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif #ifndef O_BINARY #define O_BINARY 0 #endif @@ -266,7 +263,7 @@ * same GCDA. This can fail if the filesystem doesn't support it, but in that * case we'll just carry on with the old racy behaviour and hope for the best. */ - flock(fd, LOCK_EX); + lprofLockFd(fd); output_file = fdopen(fd, mode); /* Initialize the write buffer. */ @@ -465,7 +462,7 @@ unmap_file(); } - flock(fd, LOCK_UN); + lprofUnlockFd(fd); fclose(output_file); output_file = NULL; write_buffer = NULL; Index: lib/profile/InstrProfilingFile.c =================================================================== --- lib/profile/InstrProfilingFile.c +++ lib/profile/InstrProfilingFile.c @@ -85,7 +85,6 @@ COMPILER_RT_WEAK lprofFilename lprofCurFilename = {0, 0, 0, {0}, {0}, 0, 0, 0, PNS_unknown}; -int getpid(void); static int getCurFilenameLength(); static const char *getCurFilename(char *FilenameBuf); static unsigned doMerging() { return lprofCurFilename.MergePoolSize; } Index: lib/profile/InstrProfilingPlatformLinux.c =================================================================== --- lib/profile/InstrProfilingPlatformLinux.c +++ lib/profile/InstrProfilingPlatformLinux.c @@ -9,7 +9,7 @@ #include "InstrProfiling.h" -#if defined(__linux__) || defined(__FreeBSD__) +#if defined(__linux__) || defined(__FreeBSD__) || (defined(__sun__) && defined(__svr4__)) #include #define PROF_DATA_START INSTR_PROF_SECT_START(INSTR_PROF_DATA_SECT_NAME) Index: lib/profile/InstrProfilingPlatformOther.c =================================================================== --- lib/profile/InstrProfilingPlatformOther.c +++ lib/profile/InstrProfilingPlatformOther.c @@ -9,7 +9,7 @@ #include "InstrProfiling.h" -#if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) +#if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) && !(defined(__sun__) && defined(__svr4__)) #include Index: lib/profile/InstrProfilingPort.h =================================================================== --- lib/profile/InstrProfilingPort.h +++ lib/profile/InstrProfilingPort.h @@ -107,6 +107,10 @@ #define PROF_NOTE(Format, ...) \ fprintf(stderr, "LLVM Profile Note: " Format, __VA_ARGS__); +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + #if defined(__FreeBSD__) #include Index: lib/profile/InstrProfilingUtil.h =================================================================== --- lib/profile/InstrProfilingUtil.h +++ lib/profile/InstrProfilingUtil.h @@ -16,6 +16,9 @@ /*! \brief Create a directory tree. */ void __llvm_profile_recursive_mkdir(char *Pathname); +int lprofLockFd(int fd); +int lprofUnlockFd(int fd); + /*! Open file \c Filename for read+write with write * lock for exclusive access. The caller will block * if the lock is already held by another process. */ Index: lib/profile/InstrProfilingUtil.c =================================================================== --- lib/profile/InstrProfilingUtil.c +++ lib/profile/InstrProfilingUtil.c @@ -93,9 +93,7 @@ } #endif -COMPILER_RT_VISIBILITY FILE *lprofOpenFileEx(const char *ProfileName) { - FILE *f; - int fd; +COMPILER_RT_VISIBILITY int lprofLockFd(int fd) { #ifdef COMPILER_RT_HAS_FCNTL_LCK struct flock s_flock; @@ -103,21 +101,59 @@ s_flock.l_start = 0; s_flock.l_len = 0; /* Until EOF. */ s_flock.l_pid = getpid(); + s_flock.l_type = F_WRLCK; - s_flock.l_type = F_WRLCK; + while (fcntl(fd, F_SETLKW, &s_flock) == -1) { + if (errno != EINTR) { + if (errno == ENOLCK) { + return -1; + } + break; + } + } + return 0; +#else + flock(fd, LOCK_EX); + return 0; +#endif +} + +COMPILER_RT_VISIBILITY int lprofUnlockFd(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_UNLCK; + + while (fcntl(fd, F_SETLKW, &s_flock) == -1) { + if (errno != EINTR) { + if (errno == ENOLCK) { + return -1; + } + break; + } + } + return 0; +#else + flock(fd, LOCK_UN); + return 0; +#endif +} + +COMPILER_RT_VISIBILITY FILE *lprofOpenFileEx(const char *ProfileName) { + FILE *f; + int fd; +#ifdef COMPILER_RT_HAS_FCNTL_LCK fd = open(ProfileName, O_RDWR | O_CREAT, 0666); if (fd < 0) return NULL; - while (fcntl(fd, F_SETLKW, &s_flock) == -1) { - if (errno != EINTR) { - if (errno == ENOLCK) { - PROF_WARN("Data may be corrupted during profile merging : %s\n", - "Fail to obtain file lock due to system limit."); - } - break; - } - } + if (lprofLockFd(fd) != 0) + PROF_WARN("Data may be corrupted during profile merging : %s\n", + "Fail to obtain file lock due to system limit."); f = fdopen(fd, "r+b"); #elif defined(_WIN32)