[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3 1/6] xen: add reference counter support
On Tue, Mar 14, 2023 at 08:56:29PM +0000, Volodymyr Babchuk wrote: > We can use reference counter to ease up object lifetime management. > This patch adds very basic support for reference counters. refcnt > should be used in the following way: > > 1. Protected structure should have refcnt_t field > > 2. This field should be initialized with refcnt_init() during object > construction. > > 3. If code holds a valid pointer to a structure/object it can increase > refcount with refcnt_get(). No additional locking is required. > > 4. Code should call refcnt_put() before dropping pointer to a > protected structure. `destructor` is a call back function that should > destruct object and free all resources, including structure protected > itself. Destructor will be called if reference counter reaches zero. > > 5. If code does not hold a valid pointer to a protected structure it > should use other locking mechanism to obtain a pointer. For example, > it should lock a list that hold protected objects. Sorry, I didn't look at the previous versions, but did we consider importing refcount_t and related logic from Linux? > > Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@xxxxxxxx> > > --- > v3: > - moved in from another patch series > - used structure to encapsulate refcnt_t > - removed #ifndef NDEBUG in favor of just calling ASSERT > - added assertion to refcnt_put > - added saturation support: code catches overflow and underflow > - added EMACS magic at end of the file > - fixed formatting > --- > xen/include/xen/refcnt.h | 59 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 59 insertions(+) > create mode 100644 xen/include/xen/refcnt.h > > diff --git a/xen/include/xen/refcnt.h b/xen/include/xen/refcnt.h > new file mode 100644 > index 0000000000..1ac05d927c > --- /dev/null > +++ b/xen/include/xen/refcnt.h > @@ -0,0 +1,59 @@ This seems to be missing some kind of license, can we have an SPDX tag at least? > +#ifndef __XEN_REFCNT_H__ > +#define __XEN_REFCNT_H__ > + > +#include <asm/atomic.h> > +#include <asm/bug.h> > + > +#define REFCNT_SATURATED (INT_MIN / 2) > + > +typedef struct { > + atomic_t refcnt; > +} refcnt_t; > + > +static inline void refcnt_init(refcnt_t *refcnt) > +{ > + atomic_set(&refcnt->refcnt, 1); > +} > + > +static inline int refcnt_read(refcnt_t *refcnt) const. > +{ > + return atomic_read(&refcnt->refcnt); > +} > + > +static inline void refcnt_get(refcnt_t *refcnt) > +{ > + int old = atomic_add_unless(&refcnt->refcnt, 1, 0); > + > + if ( unlikely(old < 0) || unlikely (old + 1 < 0) ) ^ extra space You want a single unlikely for both conditions. > + { > + atomic_set(&refcnt->refcnt, REFCNT_SATURATED); > + printk(XENLOG_ERR"refcnt saturation: old = %d\n", old); Should this be printed only once for refcount? I fear it might spam the console once a refcnt hits it. > + WARN(); > + } > +} > + > +static inline void refcnt_put(refcnt_t *refcnt, void (*destructor)(refcnt_t > *refcnt)) > +{ > + int ret = atomic_dec_return(&refcnt->refcnt); > + > + if ( ret == 0 ) > + destructor(refcnt); > + > + if ( unlikely(ret < 0)) ^ missing space > + { > + atomic_set(&refcnt->refcnt, REFCNT_SATURATED); > + printk(XENLOG_ERR"refcnt already hit 0: val = %d\n", ret); Same here regarding the spamming. > + WARN(); > + } > +} > + Extra newline. I will look at further patches to see how this gets used. Thanks, Roger.
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |