libfoedus-core
FOEDUS Core Library
foedus::memory::RoundRobinPageGrabBatch Class Referencefinal

A helper class to grab a bunch of pages from multiple nodes in round-robin fashion per chunk. More...

Detailed Description

A helper class to grab a bunch of pages from multiple nodes in round-robin fashion per chunk.

This grabs a large number of pages much more efficiently than grabbing one-by-one from individual node. Instead, this is not a true round-robin per page because we switch node only per chunk, which is actually an advantage as it achieves contiguous memory that is friendly for CPU cache. So far this is used when create a new array storage, which requires to grab a large number of pages in round-robin fashion to balance memory usage.

Definition at line 332 of file page_pool.hpp.

#include <page_pool.hpp>

Public Member Functions

 RoundRobinPageGrabBatch (Engine *engine)
 
 ~RoundRobinPageGrabBatch ()
 
 RoundRobinPageGrabBatch ()=delete
 
 RoundRobinPageGrabBatch (const RoundRobinPageGrabBatch &)=delete
 
RoundRobinPageGrabBatchoperator= (const RoundRobinPageGrabBatch &)=delete
 
storage::VolatilePagePointer grab ()
 Grabs an in-memory page in some NUMA node. More...
 
void release_all ()
 Called at the end to return all remaining pages to their pools. More...
 

Constructor & Destructor Documentation

foedus::memory::RoundRobinPageGrabBatch::RoundRobinPageGrabBatch ( Engine engine)
explicit

Definition at line 194 of file page_pool.cpp.

195 : engine_(engine), numa_node_count_(engine->get_options().thread_.group_count_), current_node_(0) {
196 }
foedus::memory::RoundRobinPageGrabBatch::~RoundRobinPageGrabBatch ( )

Definition at line 198 of file page_pool.cpp.

References release_all().

198  {
199  release_all();
200 }
void release_all()
Called at the end to return all remaining pages to their pools.
Definition: page_pool.cpp:241

Here is the call graph for this function:

foedus::memory::RoundRobinPageGrabBatch::RoundRobinPageGrabBatch ( )
delete
foedus::memory::RoundRobinPageGrabBatch::RoundRobinPageGrabBatch ( const RoundRobinPageGrabBatch )
delete

Member Function Documentation

storage::VolatilePagePointer foedus::memory::RoundRobinPageGrabBatch::grab ( )

Grabs an in-memory page in some NUMA node.

This internally batches the pages to return. At the end, call release_all() to release unused pages. Although the type of returned value is VolatilePagePointer, it can be used for snapshot page, too. I just want to return both NUMA node and offset. Maybe we should have another typedef for it.

Todo:
this so far doesn't handle out-of-memory case gracefully. what to do..

Definition at line 202 of file page_pool.cpp.

References ASSERT_ND, foedus::memory::PagePoolOffsetChunk::capacity(), foedus::memory::PagePoolOffsetChunk::empty(), foedus::get_error_name(), foedus::Engine::get_memory_manager(), foedus::memory::EngineMemory::get_node_memory(), foedus::memory::PagePool::get_recommended_pages_per_grab(), foedus::memory::PagePool::grab(), foedus::kErrorCodeMemoryNoFreePages, foedus::kErrorCodeOk, foedus::memory::PagePoolOffsetChunk::pop_back(), foedus::print_backtrace(), and foedus::storage::VolatilePagePointer::set().

202  {
203  if (chunk_.empty()) {
204  const thread::ThreadGroupId old = current_node_;
205  while (true) {
206  ++current_node_;
207  if (current_node_ >= numa_node_count_) {
208  current_node_ = 0;
209  }
210  PagePool* pool = engine_->get_memory_manager()->get_node_memory(current_node_)->
211  get_volatile_pool();
212  uint32_t grab_count = std::min<uint32_t>(
213  chunk_.capacity(),
214  pool->get_recommended_pages_per_grab());
215  ErrorCode code = pool->grab(grab_count, &chunk_);
216  if (code == kErrorCodeOk) {
217  break;
218  }
219 
220  if (code == kErrorCodeMemoryNoFreePages) {
221  LOG(WARNING) << "NUMA node-" << current_node_ << " has no more free pages."
222  << " trying another node..";
223  if (current_node_ == old) {
224  print_backtrace();
225  LOG(FATAL) << "No NUMA node has any free pages. This situation is so far "
226  " not handled. Aborting";
227  }
228  } else {
229  LOG(FATAL) << "Unexpected error code.. wtf error="
230  << code << "(" << get_error_name(code) << ")";
231  }
232  }
233  ASSERT_ND(!chunk_.empty());
234  }
235 
236  storage::VolatilePagePointer ret;
237  ret.set(current_node_, chunk_.pop_back());
238  return ret;
239 }
const char * get_error_name(ErrorCode code)
Returns the names of ErrorCode enum defined in error_code.xmacro.
Definition: error_code.hpp:108
0 means no-error.
Definition: error_code.hpp:87
NumaNodeMemoryRef * get_node_memory(foedus::thread::ThreadGroupId group) const
0x0301 : "MEMORY : Not enough free volatile pages. Check the config of MemoryOptions" ...
Definition: error_code.hpp:142
std::string print_backtrace()
Prints out backtrace.
Definition: assert_nd.cpp:37
#define ASSERT_ND(x)
A warning-free wrapper macro of assert() that has no performance effect in release mode even when 'x'...
Definition: assert_nd.hpp:72
uint8_t ThreadGroupId
Typedef for an ID of ThreadGroup (NUMA node).
Definition: thread_id.hpp:38
memory::EngineMemory * get_memory_manager() const
See Memory Manager.
Definition: engine.cpp:50
ErrorCode
Enum of error codes defined in error_code.xmacro.
Definition: error_code.hpp:85

Here is the call graph for this function:

RoundRobinPageGrabBatch& foedus::memory::RoundRobinPageGrabBatch::operator= ( const RoundRobinPageGrabBatch )
delete
void foedus::memory::RoundRobinPageGrabBatch::release_all ( )

Called at the end to return all remaining pages to their pools.

The grabbed pages are not returned, of course.

Definition at line 241 of file page_pool.cpp.

References ASSERT_ND, foedus::memory::PagePoolOffsetChunk::empty(), foedus::Engine::get_memory_manager(), foedus::memory::EngineMemory::get_node_memory(), foedus::memory::NumaNodeMemoryRef::get_volatile_pool(), foedus::memory::PagePool::release(), and foedus::memory::PagePoolOffsetChunk::size().

Referenced by ~RoundRobinPageGrabBatch().

241  {
242  if (chunk_.empty()) {
243  return;
244  }
245 
246  engine_->get_memory_manager()->get_node_memory(current_node_)->get_volatile_pool()->release(
247  chunk_.size(), &chunk_);
248  ASSERT_ND(chunk_.empty());
249 }
NumaNodeMemoryRef * get_node_memory(foedus::thread::ThreadGroupId group) const
void release(uint32_t desired_release_count, PagePoolOffsetChunk *chunk)
Returns the specified number of free pages from the chunk.
Definition: page_pool.cpp:134
#define ASSERT_ND(x)
A warning-free wrapper macro of assert() that has no performance effect in release mode even when 'x'...
Definition: assert_nd.hpp:72
memory::EngineMemory * get_memory_manager() const
See Memory Manager.
Definition: engine.cpp:50

Here is the call graph for this function:

Here is the caller graph for this function:


The documentation for this class was generated from the following files: