[InstCombine] Signed saturation patterns
[llvm-core.git] / lib / Support / Windows / Threading.inc
blob96649472cc90be70dbe14b54428851e77934ce19
1 //===- Windows/Threading.inc - Win32 Threading Implementation - -*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file provides the Win32 specific implementation of Threading functions.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/Twine.h"
16 #include "WindowsSupport.h"
17 #include <process.h>
19 // Windows will at times define MemoryFence.
20 #ifdef MemoryFence
21 #undef MemoryFence
22 #endif
24 namespace {
25   struct ThreadInfo {
26     void(*func)(void*);
27     void *param;
28   };
31 static unsigned __stdcall ThreadCallback(void *param) {
32   struct ThreadInfo *info = reinterpret_cast<struct ThreadInfo *>(param);
33   info->func(info->param);
35   return 0;
38 void llvm::llvm_execute_on_thread(void(*Fn)(void*), void *UserData,
39   unsigned RequestedStackSize) {
40   struct ThreadInfo param = { Fn, UserData };
42   HANDLE hThread = (HANDLE)::_beginthreadex(NULL,
43     RequestedStackSize, ThreadCallback,
44     &param, 0, NULL);
46   if (hThread) {
47     // We actually don't care whether the wait succeeds or fails, in
48     // the same way we don't care whether the pthread_join call succeeds
49     // or fails.  There's not much we could do if this were to fail. But
50     // on success, this call will wait until the thread finishes executing
51     // before returning.
52     (void)::WaitForSingleObject(hThread, INFINITE);
53     ::CloseHandle(hThread);
54   }
57 uint64_t llvm::get_threadid() {
58   return uint64_t(::GetCurrentThreadId());
61 uint32_t llvm::get_max_thread_name_length() { return 0; }
63 #if defined(_MSC_VER)
64 static void SetThreadName(DWORD Id, LPCSTR Name) {
65   constexpr DWORD MS_VC_EXCEPTION = 0x406D1388;
67 #pragma pack(push, 8)
68   struct THREADNAME_INFO {
69     DWORD dwType;     // Must be 0x1000.
70     LPCSTR szName;    // Pointer to thread name
71     DWORD dwThreadId; // Thread ID (-1 == current thread)
72     DWORD dwFlags;    // Reserved.  Do not use.
73   };
74 #pragma pack(pop)
76   THREADNAME_INFO info;
77   info.dwType = 0x1000;
78   info.szName = Name;
79   info.dwThreadId = Id;
80   info.dwFlags = 0;
82   __try {
83     ::RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR),
84       (ULONG_PTR *)&info);
85   }
86   __except (EXCEPTION_EXECUTE_HANDLER) {
87   }
89 #endif
91 void llvm::set_thread_name(const Twine &Name) {
92 #if defined(_MSC_VER)
93   // Make sure the input is null terminated.
94   SmallString<64> Storage;
95   StringRef NameStr = Name.toNullTerminatedStringRef(Storage);
96   SetThreadName(::GetCurrentThreadId(), NameStr.data());
97 #endif
100 void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
101   // "Name" is not an inherent property of a thread on Windows.  In fact, when
102   // you "set" the name, you are only firing a one-time message to a debugger
103   // which it interprets as a program setting its threads' name.  We may be
104   // able to get fancy by creating a TLS entry when someone calls
105   // set_thread_name so that subsequent calls to get_thread_name return this
106   // value.
107   Name.clear();
110 SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) {
111   // https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-setthreadpriority
112   // Begin background processing mode. The system lowers the resource scheduling
113   // priorities of the thread so that it can perform background work without
114   // significantly affecting activity in the foreground.
115   // End background processing mode. The system restores the resource scheduling
116   // priorities of the thread as they were before the thread entered background
117   // processing mode.
118   return SetThreadPriority(GetCurrentThread(),
119                            Priority == ThreadPriority::Background
120                                ? THREAD_MODE_BACKGROUND_BEGIN
121                                : THREAD_MODE_BACKGROUND_END)
122              ? SetThreadPriorityResult::SUCCESS
123              : SetThreadPriorityResult::FAILURE;