int _ret = 0; \
struct mt_list *lh = (_lh), *el = (_el); \
while (1) { \
- struct mt_list *n; \
- struct mt_list *p; \
+ struct mt_list *n, *n2; \
+ struct mt_list *p, *p2; \
n = _HA_ATOMIC_XCHG(&(lh)->next, MT_LIST_BUSY); \
if (n == MT_LIST_BUSY) \
continue; \
__ha_barrier_store(); \
continue; \
} \
- if ((el)->next != (el) || (el)->prev != (el)) { \
- (n)->prev = p; \
- (lh)->next = n; \
+ n2 = _HA_ATOMIC_XCHG(&el->next, MT_LIST_BUSY); \
+ if (n2 != el) { /* element already linked */ \
+ if (n2 != MT_LIST_BUSY) \
+ el->next = n2; \
+ n->prev = p; \
+ __ha_barrier_store(); \
+ lh->next = n; \
+ __ha_barrier_store(); \
+ if (n2 == MT_LIST_BUSY) \
+ continue; \
+ break; \
+ } \
+ p2 = _HA_ATOMIC_XCHG(&el->prev, MT_LIST_BUSY); \
+ if (p2 != el) { \
+ if (p2 != MT_LIST_BUSY) \
+ el->prev = p2; \
+ n->prev = p; \
+ el->next = el; \
__ha_barrier_store(); \
+ lh->next = n; \
+ __ha_barrier_store(); \
+ if (p2 == MT_LIST_BUSY) \
+ continue; \
break; \
} \
(el)->next = n; \
int _ret = 0; \
struct mt_list *lh = (_lh), *el = (_el); \
while (1) { \
- struct mt_list *n; \
- struct mt_list *p; \
+ struct mt_list *n, *n2; \
+ struct mt_list *p, *p2; \
p = _HA_ATOMIC_XCHG(&(lh)->prev, MT_LIST_BUSY); \
if (p == MT_LIST_BUSY) \
continue; \
__ha_barrier_store(); \
continue; \
} \
- if ((el)->next != (el) || (el)->prev != (el)) { \
+ n2 = _HA_ATOMIC_XCHG(&el->next, MT_LIST_BUSY); \
+ if (n2 != el) { /* element already linked */ \
+ if (n2 != MT_LIST_BUSY) \
+ el->next = n2; \
p->next = n; \
- (lh)->prev = p; \
__ha_barrier_store(); \
+ lh->prev = p; \
+ __ha_barrier_store(); \
+ if (n2 == MT_LIST_BUSY) \
+ continue; \
+ break; \
+ } \
+ p2 = _HA_ATOMIC_XCHG(&el->prev, MT_LIST_BUSY); \
+ if (p2 != el) { \
+ if (p2 != MT_LIST_BUSY) \
+ el->prev = p2; \
+ p->next = n; \
+ el->next = el; \
+ __ha_barrier_store(); \
+ lh->prev = p; \
+ __ha_barrier_store(); \
+ if (p2 == MT_LIST_BUSY) \
+ continue; \
break; \
} \
(el)->next = n; \