[PATCH v2 04/19] libmpathutil: add implementation of generic shared pointer
Martin Wilck <[email protected]>
| Newsgroups | dev.linux.lists.dm-devel |
|---|---|
| Message-ID | <[email protected]> |
Add a set of simple functions to handle refcounted pointers. Signed-off-by: Martin Wilck <[email protected]> Reviewed-by: Benjamin Marzinski <[email protected]> --- libmpathutil/libmpathutil.version | 7 +++++ libmpathutil/util.c | 45 ++++++++++++++++++++++++++++--- libmpathutil/util.h | 5 ++++ 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/libmpathutil/libmpathutil.version b/libmpathutil/libmpathutil.version index c69120d..51594ad 100644 --- a/libmpathutil/libmpathutil.version +++ b/libmpathutil/libmpathutil.version @@ -194,3 +194,10 @@ global: local: *; }; + +LIBMPATHUTIL_6.1 { +global: + alloc_shared_ptr; + get_shared_ptr; + put_shared_ptr; +} LIBMPATHUTIL_6.0; diff --git a/libmpathutil/util.c b/libmpathutil/util.c index 23a9797..3c623ec 100644 --- a/libmpathutil/util.c +++ b/libmpathutil/util.c @@ -12,15 +12,13 @@ #include <dirent.h> #include <unistd.h> #include <errno.h> +#include <urcu/uatomic.h> #include "mt-udev-wrap.h" #include "util.h" #include "debug.h" -#include "checkers.h" #include "vector.h" -#include "structs.h" -#include "config.h" -#include "log.h" +#include "list.h" size_t strchop(char *str) @@ -384,3 +382,42 @@ void cleanup_udev_device(struct udev_device **udd) if (*udd) udev_device_unref(*udd); } + +struct shared_ptr { + long refcnt; + void (*destructor)(void *); + char __attribute__((aligned(sizeof(void *)))) ptr[]; +}; + +void *alloc_shared_ptr(size_t size, void (*destructor)(void *)) +{ + struct shared_ptr *sp = malloc(sizeof(*sp) + size); + + if (!sp) + return NULL; + uatomic_set(&sp->refcnt, 1); + sp->destructor = destructor; + return sp->ptr; +} + +void get_shared_ptr(void *ptr) +{ + struct shared_ptr *sp = container_of(ptr, struct shared_ptr, ptr); + + if (uatomic_add_return(&sp->refcnt, 1) < 0) + condlog(0, "%s: refcount overflow", __func__); +} + +void put_shared_ptr(void *ptr) +{ + struct shared_ptr *sp; + + if (!ptr) + return; + sp = container_of(ptr, struct shared_ptr, ptr); + if (uatomic_sub_return(&sp->refcnt, 1) == 0) { + if (sp->destructor) + sp->destructor(ptr); + free(sp); + } +} diff --git a/libmpathutil/util.h b/libmpathutil/util.h index aed1bc1..ffbb182 100644 --- a/libmpathutil/util.h +++ b/libmpathutil/util.h @@ -160,4 +160,9 @@ void cleanup_charp(char **p); void cleanup_ucharp(unsigned char **p); void cleanup_udev_device(struct udev_device **udd); void cleanup_bitfield(union bitfield **p); + +void *alloc_shared_ptr(size_t size, void (*destructor)(void *)); +void get_shared_ptr(void *ptr); +void put_shared_ptr(void *ptr); + #endif /* UTIL_H_INCLUDED */ -- 2.54.0