xref: /aosp_15_r20/external/perfetto/src/base/thread_utils.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "perfetto/base/thread_utils.h"
18 #include "perfetto/ext/base/thread_utils.h"
19 
20 #include "perfetto/base/build_config.h"
21 
22 #if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
23 #include <zircon/process.h>
24 #include <zircon/syscalls.h>
25 #include <zircon/types.h>
26 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
27 #include <Windows.h>
28 #endif
29 
30 namespace perfetto {
31 namespace base {
32 
33 #if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
ResolveThreadId()34 static PlatformThreadId ResolveThreadId() {
35   zx_info_handle_basic_t basic;
36   return (zx_object_get_info(zx_thread_self(), ZX_INFO_HANDLE_BASIC, &basic,
37                              sizeof(basic), nullptr, nullptr) == ZX_OK)
38              ? basic.koid
39              : ZX_KOID_INVALID;
40 }
GetThreadId()41 PlatformThreadId GetThreadId() {
42   thread_local static PlatformThreadId thread_id = ResolveThreadId();
43   return thread_id;
44 }
45 
46 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
47 
48 // The SetThreadDescription API was brought in version 1607 of Windows 10.
49 typedef HRESULT(WINAPI* SetThreadDescription)(HANDLE hThread,
50                                               PCWSTR lpThreadDescription);
51 
52 // The SetThreadDescription API was brought in version 1607 of Windows 10.
53 typedef HRESULT(WINAPI* GetThreadDescription)(HANDLE hThread,
54                                               PWSTR* ppszThreadDescription);
55 
56 bool MaybeSetThreadName(const std::string& name) {
57   // The SetThreadDescription API works even if no debugger is attached.
58   static auto set_thread_description_func =
59       reinterpret_cast<SetThreadDescription>(
60           reinterpret_cast<void*>(::GetProcAddress(
61               ::GetModuleHandleA("Kernel32.dll"), "SetThreadDescription")));
62   if (!set_thread_description_func) {
63     return false;
64   }
65   std::wstring wide_thread_name;
66   if (!UTF8ToWide(name, wide_thread_name)) {
67     return false;
68   }
69   HRESULT result = set_thread_description_func(::GetCurrentThread(),
70                                                wide_thread_name.c_str());
71   return !FAILED(result);
72 }
73 
74 bool GetThreadName(std::string& out_result) {
75   static auto get_thread_description_func =
76       reinterpret_cast<GetThreadDescription>(
77           reinterpret_cast<void*>(::GetProcAddress(
78               ::GetModuleHandleA("Kernel32.dll"), "GetThreadDescription")));
79   if (!get_thread_description_func) {
80     return false;
81   }
82   wchar_t* wide_thread_name;
83   HRESULT result =
84       get_thread_description_func(::GetCurrentThread(), &wide_thread_name);
85   if (SUCCEEDED(result)) {
86     bool success = WideToUTF8(std::wstring(wide_thread_name), out_result);
87     LocalFree(wide_thread_name);
88     return success;
89   }
90   return false;
91 }
92 
93 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
94 
95 }  // namespace base
96 }  // namespace perfetto
97