1 /*
2 * Copyright (c) 2025 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
16 #ifdef FFRT_ENABLE_HITRACE_CHAIN
17
18 #include "dfx/trace/ffrt_trace_chain.h"
19 #include <dlfcn.h>
20
21 #ifdef APP_USE_ARM
22 constexpr const char* TRACE_CHAIN_LIB_PATH = "libhitracechain.so";
23 #else
24 constexpr const char* TRACE_CHAIN_LIB_PATH = "libhitracechain.so";
25 #endif
26
27 namespace ffrt {
28
TraceChainAdapter()29 TraceChainAdapter::TraceChainAdapter()
30 {
31 Load();
32 }
33
~TraceChainAdapter()34 TraceChainAdapter::~TraceChainAdapter()
35 {
36 UnLoad();
37 }
38
Instance()39 TraceChainAdapter& TraceChainAdapter::Instance()
40 {
41 static TraceChainAdapter instance;
42 return instance;
43 }
44
HiTraceChainGetId()45 HiTraceIdStruct TraceChainAdapter::HiTraceChainGetId()
46 {
47 if (getIdFunc_ != nullptr) {
48 return getIdFunc_();
49 }
50 return {};
51 }
52
HiTraceChainClearId()53 void TraceChainAdapter::HiTraceChainClearId()
54 {
55 auto clearIdFunc = clearIdFunc_;
56 if (clearIdFunc != nullptr) {
57 clearIdFunc();
58 }
59 }
60
HiTraceChainRestoreId(const HiTraceIdStruct * pId)61 void TraceChainAdapter::HiTraceChainRestoreId(const HiTraceIdStruct* pId)
62 {
63 if (restoreIdFunc_ != nullptr) {
64 restoreIdFunc_(pId);
65 }
66 }
67
HiTraceChainCreateSpan()68 HiTraceIdStruct TraceChainAdapter::HiTraceChainCreateSpan()
69 {
70 if (createSpanFunc_ != nullptr) {
71 return createSpanFunc_();
72 }
73 return {};
74 }
75
HiTraceChainBegin(const char * name,int flags)76 HiTraceIdStruct TraceChainAdapter::HiTraceChainBegin(const char* name, int flags)
77 {
78 if (beginChainFunc_ != nullptr) {
79 return beginChainFunc_(name, flags);
80 }
81 return {};
82 }
83
HiTraceChainEnd(const HiTraceIdStruct * pId)84 void TraceChainAdapter::HiTraceChainEnd(const HiTraceIdStruct* pId)
85 {
86 if (endChainFunc_ != nullptr) {
87 return endChainFunc_(pId);
88 }
89 }
90
Load()91 void TraceChainAdapter::Load()
92 {
93 if (handle_ != nullptr) {
94 FFRT_LOGD("handle exits");
95 return;
96 }
97
98 handle_ = dlopen(TRACE_CHAIN_LIB_PATH, RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);
99 if (handle_ == nullptr) {
100 FFRT_LOGE("load so[%s] fail", TRACE_CHAIN_LIB_PATH);
101 return;
102 }
103
104 getIdFunc_ = reinterpret_cast<HiTraceChainGetIdFunc>(dlsym(handle_, "HiTraceChainGetId"));
105 if (getIdFunc_ == nullptr) {
106 FFRT_LOGE("load func HiTraceChainGetId from %s failed", TRACE_CHAIN_LIB_PATH);
107 UnLoad();
108 return;
109 }
110
111 clearIdFunc_ = reinterpret_cast<HiTraceChainClearIdFunc>(dlsym(handle_, "HiTraceChainClearId"));
112 if (clearIdFunc_ == nullptr) {
113 FFRT_LOGE("load func HiTraceChainClearId from %s failed", TRACE_CHAIN_LIB_PATH);
114 UnLoad();
115 return;
116 }
117
118 restoreIdFunc_ = reinterpret_cast<HiTraceChainRestoreIdFunc>(dlsym(handle_, "HiTraceChainRestoreId"));
119 if (restoreIdFunc_ == nullptr) {
120 FFRT_LOGE("load func HiTraceChainRestoreId from %s failed", TRACE_CHAIN_LIB_PATH);
121 UnLoad();
122 return;
123 }
124
125 createSpanFunc_ = reinterpret_cast<HiTraceChainCreateSpanFunc>(dlsym(handle_, "HiTraceChainCreateSpan"));
126 if (createSpanFunc_ == nullptr) {
127 FFRT_LOGE("load func HiTraceChainCreateSpan from %s failed", TRACE_CHAIN_LIB_PATH);
128 UnLoad();
129 return;
130 }
131
132 beginChainFunc_ = reinterpret_cast<HiTraceChainBeginFunc>(dlsym(handle_, "HiTraceChainBegin"));
133 if (beginChainFunc_ == nullptr) {
134 FFRT_LOGE("load func HiTraceChainBegin from %s failed", TRACE_CHAIN_LIB_PATH);
135 UnLoad();
136 return;
137 }
138
139 endChainFunc_ = reinterpret_cast<HiTraceChainEndFunc>(dlsym(handle_, "HiTraceChainEnd"));
140 if (endChainFunc_ == nullptr) {
141 FFRT_LOGE("load func HiTraceChainEnd from %s failed", TRACE_CHAIN_LIB_PATH);
142 UnLoad();
143 return;
144 }
145 }
146
UnLoad()147 void TraceChainAdapter::UnLoad()
148 {
149 getIdFunc_ = nullptr;
150 clearIdFunc_ = nullptr;
151 restoreIdFunc_ = nullptr;
152 createSpanFunc_ = nullptr;
153 beginChainFunc_ = nullptr;
154 endChainFunc_ = nullptr;
155 if (handle_ != nullptr) {
156 if (dlclose(handle_) == 0) {
157 handle_ = nullptr;
158 }
159 }
160 }
161
162 } // namespace ffrt
163
164 #endif // FFRT_ENABLE_HITRACE_CHAIN