On Thu, Sep 19, 2024 at 09:57:12PM +0800, Alan Huang wrote: [...] > > > > I think you're right. (Although the node will be eventually deleted at > > cleanup_hazptr_context(), however there could be a long-live > > hazptr_context). It should be: > > > > hazptr_t val = smp_load_acquire(&hzcp->slots[i]); > > struct hazptr_slot_snap *snap = &hzcp->snaps[i]; > > > > if (val != snap->slot) { // val changed, need to update the tree node. > > // Already in the tree, need to remove first. > > if (!is_null_or_unused(snap->slot)) { > > reader_del(tree, snap); > > } > > > > // use the latest snapshot. > > snap->slot = val; > > > > // Add it into tree if there is a reader > > if (!is_null_or_unused(val)) > > reader_add(tree, snap); > > } > > It seems like that two different hazptr_context can’t be used to protect the same pointer? > > Otherwise the following can happen? > > thread1 thread2 thread3(worker) thread4 > hazptr_tryprotect(hzp1, ptr1) hazptr_tryprotect(hzp2, ptr1) > add ptr1 to tree Note that we have snapshot rb_node for each hazard pointer slot, so here thread3 actually would add two rb_nodes with ->slot == ptr1 here. > hazptr_clear(hzp1) > hazptr_tryprotect(hzp1, ptr2) > delete ptr1 from tree unpub ptr1 Therefore, there is still one rb_node with ->slot == ptr1 in the tree after the deletion, so updaters won't invoke ptr1's callback. Regards, Boqun > call_hazptr(ptr1) > oops: invoke ptr1's callback > Or am I missing something? > > > > > Regards, > > Boqun > > > >> I'm not so sure... > >> > >> Thanks > >> Lai > >