1b0e7dd80Sopenharmony_ci/* 2b0e7dd80Sopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 3b0e7dd80Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b0e7dd80Sopenharmony_ci * you may not use this file except in compliance with the License. 5b0e7dd80Sopenharmony_ci * You may obtain a copy of the License at 6b0e7dd80Sopenharmony_ci * 7b0e7dd80Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b0e7dd80Sopenharmony_ci * 9b0e7dd80Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b0e7dd80Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b0e7dd80Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b0e7dd80Sopenharmony_ci * See the License for the specific language governing permissions and 13b0e7dd80Sopenharmony_ci * limitations under the License. 14b0e7dd80Sopenharmony_ci */ 15b0e7dd80Sopenharmony_ci 16b0e7dd80Sopenharmony_ci#include "hitrace/hitracechainc.h" 17b0e7dd80Sopenharmony_ci#include <sched.h> 18b0e7dd80Sopenharmony_ci#include <stdatomic.h> 19b0e7dd80Sopenharmony_ci#include <stdio.h> 20b0e7dd80Sopenharmony_ci#include <stdlib.h> 21b0e7dd80Sopenharmony_ci#include <string.h> 22b0e7dd80Sopenharmony_ci#include <sys/time.h> 23b0e7dd80Sopenharmony_ci#include "securec.h" 24b0e7dd80Sopenharmony_ci#include "hilog/log.h" 25b0e7dd80Sopenharmony_ci#include "hilog_trace.h" 26b0e7dd80Sopenharmony_ci#include "hitracechain_inner.h" 27b0e7dd80Sopenharmony_ci#include "hitrace_meter_wrapper.h" 28b0e7dd80Sopenharmony_ci#include "hitrace_meter_c.h" 29b0e7dd80Sopenharmony_ci 30b0e7dd80Sopenharmony_ci#undef LOG_DOMAIN 31b0e7dd80Sopenharmony_ci#undef LOG_TAG 32b0e7dd80Sopenharmony_cistatic const unsigned int LOG_DOMAIN = 0xD002D33; 33b0e7dd80Sopenharmony_cistatic const char* LOG_TAG = "HiTraceC"; 34b0e7dd80Sopenharmony_cistatic const int BUFF_ZERO_NUMBER = 0; 35b0e7dd80Sopenharmony_cistatic const int BUFF_ONE_NUMBER = 1; 36b0e7dd80Sopenharmony_cistatic const int BUFF_TWO_NUMBER = 2; 37b0e7dd80Sopenharmony_ci 38b0e7dd80Sopenharmony_citypedef struct HiTraceChainIdStruct { 39b0e7dd80Sopenharmony_ci union { 40b0e7dd80Sopenharmony_ci#if __BYTE_ORDER == __LITTLE_ENDIAN 41b0e7dd80Sopenharmony_ci struct { 42b0e7dd80Sopenharmony_ci uint64_t reserved : 4; 43b0e7dd80Sopenharmony_ci uint64_t usecond : 20; 44b0e7dd80Sopenharmony_ci uint64_t second : 16; 45b0e7dd80Sopenharmony_ci uint64_t cpuId : 4; 46b0e7dd80Sopenharmony_ci uint64_t deviceId : 20; 47b0e7dd80Sopenharmony_ci }; 48b0e7dd80Sopenharmony_ci struct { 49b0e7dd80Sopenharmony_ci uint64_t padding : 4; 50b0e7dd80Sopenharmony_ci uint64_t chainId : 60; 51b0e7dd80Sopenharmony_ci }; 52b0e7dd80Sopenharmony_ci#elif __BYTE_ORDER == __BIG_ENDIAN 53b0e7dd80Sopenharmony_ci struct { 54b0e7dd80Sopenharmony_ci uint64_t deviceId : 20; 55b0e7dd80Sopenharmony_ci uint64_t cpuId : 4; 56b0e7dd80Sopenharmony_ci uint64_t second : 16; 57b0e7dd80Sopenharmony_ci uint64_t usecond : 20; 58b0e7dd80Sopenharmony_ci uint64_t reserved : 4; 59b0e7dd80Sopenharmony_ci }; 60b0e7dd80Sopenharmony_ci struct { 61b0e7dd80Sopenharmony_ci uint64_t chainId : 60; 62b0e7dd80Sopenharmony_ci uint64_t padding : 4; 63b0e7dd80Sopenharmony_ci }; 64b0e7dd80Sopenharmony_ci#else 65b0e7dd80Sopenharmony_ci#error "ERROR: No BIG_LITTLE_ENDIAN defines." 66b0e7dd80Sopenharmony_ci#endif 67b0e7dd80Sopenharmony_ci }; 68b0e7dd80Sopenharmony_ci} HiTraceChainIdStruct; 69b0e7dd80Sopenharmony_ci 70b0e7dd80Sopenharmony_citypedef struct HiTraceIdStructExtra { 71b0e7dd80Sopenharmony_ci uint32_t setTls : 1; 72b0e7dd80Sopenharmony_ci uint32_t reserved : 31; 73b0e7dd80Sopenharmony_ci} HiTraceIdStructExtra; 74b0e7dd80Sopenharmony_ci 75b0e7dd80Sopenharmony_citypedef struct HiTraceIdStructInner { 76b0e7dd80Sopenharmony_ci HiTraceIdStruct id; 77b0e7dd80Sopenharmony_ci HiTraceIdStructExtra extra; 78b0e7dd80Sopenharmony_ci} HiTraceIdStructInner; 79b0e7dd80Sopenharmony_ci 80b0e7dd80Sopenharmony_cistatic __thread HiTraceIdStructInner g_hiTraceId = {{0, 0, 0, 0, 0, 0}, {0, 0}}; 81b0e7dd80Sopenharmony_ci 82b0e7dd80Sopenharmony_cistatic inline HiTraceIdStructInner* GetThreadIdInner(void) 83b0e7dd80Sopenharmony_ci{ 84b0e7dd80Sopenharmony_ci return &g_hiTraceId; 85b0e7dd80Sopenharmony_ci} 86b0e7dd80Sopenharmony_ci 87b0e7dd80Sopenharmony_ciHiTraceIdStruct HiTraceChainGetId(void) 88b0e7dd80Sopenharmony_ci{ 89b0e7dd80Sopenharmony_ci HiTraceIdStructInner* pThreadId = GetThreadIdInner(); 90b0e7dd80Sopenharmony_ci return pThreadId->id; 91b0e7dd80Sopenharmony_ci} 92b0e7dd80Sopenharmony_ci 93b0e7dd80Sopenharmony_civoid HiTraceChainSetId(const HiTraceIdStruct* pId) 94b0e7dd80Sopenharmony_ci{ 95b0e7dd80Sopenharmony_ci if (!HiTraceChainIsValid(pId)) { 96b0e7dd80Sopenharmony_ci return; 97b0e7dd80Sopenharmony_ci } 98b0e7dd80Sopenharmony_ci 99b0e7dd80Sopenharmony_ci HiTraceIdStructInner* pThreadId = GetThreadIdInner(); 100b0e7dd80Sopenharmony_ci pThreadId->id = *pId; 101b0e7dd80Sopenharmony_ci return; 102b0e7dd80Sopenharmony_ci} 103b0e7dd80Sopenharmony_ci 104b0e7dd80Sopenharmony_civoid HiTraceChainClearId(void) 105b0e7dd80Sopenharmony_ci{ 106b0e7dd80Sopenharmony_ci HiTraceIdStructInner* pThreadId = GetThreadIdInner(); 107b0e7dd80Sopenharmony_ci HiTraceChainInitId(&(pThreadId->id)); 108b0e7dd80Sopenharmony_ci return; 109b0e7dd80Sopenharmony_ci} 110b0e7dd80Sopenharmony_ci 111b0e7dd80Sopenharmony_cistatic inline int HiTraceChainGetDeviceId(void) 112b0e7dd80Sopenharmony_ci{ 113b0e7dd80Sopenharmony_ci // save device id and use it later 114b0e7dd80Sopenharmony_ci static atomic_int deviceId = 0; 115b0e7dd80Sopenharmony_ci 116b0e7dd80Sopenharmony_ci if (deviceId == 0) { 117b0e7dd80Sopenharmony_ci struct timeval tv; 118b0e7dd80Sopenharmony_ci gettimeofday(&tv, NULL); 119b0e7dd80Sopenharmony_ci srand(tv.tv_sec); 120b0e7dd80Sopenharmony_ci deviceId = random(); 121b0e7dd80Sopenharmony_ci } 122b0e7dd80Sopenharmony_ci return deviceId; 123b0e7dd80Sopenharmony_ci} 124b0e7dd80Sopenharmony_ci 125b0e7dd80Sopenharmony_cistatic inline unsigned int HiTraceChainGetCpuId(void) 126b0e7dd80Sopenharmony_ci{ 127b0e7dd80Sopenharmony_ci // Using vdso call will make get_cpu_id faster: sched_getcpu() 128b0e7dd80Sopenharmony_ci static atomic_uint cpuId = 0; 129b0e7dd80Sopenharmony_ci cpuId++; 130b0e7dd80Sopenharmony_ci 131b0e7dd80Sopenharmony_ci return cpuId; 132b0e7dd80Sopenharmony_ci} 133b0e7dd80Sopenharmony_ci 134b0e7dd80Sopenharmony_cistatic inline uint64_t HiTraceChainCreateChainId(void) 135b0e7dd80Sopenharmony_ci{ 136b0e7dd80Sopenharmony_ci // get timestamp. Using vdso call(no system call) 137b0e7dd80Sopenharmony_ci struct timeval tv; 138b0e7dd80Sopenharmony_ci gettimeofday(&tv, NULL); 139b0e7dd80Sopenharmony_ci HiTraceChainIdStruct chainId = { 140b0e7dd80Sopenharmony_ci .padding = 0, 141b0e7dd80Sopenharmony_ci .chainId = 0 142b0e7dd80Sopenharmony_ci }; 143b0e7dd80Sopenharmony_ci chainId.deviceId = (uint64_t)(HiTraceChainGetDeviceId()); 144b0e7dd80Sopenharmony_ci chainId.cpuId = HiTraceChainGetCpuId(); 145b0e7dd80Sopenharmony_ci chainId.second = (uint64_t)(tv.tv_sec); 146b0e7dd80Sopenharmony_ci chainId.usecond = (uint64_t)(tv.tv_usec); 147b0e7dd80Sopenharmony_ci return chainId.chainId; 148b0e7dd80Sopenharmony_ci} 149b0e7dd80Sopenharmony_ci 150b0e7dd80Sopenharmony_ciHiTraceIdStruct HiTraceChainBegin(const char* name, int flags) 151b0e7dd80Sopenharmony_ci{ 152b0e7dd80Sopenharmony_ci HiTraceIdStruct id; 153b0e7dd80Sopenharmony_ci HiTraceChainInitId(&id); 154b0e7dd80Sopenharmony_ci 155b0e7dd80Sopenharmony_ci if ((flags < HITRACE_FLAG_MIN) || (flags > HITRACE_FLAG_MAX)) { 156b0e7dd80Sopenharmony_ci return id; 157b0e7dd80Sopenharmony_ci } 158b0e7dd80Sopenharmony_ci 159b0e7dd80Sopenharmony_ci HiTraceIdStructInner* pThreadId = GetThreadIdInner(); 160b0e7dd80Sopenharmony_ci if (HiTraceChainIsValid(&(pThreadId->id))) { 161b0e7dd80Sopenharmony_ci return id; 162b0e7dd80Sopenharmony_ci } 163b0e7dd80Sopenharmony_ci 164b0e7dd80Sopenharmony_ci id.valid = HITRACE_ID_VALID; 165b0e7dd80Sopenharmony_ci id.ver = HITRACE_VER_1; 166b0e7dd80Sopenharmony_ci id.chainId = HiTraceChainCreateChainId(); 167b0e7dd80Sopenharmony_ci id.flags = (uint64_t)flags; 168b0e7dd80Sopenharmony_ci id.spanId = 0; 169b0e7dd80Sopenharmony_ci id.parentSpanId = 0; 170b0e7dd80Sopenharmony_ci 171b0e7dd80Sopenharmony_ci pThreadId->id = id; 172b0e7dd80Sopenharmony_ci 173b0e7dd80Sopenharmony_ci if (!HiTraceChainIsFlagEnabled(&id, HITRACE_FLAG_NO_BE_INFO)) { 174b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "HiTraceBegin name:%{public}s flags:0x%{public}.2x.", name ? name : "", (int)id.flags); 175b0e7dd80Sopenharmony_ci } 176b0e7dd80Sopenharmony_ci return id; 177b0e7dd80Sopenharmony_ci} 178b0e7dd80Sopenharmony_ci 179b0e7dd80Sopenharmony_civoid HiTraceChainEnd(const HiTraceIdStruct* pId) 180b0e7dd80Sopenharmony_ci{ 181b0e7dd80Sopenharmony_ci if (!HiTraceChainIsValid(pId)) { 182b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "HiTraceEnd error: invalid end id."); 183b0e7dd80Sopenharmony_ci return; 184b0e7dd80Sopenharmony_ci } 185b0e7dd80Sopenharmony_ci 186b0e7dd80Sopenharmony_ci HiTraceIdStructInner* pThreadId = GetThreadIdInner(); 187b0e7dd80Sopenharmony_ci if (!HiTraceChainIsValid(&(pThreadId->id))) { 188b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "HiTraceEnd error: invalid thread id."); 189b0e7dd80Sopenharmony_ci return; 190b0e7dd80Sopenharmony_ci } 191b0e7dd80Sopenharmony_ci 192b0e7dd80Sopenharmony_ci if (HiTraceChainGetChainId(pId) != HiTraceChainGetChainId(&(pThreadId->id))) { 193b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "HiTraceEnd error: end id(%{public}llx) != thread id(%{public}llx).", 194b0e7dd80Sopenharmony_ci (unsigned long long)pId->chainId, (unsigned long long)pThreadId->id.chainId); 195b0e7dd80Sopenharmony_ci return; 196b0e7dd80Sopenharmony_ci } 197b0e7dd80Sopenharmony_ci 198b0e7dd80Sopenharmony_ci if (!HiTraceChainIsFlagEnabled(&(pThreadId->id), HITRACE_FLAG_NO_BE_INFO)) { 199b0e7dd80Sopenharmony_ci HILOG_DEBUG(LOG_CORE, "HiTraceEnd."); 200b0e7dd80Sopenharmony_ci } 201b0e7dd80Sopenharmony_ci 202b0e7dd80Sopenharmony_ci HiTraceChainInitId(&(pThreadId->id)); 203b0e7dd80Sopenharmony_ci return; 204b0e7dd80Sopenharmony_ci} 205b0e7dd80Sopenharmony_ci 206b0e7dd80Sopenharmony_ci// BKDRHash 207b0e7dd80Sopenharmony_cistatic uint32_t HashFunc(const void* pData, uint32_t dataLen) 208b0e7dd80Sopenharmony_ci{ 209b0e7dd80Sopenharmony_ci const uint32_t seed = 131; 210b0e7dd80Sopenharmony_ci 211b0e7dd80Sopenharmony_ci if ((!pData) || dataLen == 0) { 212b0e7dd80Sopenharmony_ci return 0; 213b0e7dd80Sopenharmony_ci } 214b0e7dd80Sopenharmony_ci 215b0e7dd80Sopenharmony_ci uint32_t hash = 0; 216b0e7dd80Sopenharmony_ci uint32_t len = dataLen; 217b0e7dd80Sopenharmony_ci char* p = (char*)pData; 218b0e7dd80Sopenharmony_ci 219b0e7dd80Sopenharmony_ci for (; len > 0; --len) { 220b0e7dd80Sopenharmony_ci hash = (hash * seed) + (*p++); 221b0e7dd80Sopenharmony_ci } 222b0e7dd80Sopenharmony_ci 223b0e7dd80Sopenharmony_ci return hash; 224b0e7dd80Sopenharmony_ci} 225b0e7dd80Sopenharmony_ci 226b0e7dd80Sopenharmony_ciHiTraceIdStruct HiTraceChainCreateSpan(void) 227b0e7dd80Sopenharmony_ci{ 228b0e7dd80Sopenharmony_ci static const uint32_t hashDataNum = 5; 229b0e7dd80Sopenharmony_ci 230b0e7dd80Sopenharmony_ci HiTraceIdStruct id = HiTraceChainGetId(); 231b0e7dd80Sopenharmony_ci if (!HiTraceChainIsValid(&id)) { 232b0e7dd80Sopenharmony_ci return id; 233b0e7dd80Sopenharmony_ci } 234b0e7dd80Sopenharmony_ci 235b0e7dd80Sopenharmony_ci if (HiTraceChainIsFlagEnabled(&id, HITRACE_FLAG_DONOT_CREATE_SPAN)) { 236b0e7dd80Sopenharmony_ci return id; 237b0e7dd80Sopenharmony_ci } 238b0e7dd80Sopenharmony_ci 239b0e7dd80Sopenharmony_ci // create child span id 240b0e7dd80Sopenharmony_ci struct timeval tv; 241b0e7dd80Sopenharmony_ci gettimeofday(&tv, NULL); 242b0e7dd80Sopenharmony_ci 243b0e7dd80Sopenharmony_ci uint32_t hashData[hashDataNum]; 244b0e7dd80Sopenharmony_ci hashData[0] = (uint32_t)(HiTraceChainGetDeviceId()); // 0: device id 245b0e7dd80Sopenharmony_ci hashData[1] = id.parentSpanId; // 1: parent span id 246b0e7dd80Sopenharmony_ci hashData[2] = id.spanId; // 2: span id 247b0e7dd80Sopenharmony_ci hashData[3] = (uint32_t)(tv.tv_sec); // 3: second 248b0e7dd80Sopenharmony_ci hashData[4] = (uint32_t)(tv.tv_usec); // 4: usecond 249b0e7dd80Sopenharmony_ci 250b0e7dd80Sopenharmony_ci uint32_t hash = HashFunc(hashData, hashDataNum * sizeof(uint32_t)); 251b0e7dd80Sopenharmony_ci 252b0e7dd80Sopenharmony_ci id.parentSpanId = id.spanId; 253b0e7dd80Sopenharmony_ci id.spanId = hash; 254b0e7dd80Sopenharmony_ci return id; 255b0e7dd80Sopenharmony_ci} 256b0e7dd80Sopenharmony_ci 257b0e7dd80Sopenharmony_civoid HiTraceChainTracepointInner(HiTraceCommunicationMode mode, HiTraceTracepointType type, 258b0e7dd80Sopenharmony_ci const HiTraceIdStruct* pId, const char* fmt, va_list args) 259b0e7dd80Sopenharmony_ci{ 260b0e7dd80Sopenharmony_ci static const int tpBufferSize = 1024; 261b0e7dd80Sopenharmony_ci static const char* hiTraceTypeStr[] = { "CS", "CR", "SS", "SR", "GENERAL", }; 262b0e7dd80Sopenharmony_ci static const char* hiTraceModeStr[] = { "DEFAULT", "THREAD", "PROCESS", "DEVICE", }; 263b0e7dd80Sopenharmony_ci static const int hitraceMask = 3; 264b0e7dd80Sopenharmony_ci 265b0e7dd80Sopenharmony_ci if ((mode < HITRACE_CM_MIN) || (mode > HITRACE_CM_MAX)) { 266b0e7dd80Sopenharmony_ci return; 267b0e7dd80Sopenharmony_ci } 268b0e7dd80Sopenharmony_ci if ((type < HITRACE_TP_MIN) || (type > HITRACE_TP_MAX)) { 269b0e7dd80Sopenharmony_ci return; 270b0e7dd80Sopenharmony_ci } 271b0e7dd80Sopenharmony_ci 272b0e7dd80Sopenharmony_ci if (!HiTraceChainIsValid(pId)) { 273b0e7dd80Sopenharmony_ci return; 274b0e7dd80Sopenharmony_ci } 275b0e7dd80Sopenharmony_ci 276b0e7dd80Sopenharmony_ci char buff[tpBufferSize]; 277b0e7dd80Sopenharmony_ci if (type == HITRACE_TP_CS || type == HITRACE_TP_CR) { 278b0e7dd80Sopenharmony_ci buff[BUFF_ZERO_NUMBER] = 'C'; 279b0e7dd80Sopenharmony_ci } 280b0e7dd80Sopenharmony_ci 281b0e7dd80Sopenharmony_ci if (type == HITRACE_TP_SR || type == HITRACE_TP_SS) { 282b0e7dd80Sopenharmony_ci buff[BUFF_ZERO_NUMBER] = 'S'; 283b0e7dd80Sopenharmony_ci } 284b0e7dd80Sopenharmony_ci buff[BUFF_ONE_NUMBER] = '#'; 285b0e7dd80Sopenharmony_ci buff[BUFF_TWO_NUMBER] = '#'; 286b0e7dd80Sopenharmony_ci 287b0e7dd80Sopenharmony_ci#pragma clang diagnostic push 288b0e7dd80Sopenharmony_ci#pragma clang diagnostic ignored "-Wformat-nonliteral" 289b0e7dd80Sopenharmony_ci // if using privacy parameter: vsnprintf => hilog_vsnprintf 290b0e7dd80Sopenharmony_ci int ret = vsnprintf_s(buff + hitraceMask, tpBufferSize - hitraceMask, tpBufferSize - 1 - hitraceMask, fmt, args); 291b0e7dd80Sopenharmony_ci#pragma clang diagnostic pop 292b0e7dd80Sopenharmony_ci if (ret == -1) { // -1: vsnprintf_s copy string fail 293b0e7dd80Sopenharmony_ci return; 294b0e7dd80Sopenharmony_ci } 295b0e7dd80Sopenharmony_ci if (type == HITRACE_TP_CS || type == HITRACE_TP_SR) { 296b0e7dd80Sopenharmony_ci StartTraceChainPoint(pId, buff); 297b0e7dd80Sopenharmony_ci } 298b0e7dd80Sopenharmony_ci 299b0e7dd80Sopenharmony_ci if (type == HITRACE_TP_CR || type == HITRACE_TP_SS) { 300b0e7dd80Sopenharmony_ci HiTraceFinishTrace(HITRACE_TAG_OHOS); 301b0e7dd80Sopenharmony_ci } 302b0e7dd80Sopenharmony_ci 303b0e7dd80Sopenharmony_ci if (!HiTraceChainIsFlagEnabled(pId, HITRACE_FLAG_TP_INFO) && 304b0e7dd80Sopenharmony_ci !HiTraceChainIsFlagEnabled(pId, HITRACE_FLAG_D2D_TP_INFO)) { 305b0e7dd80Sopenharmony_ci // Both tp and d2d-tp flags are disabled. 306b0e7dd80Sopenharmony_ci return; 307b0e7dd80Sopenharmony_ci } else if (!HiTraceChainIsFlagEnabled(pId, HITRACE_FLAG_TP_INFO) && (mode != HITRACE_CM_DEVICE)) { 308b0e7dd80Sopenharmony_ci // Only d2d-tp flag is enabled. But the communication mode is not device-to-device. 309b0e7dd80Sopenharmony_ci return; 310b0e7dd80Sopenharmony_ci } 311b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "<%{public}s,%{public}s,[%{public}llx,%{public}llx,%{public}llx]> %{public}s", 312b0e7dd80Sopenharmony_ci hiTraceModeStr[mode], hiTraceTypeStr[type], (unsigned long long)pId->chainId, 313b0e7dd80Sopenharmony_ci (unsigned long long)pId->spanId, (unsigned long long)pId->parentSpanId, buff + hitraceMask); 314b0e7dd80Sopenharmony_ci return; 315b0e7dd80Sopenharmony_ci} 316b0e7dd80Sopenharmony_ci 317b0e7dd80Sopenharmony_civoid HiTraceChainTracepointWithArgs(HiTraceTracepointType type, const HiTraceIdStruct* pId, const char* fmt, 318b0e7dd80Sopenharmony_ci va_list args) 319b0e7dd80Sopenharmony_ci{ 320b0e7dd80Sopenharmony_ci HiTraceChainTracepointInner(HITRACE_CM_DEFAULT, type, pId, fmt, args); 321b0e7dd80Sopenharmony_ci} 322b0e7dd80Sopenharmony_ci 323b0e7dd80Sopenharmony_civoid HiTraceChainTracepointExWithArgs(HiTraceCommunicationMode mode, HiTraceTracepointType type, 324b0e7dd80Sopenharmony_ci const HiTraceIdStruct* pId, const char* fmt, va_list args) 325b0e7dd80Sopenharmony_ci{ 326b0e7dd80Sopenharmony_ci HiTraceChainTracepointInner(mode, type, pId, fmt, args); 327b0e7dd80Sopenharmony_ci} 328b0e7dd80Sopenharmony_ci 329b0e7dd80Sopenharmony_civoid HiTraceChainTracepoint(HiTraceTracepointType type, const HiTraceIdStruct* pId, const char* fmt, ...) 330b0e7dd80Sopenharmony_ci{ 331b0e7dd80Sopenharmony_ci va_list args; 332b0e7dd80Sopenharmony_ci va_start(args, fmt); 333b0e7dd80Sopenharmony_ci HiTraceChainTracepointInner(HITRACE_CM_DEFAULT, type, pId, fmt, args); 334b0e7dd80Sopenharmony_ci va_end(args); 335b0e7dd80Sopenharmony_ci return; 336b0e7dd80Sopenharmony_ci} 337b0e7dd80Sopenharmony_ci 338b0e7dd80Sopenharmony_civoid HiTraceChainTracepointEx(HiTraceCommunicationMode mode, HiTraceTracepointType type, const HiTraceIdStruct* pId, 339b0e7dd80Sopenharmony_ci const char* fmt, ...) 340b0e7dd80Sopenharmony_ci{ 341b0e7dd80Sopenharmony_ci va_list args; 342b0e7dd80Sopenharmony_ci va_start(args, fmt); 343b0e7dd80Sopenharmony_ci HiTraceChainTracepointInner(mode, type, pId, fmt, args); 344b0e7dd80Sopenharmony_ci va_end(args); 345b0e7dd80Sopenharmony_ci return; 346b0e7dd80Sopenharmony_ci} 347b0e7dd80Sopenharmony_ci 348b0e7dd80Sopenharmony_ciint HiTraceChainGetInfo(uint64_t* chainId, uint32_t* flags, uint64_t* spanId, uint64_t* parentSpanId) 349b0e7dd80Sopenharmony_ci{ 350b0e7dd80Sopenharmony_ci if (!chainId || !flags || !spanId || !parentSpanId) { 351b0e7dd80Sopenharmony_ci return HITRACE_INFO_FAIL; 352b0e7dd80Sopenharmony_ci } 353b0e7dd80Sopenharmony_ci 354b0e7dd80Sopenharmony_ci HiTraceIdStruct id = HiTraceChainGetId(); 355b0e7dd80Sopenharmony_ci if (!HiTraceChainIsValid(&id)) { 356b0e7dd80Sopenharmony_ci return HITRACE_INFO_FAIL; 357b0e7dd80Sopenharmony_ci } 358b0e7dd80Sopenharmony_ci 359b0e7dd80Sopenharmony_ci if (HiTraceChainIsFlagEnabled(&id, HITRACE_FLAG_DONOT_ENABLE_LOG)) { 360b0e7dd80Sopenharmony_ci return HITRACE_INFO_FAIL; 361b0e7dd80Sopenharmony_ci } 362b0e7dd80Sopenharmony_ci 363b0e7dd80Sopenharmony_ci *chainId = HiTraceChainGetChainId(&id); 364b0e7dd80Sopenharmony_ci *flags = HiTraceChainGetFlags(&id); 365b0e7dd80Sopenharmony_ci 366b0e7dd80Sopenharmony_ci if (HiTraceChainIsFlagEnabled(&id, HITRACE_FLAG_DONOT_CREATE_SPAN)) { 367b0e7dd80Sopenharmony_ci *spanId = 0; 368b0e7dd80Sopenharmony_ci *parentSpanId = 0; 369b0e7dd80Sopenharmony_ci return HITRACE_INFO_ALL_VALID_EXCEPT_SPAN; 370b0e7dd80Sopenharmony_ci } 371b0e7dd80Sopenharmony_ci 372b0e7dd80Sopenharmony_ci *spanId = HiTraceChainGetSpanId(&id); 373b0e7dd80Sopenharmony_ci *parentSpanId = HiTraceChainGetParentSpanId(&id); 374b0e7dd80Sopenharmony_ci return HITRACE_INFO_ALL_VALID; 375b0e7dd80Sopenharmony_ci} 376b0e7dd80Sopenharmony_ci 377b0e7dd80Sopenharmony_ciHiTraceIdStruct HiTraceChainSaveAndSetId(const HiTraceIdStruct* pId) 378b0e7dd80Sopenharmony_ci{ 379b0e7dd80Sopenharmony_ci HiTraceIdStruct oldId = g_hiTraceId.id; 380b0e7dd80Sopenharmony_ci if (pId != NULL && pId->valid == HITRACE_ID_VALID) { 381b0e7dd80Sopenharmony_ci g_hiTraceId.id = *pId; 382b0e7dd80Sopenharmony_ci } 383b0e7dd80Sopenharmony_ci return oldId; 384b0e7dd80Sopenharmony_ci} 385b0e7dd80Sopenharmony_ci 386b0e7dd80Sopenharmony_civoid HiTraceChainRestoreId(const HiTraceIdStruct* pId) 387b0e7dd80Sopenharmony_ci{ 388b0e7dd80Sopenharmony_ci if (pId != NULL) { 389b0e7dd80Sopenharmony_ci g_hiTraceId.id = *pId; 390b0e7dd80Sopenharmony_ci } 391b0e7dd80Sopenharmony_ci} 392b0e7dd80Sopenharmony_ci 393b0e7dd80Sopenharmony_cistatic void __attribute__((constructor)) HiTraceChainInit(void) 394b0e7dd80Sopenharmony_ci{ 395b0e7dd80Sopenharmony_ci // Call HiLog Register Interface 396b0e7dd80Sopenharmony_ci HiLogRegisterGetIdFun(HiTraceChainGetInfo); 397b0e7dd80Sopenharmony_ci} 398b0e7dd80Sopenharmony_ci 399b0e7dd80Sopenharmony_cistatic void __attribute__((destructor)) HiTraceChainFini(void) 400b0e7dd80Sopenharmony_ci{ 401b0e7dd80Sopenharmony_ci HiLogUnregisterGetIdFun(HiTraceChainGetInfo); 402b0e7dd80Sopenharmony_ci} 403