In case of bypass coroutine, some buffers in stack have to convert to survive in the whole I/O submit & completion cycle.
Garbase collector is one of the best data structure for this purpose, as I thought of. Signed-off-by: Ming Lei <ming....@canonical.com> --- include/qemu/gc.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 include/qemu/gc.h diff --git a/include/qemu/gc.h b/include/qemu/gc.h new file mode 100644 index 0000000..b9a3f6e --- /dev/null +++ b/include/qemu/gc.h @@ -0,0 +1,56 @@ +#ifndef QEMU_GC_HEADER +#define QEMU_GC_HEADER + +#include "qemu/queue.h" + +/* simple garbage collector implementation for bypass coroutine */ + +/* internal type and helper */ +typedef struct SimpleGCNode SimpleGCNode; +struct SimpleGCNode { + void *addr; + void (*free)(void *data); + QLIST_ENTRY(SimpleGCNode) node; +}; + +static inline void simple_gc_free_one(SimpleGCNode *node) +{ + if (node->free) { + node->free(node->addr); + } else { + qemu_vfree(node->addr); + } + + g_free(node); +} + +/* public type and helpers */ +typedef struct { + QLIST_HEAD(, SimpleGCNode) head; +} SimpleGC; + +static inline void simple_gc_init(SimpleGC *gc) +{ + QLIST_INIT(&gc->head); +} + +static inline void simple_gc_add(SimpleGC *gc, void *addr, + void (*free)(void *data)) +{ + SimpleGCNode *node = g_malloc0(sizeof(*node)); + + node->addr = addr; + node->free = free; + QLIST_INSERT_HEAD(&gc->head, node, node); +} + +static inline void simple_gc_free_all(SimpleGC *gc) +{ + SimpleGCNode *curr, *next; + + QLIST_FOREACH_SAFE(curr, &gc->head, node, next) { + QLIST_REMOVE(curr, node); + simple_gc_free_one(curr); + } +} +#endif -- 1.7.9.5