FEAT: thread-safe pool management
thread-safe pool management
Depends on pmem/issues#871
Rationale
The behavior of pool management functions is not intuitive and probably the biggest trap for programmers in our API. This needs to change ;)
Description
The reason why we currently say that some of our functions are not thread-safe is because there are two collections that need to be updated during opening/closing of a pool:
static struct cuckoo *pools_ht; /* hash table used for searching by UUID */
static struct ravl *pools_tree; /* tree used for searching by address */
This on its own wouldn't be such a big problems if it weren't for the fact that pmemobj_direct() must be able to always safely read from the pool_ht map - and going into the kernel on every direct would kill runtime performance (futex). So, the conclusion is that we require a concurrent hashmap for the pools_ht.
The pools tree also must be updated, and we are not going to be implementing a lockfree tree but rather we will simply surround all updates /w a lock. This will impact pmemobj_pool_by_ptr(), which is critical for C++ performance - the performance degradation needs to be addressed by detecting pointers that come from stack or the heap and returning early with a NULL before having to grab a lock.
API Changes
pmemobj_create(), pmemobj_open(), pmemobj_close() will become thread-safe.
Implementation details
Detection of heap/stack pointers can be done by caching the lowest and highest addresses that we know come from pmem, and if (ptr < pmem_low || ptr > pmem_high) return NULL