XiangpengHao / VeryPM

Persistent Memory Tool Box

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

VeryPM - persistent memory tool box

Build Status

A set of progressive, non-intrusive, easy-to-use, and high performance persistent memory tools.

What's included:

  1. Epoch Manager1
  2. Garbage List
  3. Persistent CAS 2
  4. PM allocator (in progress)
  5. Pool Management (in progress)

Features

  • Progressive: components are self-sufficient, you don't need to include the whole forest just for a leaf.

  • Non-intrusive: pointers are 8-byte, typings are C++ standard.

  • Header-only

  • Persistent memory support, tested on real device.

  • High performance

Build

mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE={Debug|Release} -DPMEM={0|1} ..
make tests

1: Code adapted from PMwCAS with a few new features, all bugs are mine.

Usage - Epoch Manager and Garbage List

struct MockItem {
 public:
  MockItem() {}

  static void Destroy(void* destroyContext, void* p) {
    // some complex memory cleanup
  }

  /*
   * Usage one: manual epoch management
   * */ 
  void SolveNP(){
    epoch_manager_->Protect();

    // some algorithms to solve SAT

    epoch_manager_->Unprotect(); 
  }


  /*
   * Usage two: use epoch guard to automatically protect and unprotect
   * Makes it easy to ensure epoch protection boundaries tightly adhere to stack life
   * time even with complex control flow.
   * */
  void SolveP(){
    EpochGuard guard();

    // Some algorithms
  }
};


EpochManager epoch_manager_;
epoch_manager_.Initialize()

GarbageList garbage_list_;
// 1024 is the number of addresses that can be held aside for pointer stability.
garbage_list_.Initialize(&epoch_manager_, 1024);

// MockItem::Destory is the deallocation callback
garbage_list_.Push(new MockItem(), MockItem::Destroy, nullptr);
garbage_list_.Push(new MockItem(), MockItem::Destroy, nullptr);

Persistent Memory support

We require PMDK to support safe and efficient persistent memory operations.

Recovery

pool_ = pmemobj_open(pool_name, layout_name, pool_size, CREATE_MODE_RW);

// to create a new garbage list
garbage_list_.Initialize(&epoch_manager_, pool_, 1024);

// to recover an existing garbage list
garbage_list_.Recovery(&epoch_manager_, pool_);

Reserve Memory

Some persistent memory allocator, e.g. PMDK's, requires applications to pass a pre-existing memory location to store the pointer to the allocated memory.

For example:

void* mem = nullptr;
posix_memalign(&mem, CACHELINE_SIZE, size);

Storing mem on the stack is not safe, thus requires the application to mantain an allocation list, or even change the implementation significantly, so there is this function:

Garbagelist::Item* mem = garbage_list_.ReserveItem();
posix_memalign(&mem->removed_item, CACHELINE_SIZE, size);

The mem->removed_item is used to temporarily take the ownership of the allocated memory.

After the mem->removed_item is handed back to the data structure, the reserved memory slot should be cleared, otherwise it will be reclaimed on recovery:

garbage_list_.ResetItem(mem);

Caveat

Although both ReserveItem and ResetItem is crash/thread safe, when being used, typically they are protected by a (PMDK) transaction, because these functions implicitly implied ownership transfer which requires multi-cache line operations.

About

Persistent Memory Tool Box

License:MIT License


Languages

Language:C++ 96.7%Language:CMake 3.1%Language:Dockerfile 0.2%