aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/Unix
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support/Unix')
-rw-r--r--llvm/lib/Support/Unix/COM.inc4
-rw-r--r--llvm/lib/Support/Unix/DynamicLibrary.inc28
-rw-r--r--llvm/lib/Support/Unix/Host.inc84
-rw-r--r--llvm/lib/Support/Unix/Memory.inc76
-rw-r--r--llvm/lib/Support/Unix/Path.inc118
-rw-r--r--llvm/lib/Support/Unix/Process.inc79
-rw-r--r--llvm/lib/Support/Unix/Program.inc180
-rw-r--r--llvm/lib/Support/Unix/Signals.inc113
-rw-r--r--llvm/lib/Support/Unix/ThreadLocal.inc58
-rw-r--r--llvm/lib/Support/Unix/Threading.inc170
-rw-r--r--llvm/lib/Support/Unix/Watchdog.inc16
11 files changed, 459 insertions, 467 deletions
diff --git a/llvm/lib/Support/Unix/COM.inc b/llvm/lib/Support/Unix/COM.inc
index d97b59ac02cf..846d4b68a7eb 100644
--- a/llvm/lib/Support/Unix/COM.inc
+++ b/llvm/lib/Support/Unix/COM.inc
@@ -22,5 +22,5 @@ InitializeCOMRAII::InitializeCOMRAII(COMThreadingMode Threading,
bool SpeedOverMemory) {}
InitializeCOMRAII::~InitializeCOMRAII() = default;
-}
-}
+} // namespace sys
+} // namespace llvm
diff --git a/llvm/lib/Support/Unix/DynamicLibrary.inc b/llvm/lib/Support/Unix/DynamicLibrary.inc
index a2a379963de0..7b77da5e0c6b 100644
--- a/llvm/lib/Support/Unix/DynamicLibrary.inc
+++ b/llvm/lib/Support/Unix/DynamicLibrary.inc
@@ -25,9 +25,10 @@ DynamicLibrary::HandleSet::~HandleSet() {
}
void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
- void *Handle = ::dlopen(File, RTLD_LAZY|RTLD_GLOBAL);
+ void *Handle = ::dlopen(File, RTLD_LAZY | RTLD_GLOBAL);
if (!Handle) {
- if (Err) *Err = ::dlerror();
+ if (Err)
+ *Err = ::dlerror();
return &DynamicLibrary::Invalid;
}
@@ -41,9 +42,7 @@ void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
return Handle;
}
-void DynamicLibrary::HandleSet::DLClose(void *Handle) {
- ::dlclose(Handle);
-}
+void DynamicLibrary::HandleSet::DLClose(void *Handle) { ::dlclose(Handle); }
void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
return ::dlsym(Handle, Symbol);
@@ -54,12 +53,12 @@ void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
DynamicLibrary::HandleSet::~HandleSet() {}
void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
- if (Err) *Err = "dlopen() not supported on this platform";
+ if (Err)
+ *Err = "dlopen() not supported on this platform";
return &Invalid;
}
-void DynamicLibrary::HandleSet::DLClose(void *Handle) {
-}
+void DynamicLibrary::HandleSet::DLClose(void *Handle) {}
void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
return nullptr;
@@ -68,9 +67,11 @@ void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
#endif
// Must declare the symbols in the global namespace.
-static void *DoSearch(const char* SymbolName) {
-#define EXPLICIT_SYMBOL(SYM) \
- extern void *SYM; if (!strcmp(SymbolName, #SYM)) return (void*)&SYM
+static void *DoSearch(const char *SymbolName) {
+#define EXPLICIT_SYMBOL(SYM) \
+ extern void *SYM; \
+ if (!strcmp(SymbolName, #SYM)) \
+ return (void *)&SYM
// If this is darwin, it has some funky issues, try to solve them here. Some
// important symbols are marked 'private external' which doesn't allow
@@ -101,8 +102,9 @@ static void *DoSearch(const char* SymbolName) {
#undef EXPLICIT_SYMBOL
// This macro returns the address of a well-known, explicit symbol
-#define EXPLICIT_SYMBOL(SYM) \
- if (!strcmp(SymbolName, #SYM)) return &SYM
+#define EXPLICIT_SYMBOL(SYM) \
+ if (!strcmp(SymbolName, #SYM)) \
+ return &SYM
// Under glibc we have a weird situation. The stderr/out/in symbols are both
// macros and global variables because of standards requirements. So, we
diff --git a/llvm/lib/Support/Unix/Host.inc b/llvm/lib/Support/Unix/Host.inc
deleted file mode 100644
index dfcfdd0dee68..000000000000
--- a/llvm/lib/Support/Unix/Host.inc
+++ /dev/null
@@ -1,84 +0,0 @@
-//===- llvm/Support/Unix/Host.inc -------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the UNIX Host support.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on *all* UNIX variants.
-//===----------------------------------------------------------------------===//
-
-#include "Unix.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Config/config.h"
-#include <cctype>
-#include <string>
-#include <sys/utsname.h>
-
-using namespace llvm;
-
-static std::string getOSVersion() {
- struct utsname info;
-
- if (uname(&info))
- return "";
-
- return info.release;
-}
-
-static std::string updateTripleOSVersion(std::string TargetTripleString) {
- // On darwin, we want to update the version to match that of the target.
- std::string::size_type DarwinDashIdx = TargetTripleString.find("-darwin");
- if (DarwinDashIdx != std::string::npos) {
- TargetTripleString.resize(DarwinDashIdx + strlen("-darwin"));
- TargetTripleString += getOSVersion();
- return TargetTripleString;
- }
- std::string::size_type MacOSDashIdx = TargetTripleString.find("-macos");
- if (MacOSDashIdx != std::string::npos) {
- TargetTripleString.resize(MacOSDashIdx);
- // Reset the OS to darwin as the OS version from `uname` doesn't use the
- // macOS version scheme.
- TargetTripleString += "-darwin";
- TargetTripleString += getOSVersion();
- }
- // On AIX, the AIX version and release should be that of the current host
- // unless if the version has already been specified.
- if (Triple(LLVM_HOST_TRIPLE).getOS() == Triple::AIX) {
- Triple TT(TargetTripleString);
- if (TT.getOS() == Triple::AIX && !TT.getOSMajorVersion()) {
- struct utsname name;
- if (uname(&name) != -1) {
- std::string NewOSName = std::string(Triple::getOSTypeName(Triple::AIX));
- NewOSName += name.version;
- NewOSName += '.';
- NewOSName += name.release;
- NewOSName += ".0.0";
- TT.setOSName(NewOSName);
- return TT.str();
- }
- }
- }
- return TargetTripleString;
-}
-
-std::string sys::getDefaultTargetTriple() {
- std::string TargetTripleString =
- updateTripleOSVersion(LLVM_DEFAULT_TARGET_TRIPLE);
-
- // Override the default target with an environment variable named by
- // LLVM_TARGET_TRIPLE_ENV.
-#if defined(LLVM_TARGET_TRIPLE_ENV)
- if (const char *EnvTriple = std::getenv(LLVM_TARGET_TRIPLE_ENV))
- TargetTripleString = EnvTriple;
-#endif
-
- return TargetTripleString;
-}
diff --git a/llvm/lib/Support/Unix/Memory.inc b/llvm/lib/Support/Unix/Memory.inc
index 5e008069dd98..4c8f6b2ea7d3 100644
--- a/llvm/lib/Support/Unix/Memory.inc
+++ b/llvm/lib/Support/Unix/Memory.inc
@@ -33,7 +33,7 @@
#if defined(__APPLE__)
extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
#else
-extern "C" void __clear_cache(void *, void*);
+extern "C" void __clear_cache(void *, void *);
#endif
static int getPosixProtectionFlags(unsigned Flags) {
@@ -42,16 +42,15 @@ static int getPosixProtectionFlags(unsigned Flags) {
return PROT_READ;
case llvm::sys::Memory::MF_WRITE:
return PROT_WRITE;
- case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_WRITE:
+ case llvm::sys::Memory::MF_READ | llvm::sys::Memory::MF_WRITE:
return PROT_READ | PROT_WRITE;
- case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_EXEC:
+ case llvm::sys::Memory::MF_READ | llvm::sys::Memory::MF_EXEC:
return PROT_READ | PROT_EXEC;
case llvm::sys::Memory::MF_READ | llvm::sys::Memory::MF_WRITE |
llvm::sys::Memory::MF_EXEC:
return PROT_READ | PROT_WRITE | PROT_EXEC;
case llvm::sys::Memory::MF_EXEC:
-#if (defined(__FreeBSD__) || defined(__POWERPC__) || defined (__ppc__) || \
- defined(_POWER) || defined(_ARCH_PPC))
+#if defined(__FreeBSD__) || defined(__powerpc__)
// On PowerPC, having an executable page that has no read permission
// can have unintended consequences. The function InvalidateInstruction-
// Cache uses instructions dcbf and icbi, both of which are treated by
@@ -71,11 +70,9 @@ static int getPosixProtectionFlags(unsigned Flags) {
namespace llvm {
namespace sys {
-MemoryBlock
-Memory::allocateMappedMemory(size_t NumBytes,
- const MemoryBlock *const NearBlock,
- unsigned PFlags,
- std::error_code &EC) {
+MemoryBlock Memory::allocateMappedMemory(size_t NumBytes,
+ const MemoryBlock *const NearBlock,
+ unsigned PFlags, std::error_code &EC) {
EC = std::error_code();
if (NumBytes == 0)
return MemoryBlock();
@@ -106,18 +103,19 @@ Memory::allocateMappedMemory(size_t NumBytes,
// Use any near hint and the page size to set a page-aligned starting address
uintptr_t Start = NearBlock ? reinterpret_cast<uintptr_t>(NearBlock->base()) +
- NearBlock->allocatedSize() : 0;
+ NearBlock->allocatedSize()
+ : 0;
static const size_t PageSize = Process::getPageSizeEstimate();
- const size_t NumPages = (NumBytes+PageSize-1)/PageSize;
+ const size_t NumPages = (NumBytes + PageSize - 1) / PageSize;
if (Start && Start % PageSize)
Start += PageSize - Start % PageSize;
// FIXME: Handle huge page requests (MF_HUGE_HINT).
- void *Addr = ::mmap(reinterpret_cast<void *>(Start), PageSize*NumPages, Protect,
- MMFlags, fd, 0);
+ void *Addr = ::mmap(reinterpret_cast<void *>(Start), PageSize * NumPages,
+ Protect, MMFlags, fd, 0);
if (Addr == MAP_FAILED) {
- if (NearBlock) { //Try again without a near hint
+ if (NearBlock) { // Try again without a near hint
#if !defined(MAP_ANON)
close(fd);
#endif
@@ -137,12 +135,12 @@ Memory::allocateMappedMemory(size_t NumBytes,
MemoryBlock Result;
Result.Address = Addr;
- Result.AllocatedSize = PageSize*NumPages;
+ Result.AllocatedSize = PageSize * NumPages;
Result.Flags = PFlags;
// Rely on protectMappedMemory to invalidate instruction cache.
if (PFlags & MF_EXEC) {
- EC = Memory::protectMappedMemory (Result, PFlags);
+ EC = Memory::protectMappedMemory(Result, PFlags);
if (EC != std::error_code())
return MemoryBlock();
}
@@ -150,8 +148,7 @@ Memory::allocateMappedMemory(size_t NumBytes,
return Result;
}
-std::error_code
-Memory::releaseMappedMemory(MemoryBlock &M) {
+std::error_code Memory::releaseMappedMemory(MemoryBlock &M) {
if (M.Address == nullptr || M.AllocatedSize == 0)
return std::error_code();
@@ -164,8 +161,8 @@ Memory::releaseMappedMemory(MemoryBlock &M) {
return std::error_code();
}
-std::error_code
-Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) {
+std::error_code Memory::protectMappedMemory(const MemoryBlock &M,
+ unsigned Flags) {
static const Align PageSize = Align(Process::getPageSizeEstimate());
if (M.Address == nullptr || M.AllocatedSize == 0)
return std::error_code();
@@ -174,15 +171,18 @@ Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) {
return std::error_code(EINVAL, std::generic_category());
int Protect = getPosixProtectionFlags(Flags);
- uintptr_t Start = alignAddr((const uint8_t *)M.Address - PageSize.value() + 1, PageSize);
- uintptr_t End = alignAddr((const uint8_t *)M.Address + M.AllocatedSize, PageSize);
+ uintptr_t Start =
+ alignAddr((const uint8_t *)M.Address - PageSize.value() + 1, PageSize);
+ uintptr_t End =
+ alignAddr((const uint8_t *)M.Address + M.AllocatedSize, PageSize);
bool InvalidateCache = (Flags & MF_EXEC);
#if defined(__arm__) || defined(__aarch64__)
- // Certain ARM implementations treat icache clear instruction as a memory read,
- // and CPU segfaults on trying to clear cache on !PROT_READ page. Therefore we need
- // to temporarily add PROT_READ for the sake of flushing the instruction caches.
+ // Certain ARM implementations treat icache clear instruction as a memory
+ // read, and CPU segfaults on trying to clear cache on !PROT_READ page.
+ // Therefore we need to temporarily add PROT_READ for the sake of flushing the
+ // instruction caches.
if (InvalidateCache && !(Protect & PROT_READ)) {
int Result = ::mprotect((void *)Start, End - Start, Protect | PROT_READ);
if (Result != 0)
@@ -207,17 +207,14 @@ Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) {
/// InvalidateInstructionCache - Before the JIT can run a block of code
/// that has been emitted it must invalidate the instruction cache on some
/// platforms.
-void Memory::InvalidateInstructionCache(const void *Addr,
- size_t Len) {
+void Memory::InvalidateInstructionCache(const void *Addr, size_t Len) {
// icache invalidation for PPC and ARM.
#if defined(__APPLE__)
-# if (defined(__POWERPC__) || defined (__ppc__) || \
- defined(_POWER) || defined(_ARCH_PPC) || defined(__arm__) || \
- defined(__arm64__))
+#if (defined(__powerpc__) || defined(__arm__) || defined(__arm64__))
sys_icache_invalidate(const_cast<void *>(Addr), Len);
-# endif
+#endif
#elif defined(__Fuchsia__)
@@ -226,13 +223,12 @@ void Memory::InvalidateInstructionCache(const void *Addr,
#else
-# if (defined(__POWERPC__) || defined (__ppc__) || \
- defined(_POWER) || defined(_ARCH_PPC)) && defined(__GNUC__)
+#if defined(__powerpc__) && defined(__GNUC__)
const size_t LineSize = 32;
const intptr_t Mask = ~(LineSize - 1);
- const intptr_t StartLine = ((intptr_t) Addr) & Mask;
- const intptr_t EndLine = ((intptr_t) Addr + Len + LineSize - 1) & Mask;
+ const intptr_t StartLine = ((intptr_t)Addr) & Mask;
+ const intptr_t EndLine = ((intptr_t)Addr + Len + LineSize - 1) & Mask;
for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
asm volatile("dcbf 0, %0" : : "r"(Line));
@@ -241,15 +237,15 @@ void Memory::InvalidateInstructionCache(const void *Addr,
for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
asm volatile("icbi 0, %0" : : "r"(Line));
asm volatile("isync");
-# elif (defined(__arm__) || defined(__aarch64__) || defined(__mips__)) && \
- defined(__GNUC__)
+#elif (defined(__arm__) || defined(__aarch64__) || defined(__mips__)) && \
+ defined(__GNUC__)
// FIXME: Can we safely always call this for __GNUC__ everywhere?
const char *Start = static_cast<const char *>(Addr);
const char *End = Start + Len;
__clear_cache(const_cast<char *>(Start), const_cast<char *>(End));
-# endif
+#endif
-#endif // end apple
+#endif // end apple
ValgrindDiscardTranslations(Addr, Len);
}
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index 2ae7c6dc47e0..3efcad4f2bed 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -36,9 +36,9 @@
#include <sys/file.h>
#ifdef __APPLE__
+#include <copyfile.h>
#include <mach-o/dyld.h>
#include <sys/attr.h>
-#include <copyfile.h>
#if __has_include(<sys/clonefile.h>)
#include <sys/clonefile.h>
#endif
@@ -111,7 +111,7 @@ typedef uint_t uint;
#define STATVFS_F_FRSIZE(vfs) static_cast<uint64_t>(vfs.f_bsize)
#endif
-#if defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__) || \
+#if defined(__NetBSD__) || defined(__DragonFly__) || defined(__GNU__) || \
defined(__MVS__)
#define STATVFS_F_FLAG(vfs) (vfs).f_flag
#else
@@ -121,18 +121,16 @@ typedef uint_t uint;
using namespace llvm;
namespace llvm {
-namespace sys {
+namespace sys {
namespace fs {
const file_t kInvalidFile = -1;
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
defined(__minix) || defined(__FreeBSD_kernel__) || defined(__linux__) || \
- defined(__CYGWIN__) || defined(__DragonFly__) || defined(_AIX) || defined(__GNU__) || \
- (defined(__sun__) && defined(__svr4__))
-static int
-test_dir(char ret[PATH_MAX], const char *dir, const char *bin)
-{
+ defined(__CYGWIN__) || defined(__DragonFly__) || defined(_AIX) || \
+ defined(__GNU__) || (defined(__sun__) && defined(__svr4__))
+static int test_dir(char ret[PATH_MAX], const char *dir, const char *bin) {
struct stat sb;
char fullpath[PATH_MAX];
@@ -149,9 +147,7 @@ test_dir(char ret[PATH_MAX], const char *dir, const char *bin)
return 0;
}
-static char *
-getprogpath(char ret[PATH_MAX], const char *bin)
-{
+static char *getprogpath(char ret[PATH_MAX], const char *bin) {
if (bin == nullptr)
return nullptr;
@@ -319,7 +315,7 @@ std::string getMainExecutableImpl(const char *argv0, void *MainAddr) {
char real_path[PATH_MAX];
if (realpath(exe_path, real_path))
return std::string(real_path);
- break; // Found entry, but realpath failed.
+ break; // Found entry, but realpath failed.
}
#elif defined(HAVE_DLFCN_H) && defined(HAVE_DLADDR)
// Use dladdr to get executable path if available.
@@ -351,9 +347,7 @@ UniqueID file_status::getUniqueID() const {
return UniqueID(fs_st_dev, fs_st_ino);
}
-uint32_t file_status::getLinkCount() const {
- return fs_st_nlinks;
-}
+uint32_t file_status::getLinkCount() const { return fs_st_nlinks; }
ErrorOr<space_info> disk_space(const Twine &Path) {
struct STATVFS Vfs;
@@ -513,7 +507,8 @@ static bool is_local_impl(struct STATVFS &Vfs) {
// Haiku doesn't expose this information.
return false;
#elif defined(__sun)
- // statvfs::f_basetype contains a null-terminated FSType name of the mounted target
+ // statvfs::f_basetype contains a null-terminated FSType name of the mounted
+ // target
StringRef fstype(Vfs.f_basetype);
// NFS is the only non-local fstype??
return !fstype.equals("nfs");
@@ -637,8 +632,7 @@ bool can_execute(const Twine &Path) {
bool equivalent(file_status A, file_status B) {
assert(status_known(A) && status_known(B));
- return A.fs_st_dev == B.fs_st_dev &&
- A.fs_st_ino == B.fs_st_ino;
+ return A.fs_st_dev == B.fs_st_dev && A.fs_st_ino == B.fs_st_ino;
}
std::error_code equivalent(const Twine &A, const Twine &B, bool &result) {
@@ -676,11 +670,17 @@ static void expandTildeExpr(SmallVectorImpl<char> &Path) {
// This is a string of the form ~username/, look up this user's entry in the
// password database.
- struct passwd *Entry = nullptr;
+ std::unique_ptr<char[]> Buf;
+ long BufSize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (BufSize <= 0)
+ BufSize = 16384;
+ Buf = std::make_unique<char[]>(BufSize);
+ struct passwd Pwd;
std::string User = Expr.str();
- Entry = ::getpwnam(User.c_str());
+ struct passwd *Entry = nullptr;
+ getpwnam_r(User.c_str(), &Pwd, Buf.get(), BufSize, &Entry);
- if (!Entry) {
+ if (!Entry || !Entry->pw_dir) {
// Unable to look up the entry, just return back the original path.
return;
}
@@ -691,7 +691,6 @@ static void expandTildeExpr(SmallVectorImpl<char> &Path) {
llvm::sys::path::append(Path, Storage);
}
-
void expand_tilde(const Twine &path, SmallVectorImpl<char> &dest) {
dest.clear();
if (path.isTriviallyEmpty())
@@ -743,9 +742,9 @@ static std::error_code fillStatus(int StatRet, const struct stat &Status,
perms Perms = static_cast<perms>(Status.st_mode) & all_perms;
Result = file_status(typeForMode(Status.st_mode), Perms, Status.st_dev,
- Status.st_nlink, Status.st_ino,
- Status.st_atime, atime_nsec, Status.st_mtime, mtime_nsec,
- Status.st_uid, Status.st_gid, Status.st_size);
+ Status.st_nlink, Status.st_ino, Status.st_atime,
+ atime_nsec, Status.st_mtime, mtime_nsec, Status.st_uid,
+ Status.st_gid, Status.st_size);
return std::error_code();
}
@@ -769,7 +768,7 @@ unsigned getUmask() {
// Chose arbitary new mask and reset the umask to the old mask.
// umask(2) never fails so ignore the return of the second call.
unsigned Mask = ::umask(0);
- (void) ::umask(Mask);
+ (void)::umask(Mask);
return Mask;
}
@@ -875,9 +874,9 @@ void mapped_file_region::unmapImpl() {
void mapped_file_region::dontNeedImpl() {
assert(Mode == mapped_file_region::readonly);
if (!Mapping)
- return;
+ return;
#if defined(__MVS__) || defined(_AIX)
- // If we don't have madvise, or it isn't beneficial, treat this as a no-op.
+ // If we don't have madvise, or it isn't beneficial, treat this as a no-op.
#elif defined(POSIX_MADV_DONTNEED)
::posix_madvise(Mapping, Size, POSIX_MADV_DONTNEED);
#else
@@ -885,9 +884,7 @@ void mapped_file_region::dontNeedImpl() {
#endif
}
-int mapped_file_region::alignment() {
- return Process::getPageSizeEstimate();
-}
+int mapped_file_region::alignment() { return Process::getPageSizeEstimate(); }
std::error_code detail::directory_iterator_construct(detail::DirIterState &it,
StringRef path,
@@ -912,7 +909,7 @@ std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) {
return std::error_code();
}
-static file_type direntType(dirent* Entry) {
+static file_type direntType(dirent *Entry) {
// Most platforms provide the file type in the dirent: Linux/BSD/Mac.
// The DTTOIF macro lets us reuse our status -> type conversion.
// Note that while glibc provides a macro to see if this is supported,
@@ -1134,7 +1131,7 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD,
return EC;
// Attempt to get the real name of the file, if the user asked
- if(!RealPath)
+ if (!RealPath)
return std::error_code();
RealPath->clear();
#if defined(F_GETPATH)
@@ -1186,8 +1183,7 @@ Expected<size_t> readNativeFile(file_t FD, MutableArrayRef<char> Buf) {
#else
size_t Size = Buf.size();
#endif
- ssize_t NumRead =
- sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Size);
+ ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Size);
if (ssize_t(NumRead) == -1)
return errorCodeToError(std::error_code(errno, std::generic_category()));
return NumRead;
@@ -1206,8 +1202,7 @@ Expected<size_t> readNativeFileSlice(file_t FD, MutableArrayRef<char> Buf,
#else
if (lseek(FD, Offset, SEEK_SET) == -1)
return errorCodeToError(std::error_code(errno, std::generic_category()));
- ssize_t NumRead =
- sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Size);
+ ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Size);
#endif
if (NumRead == -1)
return errorCodeToError(std::error_code(errno, std::generic_category()));
@@ -1273,19 +1268,20 @@ static std::error_code remove_directories_impl(const T &Entry,
while (Begin != End) {
auto &Item = *Begin;
ErrorOr<basic_file_status> st = Item.status();
- if (!st && !IgnoreErrors)
- return st.getError();
+ if (st) {
+ if (is_directory(*st)) {
+ EC = remove_directories_impl(Item, IgnoreErrors);
+ if (EC && !IgnoreErrors)
+ return EC;
+ }
- if (is_directory(*st)) {
- EC = remove_directories_impl(Item, IgnoreErrors);
+ EC = fs::remove(Item.path(), true);
if (EC && !IgnoreErrors)
return EC;
+ } else if (!IgnoreErrors) {
+ return st.getError();
}
- EC = fs::remove(Item.path(), true);
- if (EC && !IgnoreErrors)
- return EC;
-
Begin.increment(EC);
if (EC && !IgnoreErrors)
return EC;
@@ -1338,9 +1334,16 @@ std::error_code changeFileOwnership(int FD, uint32_t Owner, uint32_t Group) {
namespace path {
bool home_directory(SmallVectorImpl<char> &result) {
+ std::unique_ptr<char[]> Buf;
char *RequestedDir = getenv("HOME");
if (!RequestedDir) {
- struct passwd *pw = getpwuid(getuid());
+ long BufSize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (BufSize <= 0)
+ BufSize = 16384;
+ Buf = std::make_unique<char[]>(BufSize);
+ struct passwd Pwd;
+ struct passwd *pw = nullptr;
+ getpwuid_r(getuid(), &Pwd, Buf.get(), BufSize, &pw);
if (pw && pw->pw_dir)
RequestedDir = pw->pw_dir;
}
@@ -1353,11 +1356,10 @@ bool home_directory(SmallVectorImpl<char> &result) {
}
static bool getDarwinConfDir(bool TempDir, SmallVectorImpl<char> &Result) {
- #if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR)
+#if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR)
// On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR.
// macros defined in <unistd.h> on darwin >= 9
- int ConfName = TempDir ? _CS_DARWIN_USER_TEMP_DIR
- : _CS_DARWIN_USER_CACHE_DIR;
+ int ConfName = TempDir ? _CS_DARWIN_USER_TEMP_DIR : _CS_DARWIN_USER_CACHE_DIR;
size_t ConfLen = confstr(ConfName, nullptr, 0);
if (ConfLen > 0) {
do {
@@ -1373,7 +1375,7 @@ static bool getDarwinConfDir(bool TempDir, SmallVectorImpl<char> &Result) {
Result.clear();
}
- #endif
+#endif
return false;
}
@@ -1403,7 +1405,7 @@ bool user_config_directory(SmallVectorImpl<char> &result) {
bool cache_directory(SmallVectorImpl<char> &result) {
#ifdef __APPLE__
- if (getDarwinConfDir(false/*tempDir*/, result)) {
+ if (getDarwinConfDir(false /*tempDir*/, result)) {
return true;
}
#else
@@ -1489,13 +1491,13 @@ std::error_code copy_file(const Twine &From, const Twine &To) {
auto Errno = errno;
switch (Errno) {
- case EEXIST: // To already exists.
- case ENOTSUP: // Device does not support cloning.
- case EXDEV: // From and To are on different devices.
- break;
- default:
- // Anything else will also break copyfile().
- return std::error_code(Errno, std::generic_category());
+ case EEXIST: // To already exists.
+ case ENOTSUP: // Device does not support cloning.
+ case EXDEV: // From and To are on different devices.
+ break;
+ default:
+ // Anything else will also break copyfile().
+ return std::error_code(Errno, std::generic_category());
}
// TODO: For EEXIST, profile calling fs::generateUniqueName() and
diff --git a/llvm/lib/Support/Unix/Process.inc b/llvm/lib/Support/Unix/Process.inc
index c1959b5cc2ae..2babf07944bf 100644
--- a/llvm/lib/Support/Unix/Process.inc
+++ b/llvm/lib/Support/Unix/Process.inc
@@ -15,6 +15,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h"
#include <mutex>
+#include <optional>
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
@@ -40,10 +41,10 @@
#include <malloc/malloc.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
+#include <sys/ioctl.h>
#endif
#ifdef HAVE_TERMIOS_H
-# include <termios.h>
+#include <termios.h>
#endif
//===----------------------------------------------------------------------===//
@@ -54,14 +55,15 @@
using namespace llvm;
using namespace sys;
-static std::pair<std::chrono::microseconds, std::chrono::microseconds> getRUsageTimes() {
+static std::pair<std::chrono::microseconds, std::chrono::microseconds>
+getRUsageTimes() {
#if defined(HAVE_GETRUSAGE)
struct rusage RU;
::getrusage(RUSAGE_SELF, &RU);
- return { toDuration(RU.ru_utime), toDuration(RU.ru_stime) };
+ return {toDuration(RU.ru_utime), toDuration(RU.ru_stime)};
#else
#warning Cannot get usage times on this platform
- return { std::chrono::microseconds::zero(), std::chrono::microseconds::zero() };
+ return {std::chrono::microseconds::zero(), std::chrono::microseconds::zero()};
#endif
}
@@ -99,7 +101,7 @@ size_t Process::GetMallocUsage() {
#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
malloc_statistics_t Stats;
malloc_zone_statistics(malloc_default_zone(), &Stats);
- return Stats.size_in_use; // darwin
+ return Stats.size_in_use; // darwin
#elif defined(HAVE_MALLCTL)
size_t alloc, sz;
sz = sizeof(size_t);
@@ -109,9 +111,9 @@ size_t Process::GetMallocUsage() {
#elif defined(HAVE_SBRK)
// Note this is only an approximation and more closely resembles
// the value returned by mallinfo in the arena field.
- static char *StartOfMemory = reinterpret_cast<char*>(::sbrk(0));
- char *EndOfMemory = (char*)sbrk(0);
- if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1))
+ static char *StartOfMemory = reinterpret_cast<char *>(::sbrk(0));
+ char *EndOfMemory = (char *)sbrk(0);
+ if (EndOfMemory != ((char *)-1) && StartOfMemory != ((char *)-1))
return EndOfMemory - StartOfMemory;
return 0;
#else
@@ -120,7 +122,8 @@ size_t Process::GetMallocUsage() {
#endif
}
-void Process::GetTimeUsage(TimePoint<> &elapsed, std::chrono::nanoseconds &user_time,
+void Process::GetTimeUsage(TimePoint<> &elapsed,
+ std::chrono::nanoseconds &user_time,
std::chrono::nanoseconds &sys_time) {
elapsed = std::chrono::system_clock::now();
std::tie(user_time, sys_time) = getRUsageTimes();
@@ -149,10 +152,9 @@ void Process::PreventCoreFiles() {
exception_port_t OriginalPorts[EXC_TYPES_COUNT];
exception_behavior_t OriginalBehaviors[EXC_TYPES_COUNT];
thread_state_flavor_t OriginalFlavors[EXC_TYPES_COUNT];
- kern_return_t err =
- task_get_exception_ports(mach_task_self(), EXC_MASK_ALL, OriginalMasks,
- &Count, OriginalPorts, OriginalBehaviors,
- OriginalFlavors);
+ kern_return_t err = task_get_exception_ports(
+ mach_task_self(), EXC_MASK_ALL, OriginalMasks, &Count, OriginalPorts,
+ OriginalBehaviors, OriginalFlavors);
if (err == KERN_SUCCESS) {
// replace each with MACH_PORT_NULL.
for (unsigned i = 0; i != Count; ++i)
@@ -163,20 +165,20 @@ void Process::PreventCoreFiles() {
// Disable crash reporting on Mac OS X 10.5
signal(SIGABRT, _exit);
- signal(SIGILL, _exit);
- signal(SIGFPE, _exit);
+ signal(SIGILL, _exit);
+ signal(SIGFPE, _exit);
signal(SIGSEGV, _exit);
- signal(SIGBUS, _exit);
+ signal(SIGBUS, _exit);
#endif
coreFilesPrevented = true;
}
-Optional<std::string> Process::GetEnv(StringRef Name) {
+std::optional<std::string> Process::GetEnv(StringRef Name) {
std::string NameStr = Name.str();
const char *Val = ::getenv(NameStr.c_str());
if (!Val)
- return None;
+ return std::nullopt;
return std::string(Val);
}
@@ -197,7 +199,7 @@ private:
int &FD;
bool KeepOpen;
};
-}
+} // namespace
std::error_code Process::FixupStandardFileDescriptors() {
int NullFD = -1;
@@ -239,7 +241,7 @@ std::error_code Process::SafelyCloseFileDescriptor(int FD) {
if (sigfillset(&FullSet) < 0 || sigfillset(&SavedSet) < 0)
return std::error_code(errno, std::generic_category());
- // Atomically swap our current signal mask with a full mask.
+ // Atomically swap our current signal mask with a full mask.
#if LLVM_ENABLE_THREADS
if (int EC = pthread_sigmask(SIG_SETMASK, &FullSet, &SavedSet))
return std::error_code(EC, std::generic_category());
@@ -329,15 +331,15 @@ extern "C" int tigetnum(char *capname);
bool checkTerminalEnvironmentForColors() {
if (const char *TermStr = std::getenv("TERM")) {
return StringSwitch<bool>(TermStr)
- .Case("ansi", true)
- .Case("cygwin", true)
- .Case("linux", true)
- .StartsWith("screen", true)
- .StartsWith("xterm", true)
- .StartsWith("vt100", true)
- .StartsWith("rxvt", true)
- .EndsWith("color", true)
- .Default(false);
+ .Case("ansi", true)
+ .Case("cygwin", true)
+ .Case("linux", true)
+ .StartsWith("screen", true)
+ .StartsWith("xterm", true)
+ .StartsWith("vt100", true)
+ .StartsWith("rxvt", true)
+ .EndsWith("color", true)
+ .Default(false);
}
return false;
@@ -370,7 +372,8 @@ static bool terminalHasColors(int fd) {
// The 'tigetnum' routine returns -2 or -1 on errors, and might return 0 if
// the terminfo says that no colors are supported.
int colors_ti = tigetnum(const_cast<char *>("colors"));
- bool HasColors = colors_ti >= 0 ? colors_ti : checkTerminalEnvironmentForColors();
+ bool HasColors =
+ colors_ti >= 0 ? colors_ti : checkTerminalEnvironmentForColors();
// Now extract the structure allocated by setupterm and free its memory
// through a really silly dance.
@@ -410,20 +413,14 @@ bool Process::ColorNeedsFlush() {
}
const char *Process::OutputColor(char code, bool bold, bool bg) {
- return colorcodes[bg?1:0][bold?1:0][code&7];
+ return colorcodes[bg ? 1 : 0][bold ? 1 : 0][code & 7];
}
-const char *Process::OutputBold(bool bg) {
- return "\033[1m";
-}
+const char *Process::OutputBold(bool bg) { return "\033[1m"; }
-const char *Process::OutputReverse() {
- return "\033[7m";
-}
+const char *Process::OutputReverse() { return "\033[7m"; }
-const char *Process::ResetColor() {
- return "\033[0m";
-}
+const char *Process::ResetColor() { return "\033[0m"; }
#if !HAVE_DECL_ARC4RANDOM
static unsigned GetRandomNumberSeed() {
diff --git a/llvm/lib/Support/Unix/Program.inc b/llvm/lib/Support/Unix/Program.inc
index 089342030b97..897e22711ae2 100644
--- a/llvm/lib/Support/Unix/Program.inc
+++ b/llvm/lib/Support/Unix/Program.inc
@@ -1,4 +1,4 @@
-//===- llvm/Support/Unix/Program.cpp -----------------------------*- C++ -*-===//
+//===- llvm/Support/Unix/Program.inc ----------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -11,8 +11,8 @@
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on *all* UNIX variants.
+//=== WARNING: Implementation here must contain only generic UNIX
+//=== code that is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
#include "llvm/Support/Program.h"
@@ -55,7 +55,7 @@
#endif
#if !USE_NSGETENVIRON
- extern char **environ;
+extern char **environ;
#else
#include <crt_externs.h> // _NSGetEnviron
#endif
@@ -89,12 +89,12 @@ ErrorOr<std::string> sys::findProgramByName(StringRef Name,
SmallString<128> FilePath(Path);
sys::path::append(FilePath, Name);
if (sys::fs::can_execute(FilePath.c_str()))
- return std::string(FilePath.str()); // Found the executable!
+ return std::string(FilePath.str()); // Found the executable!
}
return errc::no_such_file_or_directory;
}
-static bool RedirectIO(Optional<StringRef> Path, int FD, std::string* ErrMsg) {
+static bool RedirectIO(std::optional<StringRef> Path, int FD, std::string *ErrMsg) {
if (!Path) // Noop
return false;
std::string File;
@@ -105,10 +105,10 @@ static bool RedirectIO(Optional<StringRef> Path, int FD, std::string* ErrMsg) {
File = std::string(*Path);
// Open the file
- int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
+ int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY | O_CREAT, 0666);
if (InFD == -1) {
- MakeErrMsg(ErrMsg, "Cannot open file '" + File + "' for "
- + (FD == 0 ? "input" : "output"));
+ MakeErrMsg(ErrMsg, "Cannot open file '" + File + "' for " +
+ (FD == 0 ? "input" : "output"));
return true;
}
@@ -118,7 +118,7 @@ static bool RedirectIO(Optional<StringRef> Path, int FD, std::string* ErrMsg) {
close(InFD);
return true;
}
- close(InFD); // Close the original FD
+ close(InFD); // Close the original FD
return false;
}
@@ -135,30 +135,28 @@ static bool RedirectIO_PS(const std::string *Path, int FD, std::string *ErrMsg,
File = Path->c_str();
if (int Err = posix_spawn_file_actions_addopen(
- FileActions, FD, File,
- FD == 0 ? O_RDONLY : O_WRONLY | O_CREAT, 0666))
+ FileActions, FD, File, FD == 0 ? O_RDONLY : O_WRONLY | O_CREAT, 0666))
return MakeErrMsg(ErrMsg, "Cannot posix_spawn_file_actions_addopen", Err);
return false;
}
#endif
-static void TimeOutHandler(int Sig) {
-}
+static void TimeOutHandler(int Sig) {}
static void SetMemoryLimits(unsigned size) {
#if HAVE_SYS_RESOURCE_H && HAVE_GETRLIMIT && HAVE_SETRLIMIT
struct rlimit r;
- __typeof__ (r.rlim_cur) limit = (__typeof__ (r.rlim_cur)) (size) * 1048576;
+ __typeof__(r.rlim_cur) limit = (__typeof__(r.rlim_cur))(size)*1048576;
// Heap size
- getrlimit (RLIMIT_DATA, &r);
+ getrlimit(RLIMIT_DATA, &r);
r.rlim_cur = limit;
- setrlimit (RLIMIT_DATA, &r);
+ setrlimit(RLIMIT_DATA, &r);
#ifdef RLIMIT_RSS
// Resident set size.
- getrlimit (RLIMIT_RSS, &r);
+ getrlimit(RLIMIT_RSS, &r);
r.rlim_cur = limit;
- setrlimit (RLIMIT_RSS, &r);
+ setrlimit(RLIMIT_RSS, &r);
#endif
#endif
}
@@ -173,8 +171,8 @@ toNullTerminatedCStringArray(ArrayRef<StringRef> Strings, StringSaver &Saver) {
}
static bool Execute(ProcessInfo &PI, StringRef Program,
- ArrayRef<StringRef> Args, Optional<ArrayRef<StringRef>> Env,
- ArrayRef<Optional<StringRef>> Redirects,
+ ArrayRef<StringRef> Args, std::optional<ArrayRef<StringRef>> Env,
+ ArrayRef<std::optional<StringRef>> Redirects,
unsigned MemoryLimit, std::string *ErrMsg,
BitVector *AffinityMask) {
if (!llvm::sys::fs::exists(Program)) {
@@ -263,7 +261,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
posix_spawn_file_actions_destroy(FileActions);
if (Err)
- return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
+ return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
PI.Pid = PID;
PI.Process = PID;
@@ -275,56 +273,62 @@ static bool Execute(ProcessInfo &PI, StringRef Program,
// Create a child process.
int child = fork();
switch (child) {
- // An error occurred: Return to the caller.
- case -1:
- MakeErrMsg(ErrMsg, "Couldn't fork");
- return false;
+ // An error occurred: Return to the caller.
+ case -1:
+ MakeErrMsg(ErrMsg, "Couldn't fork");
+ return false;
- // Child process: Execute the program.
- case 0: {
- // Redirect file descriptors...
- if (!Redirects.empty()) {
- // Redirect stdin
- if (RedirectIO(Redirects[0], 0, ErrMsg)) { return false; }
- // Redirect stdout
- if (RedirectIO(Redirects[1], 1, ErrMsg)) { return false; }
- if (Redirects[1] && Redirects[2] && *Redirects[1] == *Redirects[2]) {
- // If stdout and stderr should go to the same place, redirect stderr
- // to the FD already open for stdout.
- if (-1 == dup2(1,2)) {
- MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout");
- return false;
- }
- } else {
- // Just redirect stderr
- if (RedirectIO(Redirects[2], 2, ErrMsg)) { return false; }
- }
+ // Child process: Execute the program.
+ case 0: {
+ // Redirect file descriptors...
+ if (!Redirects.empty()) {
+ // Redirect stdin
+ if (RedirectIO(Redirects[0], 0, ErrMsg)) {
+ return false;
}
-
- // Set memory limits
- if (MemoryLimit!=0) {
- SetMemoryLimits(MemoryLimit);
+ // Redirect stdout
+ if (RedirectIO(Redirects[1], 1, ErrMsg)) {
+ return false;
+ }
+ if (Redirects[1] && Redirects[2] && *Redirects[1] == *Redirects[2]) {
+ // If stdout and stderr should go to the same place, redirect stderr
+ // to the FD already open for stdout.
+ if (-1 == dup2(1, 2)) {
+ MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout");
+ return false;
+ }
+ } else {
+ // Just redirect stderr
+ if (RedirectIO(Redirects[2], 2, ErrMsg)) {
+ return false;
+ }
}
+ }
- // Execute!
- std::string PathStr = std::string(Program);
- if (Envp != nullptr)
- execve(PathStr.c_str(), const_cast<char **>(Argv),
- const_cast<char **>(Envp));
- else
- execv(PathStr.c_str(), const_cast<char **>(Argv));
- // If the execve() failed, we should exit. Follow Unix protocol and
- // return 127 if the executable was not found, and 126 otherwise.
- // Use _exit rather than exit so that atexit functions and static
- // object destructors cloned from the parent process aren't
- // redundantly run, and so that any data buffered in stdio buffers
- // cloned from the parent aren't redundantly written out.
- _exit(errno == ENOENT ? 127 : 126);
+ // Set memory limits
+ if (MemoryLimit != 0) {
+ SetMemoryLimits(MemoryLimit);
}
- // Parent process: Break out of the switch to do our processing.
- default:
- break;
+ // Execute!
+ std::string PathStr = std::string(Program);
+ if (Envp != nullptr)
+ execve(PathStr.c_str(), const_cast<char **>(Argv),
+ const_cast<char **>(Envp));
+ else
+ execv(PathStr.c_str(), const_cast<char **>(Argv));
+ // If the execve() failed, we should exit. Follow Unix protocol and
+ // return 127 if the executable was not found, and 126 otherwise.
+ // Use _exit rather than exit so that atexit functions and static
+ // object destructors cloned from the parent process aren't
+ // redundantly run, and so that any data buffered in stdio buffers
+ // cloned from the parent aren't redundantly written out.
+ _exit(errno == ENOENT ? 127 : 126);
+ }
+
+ // Parent process: Break out of the switch to do our processing.
+ default:
+ break;
}
PI.Pid = child;
@@ -339,7 +343,7 @@ namespace sys {
#ifndef _AIX
using ::wait4;
#else
-static pid_t (wait4)(pid_t pid, int *status, int options, struct rusage *usage);
+static pid_t(wait4)(pid_t pid, int *status, int options, struct rusage *usage);
#endif
} // namespace sys
@@ -347,11 +351,11 @@ static pid_t (wait4)(pid_t pid, int *status, int options, struct rusage *usage);
#ifdef _AIX
#ifndef _ALL_SOURCE
-extern "C" pid_t (wait4)(pid_t pid, int *status, int options,
- struct rusage *usage);
+extern "C" pid_t(wait4)(pid_t pid, int *status, int options,
+ struct rusage *usage);
#endif
-pid_t (llvm::sys::wait4)(pid_t pid, int *status, int options,
- struct rusage *usage) {
+pid_t(llvm::sys::wait4)(pid_t pid, int *status, int options,
+ struct rusage *usage) {
assert(pid > 0 && "Only expecting to handle actual PID values!");
assert((options & ~WNOHANG) == 0 && "Expecting WNOHANG at most!");
assert(usage && "Expecting usage collection!");
@@ -379,17 +383,23 @@ pid_t (llvm::sys::wait4)(pid_t pid, int *status, int options,
}
#endif
-ProcessInfo llvm::sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
- bool WaitUntilTerminates, std::string *ErrMsg,
- Optional<ProcessStatistics> *ProcStat) {
+ProcessInfo llvm::sys::Wait(const ProcessInfo &PI,
+ std::optional<unsigned> SecondsToWait,
+ std::string *ErrMsg,
+ std::optional<ProcessStatistics> *ProcStat,
+ bool Polling) {
struct sigaction Act, Old;
assert(PI.Pid && "invalid pid to wait on, process not started?");
int WaitPidOptions = 0;
pid_t ChildPid = PI.Pid;
- if (WaitUntilTerminates) {
- SecondsToWait = 0;
- } else if (SecondsToWait) {
+ bool WaitUntilTerminates = false;
+ if (!SecondsToWait) {
+ WaitUntilTerminates = true;
+ } else {
+ if (*SecondsToWait == 0)
+ WaitPidOptions = WNOHANG;
+
// Install a timeout handler. The handler itself does nothing, but the
// simple fact of having a handler at all causes the wait below to return
// with EINTR, unlike if we used SIG_IGN.
@@ -398,12 +408,11 @@ ProcessInfo llvm::sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
sigemptyset(&Act.sa_mask);
sigaction(SIGALRM, &Act, &Old);
// FIXME The alarm signal may be delivered to another thread.
- alarm(SecondsToWait);
- } else if (SecondsToWait == 0)
- WaitPidOptions = WNOHANG;
+ alarm(*SecondsToWait);
+ }
// Parent process: Wait for the child process to terminate.
- int status;
+ int status = 0;
ProcessInfo WaitResult;
rusage Info;
if (ProcStat)
@@ -418,7 +427,7 @@ ProcessInfo llvm::sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
// Non-blocking wait.
return WaitResult;
} else {
- if (SecondsToWait && errno == EINTR) {
+ if (SecondsToWait && errno == EINTR && !Polling) {
// Kill the child.
kill(PI.Pid, SIGKILL);
@@ -494,13 +503,13 @@ ProcessInfo llvm::sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait,
return WaitResult;
}
-std::error_code llvm::sys::ChangeStdinMode(fs::OpenFlags Flags){
+std::error_code llvm::sys::ChangeStdinMode(fs::OpenFlags Flags) {
if (!(Flags & fs::OF_Text))
return ChangeStdinToBinary();
return std::error_code();
}
-std::error_code llvm::sys::ChangeStdoutMode(fs::OpenFlags Flags){
+std::error_code llvm::sys::ChangeStdoutMode(fs::OpenFlags Flags) {
if (!(Flags & fs::OF_Text))
return ChangeStdoutToBinary();
return std::error_code();
@@ -520,7 +529,8 @@ std::error_code
llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
WindowsEncodingMethod Encoding /*unused*/) {
std::error_code EC;
- llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::OF_TextWithCRLF);
+ llvm::raw_fd_ostream OS(FileName, EC,
+ llvm::sys::fs::OpenFlags::OF_TextWithCRLF);
if (EC)
return EC;
diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc
index bf145bffe8bf..05a7335216f4 100644
--- a/llvm/lib/Support/Unix/Signals.inc
+++ b/llvm/lib/Support/Unix/Signals.inc
@@ -48,7 +48,7 @@
#include <algorithm>
#include <string>
#ifdef HAVE_BACKTRACE
-# include BACKTRACE_HEADER // For backtrace().
+#include BACKTRACE_HEADER // For backtrace().
#endif
#if HAVE_SIGNAL_H
#include <signal.h>
@@ -79,8 +79,8 @@
using namespace llvm;
-static void SignalHandler(int Sig); // defined below.
-static void InfoSignalHandler(int Sig); // defined below.
+static void SignalHandler(int Sig); // defined below.
+static void InfoSignalHandler(int Sig); // defined below.
using SignalHandlerFunctionType = void (*)();
/// The function to call if ctrl-c is pressed.
@@ -208,40 +208,45 @@ static StringRef Argv0;
/// Signals that represent requested termination. There's no bug or failure, or
/// if there is, it's not our direct responsibility. For whatever reason, our
/// continued execution is no longer desirable.
-static const int IntSigs[] = {
- SIGHUP, SIGINT, SIGTERM, SIGUSR2
-};
+static const int IntSigs[] = {SIGHUP, SIGINT, SIGTERM, SIGUSR2};
/// Signals that represent that we have a bug, and our prompt termination has
/// been ordered.
-static const int KillSigs[] = {
- SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV, SIGQUIT
+static const int KillSigs[] = {SIGILL,
+ SIGTRAP,
+ SIGABRT,
+ SIGFPE,
+ SIGBUS,
+ SIGSEGV,
+ SIGQUIT
#ifdef SIGSYS
- , SIGSYS
+ ,
+ SIGSYS
#endif
#ifdef SIGXCPU
- , SIGXCPU
+ ,
+ SIGXCPU
#endif
#ifdef SIGXFSZ
- , SIGXFSZ
+ ,
+ SIGXFSZ
#endif
#ifdef SIGEMT
- , SIGEMT
+ ,
+ SIGEMT
#endif
};
/// Signals that represent requests for status.
-static const int InfoSigs[] = {
- SIGUSR1
+static const int InfoSigs[] = {SIGUSR1
#ifdef SIGINFO
- , SIGINFO
+ ,
+ SIGINFO
#endif
};
-static const size_t NumSigs =
- array_lengthof(IntSigs) + array_lengthof(KillSigs) +
- array_lengthof(InfoSigs) + 1 /* SIGPIPE */;
-
+static const size_t NumSigs = std::size(IntSigs) + std::size(KillSigs) +
+ std::size(InfoSigs) + 1 /* SIGPIPE */;
static std::atomic<unsigned> NumRegisteredSignals = ATOMIC_VAR_INIT(0);
static struct {
@@ -298,7 +303,7 @@ static void RegisterHandlers() { // Not signal-safe.
enum class SignalKind { IsKill, IsInfo };
auto registerHandler = [&](int Signal, SignalKind Kind) {
unsigned Index = NumRegisteredSignals.load();
- assert(Index < array_lengthof(RegisteredSignalInfo) &&
+ assert(Index < std::size(RegisteredSignalInfo) &&
"Out of space for signal handlers!");
struct sigaction NewHandler;
@@ -334,8 +339,8 @@ static void RegisterHandlers() { // Not signal-safe.
void sys::unregisterHandlers() {
// Restore all of the signal handlers to how they were before we showed up.
for (unsigned i = 0, e = NumRegisteredSignals.load(); i != e; ++i) {
- sigaction(RegisteredSignalInfo[i].SigNo,
- &RegisteredSignalInfo[i].SA, nullptr);
+ sigaction(RegisteredSignalInfo[i].SigNo, &RegisteredSignalInfo[i].SA,
+ nullptr);
--NumRegisteredSignals;
}
}
@@ -407,14 +412,12 @@ static void SignalHandler(int Sig) {
}
static void InfoSignalHandler(int Sig) {
- SaveAndRestore<int> SaveErrnoDuringASignalHandler(errno);
+ SaveAndRestore SaveErrnoDuringASignalHandler(errno);
if (SignalHandlerFunctionType CurrentInfoFunction = InfoSignalFunction)
CurrentInfoFunction();
}
-void llvm::sys::RunInterruptHandlers() {
- RemoveFilesToRemove();
-}
+void llvm::sys::RunInterruptHandlers() { RemoveFilesToRemove(); }
void llvm::sys::SetInterruptFunction(void (*IF)()) {
InterruptFunction.exchange(IF);
@@ -432,17 +435,12 @@ void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) {
}
void llvm::sys::DefaultOneShotPipeSignalHandler() {
- // UNIX03 conformance requires a non-zero exit code and an error message
- // to stderr when writing to a closed stdout fails.
- errs() << "error: write on a pipe with no reader\n";
-
// Send a special return code that drivers can check for, from sysexits.h.
exit(EX_IOERR);
}
// The public API
-bool llvm::sys::RemoveFileOnSignal(StringRef Filename,
- std::string* ErrMsg) {
+bool llvm::sys::RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg) {
// Ensure that cleanup will occur as soon as one file is added.
static ManagedStatic<FilesToRemoveCleanup> FilesToRemoveCleanup;
*FilesToRemoveCleanup;
@@ -465,7 +463,7 @@ void llvm::sys::AddSignalHandler(sys::SignalHandlerCallback FnPtr,
RegisterHandlers();
}
-#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && HAVE_LINK_H && \
+#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && HAVE_LINK_H && \
(defined(__linux__) || defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || defined(__NetBSD__))
struct DlIteratePhdrData {
@@ -478,7 +476,7 @@ struct DlIteratePhdrData {
};
static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
- DlIteratePhdrData *data = (DlIteratePhdrData*)arg;
+ DlIteratePhdrData *data = (DlIteratePhdrData *)arg;
const char *name = data->first ? data->main_exec_name : info->dlpi_name;
data->first = false;
for (int i = 0; i < info->dlpi_phnum; i++) {
@@ -566,13 +564,13 @@ void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) {
#if defined(HAVE_BACKTRACE)
// Use backtrace() to output a backtrace on Linux systems with glibc.
if (!depth)
- depth = backtrace(StackTrace, static_cast<int>(array_lengthof(StackTrace)));
+ depth = backtrace(StackTrace, static_cast<int>(std::size(StackTrace)));
#endif
#if defined(HAVE__UNWIND_BACKTRACE)
// Try _Unwind_Backtrace() if backtrace() failed.
if (!depth)
- depth = unwindBacktrace(StackTrace,
- static_cast<int>(array_lengthof(StackTrace)));
+ depth =
+ unwindBacktrace(StackTrace, static_cast<int>(std::size(StackTrace)));
#endif
if (!depth)
return;
@@ -590,13 +588,16 @@ void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) {
for (int i = 0; i < depth; ++i) {
Dl_info dlinfo;
dladdr(StackTrace[i], &dlinfo);
- const char* name = strrchr(dlinfo.dli_fname, '/');
+ const char *name = strrchr(dlinfo.dli_fname, '/');
int nwidth;
- if (!name) nwidth = strlen(dlinfo.dli_fname);
- else nwidth = strlen(name) - 1;
+ if (!name)
+ nwidth = strlen(dlinfo.dli_fname);
+ else
+ nwidth = strlen(name) - 1;
- if (nwidth > width) width = nwidth;
+ if (nwidth > width)
+ width = nwidth;
}
for (int i = 0; i < depth; ++i) {
@@ -605,23 +606,27 @@ void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) {
OS << format("%-2d", i);
- const char* name = strrchr(dlinfo.dli_fname, '/');
- if (!name) OS << format(" %-*s", width, dlinfo.dli_fname);
- else OS << format(" %-*s", width, name+1);
+ const char *name = strrchr(dlinfo.dli_fname, '/');
+ if (!name)
+ OS << format(" %-*s", width, dlinfo.dli_fname);
+ else
+ OS << format(" %-*s", width, name + 1);
- OS << format(" %#0*lx", (int)(sizeof(void*) * 2) + 2,
+ OS << format(" %#0*lx", (int)(sizeof(void *) * 2) + 2,
(unsigned long)StackTrace[i]);
if (dlinfo.dli_sname != nullptr) {
OS << ' ';
int res;
- char* d = itaniumDemangle(dlinfo.dli_sname, nullptr, nullptr, &res);
- if (!d) OS << dlinfo.dli_sname;
- else OS << d;
+ char *d = itaniumDemangle(dlinfo.dli_sname, nullptr, nullptr, &res);
+ if (!d)
+ OS << dlinfo.dli_sname;
+ else
+ OS << d;
free(d);
- OS << format(" + %tu", (static_cast<const char*>(StackTrace[i])-
- static_cast<const char*>(dlinfo.dli_saddr)));
+ OS << format(" + %tu", (static_cast<const char *>(StackTrace[i]) -
+ static_cast<const char *>(dlinfo.dli_saddr)));
}
OS << '\n';
}
@@ -652,11 +657,9 @@ void llvm::sys::PrintStackTraceOnErrorSignal(StringRef Argv0,
exception_mask_t mask = EXC_MASK_CRASH;
- kern_return_t ret = task_set_exception_ports(self,
- mask,
- MACH_PORT_NULL,
- EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES,
- THREAD_STATE_NONE);
+ kern_return_t ret = task_set_exception_ports(
+ self, mask, MACH_PORT_NULL,
+ EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, THREAD_STATE_NONE);
(void)ret;
}
#endif
diff --git a/llvm/lib/Support/Unix/ThreadLocal.inc b/llvm/lib/Support/Unix/ThreadLocal.inc
deleted file mode 100644
index 0a958a2b952f..000000000000
--- a/llvm/lib/Support/Unix/ThreadLocal.inc
+++ /dev/null
@@ -1,58 +0,0 @@
-//=== llvm/Support/Unix/ThreadLocal.inc - Unix Thread Local Data -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Unix specific (non-pthread) ThreadLocal class.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on *all* UNIX variants.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Config/config.h"
-
-#include <cassert>
-#include <pthread.h>
-#include <stdlib.h>
-
-namespace llvm {
-using namespace sys;
-
-ThreadLocalImpl::ThreadLocalImpl() : data() {
- static_assert(sizeof(pthread_key_t) <= sizeof(data), "size too big");
- pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
- int errorcode = pthread_key_create(key, nullptr);
- assert(errorcode == 0);
- (void) errorcode;
-}
-
-ThreadLocalImpl::~ThreadLocalImpl() {
- pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
- int errorcode = pthread_key_delete(*key);
- assert(errorcode == 0);
- (void) errorcode;
-}
-
-void ThreadLocalImpl::setInstance(const void* d) {
- pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
- int errorcode = pthread_setspecific(*key, d);
- assert(errorcode == 0);
- (void) errorcode;
-}
-
-void *ThreadLocalImpl::getInstance() {
- pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
- return pthread_getspecific(*key);
-}
-
-void ThreadLocalImpl::removeInstance() {
- setInstance(nullptr);
-}
-
-}
diff --git a/llvm/lib/Support/Unix/Threading.inc b/llvm/lib/Support/Unix/Threading.inc
index 99f64b4f553d..819748db4ec2 100644
--- a/llvm/lib/Support/Unix/Threading.inc
+++ b/llvm/lib/Support/Unix/Threading.inc
@@ -13,12 +13,18 @@
#include "Unix.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
#if defined(__APPLE__)
#include <mach/mach_init.h>
#include <mach/mach_port.h>
#include <pthread/qos.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
#endif
#include <pthread.h>
@@ -52,7 +58,7 @@
namespace llvm {
pthread_t
llvm_execute_on_thread_impl(void *(*ThreadFunc)(void *), void *Arg,
- llvm::Optional<unsigned> StackSizeInBytes) {
+ std::optional<unsigned> StackSizeInBytes) {
int errnum;
// Construct the attributes object.
@@ -98,13 +104,9 @@ void llvm_thread_join_impl(pthread_t Thread) {
}
}
-pthread_t llvm_thread_get_id_impl(pthread_t Thread) {
- return Thread;
-}
+pthread_t llvm_thread_get_id_impl(pthread_t Thread) { return Thread; }
-pthread_t llvm_thread_get_current_id_impl() {
- return ::pthread_self();
-}
+pthread_t llvm_thread_get_current_id_impl() { return ::pthread_self(); }
} // namespace llvm
@@ -131,7 +133,6 @@ uint64_t llvm::get_threadid() {
#endif
}
-
static constexpr uint32_t get_max_thread_name_length_impl() {
#if defined(__NetBSD__)
return PTHREAD_MAX_NAMELEN_NP;
@@ -180,7 +181,7 @@ void llvm::set_thread_name(const Twine &Name) {
::pthread_set_name_np(::pthread_self(), NameStr.data());
#elif defined(__NetBSD__)
::pthread_setname_np(::pthread_self(), "%s",
- const_cast<char *>(NameStr.data()));
+ const_cast<char *>(NameStr.data()));
#elif defined(__APPLE__)
::pthread_setname_np(NameStr.data());
#endif
@@ -196,8 +197,8 @@ void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
struct kinfo_proc *kp = nullptr, *nkp;
size_t len = 0;
int error;
- int ctl[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
- (int)pid };
+ int ctl[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
+ (int)pid};
while (1) {
error = sysctl(ctl, 4, kp, &len, nullptr, 0);
@@ -240,7 +241,7 @@ void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
#elif defined(__linux__)
#if HAVE_PTHREAD_GETNAME_NP
constexpr uint32_t len = get_max_thread_name_length_impl();
- char Buffer[len] = {'\0'}; // FIXME: working around MSan false positive.
+ char Buffer[len] = {'\0'}; // FIXME: working around MSan false positive.
if (0 == ::pthread_getname_np(::pthread_self(), Buffer, len))
Name.append(Buffer, Buffer + strlen(Buffer));
#endif
@@ -267,18 +268,22 @@ SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) {
#elif defined(__APPLE__)
// https://developer.apple.com/documentation/apple-silicon/tuning-your-code-s-performance-for-apple-silicon
//
- // Background - Applies to work that isn’t visible to the user and may take significant
- // time to complete. Examples include indexing, backing up, or synchronizing data. This
- // class emphasizes energy efficiency.
+ // Background - Applies to work that isn’t visible to the user and may take
+ // significant time to complete. Examples include indexing, backing up, or
+ // synchronizing data. This class emphasizes energy efficiency.
//
- // Utility - Applies to work that takes anywhere from a few seconds to a few minutes to
- // complete. Examples include downloading a document or importing data. This class
- // offers a balance between responsiveness, performance, and energy efficiency.
- const auto qosClass = [&](){
+ // Utility - Applies to work that takes anywhere from a few seconds to a few
+ // minutes to complete. Examples include downloading a document or importing
+ // data. This class offers a balance between responsiveness, performance, and
+ // energy efficiency.
+ const auto qosClass = [&]() {
switch (Priority) {
- case ThreadPriority::Background: return QOS_CLASS_BACKGROUND;
- case ThreadPriority::Low: return QOS_CLASS_UTILITY;
- case ThreadPriority::Default: return QOS_CLASS_DEFAULT;
+ case ThreadPriority::Background:
+ return QOS_CLASS_BACKGROUND;
+ case ThreadPriority::Low:
+ return QOS_CLASS_UTILITY;
+ case ThreadPriority::Default:
+ return QOS_CLASS_DEFAULT;
}
}();
return !pthread_set_qos_class_self_np(qosClass, 0)
@@ -290,7 +295,7 @@ SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) {
#include <thread>
-int computeHostNumHardwareThreads() {
+static int computeHostNumHardwareThreads() {
#if defined(__FreeBSD__)
cpuset_t mask;
CPU_ZERO(&mask);
@@ -317,3 +322,122 @@ llvm::BitVector llvm::get_thread_affinity_mask() {
}
unsigned llvm::get_cpus() { return 1; }
+
+#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
+// On Linux, the number of physical cores can be computed from /proc/cpuinfo,
+// using the number of unique physical/core id pairs. The following
+// implementation reads the /proc/cpuinfo format on an x86_64 system.
+static int computeHostNumPhysicalCores() {
+ // Enabled represents the number of physical id/core id pairs with at least
+ // one processor id enabled by the CPU affinity mask.
+ cpu_set_t Affinity, Enabled;
+ if (sched_getaffinity(0, sizeof(Affinity), &Affinity) != 0)
+ return -1;
+ CPU_ZERO(&Enabled);
+
+ // Read /proc/cpuinfo as a stream (until EOF reached). It cannot be
+ // mmapped because it appears to have 0 size.
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
+ llvm::MemoryBuffer::getFileAsStream("/proc/cpuinfo");
+ if (std::error_code EC = Text.getError()) {
+ llvm::errs() << "Can't read "
+ << "/proc/cpuinfo: " << EC.message() << "\n";
+ return -1;
+ }
+ SmallVector<StringRef, 8> strs;
+ (*Text)->getBuffer().split(strs, "\n", /*MaxSplit=*/-1,
+ /*KeepEmpty=*/false);
+ int CurProcessor = -1;
+ int CurPhysicalId = -1;
+ int CurSiblings = -1;
+ int CurCoreId = -1;
+ for (StringRef Line : strs) {
+ std::pair<StringRef, StringRef> Data = Line.split(':');
+ auto Name = Data.first.trim();
+ auto Val = Data.second.trim();
+ // These fields are available if the kernel is configured with CONFIG_SMP.
+ if (Name == "processor")
+ Val.getAsInteger(10, CurProcessor);
+ else if (Name == "physical id")
+ Val.getAsInteger(10, CurPhysicalId);
+ else if (Name == "siblings")
+ Val.getAsInteger(10, CurSiblings);
+ else if (Name == "core id") {
+ Val.getAsInteger(10, CurCoreId);
+ // The processor id corresponds to an index into cpu_set_t.
+ if (CPU_ISSET(CurProcessor, &Affinity))
+ CPU_SET(CurPhysicalId * CurSiblings + CurCoreId, &Enabled);
+ }
+ }
+ return CPU_COUNT(&Enabled);
+}
+#elif defined(__linux__) && defined(__s390x__)
+static int computeHostNumPhysicalCores() {
+ return sysconf(_SC_NPROCESSORS_ONLN);
+}
+#elif defined(__linux__) && !defined(__ANDROID__)
+static int computeHostNumPhysicalCores() {
+ cpu_set_t Affinity;
+ if (sched_getaffinity(0, sizeof(Affinity), &Affinity) == 0)
+ return CPU_COUNT(&Affinity);
+
+ // The call to sched_getaffinity() may have failed because the Affinity
+ // mask is too small for the number of CPU's on the system (i.e. the
+ // system has more than 1024 CPUs). Allocate a mask large enough for
+ // twice as many CPUs.
+ cpu_set_t *DynAffinity;
+ DynAffinity = CPU_ALLOC(2048);
+ if (sched_getaffinity(0, CPU_ALLOC_SIZE(2048), DynAffinity) == 0) {
+ int NumCPUs = CPU_COUNT(DynAffinity);
+ CPU_FREE(DynAffinity);
+ return NumCPUs;
+ }
+ return -1;
+}
+#elif defined(__APPLE__)
+// Gets the number of *physical cores* on the machine.
+static int computeHostNumPhysicalCores() {
+ uint32_t count;
+ size_t len = sizeof(count);
+ sysctlbyname("hw.physicalcpu", &count, &len, NULL, 0);
+ if (count < 1) {
+ int nm[2];
+ nm[0] = CTL_HW;
+ nm[1] = HW_AVAILCPU;
+ sysctl(nm, 2, &count, &len, NULL, 0);
+ if (count < 1)
+ return -1;
+ }
+ return count;
+}
+#elif defined(__MVS__)
+static int computeHostNumPhysicalCores() {
+ enum {
+ // Byte offset of the pointer to the Communications Vector Table (CVT) in
+ // the Prefixed Save Area (PSA). The table entry is a 31-bit pointer and
+ // will be zero-extended to uintptr_t.
+ FLCCVT = 16,
+ // Byte offset of the pointer to the Common System Data Area (CSD) in the
+ // CVT. The table entry is a 31-bit pointer and will be zero-extended to
+ // uintptr_t.
+ CVTCSD = 660,
+ // Byte offset to the number of live CPs in the LPAR, stored as a signed
+ // 32-bit value in the table.
+ CSD_NUMBER_ONLINE_STANDARD_CPS = 264,
+ };
+ char *PSA = 0;
+ char *CVT = reinterpret_cast<char *>(
+ static_cast<uintptr_t>(reinterpret_cast<unsigned int &>(PSA[FLCCVT])));
+ char *CSD = reinterpret_cast<char *>(
+ static_cast<uintptr_t>(reinterpret_cast<unsigned int &>(CVT[CVTCSD])));
+ return reinterpret_cast<int &>(CSD[CSD_NUMBER_ONLINE_STANDARD_CPS]);
+}
+#else
+// On other systems, return -1 to indicate unknown.
+static int computeHostNumPhysicalCores() { return -1; }
+#endif
+
+int llvm::get_physical_cores() {
+ static int NumCores = computeHostNumPhysicalCores();
+ return NumCores;
+}
diff --git a/llvm/lib/Support/Unix/Watchdog.inc b/llvm/lib/Support/Unix/Watchdog.inc
index b363ef779560..b33e52d88500 100644
--- a/llvm/lib/Support/Unix/Watchdog.inc
+++ b/llvm/lib/Support/Unix/Watchdog.inc
@@ -17,17 +17,17 @@
#endif
namespace llvm {
- namespace sys {
- Watchdog::Watchdog(unsigned int seconds) {
+namespace sys {
+Watchdog::Watchdog(unsigned int seconds) {
#ifdef HAVE_UNISTD_H
- alarm(seconds);
+ alarm(seconds);
#endif
- }
+}
- Watchdog::~Watchdog() {
+Watchdog::~Watchdog() {
#ifdef HAVE_UNISTD_H
- alarm(0);
+ alarm(0);
#endif
- }
- }
}
+} // namespace sys
+} // namespace llvm