blob: 150d8c73d040a298a7b89891c0edb2978a1cea21 [file] [log] [blame]
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "dctv.h"
#include <utility>
#include <sys/mman.h>
#include "bitbash.h"
namespace dctv {
// Basic handle to a region of address space managed with mmap or
// something like mmap. The mapping's size is rounded up to whatever
// the current system's allocation granularity is, and the size
// reported by the mapping is this expanded size.
struct Mmap : NoCopy {
inline constexpr Mmap(Mmap&& other) noexcept;
inline constexpr Mmap& operator=(Mmap&& other) noexcept;
inline ~Mmap() noexcept;
static Mmap map(
void* addr,
size_t nbytes,
int prot,
int flags,
int fd,
off_t offset);
static Mmap anonymous(size_t nbytes);
inline void* addr() const noexcept;
inline size_t nbytes() const noexcept;
inline void release() noexcept; // Stop managing the memory region
protected:
inline Mmap(void* addr, size_t nbytes) noexcept;
void do_unmap() noexcept;
void* addr_;
size_t nbytes_;
};
// A memory mapping that can be mapped into several places in virtual
// memory at once without copying the underlying bytes.
struct MmapShared : Mmap {
// Make a new mapping of the given size somewhere. If NEW_ADDR is
// non-nullptr, place the mapping at NEW_ADDR.
static MmapShared make(size_t nbytes, void* new_addr = nullptr);
// Make a new mapping backed by a file.
static MmapShared of_file(int fd, size_t nbytes, int prot);
// Create another mapping of this memory at a specific location.
// If NEW_ADDR is nullptr, the OS picks the new location.
// If NEW_NBYTES is zero, it defaults to the size of this mapping.
// NEW_NBYTES is the size of the new mapping, which can be smaller
// than the source.
MmapShared dup(void* new_addr = nullptr,
size_t new_nbytes = 0);
// Resize this mapping while preserving contents. May change the
// base address of the mapping!
void resize(size_t new_nbytes);
private:
explicit inline MmapShared(Mmap&& mmap) noexcept;
inline MmapShared(void* addr, size_t nbytes) noexcept;
};
// The const attribute here helps the compiler prevent re-reads of
// cached_page_size.
extern const size_t cached_page_size;
__attribute__((const)) inline size_t page_size() noexcept;
inline size_t mmap_round_size_up(size_t nbytes) noexcept;
inline size_t mmap_round_size_down(size_t nbytes) noexcept;
inline bool mmap_aligned_p(size_t bytes) noexcept;
} // namespace dctv
#include "mmap-inl.h"