21 #include <glog/logging.h>
43 numa_node_(numa_node),
44 cores_(engine_->get_options().thread_.thread_count_per_group_),
45 loggers_(engine_->get_options().log_.loggers_per_node_),
46 snapshot_cache_table_(nullptr) {
58 LOG(INFO) <<
"Initializing NumaNodeMemory for node " <<
static_cast<int>(numa_node_) <<
"."
64 uint64_t volatile_size =
73 std::string(
"VolatilePool-")
74 + std::to_string(static_cast<int>(numa_node_)));
77 uint64_t snapshot_pool_bytes
81 LOG(INFO) <<
"rigorous_page_boundary_check_ is specified, so disabled hugepages.";
88 reinterpret_cast<PagePoolControlBlock*>(snapshot_pool_control_block_.
get_block()),
94 std::string(
"SnapshotPool-")
95 + std::to_string(static_cast<int>(numa_node_)));
105 CHECK_ERROR(initialize_page_offset_chunk_memory());
107 for (
auto ordinal = 0; ordinal < cores_; ++ordinal) {
112 ASSERT_ND(core_memories_.size() == cores_);
113 ASSERT_ND(volatile_offset_chunk_memory_pieces_.size() == cores_);
114 ASSERT_ND(snapshot_offset_chunk_memory_pieces_.size() == cores_);
115 ASSERT_ND(log_buffer_memory_pieces_.size() == cores_);
117 LOG(INFO) <<
"Initialized NumaNodeMemory for node " <<
static_cast<int>(numa_node_) <<
"."
121 ErrorStack NumaNodeMemory::initialize_page_offset_chunk_memory() {
123 size_t total_size = size_per_core * cores_;
124 LOG(INFO) <<
"Initializing page_offset_chunk_memory_. total_size=" << total_size <<
" bytes";
128 LOG(INFO) <<
"Allocating extra space to utilize hugepage.";
132 for (
auto ordinal = 0; ordinal < cores_; ++ordinal) {
134 PagePoolOffsetChunk* chunk =
reinterpret_cast<PagePoolOffsetChunk*
>(
135 volatile_offset_chunk_memory_.
get_block()) + ordinal;
137 volatile_offset_chunk_memory_pieces_.push_back(chunk);
140 PagePoolOffsetChunk* chunk =
reinterpret_cast<PagePoolOffsetChunk*
>(
141 snapshot_offset_chunk_memory_.
get_block()) + ordinal;
143 snapshot_offset_chunk_memory_pieces_.push_back(chunk);
150 ErrorStack NumaNodeMemory::initialize_log_buffers_memory() {
152 uint64_t private_total = (cores_ * size_per_core_);
153 LOG(INFO) <<
"Initializing log_buffer_memory_. total_size=" << private_total;
155 LOG(INFO) <<
"log_buffer_memory_ allocated. addr=" << log_buffer_memory_.
get_block();
156 for (
auto ordinal = 0; ordinal < cores_; ++ordinal) {
157 AlignedMemorySlice piece(&log_buffer_memory_, size_per_core_ * ordinal, size_per_core_);
158 LOG(INFO) <<
"log_buffer_piece[" << ordinal <<
"] addr=" << piece.get_block();
159 log_buffer_memory_pieces_.push_back(piece);
168 NumaCoreMemory* core_memory =
new NumaCoreMemory(engine_,
this, core_id);
169 core_memories_.push_back(core_memory);
176 LOG(INFO) <<
"Uninitializing NumaNodeMemory for node " <<
static_cast<int>(numa_node_) <<
"."
181 volatile_offset_chunk_memory_pieces_.clear();
183 snapshot_offset_chunk_memory_pieces_.clear();
185 log_buffer_memory_pieces_.clear();
187 if (snapshot_cache_table_) {
188 delete snapshot_cache_table_;
189 snapshot_cache_table_ =
nullptr;
196 LOG(INFO) <<
"Uninitialized NumaNodeMemory for node " <<
static_cast<int>(numa_node_) <<
"."
208 && size >= (1ULL << 30) * 8 / 10) {
209 LOG(INFO) <<
"This is a big memory allocation. Let's use the mmap hugepage (1GB pages)";
221 std::stringstream ret;
223 ret <<
" Volatile-Pool: " << volatile_stat.
allocated_pages_ <<
" allocated pages, "
228 ret <<
" Snapshot-Pool: " << snapshot_stat.
allocated_pages_ <<
" allocated pages, "
236 : engine_(engine), numa_node_(numa_node) {
247 std::stringstream ret;
249 ret <<
" Volatile-Pool: " << volatile_stat.
allocated_pages_ <<
" allocated pages, "
void attach(PagePoolControlBlock *control_block, void *memory, uint64_t memory_size, bool owns, bool rigorous_page_boundary_check)
std::string dump_free_memory_stat() const
Report rough statistics of free memory.
uint64_t allocated_pages_
0x0001 : "GENERAL: Out of memory" .
ErrorStack allocate_numa_memory(uint64_t size, AlignedMemory *out) const
numa_alloc_onnode() and numa_free().
uint8_t ThreadLocalOrdinal
Typedef for a local ID of Thread (core), which is NOT unique across NUMA nodes.
void emprace_back(ErrorStack &&error_stack)
If the given ErrorStack is an error, this method adds it to the end of this batch.
#define ERROR_STACK(e)
Instantiates ErrorStack with the given foedus::error_code, creating an error stack with the current f...
int64_t get_numa_node_size(int node)
void release_block()
Releases the memory block.
Root package of FOEDUS (Fast Optimistic Engine for Data Unification Services).
NumaNodeMemoryRef()=delete
Brings error stacktrace information as return value of functions.
void * get_volatile_pool(SocId node)
void alloc(uint64_t size, uint64_t alignment, AllocType alloc_type, int numa_node) noexcept
Allocate a memory, releasing the current memory if exists.
long numa_node_size(int node, long *freep)
NodeMemoryAnchors * get_node_memory_anchors(SocId node)
std::string dump_free_memory_stat() const
Report rough statistics of free memory.
ErrorStack initialize_once() override
ErrorStack uninitialize() override
An idempotent method to release all resources of this object, if any.
const EngineOptions & get_options() const
const uint64_t kHugepageSize
So far 2MB is the only page size available via Transparent Huge Page (THP).
Batches zero or more ErrorStack objects to represent in one ErrorStack.
memory::MemoryOptions memory_
ErrorStack initialize() override
Acquires resources in this object, usually called right after constructor.
uint32_t log_buffer_kb_
Size in KB of log buffer for each worker thread.
Database engine object that holds all resources and provides APIs.
ErrorStack allocate_huge_numa_memory(uint64_t size, AlignedMemory *out) const
A NUMA-local hashtable of cached snapshot pages.
void * get_block() const
Returns the memory block.
Repository of all shared memory in one FOEDUS instance.
uint64_t get_size() const
Returns the byte size of the memory block.
ThreadId compose_thread_id(ThreadGroupId node, ThreadLocalOrdinal local_core)
Returns a globally unique ID of Thread (core) for the given node and ordinal in the node...
#define SUMMARIZE_ERROR_BATCH(x)
This macro calls ErrorStackBatch::summarize() with automatically provided parameters.
bool use_mmap_hugepages_
Whether to use non-transparent hugepages for big memories (1GB huge pages).
To reduce the overhead of grabbing/releasing pages from pool, we pack this many pointers for each gra...
#define CHECK_ERROR(x)
This macro calls x and checks its returned value.
uint32_t page_pool_size_mb_per_node_
Size of the page pool in MB per each NUMA node.
Represents one memory block aligned to actual OS/hardware pages.
void uninitialize_and_delete_all(std::vector< T * > *vec)
A convenience method to uninitialize and delete all Initializable objects in a vector, storing all errors in this batch.
const ErrorStack kRetOk
Normal return value for no-error case.
soc::SocManager * get_soc_manager() const
See SOC and IPC.
uint64_t get_memory_size() const
ErrorStack uninitialize_once() override
uint32_t snapshot_cache_size_mb_per_node_
Size of the snapshot cache in MB per each NUMA node.
bool is_initialized() const override
Returns whether the object has been already initialized or not.
#define ASSERT_ND(x)
A warning-free wrapper macro of assert() that has no performance effect in release mode even when 'x'...
uint8_t ThreadGroupId
Typedef for an ID of ThreadGroup (NUMA node).
bool rigorous_page_boundary_check_
Whether to use mprotect() for page boundaries to detect bogus memory accesses.
memory::PagePoolControlBlock * volatile_pool_status_
PagePool's status and its synchronization mechanism for the volatile pool on this node...
const uint16_t kPageSize
A constant defining the page size (in bytes) of both snapshot pages and volatile pages.
ErrorStack allocate_numa_memory_general(uint64_t size, uint64_t alignment, AlignedMemory *out) const
Allocate a memory of the given size on this NUMA node.
void set_debug_pool_name(const std::string &name)
Call this anytime after attach()
cache::CacheOptions cache_
SharedMemoryRepo * get_shared_memory_repo()
Returns the shared memories maintained across SOCs.
bool is_null() const
Returns if this object doesn't hold a valid memory block.