diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/Unix')
9 files changed, 126 insertions, 185 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc index a0927da50e48..79b1759359e1 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc @@ -42,9 +42,7 @@ extern "C" void sys_icache_invalidate(const void *Addr, size_t len); extern "C" void __clear_cache(void *, void*); #endif -namespace { - -int getPosixProtectionFlags(unsigned Flags) { +static int getPosixProtectionFlags(unsigned Flags) { switch (Flags & llvm::sys::Memory::MF_RWE_MASK) { case llvm::sys::Memory::MF_READ: return PROT_READ; @@ -76,8 +74,6 @@ int getPosixProtectionFlags(unsigned Flags) { return PROT_NONE; } -} // anonymous namespace - namespace llvm { namespace sys { @@ -176,7 +172,7 @@ Memory::releaseMappedMemory(MemoryBlock &M) { std::error_code Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) { - static const size_t PageSize = Process::getPageSizeEstimate(); + static const Align PageSize = Align(Process::getPageSizeEstimate()); if (M.Address == nullptr || M.AllocatedSize == 0) return std::error_code(); @@ -184,8 +180,8 @@ Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) { return std::error_code(EINVAL, std::generic_category()); int Protect = getPosixProtectionFlags(Flags); - uintptr_t Start = alignAddr((uint8_t *)M.Address - PageSize + 1, PageSize); - uintptr_t End = alignAddr((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); diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Mutex.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Mutex.inc deleted file mode 100644 index 2c982b38d6ff..000000000000 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Mutex.inc +++ /dev/null @@ -1,42 +0,0 @@ -//===- llvm/Support/Unix/Mutex.inc - Unix Mutex Implementation ---*- 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) Mutex class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic UNIX code that -//=== is guaranteed to work on *all* UNIX variants. -//===----------------------------------------------------------------------===// - -namespace llvm -{ -using namespace sys; - -MutexImpl::MutexImpl( bool recursive) -{ -} - -MutexImpl::~MutexImpl() -{ -} - -bool -MutexImpl::release() -{ - return true; -} - -bool -MutexImpl::tryacquire( void ) -{ - return true; -} - -} diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Path.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Path.inc index a64ef8a6da3a..2a03dc682bce 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Path.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Path.inc @@ -201,8 +201,8 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) { if (elf_aux_info(AT_EXECPATH, exe_path, sizeof(exe_path)) == 0) return exe_path; #else - // elf_aux_info(AT_EXECPATH, ... is not available on older FreeBSD. Fall - // back to finding the ELF auxiliary vectors after the processes's + // elf_aux_info(AT_EXECPATH, ... is not available in all supported versions, + // fall back to finding the ELF auxiliary vectors after the process's // environment. char **p = ::environ; while (*p++ != 0) @@ -221,12 +221,12 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) { // Fall back to argv[0] if auxiliary vectors are not available. if (getprogpath(exe_path, argv0) != NULL) return exe_path; -#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__minix) || \ +#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__minix) || \ defined(__DragonFly__) || defined(__FreeBSD_kernel__) || defined(_AIX) - StringRef curproc("/proc/curproc/file"); + const char *curproc = "/proc/curproc/file"; char exe_path[PATH_MAX]; if (sys::fs::exists(curproc)) { - ssize_t len = readlink(curproc.str().c_str(), exe_path, sizeof(exe_path)); + ssize_t len = readlink(curproc, exe_path, sizeof(exe_path)); if (len > 0) { // Null terminate the string for realpath. readlink never null // terminates its output. @@ -238,12 +238,12 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) { // If we don't have procfs mounted, fall back to argv[0] if (getprogpath(exe_path, argv0) != NULL) return exe_path; -#elif defined(__linux__) || defined(__CYGWIN__) +#elif defined(__linux__) || defined(__CYGWIN__) || defined(__gnu_hurd__) char exe_path[MAXPATHLEN]; - StringRef aPath("/proc/self/exe"); + const char *aPath = "/proc/self/exe"; if (sys::fs::exists(aPath)) { // /proc is not always mounted under Linux (chroot for example). - ssize_t len = readlink(aPath.str().c_str(), exe_path, sizeof(exe_path)); + ssize_t len = readlink(aPath, exe_path, sizeof(exe_path)); if (len < 0) return ""; @@ -478,7 +478,7 @@ static bool is_local_impl(struct STATVFS &Vfs) { std::unique_ptr<char[]> Buf; int Tries = 3; while (Tries--) { - Buf = llvm::make_unique<char[]>(BufSize); + Buf = std::make_unique<char[]>(BufSize); Ret = mntctl(MCTL_QUERY, BufSize, Buf.get()); if (Ret != 0) break; @@ -868,7 +868,10 @@ std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) { 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. -#if defined(_DIRENT_HAVE_D_TYPE) && defined(DTTOIF) + // Note that while glibc provides a macro to see if this is supported, + // _DIRENT_HAVE_D_TYPE, it's not defined on BSD/Mac, so we test for the + // d_type-to-mode_t conversion macro instead. +#if defined(DTTOIF) return typeForMode(DTTOIF(Entry->d_type)); #else // Other platforms such as Solaris require a stat() to get the type. @@ -919,9 +922,9 @@ static int nativeOpenFlags(CreationDisposition Disp, OpenFlags Flags, else if (Access == (FA_Read | FA_Write)) Result |= O_RDWR; - // This is for compatibility with old code that assumed F_Append implied + // This is for compatibility with old code that assumed OF_Append implied // would open an existing file. See Windows/Path.inc for a longer comment. - if (Flags & F_Append) + if (Flags & OF_Append) Disp = CD_OpenAlways; if (Disp == CD_CreateNew) { @@ -936,7 +939,7 @@ static int nativeOpenFlags(CreationDisposition Disp, OpenFlags Flags, // Nothing special, just don't add O_CREAT and we get these semantics. } - if (Flags & F_Append) + if (Flags & OF_Append) Result |= O_APPEND; #ifdef O_CLOEXEC @@ -1031,44 +1034,28 @@ file_t getStdinHandle() { return 0; } file_t getStdoutHandle() { return 1; } file_t getStderrHandle() { return 2; } -std::error_code readNativeFile(file_t FD, MutableArrayRef<char> Buf, - size_t *BytesRead) { - *BytesRead = sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Buf.size()); - if (ssize_t(*BytesRead) == -1) - return std::error_code(errno, std::generic_category()); - return std::error_code(); +Expected<size_t> readNativeFile(file_t FD, MutableArrayRef<char> Buf) { + ssize_t NumRead = + sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Buf.size()); + if (ssize_t(NumRead) == -1) + return errorCodeToError(std::error_code(errno, std::generic_category())); + return NumRead; } -std::error_code readNativeFileSlice(file_t FD, MutableArrayRef<char> Buf, - size_t Offset) { - char *BufPtr = Buf.data(); - size_t BytesLeft = Buf.size(); - -#ifndef HAVE_PREAD - // If we don't have pread, seek to Offset. - if (lseek(FD, Offset, SEEK_SET) == -1) - return std::error_code(errno, std::generic_category()); -#endif - - while (BytesLeft) { +Expected<size_t> readNativeFileSlice(file_t FD, MutableArrayRef<char> Buf, + uint64_t Offset) { #ifdef HAVE_PREAD - ssize_t NumRead = sys::RetryAfterSignal(-1, ::pread, FD, BufPtr, BytesLeft, - Buf.size() - BytesLeft + Offset); + ssize_t NumRead = + sys::RetryAfterSignal(-1, ::pread, FD, Buf.data(), Buf.size(), Offset); #else - ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, BufPtr, BytesLeft); + 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(), Buf.size()); #endif - if (NumRead == -1) { - // Error while reading. - return std::error_code(errno, std::generic_category()); - } - if (NumRead == 0) { - memset(BufPtr, 0, BytesLeft); // zero-initialize rest of the buffer. - break; - } - BytesLeft -= NumRead; - BufPtr += NumRead; - } - return std::error_code(); + if (NumRead == -1) + return errorCodeToError(std::error_code(errno, std::generic_category())); + return NumRead; } std::error_code closeFile(file_t &F) { diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc index 4115ee396582..dfe81d7e2833 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc @@ -15,8 +15,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Config/config.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Mutex.h" -#include "llvm/Support/MutexGuard.h" +#include <mutex> #if HAVE_FCNTL_H #include <fcntl.h> #endif @@ -327,13 +326,13 @@ extern "C" int tigetnum(char *capname); #endif #ifdef HAVE_TERMINFO -static ManagedStatic<sys::Mutex> TermColorMutex; +static ManagedStatic<std::mutex> TermColorMutex; #endif static bool terminalHasColors(int fd) { #ifdef HAVE_TERMINFO // First, acquire a global lock because these C routines are thread hostile. - MutexGuard G(*TermColorMutex); + std::lock_guard<std::mutex> G(*TermColorMutex); int errret = 0; if (setupterm(nullptr, fd, &errret) != 0) diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Program.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Program.inc index c4123a64046f..520685a0e987 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Program.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Program.inc @@ -136,7 +136,7 @@ static bool RedirectIO_PS(const std::string *Path, int FD, std::string *ErrMsg, if (int Err = posix_spawn_file_actions_addopen( FileActions, FD, File, FD == 0 ? O_RDONLY : O_WRONLY | O_CREAT, 0666)) - return MakeErrMsg(ErrMsg, "Cannot dup2", Err); + return MakeErrMsg(ErrMsg, "Cannot posix_spawn_file_actions_addopen", Err); return false; } #endif @@ -444,7 +444,7 @@ 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::F_Text); + llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::OF_Text); if (EC) return EC; diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/RWMutex.inc b/contrib/llvm-project/llvm/lib/Support/Unix/RWMutex.inc deleted file mode 100644 index 8b47dfa0f85c..000000000000 --- a/contrib/llvm-project/llvm/lib/Support/Unix/RWMutex.inc +++ /dev/null @@ -1,50 +0,0 @@ -//= llvm/Support/Unix/RWMutex.inc - Unix Reader/Writer Mutual Exclusion Lock =// -// -// 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) RWMutex class. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic UNIX code that -//=== is guaranteed to work on *all* UNIX variants. -//===----------------------------------------------------------------------===// - -#include "llvm/Support/Mutex.h" - -namespace llvm { - -using namespace sys; - -// This naive implementation treats readers the same as writers. This -// will therefore deadlock if a thread tries to acquire a read lock -// multiple times. - -RWMutexImpl::RWMutexImpl() : data_(new MutexImpl(false)) { } - -RWMutexImpl::~RWMutexImpl() { - delete static_cast<MutexImpl *>(data_); -} - -bool RWMutexImpl::reader_acquire() { - return static_cast<MutexImpl *>(data_)->acquire(); -} - -bool RWMutexImpl::reader_release() { - return static_cast<MutexImpl *>(data_)->release(); -} - -bool RWMutexImpl::writer_acquire() { - return static_cast<MutexImpl *>(data_)->acquire(); -} - -bool RWMutexImpl::writer_release() { - return static_cast<MutexImpl *>(data_)->release(); -} - -} diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc index 634c16aa36c7..f68374d29f02 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc @@ -43,7 +43,6 @@ #include "llvm/Support/Mutex.h" #include "llvm/Support/Program.h" #include "llvm/Support/SaveAndRestore.h" -#include "llvm/Support/UniqueLock.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <string> @@ -89,6 +88,9 @@ static std::atomic<SignalHandlerFunctionType> InterruptFunction = ATOMIC_VAR_INIT(nullptr); static std::atomic<SignalHandlerFunctionType> InfoSignalFunction = ATOMIC_VAR_INIT(nullptr); +/// The function to call on SIGPIPE (one-time use only). +static std::atomic<SignalHandlerFunctionType> OneShotPipeSignalFunction = + ATOMIC_VAR_INIT(nullptr); namespace { /// Signal-safe removal of files. @@ -207,7 +209,7 @@ static StringRef Argv0; /// 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, SIGPIPE, SIGTERM, SIGUSR2 + SIGHUP, SIGINT, SIGTERM, SIGUSR2 }; /// Signals that represent that we have a bug, and our prompt termination has @@ -238,7 +240,7 @@ static const int InfoSigs[] = { static const size_t NumSigs = array_lengthof(IntSigs) + array_lengthof(KillSigs) + - array_lengthof(InfoSigs); + array_lengthof(InfoSigs) + 1 /* SIGPIPE */; static std::atomic<unsigned> NumRegisteredSignals = ATOMIC_VAR_INIT(0); @@ -323,6 +325,8 @@ static void RegisterHandlers() { // Not signal-safe. registerHandler(S, SignalKind::IsKill); for (auto S : KillSigs) registerHandler(S, SignalKind::IsKill); + if (OneShotPipeSignalFunction) + registerHandler(SIGPIPE, SignalKind::IsKill); for (auto S : InfoSigs) registerHandler(S, SignalKind::IsInfo); } @@ -341,6 +345,22 @@ static void RemoveFilesToRemove() { FileToRemoveList::removeAllFiles(FilesToRemove); } +void sys::CleanupOnSignal(uintptr_t Context) { + int Sig = (int)Context; + + if (llvm::is_contained(InfoSigs, Sig)) { + InfoSignalHandler(Sig); + return; + } + + RemoveFilesToRemove(); + + if (llvm::is_contained(IntSigs, Sig) || Sig == SIGPIPE) + return; + + llvm::sys::RunSignalHandlers(); +} + // The signal handler that runs. static RETSIGTYPE SignalHandler(int Sig) { // Restore the signal behavior to default, so that the program actually @@ -357,15 +377,16 @@ static RETSIGTYPE SignalHandler(int Sig) { { RemoveFilesToRemove(); + if (Sig == SIGPIPE) + if (auto OldOneShotPipeFunction = + OneShotPipeSignalFunction.exchange(nullptr)) + return OldOneShotPipeFunction(); + if (std::find(std::begin(IntSigs), std::end(IntSigs), Sig) != std::end(IntSigs)) { if (auto OldInterruptFunction = InterruptFunction.exchange(nullptr)) return OldInterruptFunction(); - // Send a special return code that drivers can check for, from sysexits.h. - if (Sig == SIGPIPE) - exit(EX_IOERR); - raise(Sig); // Execute the default handler. return; } @@ -404,6 +425,16 @@ void llvm::sys::SetInfoSignalFunction(void (*Handler)()) { RegisterHandlers(); } +void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) { + OneShotPipeSignalFunction.exchange(Handler); + RegisterHandlers(); +} + +void llvm::sys::DefaultOneShotPipeSignalHandler() { + // 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) { diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc index ed9a96563055..afb887fc1096 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc @@ -10,6 +10,8 @@ // //===----------------------------------------------------------------------===// +#include "Unix.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" @@ -40,47 +42,56 @@ #include <unistd.h> // For syscall() #endif -namespace { - struct ThreadInfo { - void(*UserFn)(void *); - void *UserData; - }; +static void *threadFuncSync(void *Arg) { + SyncThreadInfo *TI = static_cast<SyncThreadInfo *>(Arg); + TI->UserFn(TI->UserData); + return nullptr; } -static void *ExecuteOnThread_Dispatch(void *Arg) { - ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg); - TI->UserFn(TI->UserData); +static void *threadFuncAsync(void *Arg) { + std::unique_ptr<AsyncThreadInfo> Info(static_cast<AsyncThreadInfo *>(Arg)); + (*Info)(); return nullptr; } -void llvm::llvm_execute_on_thread(void(*Fn)(void*), void *UserData, - unsigned RequestedStackSize) { - ThreadInfo Info = { Fn, UserData }; - pthread_attr_t Attr; - pthread_t Thread; +static void +llvm_execute_on_thread_impl(void *(*ThreadFunc)(void *), void *Arg, + llvm::Optional<unsigned> StackSizeInBytes, + JoiningPolicy JP) { + int errnum; // Construct the attributes object. - if (::pthread_attr_init(&Attr) != 0) - return; + pthread_attr_t Attr; + if ((errnum = ::pthread_attr_init(&Attr)) != 0) { + ReportErrnumFatal("pthread_attr_init failed", errnum); + } + + auto AttrGuard = llvm::make_scope_exit([&] { + if ((errnum = ::pthread_attr_destroy(&Attr)) != 0) { + ReportErrnumFatal("pthread_attr_destroy failed", errnum); + } + }); // Set the requested stack size, if given. - if (RequestedStackSize != 0) { - if (::pthread_attr_setstacksize(&Attr, RequestedStackSize) != 0) - goto error; + if (StackSizeInBytes) { + if ((errnum = ::pthread_attr_setstacksize(&Attr, *StackSizeInBytes)) != 0) { + ReportErrnumFatal("pthread_attr_setstacksize failed", errnum); + } } // Construct and execute the thread. - if (::pthread_create(&Thread, &Attr, ExecuteOnThread_Dispatch, &Info) != 0) - goto error; - - // Wait for the thread and clean up. - ::pthread_join(Thread, nullptr); + pthread_t Thread; + if ((errnum = ::pthread_create(&Thread, &Attr, ThreadFunc, Arg)) != 0) + ReportErrnumFatal("pthread_create failed", errnum); -error: - ::pthread_attr_destroy(&Attr); + if (JP == JoiningPolicy::Join) { + // Wait for the thread + if ((errnum = ::pthread_join(Thread, nullptr)) != 0) { + ReportErrnumFatal("pthread_join failed", errnum); + } + } } - uint64_t llvm::get_threadid() { #if defined(__APPLE__) // Calling "mach_thread_self()" bumps the reference count on the thread diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Unix.h b/contrib/llvm-project/llvm/lib/Support/Unix/Unix.h index 86309b0567f5..1fc9a414f749 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Unix.h +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Unix.h @@ -21,6 +21,7 @@ #include "llvm/Config/config.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/Errno.h" +#include "llvm/Support/ErrorHandling.h" #include <algorithm> #include <assert.h> #include <cerrno> @@ -69,6 +70,14 @@ static inline bool MakeErrMsg( return true; } +// Include StrError(errnum) in a fatal error message. +LLVM_ATTRIBUTE_NORETURN static inline void ReportErrnumFatal(const char *Msg, + int errnum) { + std::string ErrMsg; + MakeErrMsg(&ErrMsg, Msg, errnum); + llvm::report_fatal_error(ErrMsg); +} + namespace llvm { namespace sys { |
