migration: Support QLIST migration

Support QLIST migration using the same principle as QTAILQ:
94869d5c52 ("migration: migrate QTAILQ").

The VMSTATE_QLIST_V macro has the same proto as VMSTATE_QTAILQ_V.
The change mainly resides in QLIST RAW macros: QLIST_RAW_INSERT_HEAD
and QLIST_RAW_REVERSE.

Tests also are provided.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
This commit is contained in:
Eric Auger 2020-01-13 14:48:23 +01:00 committed by Juan Quintela
parent 0ab994867c
commit 4746dbf8a9
5 changed files with 305 additions and 0 deletions

View file

@ -501,4 +501,43 @@ union { \
QTAILQ_RAW_TQH_CIRC(head)->tql_prev = QTAILQ_RAW_TQE_CIRC(elm, entry); \
} while (/*CONSTCOND*/0)
#define QLIST_RAW_FIRST(head) \
field_at_offset(head, 0, void *)
#define QLIST_RAW_NEXT(elm, entry) \
field_at_offset(elm, entry, void *)
#define QLIST_RAW_PREVIOUS(elm, entry) \
field_at_offset(elm, entry + sizeof(void *), void *)
#define QLIST_RAW_FOREACH(elm, head, entry) \
for ((elm) = *QLIST_RAW_FIRST(head); \
(elm); \
(elm) = *QLIST_RAW_NEXT(elm, entry))
#define QLIST_RAW_INSERT_HEAD(head, elm, entry) do { \
void *first = *QLIST_RAW_FIRST(head); \
*QLIST_RAW_FIRST(head) = elm; \
*QLIST_RAW_PREVIOUS(elm, entry) = QLIST_RAW_FIRST(head); \
if (first) { \
*QLIST_RAW_NEXT(elm, entry) = first; \
*QLIST_RAW_PREVIOUS(first, entry) = QLIST_RAW_NEXT(elm, entry); \
} else { \
*QLIST_RAW_NEXT(elm, entry) = NULL; \
} \
} while (0)
#define QLIST_RAW_REVERSE(head, elm, entry) do { \
void *iter = *QLIST_RAW_FIRST(head), *prev = NULL, *next; \
while (iter) { \
next = *QLIST_RAW_NEXT(iter, entry); \
*QLIST_RAW_PREVIOUS(iter, entry) = QLIST_RAW_NEXT(next, entry); \
*QLIST_RAW_NEXT(iter, entry) = prev; \
prev = iter; \
iter = next; \
} \
*QLIST_RAW_FIRST(head) = prev; \
*QLIST_RAW_PREVIOUS(prev, entry) = QLIST_RAW_FIRST(head); \
} while (0)
#endif /* QEMU_SYS_QUEUE_H */