struct __fifo_node_t {
void *next;
};
typedef struct __fifo_node_t fifo_node_t;
struct __fifo_list_t {
void *next;
void *tail;
};
typedef struct __fifo_list_t fifo_list_t;
static inline void __fifo_list_push(fifo_list_t *head, fifo_node_t *node)
{
fifo_node_t *prev;
node->next = head;
prev = atomic_xchg64(&head->tail, node);
prev->next = node;
}
static inline fifo_node_t *__fifo_list_pop(fifo_list_t *head)
{
fifo_node_t *node;
while ((node = ACCESS_ONCE(head->next)) != head) {
fifo_node_t *next = ACCESS_ONCE(node->next);
if (cmpxchg_eq(&head->next, node, next) == node) {
if (cmpxchg_eq(&head->tail, node, head) != node &&
next == head)
while (ACCESS_ONCE(head->next) == next)
head->next = ACCESS_ONCE(node->next);
return node;
}
}
return NULL;
}
static inline void __fifo_list_init(fifo_list_t *head)
{
head->next = head->tail = head;
}
atomic_xchg64
- Atomic exchange 64bit with new value and return the old value
cmpxchg_eq
- Atomic compare and exchange 64bit with new value and return the old value
ACCESS_ONCE
- (*(volatile typeof(x) *)&(x))
Can you review it? Is this implementation thread-safe ?
Thank you.