1484543d1Sopenharmony_ci/* 2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License. 5484543d1Sopenharmony_ci * You may obtain a copy of the License at 6484543d1Sopenharmony_ci * 7484543d1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8484543d1Sopenharmony_ci * 9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and 13484543d1Sopenharmony_ci * limitations under the License. 14484543d1Sopenharmony_ci */ 15484543d1Sopenharmony_ci#ifndef UTIL_TIME_FORMAT_H 16484543d1Sopenharmony_ci#define UTIL_TIME_FORMAT_H 17484543d1Sopenharmony_ci 18484543d1Sopenharmony_ci#include <chrono> 19484543d1Sopenharmony_ci#include <string> 20484543d1Sopenharmony_ci#include <securec.h> 21484543d1Sopenharmony_ci 22484543d1Sopenharmony_cinamespace ffrt { 23484543d1Sopenharmony_citypedef enum { 24484543d1Sopenharmony_ci millisecond, 25484543d1Sopenharmony_ci microsecond, 26484543d1Sopenharmony_ci} time_unit_t; 27484543d1Sopenharmony_ci 28484543d1Sopenharmony_cistatic std::string FormatDateString(const std::chrono::system_clock::time_point& timePoint, 29484543d1Sopenharmony_ci time_unit_t timeUnit = millisecond) 30484543d1Sopenharmony_ci{ 31484543d1Sopenharmony_ci constexpr int MaxMsLength = 3; 32484543d1Sopenharmony_ci constexpr int MsPerSecond = 1000; 33484543d1Sopenharmony_ci constexpr int DatetimeStringLength = 80; 34484543d1Sopenharmony_ci constexpr int MaxUsLength = 6; 35484543d1Sopenharmony_ci constexpr int UsPerSecond = 1000 * 1000; 36484543d1Sopenharmony_ci 37484543d1Sopenharmony_ci std::string remainder; 38484543d1Sopenharmony_ci if (timeUnit == microsecond) { 39484543d1Sopenharmony_ci auto tp = std::chrono::time_point_cast<std::chrono::microseconds>(timePoint); 40484543d1Sopenharmony_ci auto us = tp.time_since_epoch().count() % UsPerSecond; 41484543d1Sopenharmony_ci remainder = std::to_string(us); 42484543d1Sopenharmony_ci if (remainder.length() < MaxUsLength) { 43484543d1Sopenharmony_ci remainder = std::string(MaxUsLength - remainder.length(), '0') + remainder; 44484543d1Sopenharmony_ci } 45484543d1Sopenharmony_ci } else { 46484543d1Sopenharmony_ci auto tp = std::chrono::time_point_cast<std::chrono::milliseconds>(timePoint); 47484543d1Sopenharmony_ci auto ms = tp.time_since_epoch().count() % MsPerSecond; 48484543d1Sopenharmony_ci remainder = std::to_string(ms); 49484543d1Sopenharmony_ci if (remainder.length() < MaxMsLength) { 50484543d1Sopenharmony_ci remainder = std::string(MaxMsLength - remainder.length(), '0') + remainder; 51484543d1Sopenharmony_ci } 52484543d1Sopenharmony_ci } 53484543d1Sopenharmony_ci auto tt = std::chrono::system_clock::to_time_t(timePoint); 54484543d1Sopenharmony_ci struct tm curTime; 55484543d1Sopenharmony_ci if (memset_s(&curTime, sizeof(curTime), 0, sizeof(curTime)) != EOK) { 56484543d1Sopenharmony_ci FFRT_LOGE("Fail to memset"); 57484543d1Sopenharmony_ci return ""; 58484543d1Sopenharmony_ci } 59484543d1Sopenharmony_ci localtime_r(&tt, &curTime); 60484543d1Sopenharmony_ci char sysTime[DatetimeStringLength]; 61484543d1Sopenharmony_ci std::strftime(sysTime, sizeof(char) * DatetimeStringLength, "%Y-%m-%d %H:%M:%S.", &curTime); 62484543d1Sopenharmony_ci return std::string(sysTime) + remainder; 63484543d1Sopenharmony_ci} 64484543d1Sopenharmony_ci 65484543d1Sopenharmony_cistatic std::string FormatDateString4SteadyClock(uint64_t steadyClockTimeStamp, time_unit_t timeUnit = millisecond) 66484543d1Sopenharmony_ci{ 67484543d1Sopenharmony_ci static uint64_t globalTimeStamp = std::chrono::duration_cast<std::chrono::microseconds>( 68484543d1Sopenharmony_ci std::chrono::steady_clock::now().time_since_epoch()).count(); 69484543d1Sopenharmony_ci static auto globalTp = std::chrono::system_clock::now(); 70484543d1Sopenharmony_ci 71484543d1Sopenharmony_ci std::chrono::microseconds us((int64_t)(steadyClockTimeStamp - globalTimeStamp)); 72484543d1Sopenharmony_ci return FormatDateString(globalTp + us, timeUnit); 73484543d1Sopenharmony_ci} 74484543d1Sopenharmony_ci 75484543d1Sopenharmony_cistatic inline uint64_t Arm64CntFrq(void) 76484543d1Sopenharmony_ci{ 77484543d1Sopenharmony_ci uint64_t freq = 1; 78484543d1Sopenharmony_ci asm volatile("mrs %0, cntfrq_el0" : "=r" (freq)); 79484543d1Sopenharmony_ci return freq; 80484543d1Sopenharmony_ci} 81484543d1Sopenharmony_ci 82484543d1Sopenharmony_cistatic inline uint64_t Arm64CntCt(void) 83484543d1Sopenharmony_ci{ 84484543d1Sopenharmony_ci uint64_t tsc = 1; 85484543d1Sopenharmony_ci asm volatile("mrs %0, cntvct_el0" : "=r" (tsc)); 86484543d1Sopenharmony_ci return tsc; 87484543d1Sopenharmony_ci} 88484543d1Sopenharmony_ci 89484543d1Sopenharmony_cistatic std::string FormatDateString4CntCt(uint64_t cntCtTimeStamp, time_unit_t timeUnit = millisecond) 90484543d1Sopenharmony_ci{ 91484543d1Sopenharmony_ci constexpr int Ratio = 1000 * 1000; 92484543d1Sopenharmony_ci 93484543d1Sopenharmony_ci static int64_t globalFreq = Arm64CntFrq(); 94484543d1Sopenharmony_ci if (globalFreq == 0) { 95484543d1Sopenharmony_ci return ""; 96484543d1Sopenharmony_ci } 97484543d1Sopenharmony_ci static uint64_t globalCntCt = Arm64CntCt(); 98484543d1Sopenharmony_ci static auto globalTp = std::chrono::system_clock::now(); 99484543d1Sopenharmony_ci std::chrono::microseconds us((int64_t)(cntCtTimeStamp - globalCntCt) * Ratio / globalFreq); 100484543d1Sopenharmony_ci return FormatDateString(globalTp + us, timeUnit); 101484543d1Sopenharmony_ci} 102484543d1Sopenharmony_ci} 103484543d1Sopenharmony_ci#endif // UTIL_TIME_FORAMT_H 104