khizmax/libcds

BronsonAVLTreeMap Usage

Closed this issue · 4 comments

I am having trouble with setting up the BronsonAVLTreeMap. In particular, I observe this assertion failure:

map_test: /home/parallels/git/peloton/third_party/libcds/cds/urcu/details/gp.h:94: static bool cds::urcu::details::gp_thread_gc<GPRCUtag>::is_locked() [with GPRCUtag = cds::urcu::general_buffered_tag]: Assertion `pRec != nullptr' failed.

Relevant code snippets:

// HEADER FILE

#include "libcds/cds/init.h"
#include "libcds/cds/urcu/general_buffered.h"
#include "libcds/cds/sync/pool_monitor.h"
#include "libcds/cds/memory/vyukov_queue_pool.h"
#include "libcds/cds/container/bronson_avltree_map_rcu.h"

  // rcu implementation
  typedef cds::urcu::general_buffered<> RCUImpl;

  // rcu type
  typedef cds::urcu::gc<RCUImpl> RCUType;

  typedef cds::container::BronsonAVLTreeMap<RCUType, KeyType, MappedType> avl_tree_t;
// SOURCE FILE

MAP_TEMPLATE_ARGUMENTS
MAP_TYPE::Map(){

  // Create URCU general_buffered singleton
  RCUImpl::Construct();

}

MAP_TEMPLATE_ARGUMENTS
MAP_TYPE::~Map(){

  // Destroy URCU general_buffered singleton
  RCUImpl::Destruct();

}
// TEST FILE

TEST_F(MapTest, BasicTest) {
  size_t const element_count = 3;

  // Initialize CDS library
  cds::Initialize();

  typedef uint32_t  key_type;
  typedef uint32_t  value_type;
  typedef uint32_t* value_ptr_type;

  {
    // Attach thread
    cds::threading::Manager::attachThread();

    Map<key_type, value_type> map;

    for (size_t element = 0; element < element_count; ++element ) {
      value_ptr_type val = new value_type(element);
      auto status = map.Insert(element, val);
    }

    EXPECT_EQ(map.GetSize(), element_count);

    // Detach thread
    cds::threading::Manager::detachThread();
  }

  // Terminate CDS library
  cds::Terminate();

}

Any pointers would be helpful. Thanks.

Hi,

You should construct RCU before attachThread():

 // Initialize CDS library
  cds::Initialize();

{
    // Initialize RCU
    RCUType rcu;

    // Attach thread
    cds::threading::Manager::attachThread();

   // now yu can do all you need
   ....

    // Detach thread
    cds::threading::Manager::detachThread();
}

// Terminate CDS library
cds::Terminate();

When you call attachThread() all gc (RCU, HP) must be created

Yes, that fixed it. Thanks. Is there any reason why the container currently does not support iterators ?
We could construct one based on succNode in the paper.
http://arsenalfc.stanford.edu/papers/ppopp207-bronson.pdf

Iterators in concurrent data structs are tricky.
At the first glance, it is simple for Bronson's AVLtree under RCU. Maybe, I'll implement it in the future. Or you can try to implement it.
Now I'm thinking about iterators in list-based structs like MichaelMap/SplitList/SkipList. Today it is more interesting for me.

Sure, I will give it a try. Sounds good. Thanks for developing such an awesome library.