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 static FFRTCollectAsyncStackFunc g_collectAsyncStackFunc = nullptr;
27 static FFRTSetStackIdFunc g_setStackIdFunc = nullptr;
28 static bool g_enabledFFRTAsyncStack = false;
29
LoadDfxAsyncStackLib()30 static void LoadDfxAsyncStackLib()
31 {
32 const char* debuggableEnv = getenv("HAP_DEBUGGABLE");
33 if ((debuggableEnv == nullptr) || (strcmp(debuggableEnv, "true") != 0)) {
34 return;
35 }
36
37 // if async stack is not enabled, the lib should not be unloaded
38 static void* asyncStackLibHandle = dlopen("libasync_stack.z.so", RTLD_NOW);
39 if (asyncStackLibHandle == nullptr) {
40 return;
41 }
42
43 g_collectAsyncStackFunc = reinterpret_cast<FFRTCollectAsyncStackFunc>(dlsym(asyncStackLibHandle,
44 "CollectAsyncStack"));
45 if (g_collectAsyncStackFunc == nullptr) {
46 dlclose(asyncStackLibHandle);
47 asyncStackLibHandle = nullptr;
48 return;
49 }
50
51 g_setStackIdFunc = reinterpret_cast<FFRTSetStackIdFunc>(dlsym(asyncStackLibHandle, "SetStackId"));
52 if (g_setStackIdFunc == nullptr) {
53 g_collectAsyncStackFunc = nullptr;
54 dlclose(asyncStackLibHandle);
55 asyncStackLibHandle = nullptr;
56 return;
57 }
58
59 g_enabledFFRTAsyncStack = true;
60 }
61
IsFFRTAsyncStackEnabled()62 static bool IsFFRTAsyncStackEnabled()
63 {
64 static std::once_flag onceFlag;
65 std::call_once(onceFlag, LoadDfxAsyncStackLib);
66 return g_enabledFFRTAsyncStack;
67 }
68
69 namespace ffrt {
FFRTCollectAsyncStack(void)70 uint64_t FFRTCollectAsyncStack(void)
71 {
72 if (IsFFRTAsyncStackEnabled() &&
73 (g_collectAsyncStackFunc != nullptr)) {
74 return g_collectAsyncStackFunc();
75 }
76
77 return 0;
78 }
79
FFRTSetStackId(uint64_t stackId)80 void FFRTSetStackId(uint64_t stackId)
81 {
82 if (IsFFRTAsyncStackEnabled() &&
83 (g_setStackIdFunc != nullptr)) {
84 return g_setStackIdFunc(stackId);
85 }
86 }
87 }
88