From 83ef91e8cd2bee343c692761416d2e8de1793467 Mon Sep 17 00:00:00 2001 From: RinHizakura Date: Sun, 8 Aug 2021 03:22:56 +0800 Subject: [PATCH] Fix error of __list_find The node on the linked list should follow the ordering by its key. However, the function list_insert doesn't actually do this because of the wrong implementation of __list_find. There are three main fixes in this patch. First, once we should do synchronization, we have to iterate the list again but not return from the function. Second, the while loop should iterate until the last node but not the second last one. Finally, under the normal situation that the tail node with key UINTPTR_MAX should not be deleted (unless the end of the program), some codes are never executed which can be removed. --- hp_list/main.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/hp_list/main.c b/hp_list/main.c index 88f51f6..ae42683 100644 --- a/hp_list/main.c +++ b/hp_list/main.c @@ -230,14 +230,14 @@ static bool __list_find(list_t *list, if (atomic_load(prev) != get_unmarked(curr)) goto try_again; while (true) { - if (!get_unmarked_node(curr)) - return false; next = (list_node_t *) atomic_load(&get_unmarked_node(curr)->next); (void) list_hp_protect_ptr(list->hp, HP_NEXT, get_unmarked(next)); + /* On a CAS failure, the search function, "__list_find," will simply + * have to go backwards in the list until an unmarked element is found + * from which the search in increasing key order can be started. + */ if (atomic_load(&get_unmarked_node(curr)->next) != (uintptr_t) next) - break; - if (get_unmarked(next) == atomic_load((atomic_uintptr_t *) &list->tail)) - break; + goto try_again; if (atomic_load(prev) != get_unmarked(curr)) goto try_again; if (get_unmarked_node(next) == next) { @@ -259,11 +259,6 @@ static bool __list_find(list_t *list, curr = next; (void) list_hp_protect_release(list->hp, HP_CURR, get_unmarked(next)); } - *par_curr = curr; - *par_prev = prev; - *par_next = next; - - return false; } bool list_insert(list_t *list, list_key_t key)