• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
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 #include "stack_data_repeater.h"
16 #include "hook_common.h"
17 
18 using namespace OHOS::Developtools::NativeDaemon;
19 
StackDataRepeater(size_t maxSize)20 StackDataRepeater::StackDataRepeater(size_t maxSize)
21 {
22     maxSize_ = maxSize;
23     closed_ = false;
24     reducedStackCount_ = 0;
25 }
26 
~StackDataRepeater()27 StackDataRepeater::~StackDataRepeater()
28 {
29     Close();
30 }
31 
Size()32 size_t StackDataRepeater::Size()
33 {
34     std::unique_lock<std::mutex> lock(mutex_);
35     return rawDataQueue_.size();
36 }
37 
Reset()38 void StackDataRepeater::Reset()
39 {
40     std::unique_lock<std::mutex> lock(mutex_);
41     closed_ = false;
42 }
43 
Close()44 void StackDataRepeater::Close()
45 {
46     {
47         std::unique_lock<std::mutex> lock(mutex_);
48         rawDataQueue_.clear();
49         closed_ = true;
50     }
51     PROFILER_LOG_INFO(LOG_CORE, "StackDataRepeater Close, reducedStackCount_ : %" PRIx64 " ", reducedStackCount_);
52     slotCondVar_.notify_all();
53     itemCondVar_.notify_all();
54 }
55 
PutRawStack(const RawStackPtr & rawData,bool isRecordAccurately)56 bool StackDataRepeater::PutRawStack(const RawStackPtr& rawData, bool isRecordAccurately)
57 {
58     bool needInsert = true;
59     std::unique_lock<std::mutex> lock(mutex_);
60 
61     if ((rawData == nullptr) && (rawDataQueue_.size() > 0)) {
62         PROFILER_LOG_INFO(LOG_CORE, "no need put nullptr if queue has data, rawDataQueue_.size() = %zu",
63                           rawDataQueue_.size());
64         return true;
65     }
66     while (rawDataQueue_.size() >= maxSize_ && !closed_) {
67         slotCondVar_.wait(lock);
68     }
69     if (closed_) {
70         return false;
71     }
72 
73     if (__builtin_expect((rawData != nullptr) && !isRecordAccurately, true)) {
74         if (rawData->stackConext->type == FREE_MSG) {
75             auto temp = mallocMap_.find(rawData->stackConext->addr);
76             // true  : pair of malloc and free matched, both malloc and free will be ignored
77             // false : can not match, send free's data anyway
78             if (temp != mallocMap_.end()) {
79                 temp->second->reportFlag = false; // will be ignore later
80                 mallocMap_.erase(rawData->stackConext->addr);
81                 needInsert = false;
82             }
83         } else if (rawData->stackConext->type == MALLOC_MSG) {
84             mallocMap_.insert(std::pair<void*, std::shared_ptr<RawStack>>(rawData->stackConext->addr, rawData));
85         }
86         if (needInsert) {
87             rawDataQueue_.push_back(rawData);
88         }
89     } else {
90         rawDataQueue_.push_back(rawData);
91     }
92 
93     lock.unlock();
94     itemCondVar_.notify_one();
95     return true;
96 }
97 
TakeRawData(uint32_t during,clockid_t clockId,uint32_t batchCount,RawStackPtr batchRawStack[])98 RawStackPtr StackDataRepeater::TakeRawData(uint32_t during, clockid_t clockId, uint32_t batchCount,
99     RawStackPtr batchRawStack[])
100 {
101     uint32_t rawDataQueueSize = 0;
102     std::unique_lock<std::mutex> lock(mutex_);
103     while (rawDataQueue_.empty() && !closed_) {
104         itemCondVar_.wait(lock);
105     }
106     if (closed_) {
107         return nullptr;
108     }
109     RawStackPtr result = nullptr;
110     rawDataQueueSize = rawDataQueue_.size();
111     int resultSize = rawDataQueueSize > batchCount ? batchCount : rawDataQueueSize;
112     bool needReduceStack = rawDataQueueSize >= SPEED_UP_THRESHOLD;
113     for (int i = 0; i < resultSize; i++) {
114         result = rawDataQueue_.front();
115         rawDataQueue_.pop_front();
116         batchRawStack[i] = result;
117         if ((result != nullptr) && (result->stackConext->type == MALLOC_MSG)) {
118             mallocMap_.erase(result->stackConext->addr);
119             if (needReduceStack) {
120                 result->reduceStackFlag = true;
121                 reducedStackCount_++;
122             }
123         }
124     }
125 
126     lock.unlock();
127     slotCondVar_.notify_one();
128     return result;
129 }