xref: /aosp_15_r20/external/perfetto/src/trace_processor/trace_blob.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "perfetto/trace_processor/trace_blob.h"
18 
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
23     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
24     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
25 #include <sys/mman.h>
26 #endif
27 
28 #include <algorithm>
29 
30 #include "perfetto/base/compiler.h"
31 #include "perfetto/base/logging.h"
32 #include "perfetto/ext/base/scoped_mmap.h"
33 #include "perfetto/ext/base/utils.h"
34 #include "perfetto/trace_processor/basic_types.h"
35 #include "perfetto/trace_processor/ref_counted.h"
36 
37 namespace perfetto {
38 namespace trace_processor {
39 
40 // static
Allocate(size_t size)41 TraceBlob TraceBlob::Allocate(size_t size) {
42   TraceBlob blob(Ownership::kHeapBuf, new uint8_t[size], size);
43   PERFETTO_CHECK(blob.data_);
44   return blob;
45 }
46 
47 // static
CopyFrom(const void * src,size_t size)48 TraceBlob TraceBlob::CopyFrom(const void* src, size_t size) {
49   TraceBlob blob = Allocate(size);
50   const uint8_t* src_u8 = static_cast<const uint8_t*>(src);
51   std::copy(src_u8, src_u8 + size, blob.data_);
52   return blob;
53 }
54 
55 // static
TakeOwnership(std::unique_ptr<uint8_t[]> buf,size_t size)56 TraceBlob TraceBlob::TakeOwnership(std::unique_ptr<uint8_t[]> buf,
57                                    size_t size) {
58   PERFETTO_CHECK(buf);
59   return TraceBlob(Ownership::kHeapBuf, buf.release(), size);
60 }
61 
62 // static
FromMmap(base::ScopedMmap mapped)63 TraceBlob TraceBlob::FromMmap(base::ScopedMmap mapped) {
64   PERFETTO_CHECK(mapped.IsValid());
65   TraceBlob blob(Ownership::kNullOrMmaped, static_cast<uint8_t*>(mapped.data()),
66                  mapped.length());
67   blob.mapping_ = std::make_unique<base::ScopedMmap>(std::move(mapped));
68   return blob;
69 }
70 
71 // static
FromMmap(void * data,size_t size)72 TraceBlob TraceBlob::FromMmap(void* data, size_t size) {
73 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
74     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
75     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
76   PERFETTO_CHECK(data);
77   TraceBlob blob(Ownership::kNullOrMmaped, static_cast<uint8_t*>(data), size);
78   blob.mapping_ = std::make_unique<base::ScopedMmap>(
79       base::ScopedMmap::InheritMmappedRange(data, size));
80   return blob;
81 #else
82   base::ignore_result(data);
83   base::ignore_result(size);
84   PERFETTO_FATAL("mmap not supported");
85 #endif
86 }
87 
TraceBlob(Ownership ownership,uint8_t * data,size_t size)88 TraceBlob::TraceBlob(Ownership ownership, uint8_t* data, size_t size)
89     : ownership_(ownership), data_(data), size_(size) {}
90 
~TraceBlob()91 TraceBlob::~TraceBlob() {
92   switch (ownership_) {
93     case Ownership::kHeapBuf:
94       delete[] data_;
95       break;
96 
97     case Ownership::kNullOrMmaped:
98       if (mapping_) {
99         PERFETTO_CHECK(mapping_->reset());
100       }
101       break;
102   }
103   data_ = nullptr;
104   size_ = 0;
105 }
106 
TraceBlob(TraceBlob && other)107 TraceBlob::TraceBlob(TraceBlob&& other) noexcept
108     : RefCounted(std::move(other)) {
109   static_assert(
110       sizeof(*this) == base::AlignUp<sizeof(void*)>(
111                            sizeof(data_) + sizeof(size_) + sizeof(ownership_) +
112                            sizeof(mapping_) + sizeof(RefCounted)),
113       "TraceBlob move constructor needs updating");
114   data_ = other.data_;
115   size_ = other.size_;
116   ownership_ = other.ownership_;
117   mapping_ = std::move(other.mapping_);
118   other.data_ = nullptr;
119   other.size_ = 0;
120   other.ownership_ = Ownership::kNullOrMmaped;
121   other.mapping_ = nullptr;
122 }
123 
operator =(TraceBlob && other)124 TraceBlob& TraceBlob::operator=(TraceBlob&& other) noexcept {
125   if (this == &other)
126     return *this;
127   this->~TraceBlob();
128   new (this) TraceBlob(std::move(other));
129   return *this;
130 }
131 
132 }  // namespace trace_processor
133 }  // namespace perfetto
134