1 /*
2 * Copyright (C) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "trace_buffer_manager.h"
17
18 #include <cinttypes>
19 #include <iostream>
20 #include <memory>
21 #include <vector>
22 #include <mutex>
23
24 #include "hilog/log.h"
25 #include "securec.h"
26
27 namespace OHOS {
28 namespace HiviewDFX {
29 namespace Hitrace {
30 namespace {
31 #ifdef LOG_DOMAIN
32 #undef LOG_DOMAIN
33 #define LOG_DOMAIN 0xD002D33
34 #endif
35 #ifdef LOG_TAG
36 #undef LOG_TAG
37 #define LOG_TAG "HitraceBufferManager"
38 #endif
39 } // namespace
40
FreeBytes() const41 size_t BufferBlock::FreeBytes() const
42 {
43 return data.size() - usedBytes;
44 }
45
Append(const uint8_t * src,size_t size)46 bool BufferBlock::Append(const uint8_t* src, size_t size)
47 {
48 if (FreeBytes() < size) {
49 HILOG_ERROR(LOG_CORE, "Append : cannot append more data");
50 return false;
51 }
52 if (memcpy_s(data.data() + usedBytes, size, src, size) != EOK) {
53 HILOG_ERROR(LOG_CORE, "Append : memcpy_s failed");
54 return false;
55 }
56 usedBytes += size;
57 return true;
58 }
59
AllocateBlock(const uint64_t taskId,const int cpu)60 BufferBlockPtr TraceBufferManager::AllocateBlock(const uint64_t taskId, const int cpu)
61 {
62 std::lock_guard<std::mutex> lck(mutex_);
63
64 if (curTotalSz_ + blockSz_ > maxTotalSz_) {
65 HILOG_ERROR(LOG_CORE, "AllocateBlock : taskid(%{public}" PRIu64 ") cannot allocate more blocks", taskId);
66 return nullptr;
67 }
68
69 auto buffer = std::make_shared<BufferBlock>(cpu, blockSz_);
70 taskBuffers_[taskId].push_back(buffer);
71 curTotalSz_ += blockSz_;
72 return buffer;
73 }
74
ReleaseTaskBlocks(const uint64_t taskId)75 void TraceBufferManager::ReleaseTaskBlocks(const uint64_t taskId)
76 {
77 std::lock_guard<std::mutex> lck(mutex_);
78 if (auto it = taskBuffers_.find(taskId); it != taskBuffers_.end()) {
79 size_t released = it->second.size() * blockSz_;
80 curTotalSz_ -= released;
81 taskBuffers_.erase(it);
82 }
83 }
84
GetTaskBuffers(const uint64_t taskId)85 BufferList TraceBufferManager::GetTaskBuffers(const uint64_t taskId)
86 {
87 std::lock_guard<std::mutex> lck(mutex_);
88 if (auto it = taskBuffers_.find(taskId); it != taskBuffers_.end()) {
89 return it->second;
90 }
91 HILOG_WARN(LOG_CORE, "GetTaskBuffers : taskid(%{public}" PRIu64 ") not found.", taskId);
92 return {};
93 }
94
GetTaskTotalUsedBytes(const uint64_t taskId)95 size_t TraceBufferManager::GetTaskTotalUsedBytes(const uint64_t taskId)
96 {
97 size_t totalUsed = 0;
98 std::lock_guard<std::mutex> lck(mutex_);
99 if (auto it = taskBuffers_.find(taskId); it != taskBuffers_.end()) {
100 for (auto& bufBlock : it->second) {
101 totalUsed += bufBlock->usedBytes;
102 }
103 }
104 return totalUsed;
105 }
106
GetCurrentTotalSize()107 size_t TraceBufferManager::GetCurrentTotalSize()
108 {
109 std::lock_guard<std::mutex> lck(mutex_);
110 return curTotalSz_;
111 }
112
GetBlockSize() const113 size_t TraceBufferManager::GetBlockSize() const
114 {
115 return blockSz_;
116 }
117 } // namespace Hitrace
118 } // namespace HiviewDFX
119 } // namespace OHOS