blob: 50147f8f543160e8c448093e78a198be2287fc5b [file] [log] [blame]
/*
* Copyright 2014, 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.
*/
#ifndef ANDROID_CAZE_MEMORY_MANAGER_H
#define ANDROID_CAZE_MEMORY_MANAGER_H
#include <stdint.h>
#include <memory>
#include <type_traits>
#include <utility>
#include <vector>
namespace android {
namespace caze {
// Memory manager class for managing the memory used by the replay system. Outside of this class
// there shouldn't be any significant heap allocation in the replay daemon itself (small allocations
// are possible for bookkeeping)
//
// The layout of the memory managed by the memory manager (extra paddings are possible between the
// different memory regions):
// | In memory resource cache | Volatile Memory | Replay data |
class MemoryManager {
public:
// Creating a memory manager with try to allocate memory based on the size list provided.
// Stopping after the first successful allocation and cause a fatal error if all allocation was
// unsuccessful
explicit MemoryManager(const std::vector<uint32_t>& sizeList);
// Sets the size of the replay data. Returns true if the given size fits in the memory and false
// otherwise
bool setReplayDataSize(uint32_t size);
// Sets the size of the volatile memory. Returns true if the given size fits in the memory and
// false otherwise
bool setVolatileMemory(uint32_t size);
// Sets the size and the base address of the constant memory. The given memory range have to be
// inside the range of the volatile memory that is accessible with the getVolatileBaseAddress()
// and the getVloatileSize() function calls
void setConstantMemory(const std::pair<const void*, uint32_t>& constantMemory);
// Returns the size and the base address of the different memory regions managed by the memory
// manager
void* getBaseAddress() const { return mMemory.get(); }
void* getReplayAddress() const { return mReplayData.base; }
void* getVolatileAddress() const { return mVolatileMemory.base; }
uint32_t getSize() const { return mSize; }
uint32_t getConstantSize() const { return mConstantMemory.size; }
uint32_t getVolatileSize() const { return mVolatileMemory.size; }
// Converts a given relative (constant or volatile) pointer to an absolute pointer without
// checking if the given offset is inside the range of that memory
const void* constantToAbsolute(uint32_t offset) const;
void* volatileToAbsolute(uint32_t offset) const;
// Converts an absolute pointer to a relative (constant or volatile) pointer without checking if
// the address is inside the range
uint32_t absoluteToConstant(const void* address) const;
uint32_t absoluteToVolatile(const void* address) const;
// Checks if the given absolute pointer is points inside the constant or inside the volatile
// memory
bool isConstantAddress(const void* address) const;
bool isVolatileAddress(const void* address) const;
private:
// Struct to represent a memory interval inside the memory manager with its base address and its
// size
struct MemoryRange {
MemoryRange();
MemoryRange(uint8_t* base, uint32_t size);
uint8_t* end() const { return base + size; }
uint8_t* base;
uint32_t size;
};
// Alignment used for each memory region in bytes
static const uint32_t kAlignment = std::alignment_of<double>::value;
// Align a given pointer based on the 'kAlignment' value. The return address is always smaller
// or equal to the given address what is required by the memory layout used
uint8_t* align(uint8_t* addr) const;
// The size and the base address of the memory block managed by the memory manager. This pointer
// owns the allocated memory
uint32_t mSize;
std::unique_ptr<uint8_t[]> mMemory;
// The size and base address of the replay data. The memory range specified by these values have
// to specify a subset of the memory managed by the memory manager.
MemoryRange mReplayData;
// The size and base address of the constant memory. The constant memory is located inside the
// replay data, so the memory range specified by these values have to be the subset of the
// memory range specified by the replay data variables (size and pointer)
MemoryRange mConstantMemory;
// The size and the base address of the volatile memory. The memory range specified by these
// values have to specify a subset of the memory managed by the memory manager.
MemoryRange mVolatileMemory;
};
} // end of namespace caze
} // end of namespace android
#endif // ANDROID_CAZE_MEMORY_MANAGER_H