ck_queue: Add CK_?LIST_MOVE operation.

This operation is of format:
CK_S*LIST_MOVE(a, b, linkage) and is equivalent to intializing
a with the contents of b. This is done in a manner that is atomic
with respect to readers. Read-only operations are still valid in
b, but behavior is undefined for write-side operations on b after
a MOVE operation.
ck_pring
Samy Al Bahra 12 years ago
parent 5df8882840
commit cb1c72d36b

@ -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.
*/

@ -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);
}

@ -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);
}
}

Loading…
Cancel
Save