[llvm] r296887 - [Support] Provide access to current thread name/thread id.

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 3 13:05:11 PST 2017


Ok, let me come up with something then.

-Krzysztof

On 3/3/2017 2:59 PM, Zachary Turner wrote:
> Although I suppose checking for the existence of the functions would be
> even better.  I don't have access to that kind of system though, so if
> it's easy and you think you can get a patch that checks for the
> existence of the functions in CMake, perhaps that would be better.
>
> On Fri, Mar 3, 2017 at 12:58 PM Zachary Turner <zturner at google.com
> <mailto:zturner at google.com>> wrote:
>
>     Can we can just check for glibc version inside of the #ifdef
>     __linux__ branch and then do nothing if the glibc version is too
>     small?
>
>     On Fri, Mar 3, 2017 at 12:52 PM Krzysztof Parzyszek
>     <kparzysz at codeaurora.org <mailto:kparzysz at codeaurora.org>> wrote:
>
>         These are our local builds on SUSE 11.4 (glibc 2.11.3). The
>         functions
>         are pthread_setname_np and pthread_getname_np.
>
>         It should be fine if the functions you added do nothing on that
>         system,
>         as long as the code compiles.
>
>         If you don't have access to this kind of OS, I could come up
>         with some
>         patch (test for these functions in cmake).
>
>         -Krzysztof
>
>
>         On 3/3/2017 2:42 PM, Zachary Turner wrote:
>         > Which function does it not provide specifically?  Can you link
>         me to a
>         > failing buildbot?
>         >
>         > On Fri, Mar 3, 2017 at 11:01 AM Krzysztof Parzyszek via
>         llvm-commits
>         > <llvm-commits at lists.llvm.org
>         <mailto:llvm-commits at lists.llvm.org>
>         <mailto:llvm-commits at lists.llvm.org
>         <mailto:llvm-commits at lists.llvm.org>>> wrote:
>         >
>         >     This thing fails to build on older Linuxes (e.g. SUSE).
>         >     Glibc 2.11.3 does not provide this function.
>         >
>         >     This breaks some of our builds.
>         >
>         >     -Krzysztof
>         >
>         >
>         >     On 3/3/2017 11:15 AM, Zachary Turner via llvm-commits wrote:
>         >     > Author: zturner
>         >     > Date: Fri Mar  3 11:15:17 2017
>         >     > New Revision: 296887
>         >     >
>         >     > URL: http://llvm.org/viewvc/llvm-project?rev=296887&view=rev
>         >     > Log:
>         >     > [Support] Provide access to current thread name/thread id.
>         >     >
>         >     > Applications often need the current thread id when making
>         >     > system calls, and some operating systems provide the notion
>         >     > of a thread name, which can be useful in enabling better
>         >     > diagnostics when debugging or logging.
>         >     >
>         >     > This patch adds an accessor for the thread id, and "best
>         effort"
>         >     > getters and setters for the thread name.  Since this is
>         >     > non critical functionality, no error is returned to indicate
>         >     > that a platform doesn't support thread names.
>         >     >
>         >     > Differential Revision: https://reviews.llvm.org/D30526
>         >     >
>         >     > Added:
>         >     >     llvm/trunk/lib/Support/Unix/Threading.inc
>         >     >     llvm/trunk/lib/Support/Windows/Threading.inc
>         >     > Modified:
>         >     >     llvm/trunk/include/llvm/Support/Threading.h
>         >     >     llvm/trunk/lib/Support/Threading.cpp
>         >     >
>         >     > Modified: llvm/trunk/include/llvm/Support/Threading.h
>         >     > URL:
>         >
>          http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Threading.h?rev=296887&r1=296886&r2=296887&view=diff
>         >     >
>         >
>          ==============================================================================
>         >     > --- llvm/trunk/include/llvm/Support/Threading.h (original)
>         >     > +++ llvm/trunk/include/llvm/Support/Threading.h Fri Mar  3
>         >     11:15:17 2017
>         >     > @@ -15,6 +15,7 @@
>         >     >  #ifndef LLVM_SUPPORT_THREADING_H
>         >     >  #define LLVM_SUPPORT_THREADING_H
>         >     >
>         >     > +#include "llvm/ADT/SmallVector.h"
>         >     >  #include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
>         >     >  #include "llvm/Support/Compiler.h"
>         >     >  #include <ciso646> // So we can check the C++ standard
>         lib macros.
>         >     > @@ -42,24 +43,26 @@
>         >     >  #endif
>         >     >
>         >     >  namespace llvm {
>         >     > -  /// Returns true if LLVM is compiled with support for
>         >     multi-threading, and
>         >     > -  /// false otherwise.
>         >     > -  bool llvm_is_multithreaded();
>         >     > -
>         >     > -  /// llvm_execute_on_thread - Execute the given \p
>         UserFn on a
>         >     separate
>         >     > -  /// thread, passing it the provided \p UserData and
>         waits for
>         >     thread
>         >     > -  /// completion.
>         >     > -  ///
>         >     > -  /// This function does not guarantee that the code will
>         >     actually be executed
>         >     > -  /// on a separate thread or honoring the requested
>         stack size,
>         >     but tries to do
>         >     > -  /// so where system support is available.
>         >     > -  ///
>         >     > -  /// \param UserFn - The callback to execute.
>         >     > -  /// \param UserData - An argument to pass to the
>         callback function.
>         >     > -  /// \param RequestedStackSize - If non-zero, a
>         requested size
>         >     (in bytes) for
>         >     > -  /// the thread stack.
>         >     > -  void llvm_execute_on_thread(void (*UserFn)(void*),
>         void *UserData,
>         >     > -                              unsigned
>         RequestedStackSize = 0);
>         >     > +class Twine;
>         >     > +
>         >     > +/// Returns true if LLVM is compiled with support for
>         >     multi-threading, and
>         >     > +/// false otherwise.
>         >     > +bool llvm_is_multithreaded();
>         >     > +
>         >     > +/// llvm_execute_on_thread - Execute the given \p
>         UserFn on a
>         >     separate
>         >     > +/// thread, passing it the provided \p UserData and
>         waits for thread
>         >     > +/// completion.
>         >     > +///
>         >     > +/// This function does not guarantee that the code will
>         actually
>         >     be executed
>         >     > +/// on a separate thread or honoring the requested
>         stack size,
>         >     but tries to do
>         >     > +/// so where system support is available.
>         >     > +///
>         >     > +/// \param UserFn - The callback to execute.
>         >     > +/// \param UserData - An argument to pass to the
>         callback function.
>         >     > +/// \param RequestedStackSize - If non-zero, a
>         requested size (in
>         >     bytes) for
>         >     > +/// the thread stack.
>         >     > +void llvm_execute_on_thread(void (*UserFn)(void *),
>         void *UserData,
>         >     > +                            unsigned RequestedStackSize
>         = 0);
>         >     >
>         >     >  #if LLVM_THREADING_USE_STD_CALL_ONCE
>         >     >
>         >     > @@ -127,6 +130,28 @@ namespace llvm {
>         >     >    /// thread::hardware_concurrency().
>         >     >    /// Returns 1 when LLVM is configured with
>         LLVM_ENABLE_THREADS=OFF
>         >     >    unsigned heavyweight_hardware_concurrency();
>         >     > +
>         >     > +  /// \brief Return the current thread id, as used in
>         various OS
>         >     system calls.
>         >     > +  /// Note that not all platforms guarantee that the value
>         >     returned will be
>         >     > +  /// unique across the entire system, so portable code
>         should
>         >     not assume
>         >     > +  /// this.
>         >     > +  uint64_t get_threadid();
>         >     > +
>         >     > +  /// \brief Set the name of the current thread.  Setting a
>         >     thread's name can
>         >     > +  /// be helpful for enabling useful diagnostics under
>         a debugger
>         >     or when
>         >     > +  /// logging.  The level of support for setting a
>         thread's name
>         >     varies
>         >     > +  /// wildly across operating systems, and we only make
>         a best
>         >     effort to
>         >     > +  /// perform the operation on supported platforms.  No
>         >     indication of success
>         >     > +  /// or failure is returned.
>         >     > +  void set_thread_name(const Twine &Name);
>         >     > +
>         >     > +  /// \brief Get the name of the current thread.  The
>         level of
>         >     support for
>         >     > +  /// getting a thread's name varies wildly across
>         operating
>         >     systems, and it
>         >     > +  /// is not even guaranteed that if you can
>         successfully set a
>         >     thread's name
>         >     > +  /// that you can later get it back.  This function is
>         intended
>         >     for diagnostic
>         >     > +  /// purposes, and as with setting a thread's name no
>         indication
>         >     of whether
>         >     > +  /// the operation succeeded or failed is returned.
>         >     > +  void get_thread_name(SmallVectorImpl<char> &Name);
>         >     >  }
>         >     >
>         >     >  #endif
>         >     >
>         >     > Modified: llvm/trunk/lib/Support/Threading.cpp
>         >     > URL:
>         >
>          http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Threading.cpp?rev=296887&r1=296886&r2=296887&view=diff
>         >     >
>         >
>          ==============================================================================
>         >     > --- llvm/trunk/lib/Support/Threading.cpp (original)
>         >     > +++ llvm/trunk/lib/Support/Threading.cpp Fri Mar  3
>         11:15:17 2017
>         >     > @@ -14,14 +14,21 @@
>         >     >
>         >     >  #include "llvm/Support/Threading.h"
>         >     >  #include "llvm/Config/config.h"
>         >     > -#include "llvm/Support/Atomic.h"
>         >     >  #include "llvm/Support/Host.h"
>         >     > -#include "llvm/Support/Mutex.h"
>         >     >  #include "llvm/Support/thread.h"
>         >     > +
>         >     >  #include <cassert>
>         >     > +#include <errno.h>
>         >     > +#include <stdlib.h>
>         >     > +#include <string.h>
>         >     >
>         >     >  using namespace llvm;
>         >     >
>         >     >
>         >
>          +//===----------------------------------------------------------------------===//
>         >     > +//=== WARNING: Implementation here must contain only TRULY
>         >     operating system
>         >     > +//===          independent code.
>         >     >
>         >
>          +//===----------------------------------------------------------------------===//
>         >     > +
>         >     >  bool llvm::llvm_is_multithreaded() {
>         >     >  #if LLVM_ENABLE_THREADS != 0
>         >     >    return true;
>         >     > @@ -30,100 +37,38 @@ bool llvm::llvm_is_multithreaded() {
>         >     >  #endif
>         >     >  }
>         >     >
>         >     > -#if LLVM_ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H)
>         >     > -#include <pthread.h>
>         >     > -
>         >     > -struct ThreadInfo {
>         >     > -  void (*UserFn)(void *);
>         >     > -  void *UserData;
>         >     > -};
>         >     > -static void *ExecuteOnThread_Dispatch(void *Arg) {
>         >     > -  ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg);
>         >     > -  TI->UserFn(TI->UserData);
>         >     > -  return nullptr;
>         >     > -}
>         >     > -
>         >     > -void llvm::llvm_execute_on_thread(void (*Fn)(void*),
>         void *UserData,
>         >     > +#if LLVM_ENABLE_THREADS == 0 ||
>         >                   \
>         >     > +    (!defined(LLVM_ON_WIN32) && !defined(HAVE_PTHREAD_H))
>         >     > +// Support for non-Win32, non-pthread implementation.
>         >     > +void llvm::llvm_execute_on_thread(void (*Fn)(void *),
>         void *UserData,
>         >     >                                    unsigned
>         RequestedStackSize) {
>         >     > -  ThreadInfo Info = { Fn, UserData };
>         >     > -  pthread_attr_t Attr;
>         >     > -  pthread_t Thread;
>         >     > -
>         >     > -  // Construct the attributes object.
>         >     > -  if (::pthread_attr_init(&Attr) != 0)
>         >     > -    return;
>         >     > -
>         >     > -  // Set the requested stack size, if given.
>         >     > -  if (RequestedStackSize != 0) {
>         >     > -    if (::pthread_attr_setstacksize(&Attr,
>         RequestedStackSize) != 0)
>         >     > -      goto error;
>         >     > -  }
>         >     > -
>         >     > -  // 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);
>         >     > -
>         >     > - error:
>         >     > -  ::pthread_attr_destroy(&Attr);
>         >     > +  (void)RequestedStackSize;
>         >     > +  Fn(UserData);
>         >     >  }
>         >     > -#elif LLVM_ENABLE_THREADS!=0 && defined(LLVM_ON_WIN32)
>         >     > -#include "Windows/WindowsSupport.h"
>         >     > -#include <process.h>
>         >     > -
>         >     > -// Windows will at times define MemoryFence.
>         >     > -#ifdef MemoryFence
>         >     > -#undef MemoryFence
>         >     > -#endif
>         >     >
>         >     > -struct ThreadInfo {
>         >     > -  void (*func)(void*);
>         >     > -  void *param;
>         >     > -};
>         >     > -
>         >     > -static unsigned __stdcall ThreadCallback(void *param) {
>         >     > -  struct ThreadInfo *info = reinterpret_cast<struct
>         ThreadInfo
>         >     *>(param);
>         >     > -  info->func(info->param);
>         >     > +unsigned llvm::heavyweight_hardware_concurrency() {
>         return 1; }
>         >     >
>         >     > -  return 0;
>         >     > -}
>         >     > +uint64_t llvm::get_threadid_np() { return 0; }
>         >     >
>         >     > -void llvm::llvm_execute_on_thread(void (*Fn)(void*),
>         void *UserData,
>         >     > -                                  unsigned
>         RequestedStackSize) {
>         >     > -  struct ThreadInfo param = { Fn, UserData };
>         >     > +void llvm::set_thread_name(const Twine &Name) {}
>         >     >
>         >     > -  HANDLE hThread = (HANDLE)::_beginthreadex(NULL,
>         >     > -
>         RequestedStackSize,
>         >     ThreadCallback,
>         >     > -                                            &param, 0,
>         NULL);
>         >     > -
>         >     > -  if (hThread) {
>         >     > -    // We actually don't care whether the wait succeeds
>         or fails, in
>         >     > -    // the same way we don't care whether the
>         pthread_join call
>         >     succeeds
>         >     > -    // or fails.  There's not much we could do if this
>         were to
>         >     fail. But
>         >     > -    // on success, this call will wait until the thread
>         finishes
>         >     executing
>         >     > -    // before returning.
>         >     > -    (void)::WaitForSingleObject(hThread, INFINITE);
>         >     > -    ::CloseHandle(hThread);
>         >     > -  }
>         >     > -}
>         >     > -#else
>         >     > -// Support for non-Win32, non-pthread implementation.
>         >     > -void llvm::llvm_execute_on_thread(void (*Fn)(void*),
>         void *UserData,
>         >     > -                                  unsigned
>         RequestedStackSize) {
>         >     > -  (void) RequestedStackSize;
>         >     > -  Fn(UserData);
>         >     > -}
>         >     > +void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
>         >     Name.clear(); }
>         >     >
>         >     > -#endif
>         >     > +#else
>         >     >
>         >     >  unsigned llvm::heavyweight_hardware_concurrency() {
>         >     > -#if !LLVM_ENABLE_THREADS
>         >     > -  return 1;
>         >     > -#endif
>         >     >    int NumPhysical = sys::getHostNumPhysicalCores();
>         >     >    if (NumPhysical == -1)
>         >     >      return thread::hardware_concurrency();
>         >     >    return NumPhysical;
>         >     >  }
>         >     > +
>         >     > +// Include the platform-specific parts of this class.
>         >     > +#ifdef LLVM_ON_UNIX
>         >     > +#include "Unix/Threading.inc"
>         >     > +#endif
>         >     > +#ifdef LLVM_ON_WIN32
>         >     > +#include "Windows/Threading.inc"
>         >     > +#endif
>         >     > +
>         >     > +#endif
>         >     >
>         >     > Added: llvm/trunk/lib/Support/Unix/Threading.inc
>         >     > URL:
>         >
>          http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Threading.inc?rev=296887&view=auto
>         >     >
>         >
>          ==============================================================================
>         >     > --- llvm/trunk/lib/Support/Unix/Threading.inc (added)
>         >     > +++ llvm/trunk/lib/Support/Unix/Threading.inc Fri Mar  3
>         11:15:17 2017
>         >     > @@ -0,0 +1,181 @@
>         >     > +//===- Unix/Threading.inc - Unix Threading
>         Implementation -----
>         >     -*- C++ -*-===//
>         >     > +//
>         >     > +//                     The LLVM Compiler Infrastructure
>         >     > +//
>         >     > +// This file is distributed under the University of
>         Illinois Open
>         >     Source
>         >     > +// License. See LICENSE.TXT for details.
>         >     > +//
>         >     >
>         >
>          +//===----------------------------------------------------------------------===//
>         >     > +//
>         >     > +// This file provides the Unix specific implementation of
>         >     Threading functions.
>         >     > +//
>         >     >
>         >
>          +//===----------------------------------------------------------------------===//
>         >     > +
>         >     > +#include "llvm/ADT/SmallString.h"
>         >     > +#include "llvm/ADT/Twine.h"
>         >     > +
>         >     > +#if defined(__APPLE__)
>         >     > +#include <mach/mach_init.h>
>         >     > +#include <mach/mach_port.h>
>         >     > +#endif
>         >     > +
>         >     > +#include <pthread.h>
>         >     > +
>         >     > +#if defined(__FreeBSD__)
>         >     > +#include <pthread_np.h>
>         >     > +#endif
>         >     > +
>         >     > +#if defined(__NetBSD__)
>         >     > +#include <lwp.h>
>         >     > +#endif
>         >     > +
>         >     > +#if defined(__linux__)
>         >     > +#include <sys/syscall.h>
>         >     > +#endif
>         >     > +
>         >     > +#if defined(__NetBSD__) || defined(__FreeBSD__) ||
>         >     defined(__FreeBSD_kernel__)
>         >     > +#include <sys/sysctl.h>
>         >     > +#include <sys/user.h>
>         >     > +#endif
>         >     > +
>         >     > +namespace {
>         >     > +  struct ThreadInfo {
>         >     > +    void(*UserFn)(void *);
>         >     > +    void *UserData;
>         >     > +  };
>         >     > +}
>         >     > +
>         >     > +static void *ExecuteOnThread_Dispatch(void *Arg) {
>         >     > +  ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg);
>         >     > +  TI->UserFn(TI->UserData);
>         >     > +  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;
>         >     > +
>         >     > +  // Construct the attributes object.
>         >     > +  if (::pthread_attr_init(&Attr) != 0)
>         >     > +    return;
>         >     > +
>         >     > +  // Set the requested stack size, if given.
>         >     > +  if (RequestedStackSize != 0) {
>         >     > +    if (::pthread_attr_setstacksize(&Attr,
>         RequestedStackSize) != 0)
>         >     > +      goto error;
>         >     > +  }
>         >     > +
>         >     > +  // 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);
>         >     > +
>         >     > +error:
>         >     > +  ::pthread_attr_destroy(&Attr);
>         >     > +}
>         >     > +
>         >     > +
>         >     > +uint64_t llvm::get_threadid() {
>         >     > +#if defined(__APPLE__)
>         >     > +  // Calling "mach_thread_self()" bumps the reference
>         count on
>         >     the thread
>         >     > +  // port, so we need to deallocate it.
>         mach_task_self() doesn't
>         >     bump the ref
>         >     > +  // count.
>         >     > +  thread_port_t Self = mach_thread_self();
>         >     > +  mach_port_deallocate(mach_task_self(), Self);
>         >     > +  return Self;
>         >     > +#elif defined(__FreeBSD__)
>         >     > +  return uint64_t(pthread_getthreadid_np());
>         >     > +#elif defined(__NetBSD__)
>         >     > +  return uint64_t(_lwp_self());
>         >     > +#elif defined(__ANDROID__)
>         >     > +  return uint64_t(gettid());
>         >     > +#elif defined(__linux__)
>         >     > +  return uint64_t(syscall(SYS_gettid));
>         >     > +#elif defined(LLVM_ON_WIN32)
>         >     > +  return uint64_t(::GetCurrentThreadId());
>         >     > +#else
>         >     > +  return uint64_t(pthread_self());
>         >     > +#endif
>         >     > +}
>         >     > +
>         >     > +
>         >     > +void llvm::set_thread_name(const Twine &Name) {
>         >     > +  // Make sure the input is null terminated.
>         >     > +  SmallString<64> Storage;
>         >     > +  StringRef NameStr =
>         Name.toNullTerminatedStringRef(Storage);
>         >     > +#if defined(__linux__)
>         >     > +#if (defined(__GLIBC__) && defined(_GNU_SOURCE)) ||
>         >     defined(__ANDROID__)
>         >     > +  ::pthread_setname_np(::pthread_self(), NameStr.data());
>         >     > +#endif
>         >     > +#elif defined(__FreeBSD__)
>         >     > +  ::pthread_set_name_np(::pthread_self(), NameStr.data());
>         >     > +#elif defined(__NetBSD__)
>         >     > +  ::pthread_setname_np(::pthread_self(), "%s",
>         >     > +    const_cast<char *>(NameStr.data()));
>         >     > +#elif defined(__APPLE__)
>         >     > +  ::pthread_setname_np(NameStr.data());
>         >     > +#endif
>         >     > +}
>         >     > +
>         >     > +void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
>         >     > +  Name.clear();
>         >     > +
>         >     > +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
>         >     > +#if defined(__FreeBSD_kernel__)
>         >     > +  int pid = ::pthread_self();
>         >     > +#else
>         >     > +  int pid = ::getpid();
>         >     > +#endif
>         >     > +
>         >     > +  int tid = ::pthread_getthreadid_np();
>         >     > +
>         >     > +  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 };
>         >     > +
>         >     > +  while (1) {
>         >     > +    error = sysctl(ctl, 4, kp, &len, nullptr, 0);
>         >     > +    if (kp == nullptr || (error != 0 && errno == ENOMEM)) {
>         >     > +      // Add extra space in case threads are added
>         before next call.
>         >     > +      len += sizeof(*kp) + len / 10;
>         >     > +      nkp = (struct kinfo_proc *)realloc(kp, len);
>         >     > +      if (nkp == nullptr) {
>         >     > +        free(kp);
>         >     > +        return;
>         >     > +      }
>         >     > +      kp = nkp;
>         >     > +      continue;
>         >     > +    }
>         >     > +    if (error != 0)
>         >     > +      len = 0;
>         >     > +    break;
>         >     > +  }
>         >     > +
>         >     > +  for (size_t i = 0; i < len / sizeof(*kp); i++) {
>         >     > +    if (kp[i].ki_tid == (lwpid_t)tid) {
>         >     > +      Name.append(kp[i].ki_tdname, kp[i].ki_tdname +
>         >     strlen(kp[i].ki_tdname));
>         >     > +      break;
>         >     > +    }
>         >     > +  }
>         >     > +  free(kp);
>         >     > +  return;
>         >     > +#elif defined(__NetBSD__)
>         >     > +  char buf[PTHREAD_MAX_NAMELEN_NP];
>         >     > +  ::pthread_getname_np(::pthread_self(), buf,
>         >     PTHREAD_MAX_NAMELEN_NP);
>         >     > +
>         >     > +  Name.append(buf, buf + strlen(buf));
>         >     > +#elif defined(__linux__)
>         >     > +#if (defined(__GLIBC__) && defined(_GNU_SOURCE)) ||
>         >     defined(__ANDROID__)
>         >     > +  constexpr int MAXNAMELEN = 16;
>         >     > +  char Buffer[MAXNAMELEN];
>         >     > +  if (0 == ::pthread_getname_np(::pthread_self(), Buffer,
>         >     MAXNAMELEN))
>         >     > +    Name.append(Buffer, Buffer + strlen(Buffer));
>         >     > +#endif
>         >     > +#endif
>         >     > +}
>         >     >
>         >     > Added: llvm/trunk/lib/Support/Windows/Threading.inc
>         >     > URL:
>         >
>          http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/Threading.inc?rev=296887&view=auto
>         >     >
>         >
>          ==============================================================================
>         >     > --- llvm/trunk/lib/Support/Windows/Threading.inc (added)
>         >     > +++ llvm/trunk/lib/Support/Windows/Threading.inc Fri Mar  3
>         >     11:15:17 2017
>         >     > @@ -0,0 +1,101 @@
>         >     > +//===- Windows/Threading.inc - Win32 Threading
>         Implementation -
>         >     -*- C++ -*-===//
>         >     > +//
>         >     > +//                     The LLVM Compiler Infrastructure
>         >     > +//
>         >     > +// This file is distributed under the University of
>         Illinois Open
>         >     Source
>         >     > +// License. See LICENSE.TXT for details.
>         >     > +//
>         >     >
>         >
>          +//===----------------------------------------------------------------------===//
>         >     > +//
>         >     > +// This file provides the Win32 specific implementation of
>         >     Threading functions.
>         >     > +//
>         >     >
>         >
>          +//===----------------------------------------------------------------------===//
>         >     > +
>         >     > +#include "llvm/ADT/SmallString.h"
>         >     > +#include "llvm/ADT/Twine.h"
>         >     > +
>         >     > +#include "Windows/WindowsSupport.h"
>         >     > +#include <process.h>
>         >     > +
>         >     > +// Windows will at times define MemoryFence.
>         >     > +#ifdef MemoryFence
>         >     > +#undef MemoryFence
>         >     > +#endif
>         >     > +
>         >     > +namespace {
>         >     > +  struct ThreadInfo {
>         >     > +    void(*func)(void*);
>         >     > +    void *param;
>         >     > +  };
>         >     > +}
>         >     > +
>         >     > +static unsigned __stdcall ThreadCallback(void *param) {
>         >     > +  struct ThreadInfo *info = reinterpret_cast<struct
>         ThreadInfo
>         >     *>(param);
>         >     > +  info->func(info->param);
>         >     > +
>         >     > +  return 0;
>         >     > +}
>         >     > +
>         >     > +void llvm::llvm_execute_on_thread(void(*Fn)(void*),
>         void *UserData,
>         >     > +  unsigned RequestedStackSize) {
>         >     > +  struct ThreadInfo param = { Fn, UserData };
>         >     > +
>         >     > +  HANDLE hThread = (HANDLE)::_beginthreadex(NULL,
>         >     > +    RequestedStackSize, ThreadCallback,
>         >     > +    &param, 0, NULL);
>         >     > +
>         >     > +  if (hThread) {
>         >     > +    // We actually don't care whether the wait succeeds
>         or fails, in
>         >     > +    // the same way we don't care whether the
>         pthread_join call
>         >     succeeds
>         >     > +    // or fails.  There's not much we could do if this
>         were to
>         >     fail. But
>         >     > +    // on success, this call will wait until the thread
>         finishes
>         >     executing
>         >     > +    // before returning.
>         >     > +    (void)::WaitForSingleObject(hThread, INFINITE);
>         >     > +    ::CloseHandle(hThread);
>         >     > +  }
>         >     > +}
>         >     > +
>         >     > +uint64_t llvm::get_threadid() {
>         >     > +  return uint64_t(::GetCurrentThreadId());
>         >     > +}
>         >     > +
>         >     > +void llvm::set_thread_name(const Twine &Name) {
>         >     > +#if defined(_MSC_VER)
>         >     > +  // Make sure the input is null terminated.
>         >     > +  SmallString<64> Storage;
>         >     > +  StringRef NameStr =
>         Name.toNullTerminatedStringRef(Storage);
>         >     > +  constexpr DWORD MS_VC_EXCEPTION = 0x406D1388;
>         >     > +
>         >     > +#pragma pack(push, 8)
>         >     > +  struct THREADNAME_INFO {
>         >     > +    DWORD dwType;     // Must be 0x1000.
>         >     > +    LPCSTR szName;    // Pointer to thread name
>         >     > +    DWORD dwThreadId; // Thread ID (-1 == current thread)
>         >     > +    DWORD dwFlags;    // Reserved.  Do not use.
>         >     > +  };
>         >     > +#pragma pack(pop)
>         >     > +
>         >     > +  THREADNAME_INFO info;
>         >     > +  info.dwType = 0x1000;
>         >     > +  info.szName = NameStr.data();
>         >     > +  info.dwThreadId = ::GetCurrentThreadId();
>         >     > +  info.dwFlags = 0;
>         >     > +
>         >     > +  __try {
>         >     > +    ::RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) /
>         >     sizeof(ULONG_PTR),
>         >     > +      (ULONG_PTR *)&info);
>         >     > +  }
>         >     > +  __except (EXCEPTION_EXECUTE_HANDLER) {
>         >     > +  }
>         >     > +#endif
>         >     > +}
>         >     > +
>         >     > +void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
>         >     > +  // "Name" is not an inherent property of a thread on
>         Windows.
>         >     In fact, when
>         >     > +  // you "set" the name, you are only firing a one-time
>         message
>         >     to a debugger
>         >     > +  // which it interprets as a program setting its
>         threads' name.
>         >     We may be
>         >     > +  // able to get fancy by creating a TLS entry when
>         someone calls
>         >     > +  // set_thread_name so that subsequent calls to
>         get_thread_name
>         >     return this
>         >     > +  // value.
>         >     > +  Name.clear();
>         >     > +}
>         >     >
>         >     >
>         >     > _______________________________________________
>         >     > llvm-commits mailing list
>         >     > llvm-commits at lists.llvm.org
>         <mailto:llvm-commits at lists.llvm.org>
>         <mailto:llvm-commits at lists.llvm.org
>         <mailto:llvm-commits at lists.llvm.org>>
>         >     > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>         >     >
>         >
>         >     --
>         >     Qualcomm Innovation Center, Inc. is a member of Code
>         Aurora Forum,
>         >     hosted by The Linux Foundation
>         >     _______________________________________________
>         >     llvm-commits mailing list
>         >     llvm-commits at lists.llvm.org
>         <mailto:llvm-commits at lists.llvm.org>
>         <mailto:llvm-commits at lists.llvm.org
>         <mailto:llvm-commits at lists.llvm.org>>
>         >     http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>         >
>
>         --
>         Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
>         hosted by The Linux Foundation
>

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
hosted by The Linux Foundation


More information about the llvm-commits mailing list