libisdn
refcnt.h
Go to the documentation of this file.
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_ */