libisdn
|
00001 /* 00002 * Reference counting 00003 * @note Needs a proper thread-safe implementation using atomics and spinlocks 00004 */ 00005 #ifndef _UTIL_REFCNT_H_ 00006 #define _UTIL_REFCNT_H_ 00007 00008 #include <stdlib.h> 00009 00010 #include "common.h" 00011 00012 struct refcnt { 00013 unsigned long nr_put; 00014 unsigned long nr_get; 00015 }; 00016 00017 static inline void refcnt_init(struct refcnt *r) 00018 { 00019 r->nr_put = r->nr_get = 0; 00020 } 00021 00022 static inline long refcnt_usage(const struct refcnt *r) 00023 { 00024 return labs(ACCESS_ONCE(r->nr_get) - ACCESS_ONCE(r->nr_put)); 00025 } 00026 00027 static inline unsigned long refcnt_put(struct refcnt *r) 00028 { 00029 return ACCESS_ONCE(r->nr_get)++; 00030 } 00031 00032 static inline unsigned long refcnt_get(struct refcnt *r) 00033 { 00034 return ACCESS_ONCE(r->nr_put)++; 00035 } 00036 00037 #define refcnt_obj_ref(ptr, member) ({ \ 00038 struct refcnt *__r = container_of(ptr, struct refcnt, member); \ 00039 ACCESS_ONCE(__r->nr_get)++; \ 00040 ptr; \ 00041 }) 00042 00043 #define refcnt_obj_unref(ptr, member) ({ \ 00044 struct refcnt *__r = container_of(ptr, struct refcnt, member); \ 00045 ACCESS_ONCE(__r->nr_get) - ++ACCESS_ONCE(__r->nr_put); \ 00046 }) 00047 00048 #endif /* _UTIL_REFCNT_H_ */