diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/Unix')
9 files changed, 185 insertions, 126 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc index 79b1759359e1..a0927da50e48 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc @@ -42,7 +42,9 @@ extern "C" void sys_icache_invalidate(const void *Addr, size_t len); extern "C" void __clear_cache(void *, void*); #endif -static int getPosixProtectionFlags(unsigned Flags) { +namespace { + +int getPosixProtectionFlags(unsigned Flags) { switch (Flags & llvm::sys::Memory::MF_RWE_MASK) { case llvm::sys::Memory::MF_READ: return PROT_READ; @@ -74,6 +76,8 @@ static int getPosixProtectionFlags(unsigned Flags) { return PROT_NONE; } +} // anonymous namespace + namespace llvm { namespace sys { @@ -172,7 +176,7 @@ Memory::releaseMappedMemory(MemoryBlock &M) { std::error_code Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) { - static const Align PageSize = Align(Process::getPageSizeEstimate()); + static const size_t PageSize = Process::getPageSizeEstimate(); if (M.Address == nullptr || M.AllocatedSize == 0) return std::error_code(); @@ -180,8 +184,8 @@ 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((uint8_t *)M.Address - PageSize + 1, PageSize); + uintptr_t End = alignAddr((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 new file mode 100644 index 000000000000..2c982b38d6ff --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Mutex.inc @@ -0,0 +1,42 @@ +//===- 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 2a03dc682bce..a64ef8a6da3a 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 in all supported versions, - // fall back to finding the ELF auxiliary vectors after the process's + // elf_aux_info(AT_EXECPATH, ... is not available on older FreeBSD. Fall + // back to finding the ELF auxiliary vectors after the processes'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) - const char *curproc = "/proc/curproc/file"; + StringRef curproc("/proc/curproc/file"); char exe_path[PATH_MAX]; if (sys::fs::exists(curproc)) { - ssize_t len = readlink(curproc, exe_path, sizeof(exe_path)); + ssize_t len = readlink(curproc.str().c_str(), 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__) || defined(__gnu_hurd__) +#elif defined(__linux__) || defined(__CYGWIN__) char exe_path[MAXPATHLEN]; - const char *aPath = "/proc/self/exe"; + StringRef aPath("/proc/self/exe"); if (sys::fs::exists(aPath)) { // /proc is not always mounted under Linux (chroot for example). - ssize_t len = readlink(aPath, exe_path, sizeof(exe_path)); + ssize_t len = readlink(aPath.str().c_str(), 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 = std::make_unique<char[]>(BufSize); + Buf = llvm::make_unique<char[]>(BufSize); Ret = mntctl(MCTL_QUERY, BufSize, Buf.get()); if (Ret != 0) break; @@ -868,10 +868,7 @@ 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. - // 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) +#if defined(_DIRENT_HAVE_D_TYPE) && defined(DTTOIF) return typeForMode(DTTOIF(Entry->d_type)); #else // Other platforms such as Solaris require a stat() to get the type. @@ -922,9 +919,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 OF_Append implied + // This is for compatibility with old code that assumed F_Append implied // would open an existing file. See Windows/Path.inc for a longer comment. - if (Flags & OF_Append) + if (Flags & F_Append) Disp = CD_OpenAlways; if (Disp == CD_CreateNew) { @@ -939,7 +936,7 @@ static int nativeOpenFlags(CreationDisposition Disp, OpenFlags Flags, // Nothing special, just don't add O_CREAT and we get these semantics. } - if (Flags & OF_Append) + if (Flags & F_Append) Result |= O_APPEND; #ifdef O_CLOEXEC @@ -1034,28 +1031,44 @@ file_t getStdinHandle() { return 0; } file_t getStdoutHandle() { return 1; } file_t getStderrHandle() { return 2; } -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 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> readNativeFileSlice(file_t FD, MutableArrayRef<char> Buf, - uint64_t Offset) { +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) { #ifdef HAVE_PREAD - ssize_t NumRead = - sys::RetryAfterSignal(-1, ::pread, FD, Buf.data(), Buf.size(), Offset); + ssize_t NumRead = sys::RetryAfterSignal(-1, ::pread, FD, BufPtr, BytesLeft, + Buf.size() - BytesLeft + Offset); #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(), Buf.size()); + ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, BufPtr, BytesLeft); #endif - if (NumRead == -1) - return errorCodeToError(std::error_code(errno, std::generic_category())); - return NumRead; + 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(); } 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 dfe81d7e2833..4115ee396582 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc @@ -15,7 +15,8 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Config/config.h" #include "llvm/Support/ManagedStatic.h" -#include <mutex> +#include "llvm/Support/Mutex.h" +#include "llvm/Support/MutexGuard.h" #if HAVE_FCNTL_H #include <fcntl.h> #endif @@ -326,13 +327,13 @@ extern "C" int tigetnum(char *capname); #endif #ifdef HAVE_TERMINFO -static ManagedStatic<std::mutex> TermColorMutex; +static ManagedStatic<sys::Mutex> TermColorMutex; #endif static bool terminalHasColors(int fd) { #ifdef HAVE_TERMINFO // First, acquire a global lock because these C routines are thread hostile. - std::lock_guard<std::mutex> G(*TermColorMutex); + MutexGuard 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 520685a0e987..c4123a64046f 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 posix_spawn_file_actions_addopen", Err); + return MakeErrMsg(ErrMsg, "Cannot dup2", 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::OF_Text); + llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::F_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 new file mode 100644 index 000000000000..8b47dfa0f85c --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Support/Unix/RWMutex.inc @@ -0,0 +1,50 @@ +//= 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 f68374d29f02..634c16aa36c7 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc @@ -43,6 +43,7 @@ #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> @@ -88,9 +89,6 @@ 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. @@ -209,7 +207,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, SIGTERM, SIGUSR2 + SIGHUP, SIGINT, SIGPIPE, SIGTERM, SIGUSR2 }; /// Signals that represent that we have a bug, and our prompt termination has @@ -240,7 +238,7 @@ static const int InfoSigs[] = { static const size_t NumSigs = array_lengthof(IntSigs) + array_lengthof(KillSigs) + - array_lengthof(InfoSigs) + 1 /* SIGPIPE */; + array_lengthof(InfoSigs); static std::atomic<unsigned> NumRegisteredSignals = ATOMIC_VAR_INIT(0); @@ -325,8 +323,6 @@ 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); } @@ -345,22 +341,6 @@ 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 @@ -377,16 +357,15 @@ 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; } @@ -425,16 +404,6 @@ 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 afb887fc1096..ed9a96563055 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc @@ -10,8 +10,6 @@ // //===----------------------------------------------------------------------===// -#include "Unix.h" -#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" @@ -42,56 +40,47 @@ #include <unistd.h> // For syscall() #endif -static void *threadFuncSync(void *Arg) { - SyncThreadInfo *TI = static_cast<SyncThreadInfo *>(Arg); - TI->UserFn(TI->UserData); - return nullptr; +namespace { + struct ThreadInfo { + void(*UserFn)(void *); + void *UserData; + }; } -static void *threadFuncAsync(void *Arg) { - std::unique_ptr<AsyncThreadInfo> Info(static_cast<AsyncThreadInfo *>(Arg)); - (*Info)(); +static void *ExecuteOnThread_Dispatch(void *Arg) { + ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg); + TI->UserFn(TI->UserData); return nullptr; } -static void -llvm_execute_on_thread_impl(void *(*ThreadFunc)(void *), void *Arg, - llvm::Optional<unsigned> StackSizeInBytes, - JoiningPolicy JP) { - int errnum; - - // Construct the attributes object. +void llvm::llvm_execute_on_thread(void(*Fn)(void*), void *UserData, + unsigned RequestedStackSize) { + ThreadInfo Info = { Fn, UserData }; pthread_attr_t Attr; - if ((errnum = ::pthread_attr_init(&Attr)) != 0) { - ReportErrnumFatal("pthread_attr_init failed", errnum); - } + pthread_t Thread; - auto AttrGuard = llvm::make_scope_exit([&] { - if ((errnum = ::pthread_attr_destroy(&Attr)) != 0) { - ReportErrnumFatal("pthread_attr_destroy failed", errnum); - } - }); + // Construct the attributes object. + if (::pthread_attr_init(&Attr) != 0) + return; // Set the requested stack size, if given. - if (StackSizeInBytes) { - if ((errnum = ::pthread_attr_setstacksize(&Attr, *StackSizeInBytes)) != 0) { - ReportErrnumFatal("pthread_attr_setstacksize failed", errnum); - } + if (RequestedStackSize != 0) { + if (::pthread_attr_setstacksize(&Attr, RequestedStackSize) != 0) + goto error; } // Construct and execute the thread. - pthread_t Thread; - if ((errnum = ::pthread_create(&Thread, &Attr, ThreadFunc, Arg)) != 0) - ReportErrnumFatal("pthread_create failed", errnum); + if (::pthread_create(&Thread, &Attr, ExecuteOnThread_Dispatch, &Info) != 0) + goto error; - if (JP == JoiningPolicy::Join) { - // Wait for the thread - if ((errnum = ::pthread_join(Thread, nullptr)) != 0) { - ReportErrnumFatal("pthread_join failed", errnum); - } - } + // Wait for the thread and clean up. + ::pthread_join(Thread, nullptr); + +error: + ::pthread_attr_destroy(&Attr); } + 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 1fc9a414f749..86309b0567f5 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Unix.h +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Unix.h @@ -21,7 +21,6 @@ #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> @@ -70,14 +69,6 @@ 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 { |
