};
// Marking the <next> field of a node logically removes it from the list
-#define MARK_NODE(x) TAG_VALUE((markable_t)(x), TAG1)
-#define HAS_MARK(x) (IS_TAGGED((x), TAG1) == TAG1)
+#define MARK_NODE(x) TAG_VALUE((markable_t)(x), 0x1)
+#define HAS_MARK(x) (IS_TAGGED((x), 0x1) == 0x1)
#define GET_NODE(x) ((node_t *)(x))
-#define STRIP_MARK(x) ((node_t *)STRIP_TAG((x), TAG1))
+#define STRIP_MARK(x) ((node_t *)STRIP_TAG((x), 0x1))
static node_t *node_alloc (map_key_t key, map_val_t val) {
node_t *item = (node_t *)nbd_malloc(sizeof(node_t));
+ assert(!HAS_MARK((size_t)item));
item->key = key;
item->val = val;
return item;
// Unlink logically removed items.
TRACE("l3", "find_pred: unlinking marked item %p next is %p", item, next);
- markable_t other = SYNC_CAS(&pred->next, item, STRIP_MARK(next));
+ markable_t other = SYNC_CAS(&pred->next, (markable_t)item, (markable_t)STRIP_MARK(next));
if (other == (markable_t)item) {
TRACE("l2", "find_pred: unlinked item %p from pred %p", item, pred);
item = STRIP_MARK(next);
map_key_t new_key = ll->key_type == NULL ? key : (map_key_t)ll->key_type->clone((void *)key);
node_t *new_item = node_alloc(new_key, new_val);
markable_t next = new_item->next = (markable_t)old_item;
- markable_t other = SYNC_CAS(&pred->next, next, new_item);
+ markable_t other = SYNC_CAS(&pred->next, (markable_t)next, (markable_t)new_item);
if (other == next) {
TRACE("l1", "ll_cas: successfully inserted new item %p", new_item, 0);
return DOES_NOT_EXIST; // success
}
} while (next != old_next);
TRACE("l2", "ll_remove: logically removed item %p", item, 0);
- ASSERT(HAS_MARK(((volatile node_t *)item)->next));
+ ASSERT(HAS_MARK(VOLATILE_DEREF(item).next));
// Atomically swap out the item's value in case another thread is updating the item while we are
// removing it. This establishes which operation occurs first logically, the update or the remove.
// item earlier, we logically removed it.
TRACE("l2", "ll_remove: unlink the item by linking its pred %p to its successor %p", pred, next);
markable_t other;
- if ((other = SYNC_CAS(&pred->next, item, next)) != (markable_t)item) {
+ if ((other = SYNC_CAS(&pred->next, (markable_t)item, next)) != (markable_t)item) {
TRACE("l1", "ll_remove: unlink failed; pred's link changed from %p to %p", item, other);
return val;
}
do {
item = iter->pred->next;
haz_set(hp0, STRIP_MARK(item));
- } while (item != ((volatile node_t *)iter->pred)->next);
+ } while (item != VOLATILE_DEREF(iter->pred).next);
#endif//LIST_USE_HAZARD_POINTER
iter->pred = STRIP_MARK(item);
if (iter->pred == NULL)