#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