Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct node { struct node *next; };
- int try_insert(struct node *after, struct node *node) {
- //копируем after->next в node->next
- node->next = __atomic_load_n(&after->next, __ATOMIC_ACQUIRE);
- //если after->next = 0, значит выполняется попытка удаления узла after
- if(!node->next) { return (0); }
- //если значение after->next изменилось, значит узел after удаляется либо после него был вставлен другой узел
- //если значение after->next не изменилось помещаем адрес добавляемого узла node
- return __atomic_compare_exchange_n(&after->next, &node->next, node, 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
- }
- int try_delete(struct node *after) {
- //удаляемый узел after->next
- //копируем его адрес в локальную переменную
- struct node *next = __atomic_load_n(&after->next, __ATOMIC_ACQUIRE);
- //если after->next = 0, значит узел after удаляется
- if(!next) { return (0); }
- //копируем after->next->next в локальную переменную
- //при этом атомарно помещаем в after->next->next = 0
- struct node *next_next = __atomic_exchange_n(&next->next, 0, __ATOMIC_ACQ_REL);
- //если after->next->next = 0, значит узел after->next удаляется
- if(!next_next) { return (0); }
- //если значение after->next изменилось, значит узел after удаляется либо после него был вставлен другой узел
- //если значение after->next не изменилось помещаем адрес следующего за удаляемым узла используя локальную копию
- int res = __atomic_compare_exchange_n(&after->next, &next, next_next, 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED);
- if(!res) {
- //если значение after->next все-же изменилось
- //возвращаем в after->next->next адрес следующего за удаляемым узла используя локальную копию next_next
- __atomic_store_n (&next->next, next_next, __ATOMIC_RELEASE);
- }
- return res;
- }
Add Comment
Please, Sign In to add comment