C中的lockFree列表的标记指针

时间:2016-02-21 09:34:07

标签: c++ pointers bitmask lock-free

我正在尝试使用标记指针来处理列表上的无锁操作,以便在此事务期间阻止比较和交换(CAS)通过,如果某个其他线程在列表上操作。我的节点struct和CAS看起来像这样:

struct node {
    unsigned long key;
    unsigned long val;
    struct node * next;
};

static inline bool CAS(std::atomic<node*> node, struct node* oldNode, struct node* newNode)
{
    node.compare_exchange_strong(oldNode, newNode, std::memory_order_seq_cst);
}

我找到了一些设置和检查这些指针的方法,但我不清楚它们是如何工作的,这些是设置掩码并验证它的方法。

__inline struct node* setTagMask(struct node* p, int MASK_BIT)
{
    return (struct node*) ((uintptr_t)p | MASK_BIT);
}

__inline bool isMaskFlagSet(struct node* p)
{
    return ((uintptr_t)p & MASK_BIT) != 0;
}

所以我不清楚的是例如在setTagMask中,如果我在列表中使用它,那么它将删除它对其值和下一个元素的所有引用。

有人可以向我解释如何正确设置这些位,以便列表中的其他元素保持不变?

1 个答案:

答案 0 :(得分:1)

setTagMask函数返回指针p的修改版本。如果将此修改后的指针存储在链表中,则列表会被破坏,因为修改后的指针不再指向node

指针修改如下。指针p被转换为无符号整数,该整数能够存储指针:uintptr_t。 然后根据MASK_BIT设置一个或多个比特。最后,结果将转换回指针并返回。

函数isMaskFlagSet检查掩码位是否仍然设置。

我唯一可以想象的用例是:在使用指针之前,每次都必须调用isMaskFlagSet。如果设置了掩码位,则禁止实际使用指针。