1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "ffrt_async_stack.h"
16
17 #include <cstdlib>
18 #include <mutex>
19
20 #include <dlfcn.h>
21
22 #include "dfx/log/ffrt_log_api.h"
23
24 using FFRTSetStackIdFunc = void(*)(uint64_t stackId);
25 using FFRTCollectAsyncStackFunc = uint64_t(*)();
26 namespace {
27 FFRTCollectAsyncStackFunc g_collectAsyncStackFunc = nullptr;
28 FFRTSetStackIdFunc g_setStackIdFunc = nullptr;
29 void* g_asyncStackLibHandle = nullptr;
30 bool g_enabledFFRTAsyncStack = false;
31 }
32
LoadDfxAsyncStackLib()33 static void LoadDfxAsyncStackLib()
34 {
35 const char* debuggableEnv = getenv("HAP_DEBUGGABLE");
36 if ((debuggableEnv == nullptr) || (strcmp(debuggableEnv, "true") != 0)) {
37 return;
38 }
39
40 // if async stack is not enabled, the lib should not be unloaded
41 g_asyncStackLibHandle = dlopen("libasync_stack.z.so", RTLD_NOW);
42 if (g_asyncStackLibHandle == nullptr) {
43 return;
44 }
45
46 g_collectAsyncStackFunc = reinterpret_cast<FFRTCollectAsyncStackFunc>(dlsym(g_asyncStackLibHandle,
47 "CollectAsyncStack"));
48 if (g_collectAsyncStackFunc == nullptr) {
49 dlclose(g_asyncStackLibHandle);
50 g_asyncStackLibHandle = nullptr;
51 return;
52 }
53
54 g_setStackIdFunc = reinterpret_cast<FFRTSetStackIdFunc>(dlsym(g_asyncStackLibHandle, "SetStackId"));
55 if (g_setStackIdFunc == nullptr) {
56 g_collectAsyncStackFunc = nullptr;
57 dlclose(g_asyncStackLibHandle);
58 g_asyncStackLibHandle = nullptr;
59 return;
60 }
61
62 g_enabledFFRTAsyncStack = true;
63 }
64
IsFFRTAsyncStackEnabled()65 static bool IsFFRTAsyncStackEnabled()
66 {
67 static std::once_flag onceFlag;
68 std::call_once(onceFlag, LoadDfxAsyncStackLib);
69 return g_enabledFFRTAsyncStack;
70 }
71
72 namespace ffrt {
FFRTCollectAsyncStack(void)73 uint64_t FFRTCollectAsyncStack(void)
74 {
75 if (IsFFRTAsyncStackEnabled() &&
76 (g_collectAsyncStackFunc != nullptr)) {
77 return g_collectAsyncStackFunc();
78 }
79
80 return 0;
81 }
82
FFRTSetStackId(uint64_t stackId)83 void FFRTSetStackId(uint64_t stackId)
84 {
85 if (IsFFRTAsyncStackEnabled() &&
86 (g_setStackIdFunc != nullptr)) {
87 return g_setStackIdFunc(stackId);
88 }
89 }
90
CloseAsyncStackLibHandle()91 void CloseAsyncStackLibHandle()
92 {
93 if (g_asyncStackLibHandle != nullptr) {
94 dlclose(g_asyncStackLibHandle);
95 g_asyncStackLibHandle = nullptr;
96 }
97 }
98 }