* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This file is part of the MindStudio project.
*
* MindStudio is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*/
#include "csrc/common/utils.h"
#include <linux/limits.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <ctime>
#include <unordered_map>
#include "csrc/common/plog_manager.h"
#include "securec.h"
namespace Mspti
{
namespace Common
{
const std::unordered_map<std::string, std::string> INVALID_CHAR = {
{"\n", "\\n"}, {"\f", "\\f"}, {"\r", "\\r"}, {"\b", "\\b"}, {"\t", "\\t"}, {"\v", "\\v"},
{"\u007F", "\\u007F"}, {"\"", "\\\""}, {"'", "\'"}, {"\\", "\\\\"}, {"%", "\\%"}, {">", "\\>"},
{"<", "\\<"}, {"|", "\\|"}, {"&", "\\&"}, {"$", "\\$"}, {";", "\\;"}, {"`", "\\`"}};
uint64_t Utils::GetClockMonotonicRawNs()
{
struct timespec ts;
if (memset_s(&ts, sizeof(timespec), 0, sizeof(timespec)) != EOK)
{
return 0;
}
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
return static_cast<uint64_t>(ts.tv_sec) * SECTONSEC + static_cast<uint64_t>(ts.tv_nsec);
}
uint64_t Utils::GetClockRealTimeNs()
{
struct timespec ts;
if (memset_s(&ts, sizeof(timespec), 0, sizeof(timespec)) != EOK)
{
return 0;
}
clock_gettime(CLOCK_REALTIME, &ts);
return static_cast<uint64_t>(ts.tv_sec) * SECTONSEC + static_cast<uint64_t>(ts.tv_nsec);
}
uint64_t Utils::GetHostSysCnt()
{
uint64_t cycles;
#if defined(__aarch64__)
asm volatile("mrs %0, cntvct_el0" : "=r"(cycles));
#elif defined(__x86_64__)
constexpr uint32_t uint32Bits = 32U;
uint32_t hi = 0;
uint32_t lo = 0;
__asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
cycles = (static_cast<uint64_t>(lo)) | ((static_cast<uint64_t>(hi)) << uint32Bits);
#elif defined(__arm__)
const uint32_t uint32Bits = 32U;
uint32_t hi = 0;
uint32_t lo = 0;
asm volatile("mrrc p15, 1, %0, %1, c14" : "=r"(lo), "=r"(hi));
cycles = (static_cast<uint64_t>(lo)) | ((static_cast<uint64_t>(hi)) << uint32Bits);
#else
cycles = 0;
#endif
return cycles;
}
uint32_t Utils::GetPid()
{
static thread_local uint32_t pid = static_cast<uint32_t>(getpid());
return pid;
}
uint32_t Utils::GetTid()
{
static thread_local uint32_t tid = static_cast<uint32_t>(syscall(SYS_gettid));
return tid;
}
std::string Utils::RealPath(const std::string& path)
{
if (path.empty() || path.size() > PATH_MAX)
{
return "";
}
char realPath[PATH_MAX] = {0};
if (realpath(path.c_str(), realPath) == nullptr)
{
return "";
}
return std::string(realPath);
}
std::string Utils::RelativeToAbsPath(const std::string& path)
{
if (path.empty() || path.size() > PATH_MAX)
{
return "";
}
if (path[0] != '/')
{
char pwd_path[PATH_MAX] = {0};
if (getcwd(pwd_path, PATH_MAX) != nullptr)
{
return std::string(pwd_path) + "/" + path;
}
return "";
}
return std::string(path);
}
bool Utils::FileExist(const std::string& path)
{
if (path.empty() || path.size() > PATH_MAX)
{
return false;
}
return (access(path.c_str(), F_OK) == 0) ? true : false;
}
bool Utils::FileReadable(const std::string& path)
{
if (path.empty() || path.size() > PATH_MAX)
{
return false;
}
return (access(path.c_str(), R_OK) == 0) ? true : false;
}
bool Utils::CheckCharValid(const std::string& str)
{
for (auto& item : INVALID_CHAR)
{
if (str.find(item.first) != std::string::npos)
{
MSPTI_LOGE("The path contains invalid character: %s.", item.second.c_str());
return false;
}
}
return true;
}
std::string Utils::GetEnv(const std::string& name)
{
const char* value = std::getenv(name.c_str());
return value ? std::string(value) : std::string();
}
bool Utils::StartsWith(const std::string& str, const std::string& prefix)
{
if (prefix.size() > str.size())
{
return false;
}
return str.compare(0, prefix.size(), prefix) == 0;
}
}
}