LLVM  8.0.1
Threading.inc
Go to the documentation of this file.
1 //===- Windows/Threading.inc - Win32 Threading Implementation - -*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file provides the Win32 specific implementation of Threading functions.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/ADT/SmallString.h"
15 #include "llvm/ADT/Twine.h"
16 
17 #include "WindowsSupport.h"
18 #include <process.h>
19 
20 // Windows will at times define MemoryFence.
21 #ifdef MemoryFence
22 #undef MemoryFence
23 #endif
24 
25 namespace {
26  struct ThreadInfo {
27  void(*func)(void*);
28  void *param;
29  };
30 }
31 
32 static unsigned __stdcall ThreadCallback(void *param) {
33  struct ThreadInfo *info = reinterpret_cast<struct ThreadInfo *>(param);
34  info->func(info->param);
35 
36  return 0;
37 }
38 
39 void llvm::llvm_execute_on_thread(void(*Fn)(void*), void *UserData,
40  unsigned RequestedStackSize) {
41  struct ThreadInfo param = { Fn, UserData };
42 
43  HANDLE hThread = (HANDLE)::_beginthreadex(NULL,
44  RequestedStackSize, ThreadCallback,
45  &param, 0, NULL);
46 
47  if (hThread) {
48  // We actually don't care whether the wait succeeds or fails, in
49  // the same way we don't care whether the pthread_join call succeeds
50  // or fails. There's not much we could do if this were to fail. But
51  // on success, this call will wait until the thread finishes executing
52  // before returning.
53  (void)::WaitForSingleObject(hThread, INFINITE);
54  ::CloseHandle(hThread);
55  }
56 }
57 
58 uint64_t llvm::get_threadid() {
59  return uint64_t(::GetCurrentThreadId());
60 }
61 
63 
64 #if defined(_MSC_VER)
65 static void SetThreadName(DWORD Id, LPCSTR Name) {
66  constexpr DWORD MS_VC_EXCEPTION = 0x406D1388;
67 
68 #pragma pack(push, 8)
69  struct THREADNAME_INFO {
70  DWORD dwType; // Must be 0x1000.
71  LPCSTR szName; // Pointer to thread name
72  DWORD dwThreadId; // Thread ID (-1 == current thread)
73  DWORD dwFlags; // Reserved. Do not use.
74  };
75 #pragma pack(pop)
76 
77  THREADNAME_INFO info;
78  info.dwType = 0x1000;
79  info.szName = Name;
80  info.dwThreadId = Id;
81  info.dwFlags = 0;
82 
83  __try {
84  ::RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR),
85  (ULONG_PTR *)&info);
86  }
87  __except (EXCEPTION_EXECUTE_HANDLER) {
88  }
89 }
90 #endif
91 
92 void llvm::set_thread_name(const Twine &Name) {
93 #if defined(_MSC_VER)
94  // Make sure the input is null terminated.
95  SmallString<64> Storage;
96  StringRef NameStr = Name.toNullTerminatedStringRef(Storage);
97  SetThreadName(::GetCurrentThreadId(), NameStr.data());
98 #endif
99 }
100 
101 void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
102  // "Name" is not an inherent property of a thread on Windows. In fact, when
103  // you "set" the name, you are only firing a one-time message to a debugger
104  // which it interprets as a program setting its threads' name. We may be
105  // able to get fancy by creating a TLS entry when someone calls
106  // set_thread_name so that subsequent calls to get_thread_name return this
107  // value.
108  Name.clear();
109 }
void set_thread_name(const Twine &Name)
Set the name of the current thread.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
uint32_t get_max_thread_name_length()
Get the maximum length of a thread name on this platform.
void get_thread_name(SmallVectorImpl< char > &Name)
Get the name of the current thread.
lazy value info
uint64_t get_threadid()
Return the current thread id, as used in various OS system calls.
void llvm_execute_on_thread(void(*UserFn)(void *), void *UserData, unsigned RequestedStackSize=0)
llvm_execute_on_thread - Execute the given UserFn on a separate thread, passing it the provided UserD...