diff --git a/include/ck_queue.h b/include/ck_queue.h index 911d5e1..4b2f91b 100644 --- a/include/ck_queue.h +++ b/include/ck_queue.h @@ -105,6 +105,7 @@ * _REMOVE_HEAD + - * _REMOVE + + * _SWAP + + + * _MOVE + + */ /* @@ -188,6 +189,10 @@ struct { \ (head)->slh_first->field.sle_next); \ } while (0) +#define CK_SLIST_MOVE(head1, head2, field) do { \ + ck_pr_store_ptr(&(head1)->slh_first, (head2)->slh_first); \ +} while (0) + /* * This operation is not applied atomically. */ @@ -265,6 +270,12 @@ struct { \ (elm)->field.le_next->field.le_prev = (elm)->field.le_prev; \ } while (0) +#define CK_LIST_MOVE(head1, head2, field) do { \ + ck_pr_store_ptr(&(head1)->lh_first, (head2)->lh_first); \ + if ((head1)->lh_first != NULL) \ + (head1)->lh_first->field.le_prev = &(head1)->lh_first; \ +} while (0) + /* * This operation is not applied atomically. */ diff --git a/regressions/ck_queue/validate/ck_list.c b/regressions/ck_queue/validate/ck_list.c index 3ee762c..bbf45c9 100644 --- a/regressions/ck_queue/validate/ck_list.c +++ b/regressions/ck_queue/validate/ck_list.c @@ -122,6 +122,7 @@ main(int argc, char *argv[]) { pthread_t *thread; struct test *n; + struct test_list target; int n_threads, i; if (argc != 3) { @@ -199,11 +200,13 @@ main(int argc, char *argv[]) assert(r == 0); } + CK_LIST_MOVE(&target, &head, list_entry); + for (i = 1; i <= goal; i++) { volatile int j; - if (CK_LIST_EMPTY(&head) == false) { - struct test *r = CK_LIST_FIRST(&head); + if (CK_LIST_EMPTY(&target) == false) { + struct test *r = CK_LIST_FIRST(&target); CK_LIST_REMOVE(r, list_entry); } diff --git a/regressions/ck_queue/validate/ck_slist.c b/regressions/ck_queue/validate/ck_slist.c index 6d167ca..6391ae3 100644 --- a/regressions/ck_queue/validate/ck_slist.c +++ b/regressions/ck_queue/validate/ck_slist.c @@ -122,6 +122,7 @@ main(int argc, char *argv[]) { pthread_t *thread; struct test *n; + struct test_list target; int n_threads, i; if (argc != 3) { @@ -199,17 +200,19 @@ main(int argc, char *argv[]) assert(r == 0); } + CK_SLIST_MOVE(&target, &head, list_entry); + for (i = 1; i <= goal; i++) { volatile int j; - if (CK_SLIST_EMPTY(&head) == false) - CK_SLIST_REMOVE_HEAD(&head, list_entry); + if (CK_SLIST_EMPTY(&target) == false) + CK_SLIST_REMOVE_HEAD(&target, list_entry); for (j = 0; j <= 1000; j++); - if (CK_SLIST_EMPTY(&head) == false) { - struct test *r = CK_SLIST_FIRST(&head); - CK_SLIST_REMOVE(&head, r, test, list_entry); + if (CK_SLIST_EMPTY(&target) == false) { + struct test *r = CK_SLIST_FIRST(&target); + CK_SLIST_REMOVE(&target, r, test, list_entry); } }