106f6ba60Sopenharmony_ci/*
206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License.
506f6ba60Sopenharmony_ci * You may obtain a copy of the License at
606f6ba60Sopenharmony_ci *
706f6ba60Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
806f6ba60Sopenharmony_ci *
906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and
1306f6ba60Sopenharmony_ci * limitations under the License.
1406f6ba60Sopenharmony_ci */
1506f6ba60Sopenharmony_ci#ifndef HIPERF_UTILITIES_H_
1606f6ba60Sopenharmony_ci#define HIPERF_UTILITIES_H_
1706f6ba60Sopenharmony_ci
1806f6ba60Sopenharmony_ci// for security function
1906f6ba60Sopenharmony_ci#include <securec.h>
2006f6ba60Sopenharmony_ci
2106f6ba60Sopenharmony_ci#include <algorithm>
2206f6ba60Sopenharmony_ci#include <cctype>
2306f6ba60Sopenharmony_ci#include <cinttypes>
2406f6ba60Sopenharmony_ci#include <cstdio>
2506f6ba60Sopenharmony_ci#include <fstream>
2606f6ba60Sopenharmony_ci#include <iomanip>
2706f6ba60Sopenharmony_ci#include <iostream>
2806f6ba60Sopenharmony_ci#include <sstream>
2906f6ba60Sopenharmony_ci#include <string>
3006f6ba60Sopenharmony_ci#include <vector>
3106f6ba60Sopenharmony_ci#include <unordered_set>
3206f6ba60Sopenharmony_ci
3306f6ba60Sopenharmony_ci#include <dirent.h>
3406f6ba60Sopenharmony_ci#include <fcntl.h>
3506f6ba60Sopenharmony_ci#include <file_ex.h>
3606f6ba60Sopenharmony_ci#include <stddef.h>
3706f6ba60Sopenharmony_ci#include <sys/stat.h>
3806f6ba60Sopenharmony_ci#include <unique_fd.h>
3906f6ba60Sopenharmony_ci#include <unistd.h>
4006f6ba60Sopenharmony_ci#if !is_mingw
4106f6ba60Sopenharmony_ci#include <sys/syscall.h>
4206f6ba60Sopenharmony_ci#endif
4306f6ba60Sopenharmony_ci#include <linux/types.h>
4406f6ba60Sopenharmony_ci
4506f6ba60Sopenharmony_ci#include "debug_logger.h"
4606f6ba60Sopenharmony_ci#include "noncopyable.h"
4706f6ba60Sopenharmony_ci
4806f6ba60Sopenharmony_ci// data and value
4906f6ba60Sopenharmony_ci/*
5006f6ba60Sopenharmony_cilong long always 64 only in ILP64, int is 64 otherwise int is always 32
5106f6ba60Sopenharmony_ci*/
5206f6ba60Sopenharmony_ciusing s8 = __s8;
5306f6ba60Sopenharmony_ciusing u8 = __u8;
5406f6ba60Sopenharmony_ciusing s16 = __s16;
5506f6ba60Sopenharmony_ciusing u16 = __u16;
5606f6ba60Sopenharmony_ciusing s32 = __s32;
5706f6ba60Sopenharmony_ciusing u32 = __u32;
5806f6ba60Sopenharmony_ciusing s64 = __s64;
5906f6ba60Sopenharmony_ciusing u64 = __u64;
6006f6ba60Sopenharmony_ci
6106f6ba60Sopenharmony_ciconstexpr const int NUMBER_FORMAT_HEX_BASE = 16;
6206f6ba60Sopenharmony_ciconstexpr const int BYTE_PRINT_WIDTH = 2;
6306f6ba60Sopenharmony_ciconstexpr const int UINT64_PRINT_WIDTH = BYTE_PRINT_WIDTH * 8;
6406f6ba60Sopenharmony_ciconstexpr const int BITS_OF_BYTE = 8;
6506f6ba60Sopenharmony_ciconstexpr const int BITS_OF_TWO_BYTE = 2 * BITS_OF_BYTE;
6606f6ba60Sopenharmony_ciconstexpr const int BITS_OF_FOUR_BYTE = 4 * BITS_OF_BYTE;
6706f6ba60Sopenharmony_ciconstexpr const int FULL_PERCENTAGE = 100;
6806f6ba60Sopenharmony_ciconstexpr const int FULL_PERCENTAGE_NUM_LEN = 5;      // 100.00
6906f6ba60Sopenharmony_ciconstexpr const int FULL_PERCENTAGE_DIFF_NUM_LEN = 6; // +100.00
7006f6ba60Sopenharmony_ciconstexpr const int FULL_PERCENTAGE_LEN = 6;          // 100.00%
7106f6ba60Sopenharmony_ciconstexpr const int FULL_PERCENTAGE_DIFF_LEN = 7;     // +100.00%
7206f6ba60Sopenharmony_ciconstexpr const int THOUSANDS = 1000;
7306f6ba60Sopenharmony_ciconstexpr const int HUNDREDS = 100;
7406f6ba60Sopenharmony_ciconstexpr const int DEFAULT_STRING_BUF_SIZE = 4096;
7506f6ba60Sopenharmony_ciconstexpr const int FIVE_THOUSANDS = 5000;
7606f6ba60Sopenharmony_ci#if !is_mingw
7706f6ba60Sopenharmony_ci#ifndef O_BINARY
7806f6ba60Sopenharmony_ci#define O_BINARY 0
7906f6ba60Sopenharmony_ci#endif
8006f6ba60Sopenharmony_ci#endif
8106f6ba60Sopenharmony_ci
8206f6ba60Sopenharmony_ciconstexpr const double MS_DUARTION =
8306f6ba60Sopenharmony_ci    static_cast<double>(std::chrono::milliseconds::duration::period::den);
8406f6ba60Sopenharmony_ci
8506f6ba60Sopenharmony_ciconstexpr uint64_t KILO = 1024;
8606f6ba60Sopenharmony_ci
8706f6ba60Sopenharmony_cinamespace OHOS {
8806f6ba60Sopenharmony_cinamespace Developtools {
8906f6ba60Sopenharmony_cinamespace NativeDaemon {
9006f6ba60Sopenharmony_cinamespace {
9106f6ba60Sopenharmony_ciconst std::string EMPTY_STRING = "";
9206f6ba60Sopenharmony_ciconstexpr int32_t STRING_POOL_SIZE = 4000;
9306f6ba60Sopenharmony_ci}
9406f6ba60Sopenharmony_ci
9506f6ba60Sopenharmony_ci// string function
9606f6ba60Sopenharmony_ciclass StringViewMemoryHold {
9706f6ba60Sopenharmony_cipublic:
9806f6ba60Sopenharmony_ci    const char *HoldStringView(const std::string& view)
9906f6ba60Sopenharmony_ci    {
10006f6ba60Sopenharmony_ci        pthread_spin_lock(&spin_lock_);
10106f6ba60Sopenharmony_ci        const char* str = stringSet_.emplace(view).first->data();
10206f6ba60Sopenharmony_ci        pthread_spin_unlock(&spin_lock_);
10306f6ba60Sopenharmony_ci        return str;
10406f6ba60Sopenharmony_ci    };
10506f6ba60Sopenharmony_ci
10606f6ba60Sopenharmony_ci    static StringViewMemoryHold& GetInstance()
10706f6ba60Sopenharmony_ci    {
10806f6ba60Sopenharmony_ci        static StringViewMemoryHold s;
10906f6ba60Sopenharmony_ci        return s;
11006f6ba60Sopenharmony_ci    }
11106f6ba60Sopenharmony_ci
11206f6ba60Sopenharmony_ci    void Clear()
11306f6ba60Sopenharmony_ci    {
11406f6ba60Sopenharmony_ci        pthread_spin_lock(&spin_lock_);
11506f6ba60Sopenharmony_ci        stringSet_.clear();
11606f6ba60Sopenharmony_ci        pthread_spin_unlock(&spin_lock_);
11706f6ba60Sopenharmony_ci    }
11806f6ba60Sopenharmony_ci
11906f6ba60Sopenharmony_ciprivate:
12006f6ba60Sopenharmony_ci    StringViewMemoryHold()
12106f6ba60Sopenharmony_ci    {
12206f6ba60Sopenharmony_ci        pthread_spin_init(&spin_lock_, PTHREAD_PROCESS_PRIVATE);
12306f6ba60Sopenharmony_ci    }
12406f6ba60Sopenharmony_ci    ~StringViewMemoryHold()
12506f6ba60Sopenharmony_ci    {
12606f6ba60Sopenharmony_ci        pthread_spin_destroy(&spin_lock_);
12706f6ba60Sopenharmony_ci    }
12806f6ba60Sopenharmony_ci    std::unordered_set<std::string> stringSet_{STRING_POOL_SIZE};
12906f6ba60Sopenharmony_ci    pthread_spinlock_t spin_lock_;
13006f6ba60Sopenharmony_ci};
13106f6ba60Sopenharmony_ci
13206f6ba60Sopenharmony_cistd::string StringReplace(std::string source, const std::string &from, const std::string &to);
13306f6ba60Sopenharmony_ci
13406f6ba60Sopenharmony_citemplate<class T>
13506f6ba60Sopenharmony_cistd::string VectorToString(const std::vector<T> &items)
13606f6ba60Sopenharmony_ci{
13706f6ba60Sopenharmony_ci    if constexpr (std::is_same<T, std::vector<std::string>>::value) {
13806f6ba60Sopenharmony_ci        std::vector<std::string> stringItems;
13906f6ba60Sopenharmony_ci        for (auto item : items) {
14006f6ba60Sopenharmony_ci            stringItems.push_back("[" + VectorToString(item) + "]");
14106f6ba60Sopenharmony_ci        }
14206f6ba60Sopenharmony_ci        return VectorToString(stringItems);
14306f6ba60Sopenharmony_ci    } else {
14406f6ba60Sopenharmony_ci        std::string itemsString;
14506f6ba60Sopenharmony_ci        const std::string split = ",";
14606f6ba60Sopenharmony_ci        for (auto& item : items) {
14706f6ba60Sopenharmony_ci            if (!itemsString.empty())
14806f6ba60Sopenharmony_ci                itemsString.append(split);
14906f6ba60Sopenharmony_ci            if constexpr (std::is_same<T, std::string>::value) {
15006f6ba60Sopenharmony_ci                itemsString.append(item);
15106f6ba60Sopenharmony_ci            } else {
15206f6ba60Sopenharmony_ci                itemsString.append(std::to_string(item));
15306f6ba60Sopenharmony_ci            }
15406f6ba60Sopenharmony_ci        }
15506f6ba60Sopenharmony_ci        if (itemsString.empty())
15606f6ba60Sopenharmony_ci            itemsString.append("<empty>");
15706f6ba60Sopenharmony_ci        return itemsString;
15806f6ba60Sopenharmony_ci    }
15906f6ba60Sopenharmony_ci}
16006f6ba60Sopenharmony_ci
16106f6ba60Sopenharmony_cistd::string BufferToHexString(const std::vector<unsigned char> &vec);
16206f6ba60Sopenharmony_cistd::string BufferToHexString(const unsigned char buf[], size_t size);
16306f6ba60Sopenharmony_civoid HexDump(const uint8_t *buf, size_t size, size_t max_size = 0);
16406f6ba60Sopenharmony_ci
16506f6ba60Sopenharmony_cistd::string &StringTrim(std::string &s);
16606f6ba60Sopenharmony_ci
16706f6ba60Sopenharmony_cistd::vector<std::string> StringSplit(std::string source, std::string split = ",");
16806f6ba60Sopenharmony_ci
16906f6ba60Sopenharmony_civoid AdvancedSplitString(const std::string_view& str, const std::string& delimiters, std::vector<std::string>& elems);
17006f6ba60Sopenharmony_ci
17106f6ba60Sopenharmony_cisize_t SubStringCount(const std::string &source, const std::string &sub);
17206f6ba60Sopenharmony_ci
17306f6ba60Sopenharmony_cibool StringStartsWith(const std::string &string, const std::string &with);
17406f6ba60Sopenharmony_ci
17506f6ba60Sopenharmony_cibool StringEndsWith(const std::string &string, const std::string &with);
17606f6ba60Sopenharmony_ci
17706f6ba60Sopenharmony_cibool IsSameCommand(std::string cmdLine, std::string cmdName);
17806f6ba60Sopenharmony_ci
17906f6ba60Sopenharmony_cistd::vector<pid_t> GetSubthreadIDs(const pid_t pid);
18006f6ba60Sopenharmony_ci
18106f6ba60Sopenharmony_cibool IsDigits(const std::string &str);
18206f6ba60Sopenharmony_ci
18306f6ba60Sopenharmony_cibool IsHexDigits(const std::string &str);
18406f6ba60Sopenharmony_ci
18506f6ba60Sopenharmony_ciconstexpr const int COMPRESS_READ_BUF_SIZE = 4096;
18606f6ba60Sopenharmony_ci// compress specified dataFile into gzip file
18706f6ba60Sopenharmony_cibool CompressFile(const std::string &dataFile, const std::string &destFile);
18806f6ba60Sopenharmony_ci// uncompress specified gzip file into dataFile
18906f6ba60Sopenharmony_cibool UncompressFile(const std::string &gzipFile, const std::string &dataFile);
19006f6ba60Sopenharmony_ci
19106f6ba60Sopenharmony_citemplate<typename... VA>
19206f6ba60Sopenharmony_cistd::string StringPrintf(const char *stringFormat, VA... args)
19306f6ba60Sopenharmony_ci{
19406f6ba60Sopenharmony_ci    // check howmany bytes we need
19506f6ba60Sopenharmony_ci    char bytes[DEFAULT_STRING_BUF_SIZE];
19606f6ba60Sopenharmony_ci    bytes[DEFAULT_STRING_BUF_SIZE - 1] = '\0';
19706f6ba60Sopenharmony_ci
19806f6ba60Sopenharmony_ci    if (stringFormat == nullptr) {
19906f6ba60Sopenharmony_ci        return EMPTY_STRING;
20006f6ba60Sopenharmony_ci    }
20106f6ba60Sopenharmony_ci
20206f6ba60Sopenharmony_ci    // print it to bytes
20306f6ba60Sopenharmony_ci    if (snprintf_s(bytes, sizeof(bytes), DEFAULT_STRING_BUF_SIZE - 1, stringFormat, args...) < 0) {
20406f6ba60Sopenharmony_ci        return EMPTY_STRING;
20506f6ba60Sopenharmony_ci    }
20606f6ba60Sopenharmony_ci
20706f6ba60Sopenharmony_ci    // make a string return
20806f6ba60Sopenharmony_ci    return std::string(bytes);
20906f6ba60Sopenharmony_ci}
21006f6ba60Sopenharmony_ci
21106f6ba60Sopenharmony_ci// path check
21206f6ba60Sopenharmony_cistd::vector<std::string> GetEntriesInDir(const std::string &basePath);
21306f6ba60Sopenharmony_ci
21406f6ba60Sopenharmony_cistd::vector<std::string> GetSubDirs(const std::string &basePath);
21506f6ba60Sopenharmony_ci
21606f6ba60Sopenharmony_cibool IsDir(const std::string &path);
21706f6ba60Sopenharmony_ci
21806f6ba60Sopenharmony_cibool IsPath(const std::string &fileName);
21906f6ba60Sopenharmony_ci
22006f6ba60Sopenharmony_ci#if is_mingw
22106f6ba60Sopenharmony_ciconst char PATH_SEPARATOR = '\\';
22206f6ba60Sopenharmony_ci#else
22306f6ba60Sopenharmony_ciconst char PATH_SEPARATOR = '/';
22406f6ba60Sopenharmony_ci#endif
22506f6ba60Sopenharmony_ciconst std::string PATH_SEPARATOR_STR = std::string(1, PATH_SEPARATOR);
22606f6ba60Sopenharmony_ci
22706f6ba60Sopenharmony_cistd::string PlatformPathConvert(const std::string &path);
22806f6ba60Sopenharmony_ci
22906f6ba60Sopenharmony_ci// attribute
23006f6ba60Sopenharmony_ci#define PACKED __attribute__((packed))
23106f6ba60Sopenharmony_ci
23206f6ba60Sopenharmony_ci// data align
23306f6ba60Sopenharmony_ci
23406f6ba60Sopenharmony_ci// some time u will meet signal 7 (SIGBUS), code 1 (BUS_ADRALN) in 32 or 64 arch cpu
23506f6ba60Sopenharmony_ci#define HIPERF_BUF_ALIGN alignas(64)
23606f6ba60Sopenharmony_ci
23706f6ba60Sopenharmony_ciuint32_t RoundUp(uint32_t x, const int align);
23806f6ba60Sopenharmony_ci
23906f6ba60Sopenharmony_ci// data convert funcion
24006f6ba60Sopenharmony_citemplate<class T>
24106f6ba60Sopenharmony_cistd::string ToHex(const T &source, int size = sizeof(T), bool perfix = false)
24206f6ba60Sopenharmony_ci{
24306f6ba60Sopenharmony_ci    std::stringstream ss;
24406f6ba60Sopenharmony_ci    if (perfix) {
24506f6ba60Sopenharmony_ci        ss << "0x";
24606f6ba60Sopenharmony_ci    }
24706f6ba60Sopenharmony_ci    ss << std::hex << std::setw(BYTE_PRINT_WIDTH * size) << std::setfill('0') << (uint64_t)source;
24806f6ba60Sopenharmony_ci    return ss.str();
24906f6ba60Sopenharmony_ci}
25006f6ba60Sopenharmony_ci
25106f6ba60Sopenharmony_ci// data move and copy
25206f6ba60Sopenharmony_citemplate<class S, class T>
25306f6ba60Sopenharmony_cisize_t inline CopyFromBufferAndMove(S *&buffer, T *dest, size_t size = 0)
25406f6ba60Sopenharmony_ci{
25506f6ba60Sopenharmony_ci    if (size == 0) {
25606f6ba60Sopenharmony_ci        size = sizeof(T);
25706f6ba60Sopenharmony_ci    }
25806f6ba60Sopenharmony_ci    if (memcpy_s(dest, size, buffer, size) != EOK) {
25906f6ba60Sopenharmony_ci        return size;
26006f6ba60Sopenharmony_ci    }
26106f6ba60Sopenharmony_ci    buffer = buffer + size;
26206f6ba60Sopenharmony_ci    return size;
26306f6ba60Sopenharmony_ci}
26406f6ba60Sopenharmony_ci
26506f6ba60Sopenharmony_ci// file read write
26606f6ba60Sopenharmony_cibool ReadIntFromProcFile(const std::string &path, int &value);
26706f6ba60Sopenharmony_cibool WriteIntToProcFile(const std::string &path, int value);
26806f6ba60Sopenharmony_cistd::string ReadFileToString(const std::string &fileName);
26906f6ba60Sopenharmony_cibool ReadFileToString(const std::string &fileName, std::string &content, size_t fileSize = 0);
27006f6ba60Sopenharmony_cibool WriteStringToFile(const std::string &fileName, const std::string &value);
27106f6ba60Sopenharmony_ci
27206f6ba60Sopenharmony_ci// stdout
27306f6ba60Sopenharmony_ciclass StdoutRecord {
27406f6ba60Sopenharmony_cipublic:
27506f6ba60Sopenharmony_ci    ~StdoutRecord()
27606f6ba60Sopenharmony_ci    {
27706f6ba60Sopenharmony_ci        Stop(); // stdout need restore
27806f6ba60Sopenharmony_ci    }
27906f6ba60Sopenharmony_ci    StdoutRecord(const std::string &tempFile = EMPTY_STRING,
28006f6ba60Sopenharmony_ci                 const std::string &mode = EMPTY_STRING);
28106f6ba60Sopenharmony_ci
28206f6ba60Sopenharmony_ci    bool Start();
28306f6ba60Sopenharmony_ci    std::string Stop();
28406f6ba60Sopenharmony_ci
28506f6ba60Sopenharmony_ciprivate:
28606f6ba60Sopenharmony_ci    OHOS::UniqueFd stdoutFile_;       // back and restore stdout
28706f6ba60Sopenharmony_ci    std::FILE *recordFile_ = nullptr; // save the output
28806f6ba60Sopenharmony_ci    bool stop_ = true;
28906f6ba60Sopenharmony_ci    std::string content_ = EMPTY_STRING;
29006f6ba60Sopenharmony_ci};
29106f6ba60Sopenharmony_ci
29206f6ba60Sopenharmony_ci// misc
29306f6ba60Sopenharmony_citemplate<class T>
29406f6ba60Sopenharmony_cifloat Percentage(const T &a, const T &b)
29506f6ba60Sopenharmony_ci{
29606f6ba60Sopenharmony_ci    return static_cast<float>(a) / static_cast<float>(b) * FULL_PERCENTAGE;
29706f6ba60Sopenharmony_ci}
29806f6ba60Sopenharmony_ci
29906f6ba60Sopenharmony_cibool IsRoot();
30006f6ba60Sopenharmony_cibool PowerOfTwo(int n);
30106f6ba60Sopenharmony_ci
30206f6ba60Sopenharmony_ci#define INDENT_ONE_LEVEL (indent + 1)
30306f6ba60Sopenharmony_ci#define INDENT_TWO_LEVEL (indent + 2)
30406f6ba60Sopenharmony_ci
30506f6ba60Sopenharmony_ci#define PrintIndent(indent, format, ...)                                                           \
30606f6ba60Sopenharmony_ci    if (indent >= 0) {                                                                             \
30706f6ba60Sopenharmony_ci        printf("%*s" format, (indent)*2, "", ##__VA_ARGS__);                                       \
30806f6ba60Sopenharmony_ci    } else {                                                                                       \
30906f6ba60Sopenharmony_ci        HLOGV("%s" format, "", ##__VA_ARGS__);                                                     \
31006f6ba60Sopenharmony_ci    }
31106f6ba60Sopenharmony_ci
31206f6ba60Sopenharmony_ci#ifndef MMAP_FAILED
31306f6ba60Sopenharmony_ci#define MMAP_FAILED (reinterpret_cast<void *>(-1))
31406f6ba60Sopenharmony_ci#endif
31506f6ba60Sopenharmony_ci#ifndef MAP_FAILED
31606f6ba60Sopenharmony_ci#define MAP_FAILED MMAP_FAILED
31706f6ba60Sopenharmony_ci#endif
31806f6ba60Sopenharmony_ciint32_t GetProcessPid(const std::string& processName);
31906f6ba60Sopenharmony_cibool IsArkJsFile(const std::string& filepath);
32006f6ba60Sopenharmony_ci} // namespace NativeDaemon
32106f6ba60Sopenharmony_ci} // namespace Developtools
32206f6ba60Sopenharmony_ci} // namespace OHOS
32306f6ba60Sopenharmony_ci
32406f6ba60Sopenharmony_ci// this will also used for libunwind head (out of namespace)
32506f6ba60Sopenharmony_ci#if is_mingw
32606f6ba60Sopenharmony_ci#define HAVE_MMAP   1
32706f6ba60Sopenharmony_ci#define MAP_PRIVATE 0x02
32806f6ba60Sopenharmony_ci#define PROT_NONE   0
32906f6ba60Sopenharmony_ci#define PROT_READ   1
33006f6ba60Sopenharmony_ci#define PROT_WRITE  2
33106f6ba60Sopenharmony_ci#define PROT_EXEC   4
33206f6ba60Sopenharmony_civoid *mmap(void *addr, size_t length, int prot, int flags, int fd, size_t offset);
33306f6ba60Sopenharmony_ciint munmap(void *addr, size_t);
33406f6ba60Sopenharmony_ci#endif
33506f6ba60Sopenharmony_ci
33606f6ba60Sopenharmony_ci#endif
337