无锁链表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无锁链表相关的知识,希望对你有一定的参考价值。

#ifndef lkf_h
#define lkf_h

struct lkf_node {
    struct lkf_node* next;
};

struct lkf_list {
    struct lkf_node root;
    struct lkf_node** tail;
};


#define LKF_INIT(name) {.root = {NULL}, .tail = &(name.root.next)}
#define LKF_LIST(name) struct lkf_list name = LKF_INIT(name)

#define INIT_LKF(name) do {     name->root.next = NULL;     name->tail = &(name->root.next); } while (0)

static inline void lkf_node_put(struct lkf_list* list, struct lkf_node* node)
{
    node->next = NULL;
    struct lkf_node** ptr = __sync_lock_test_and_set(&(list->tail), &(node->next));
    *ptr = node;
}

static inline struct lkf_node* lkf_node_get_one(struct lkf_list* list)
{
    struct lkf_node* head = __sync_lock_test_and_set(&(list->root.next), NULL);
    if (head == NULL) {
        return NULL;
    }

    struct lkf_node* next = head->next;
    if (next != NULL) {
        list->root.next = next;
        head->next = head;
        return head;
    }

    int b = __sync_bool_compare_and_swap(&(list->tail), &(head->next), &(list->root.next));
    if (b) {
        head->next = head;
        return head;
    }

    list->root.next = head;
    return NULL;
}

static inline struct lkf_node* lkf_node_get(struct lkf_list* list)
{
    struct lkf_node* ptr = __sync_lock_test_and_set(&(list->root.next), NULL);
    if (ptr == NULL) {
        return NULL;
    }

    struct lkf_node** last = __sync_lock_test_and_set(&(list->tail), &(list->root.next));
    *last = ptr;
    return *last;
}

static inline struct lkf_node* lkf_node_next(struct lkf_node* node)
{
    struct lkf_node* ptr = node->next;
    if (ptr == NULL || ptr->next == NULL) {
        return NULL;
    }

    if (ptr == node) {
        return ptr;
    }

    node->next = ptr->next;
    ptr->next = NULL;
    return ptr;
}

#endif

 

以上是关于无锁链表的主要内容,如果未能解决你的问题,请参考以下文章

一读多写非自旋无锁链表队列实现

一读多写非自旋无锁链表队列实现

LindedList - 星云锁链让数据发挥小宇宙

死锁链sql

被精神囚禁的群体,会用AI之匙打开锁链吗?

将数据从底部工作表对话框片段传递到片段