1 /* 2 * Copyright (C) 2024 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 #ifndef INCLUDE_PERFETTO_EXT_BASE_SCOPED_MMAP_H_ 18 #define INCLUDE_PERFETTO_EXT_BASE_SCOPED_MMAP_H_ 19 20 #include <cstddef> 21 22 #include "perfetto/base/build_config.h" 23 #include "perfetto/ext/base/scoped_file.h" 24 25 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \ 26 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) || \ 27 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \ 28 PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) 29 #define PERFETTO_HAS_MMAP() 1 30 #else 31 #define PERFETTO_HAS_MMAP() 0 32 #endif 33 34 namespace perfetto::base { 35 36 // RAII wrapper that holds ownership of an mmap()d area and of a file. Calls 37 // unmap() and close() on destruction. 38 class ScopedMmap { 39 public: 40 // Creates a memory mapping for the first `length` bytes of `file`. 41 static ScopedMmap FromHandle(base::ScopedPlatformHandle file, size_t length); 42 ScopedMmap()43 ScopedMmap() {} 44 ~ScopedMmap(); 45 ScopedMmap(ScopedMmap&& other) noexcept; 46 47 ScopedMmap& operator=(ScopedMmap&& other) noexcept; 48 49 // Returns a pointer to the mapped memory area. Only valid if `IsValid()` is 50 // true. data()51 void* data() const { return ptr_; } 52 53 // Returns true if this object contains a successfully mapped area. IsValid()54 bool IsValid() const { return ptr_ != nullptr; } 55 56 // Returns the length of the mapped area. length()57 size_t length() const { return length_; } 58 59 // Unmaps the area and closes the file. Returns false if this held a mmap()d 60 // area and unmapping failed. In any case, after this method, `IsValid()` will 61 // return false. 62 bool reset() noexcept; 63 64 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \ 65 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \ 66 PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) 67 // Takes ownership of an mmap()d area that starts at `data`, `size` bytes 68 // long. `data` should not be MAP_FAILED. 69 static ScopedMmap InheritMmappedRange(void* data, size_t size); 70 #endif 71 72 private: 73 ScopedMmap(const ScopedMmap&) = delete; 74 ScopedMmap& operator=(const ScopedMmap&) = delete; 75 76 size_t length_ = 0; 77 void* ptr_ = nullptr; 78 ScopedPlatformHandle file_; 79 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) 80 ScopedPlatformHandle map_; 81 #endif 82 }; 83 84 // Tries to open `fname` and maps its first `length` bytes in memory. 85 ScopedMmap ReadMmapFilePart(const char* fname, size_t length); 86 87 // Tries to open `fname` and maps the whole file into memory. 88 ScopedMmap ReadMmapWholeFile(const char* fname); 89 90 } // namespace perfetto::base 91 92 #endif // INCLUDE_PERFETTO_EXT_BASE_SCOPED_MMAP_H_ 93