148f512ceSopenharmony_ci/* 248f512ceSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 348f512ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 448f512ceSopenharmony_ci * you may not use this file except in compliance with the License. 548f512ceSopenharmony_ci * You may obtain a copy of the License at 648f512ceSopenharmony_ci * 748f512ceSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 848f512ceSopenharmony_ci * 948f512ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1048f512ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1148f512ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1248f512ceSopenharmony_ci * See the License for the specific language governing permissions and 1348f512ceSopenharmony_ci * limitations under the License. 1448f512ceSopenharmony_ci */ 1548f512ceSopenharmony_ci#ifndef HIEPRF_UNIQUE_STACK_TABLE_H 1648f512ceSopenharmony_ci#define HIEPRF_UNIQUE_STACK_TABLE_H 1748f512ceSopenharmony_ci#include "utilities.h" 1848f512ceSopenharmony_ci#include <cinttypes> 1948f512ceSopenharmony_ci#include <linux/perf_event.h> 2048f512ceSopenharmony_ci#include <string> 2148f512ceSopenharmony_cinamespace OHOS { 2248f512ceSopenharmony_cinamespace Developtools { 2348f512ceSopenharmony_cinamespace HiPerf { 2448f512ceSopenharmony_ci 2548f512ceSopenharmony_ci#define ADDR_BIT_LENGTH 40 2648f512ceSopenharmony_ci#define IDX_BIT_LENGTH 23 2748f512ceSopenharmony_ci#define KERNEL_FLAG_BIT_LENGTH 1 2848f512ceSopenharmony_ci#define DECONFLICT_INCREASE_STEP 3 2948f512ceSopenharmony_ci#define RESIZE_MULTIPLE 2 3048f512ceSopenharmony_ci#define NR_BIT_LENGTH 41 3148f512ceSopenharmony_ci 3248f512ceSopenharmony_ciconstexpr uint32_t INITIAL_TABLE_SIZE = 4 * 1024 * 1024; 3348f512ceSopenharmony_ciconstexpr uint32_t MAX_NODES_CNT = 1 << IDX_BIT_LENGTH ; 3448f512ceSopenharmony_ciconstexpr uint64_t IP_IN_KERNEL = 1uLL << 63; 3548f512ceSopenharmony_ciconstexpr uint64_t HEAD_NODE_INDEX = 0; 3648f512ceSopenharmony_ci// FFFFFF0000000000 3748f512ceSopenharmony_ciconstexpr uint64_t KERNEL_PREFIX = 0xFFFFFFull << 40; 3848f512ceSopenharmony_ciconstexpr uint8_t INIT_DECONFLICT_ALLOWED = 22; 3948f512ceSopenharmony_ciconstexpr uint8_t HASH_STEP_BASE_MULTIPLE = 2; 4048f512ceSopenharmony_ciconstexpr uint8_t HASH_STEP_BASE_NUM = 1; 4148f512ceSopenharmony_ci 4248f512ceSopenharmony_ci// align 4348f512ceSopenharmony_ci#pragma pack(push, 4) 4448f512ceSopenharmony_ci 4548f512ceSopenharmony_ciunion Node { 4648f512ceSopenharmony_ci uint64_t value; 4748f512ceSopenharmony_ci struct { 4848f512ceSopenharmony_ci uint64_t ip : ADDR_BIT_LENGTH; 4948f512ceSopenharmony_ci uint64_t prevIdx : IDX_BIT_LENGTH; 5048f512ceSopenharmony_ci uint64_t inKernel : KERNEL_FLAG_BIT_LENGTH; 5148f512ceSopenharmony_ci } section; 5248f512ceSopenharmony_ci}; 5348f512ceSopenharmony_ci 5448f512ceSopenharmony_cistruct UniStackNode { 5548f512ceSopenharmony_ci uint32_t index; 5648f512ceSopenharmony_ci Node node; 5748f512ceSopenharmony_ci}; 5848f512ceSopenharmony_ci 5948f512ceSopenharmony_cistruct UniStackTableInfo { 6048f512ceSopenharmony_ci uint32_t pid; 6148f512ceSopenharmony_ci uint32_t tableSize; 6248f512ceSopenharmony_ci uint32_t numNodes; 6348f512ceSopenharmony_ci std::vector<UniStackNode> nodes; 6448f512ceSopenharmony_ci}; 6548f512ceSopenharmony_ci 6648f512ceSopenharmony_ciunion StackId { 6748f512ceSopenharmony_ci uint64_t value; 6848f512ceSopenharmony_ci struct { 6948f512ceSopenharmony_ci uint64_t id : IDX_BIT_LENGTH; 7048f512ceSopenharmony_ci uint64_t nr : NR_BIT_LENGTH; 7148f512ceSopenharmony_ci } section; 7248f512ceSopenharmony_ci}; 7348f512ceSopenharmony_ci 7448f512ceSopenharmony_ci#pragma pack(pop) 7548f512ceSopenharmony_cistatic_assert(sizeof(Node) == 8, "Node size must be 8 byte"); 7648f512ceSopenharmony_ci 7748f512ceSopenharmony_ciclass UniqueStackTable { 7848f512ceSopenharmony_cipublic: 7948f512ceSopenharmony_ci bool Init(); 8048f512ceSopenharmony_ci explicit UniqueStackTable(pid_t pid) : pid_(pid) 8148f512ceSopenharmony_ci { 8248f512ceSopenharmony_ci Init(); 8348f512ceSopenharmony_ci } 8448f512ceSopenharmony_ci 8548f512ceSopenharmony_ci UniqueStackTable(pid_t pid, uint32_t size) : pid_(pid), tableSize_(size) 8648f512ceSopenharmony_ci { 8748f512ceSopenharmony_ci Init(); 8848f512ceSopenharmony_ci } 8948f512ceSopenharmony_ci ~UniqueStackTable() 9048f512ceSopenharmony_ci { 9148f512ceSopenharmony_ci tableBuf_ = nullptr; 9248f512ceSopenharmony_ci } 9348f512ceSopenharmony_ci 9448f512ceSopenharmony_ci uint64_t PutIpsInTable(StackId *stackId, u64 *ips, u64 nr); 9548f512ceSopenharmony_ci bool GetIpsByStackId(const StackId stackId, std::vector<u64>& ips); 9648f512ceSopenharmony_ci bool ImportNode(uint32_t index, const Node& node); 9748f512ceSopenharmony_ci size_t GetWriteSize(); 9848f512ceSopenharmony_ci 9948f512ceSopenharmony_ci bool Resize(); 10048f512ceSopenharmony_ci 10148f512ceSopenharmony_ci uint32_t GetPid() 10248f512ceSopenharmony_ci { 10348f512ceSopenharmony_ci return pid_; 10448f512ceSopenharmony_ci } 10548f512ceSopenharmony_ci 10648f512ceSopenharmony_ci uint32_t GetTabelSize() 10748f512ceSopenharmony_ci { 10848f512ceSopenharmony_ci return tableSize_; 10948f512ceSopenharmony_ci } 11048f512ceSopenharmony_ci 11148f512ceSopenharmony_ci std::vector<uint32_t>& GetUsedIndexes() 11248f512ceSopenharmony_ci { 11348f512ceSopenharmony_ci return usedSlots_; 11448f512ceSopenharmony_ci } 11548f512ceSopenharmony_ci 11648f512ceSopenharmony_ci Node* GetHeadNode() 11748f512ceSopenharmony_ci { 11848f512ceSopenharmony_ci return reinterpret_cast<Node *>(tableBuf_.get()); 11948f512ceSopenharmony_ci } 12048f512ceSopenharmony_ci 12148f512ceSopenharmony_ciprivate: 12248f512ceSopenharmony_ci Node* GetFrame(uint64_t stackId); 12348f512ceSopenharmony_ci uint64_t PutIpInSlot(uint64_t thisIp, uint64_t prevIdx); 12448f512ceSopenharmony_ci u32 pid_; 12548f512ceSopenharmony_ci uint32_t tableSize_ = INITIAL_TABLE_SIZE; 12648f512ceSopenharmony_ci std::unique_ptr<uint8_t[]> tableBuf_ = nullptr; 12748f512ceSopenharmony_ci std::vector<uint32_t> usedSlots_; 12848f512ceSopenharmony_ci uint32_t totalNodes_ = 0; 12948f512ceSopenharmony_ci // current available node count, include index 0 13048f512ceSopenharmony_ci uint32_t availableNodes_ = 0; 13148f512ceSopenharmony_ci uint32_t hashModulus_ = 1; 13248f512ceSopenharmony_ci // 0 for reserved, start from 1 13348f512ceSopenharmony_ci uint32_t availableIndex_ = 1; 13448f512ceSopenharmony_ci // for de-conflict 13548f512ceSopenharmony_ci uint64_t hashStep_ = 0; 13648f512ceSopenharmony_ci uint8_t deconflictTimes_ = INIT_DECONFLICT_ALLOWED; 13748f512ceSopenharmony_ci}; 13848f512ceSopenharmony_ci 13948f512ceSopenharmony_ciusing ProcessStackMap = std::map<pid_t, std::shared_ptr<UniqueStackTable>>; 14048f512ceSopenharmony_ci} // namespace HiPerf 14148f512ceSopenharmony_ci} // namespace Developtools 14248f512ceSopenharmony_ci} // namespace OHOS 14348f512ceSopenharmony_ci#endif // HIEPRF_UNIQUE_STACK_TABLE_H