sfu-dis / pibench-ep2

Benchmarking new Optane PMem-based persistent memory range indexes (VLDB 2022)
20 stars 5 forks source link

PACtree implementation #15

Closed saltway closed 1 year ago

saltway commented 2 years ago

hi, the implementation of PACtree may incur segmentation fault in my experiments. I follow the tips provided here https://github.com/cosmoss-jigu/pactree/issues/1 but segmentation fault still exists I hope you can help me. Thanks

jr-shen commented 2 years ago

There seems to be another two bugs in the implementation of PACtree.

  1. OpLogs may overlap with each other when key length is not 8, because sizeof(OpStruct) is hard-coded to 64 in PMem::getOpLog. However, when key length is not 8, sizeof(OpStruct) is not 64. I changed 64 to sizeof(OpStruct) and it seems to work.

    static void* getOpLog(int i){
    unsigned long vaddr = (unsigned long)logVaddr[0];
    //printf("vaddr :%p %p\n",vaddr, (void *)(vaddr+(64*i)));
    
        // return (void*)(vaddr + (64*i));
    return (void*)(vaddr + (sizeof(OpStruct)*i));
    }
  2. Current pptr implementation may cause racing condition. When rawPtr is changed by other threads between [1], [2] or [3], [4], inconsistent vaddr may be generated. This may occur when using low compiler optimization level (like -O0) for debugging purposes because the compiler will generate two load instructions for rawPtr in each function.

    
    T *operator->() {
    int poolId = (rawPtr&MASK_POOL) >> 48; // [1]
    void *baseAddr = PMem::getBaseOf(poolId); 
    unsigned long offset = rawPtr & MASK; // [2]
    return (T *)((unsigned long)baseAddr + offset);
    }

T *getVaddr() { unsigned long offset = rawPtr & MASK; // [3] if(offset == 0){ return nullptr; }

int poolId = (rawPtr&MASK_POOL) >> 48; // [4] void *baseAddr = PMem::getBaseOf(poolId);

return (T *)((unsigned long)baseAddr + offset); }

I modified it as following:
```C
T *operator->() {
  unsigned long p = rawPtr;
  int poolId = (p&MASK_POOL) >> 48; // [1]
  void *baseAddr = PMem::getBaseOf(poolId); 
  unsigned long offset = p & MASK; // [2]
  return (T *)((unsigned long)baseAddr + offset);
}

T *getVaddr() {
  unsigned long p = rawPtr;
  unsigned long offset = p & MASK; // [3]
  if(offset == 0){
    return nullptr;
  }

  int poolId = (p&MASK_POOL) >> 48; // [4]
  void *baseAddr = PMem::getBaseOf(poolId); 

  return (T *)((unsigned long)baseAddr + offset);
}
georgeh0214 commented 2 years ago

The segmentation fault issue does occur with inserts and occurs more frequently with the number of concurrent threads. After applying the fixes in https://github.com/cosmoss-jigu/pactree/issues/1#issuecomment-1045699089 and the one above, it still crashes occasionally. I would suggest adding the above fix to the issue in pactree's repo.