DragonFly BSD
DragonFly kernel List (threaded) for 2010-12
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Super Light Weight Reference counting

From: Venkatesh Srinivas <me@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 21 Dec 2010 12:20:24 -0500


I had a need for a very light-weight reference counting system in
kernel (much lighter than sysref), so I came up with:

ref.h :=====================
cat struct kref {
	void		*priv;
	int		refcount;

typedef struct kref *kref_t;

void kref_init(struct kref *ref, void *priv1, int count);
void kref_inc(struct kref *ref);
void kref_dec(struct kref *ref, void (*deconstruct)(void*, void*), void *priv2);

kern_ref.c :=========================

#include <sys/atomic.h>

kref_init(struct kref *ref, void *priv, int count)
	ref->refcount = count;
	ref->priv = priv;

kref_inc(struct kref *ref)
	atomic_add_int(&ref->refcount, 1);

kref_dec(struct kref *ref, void (*deconstruct)(void *, void *), void *priv2)
	int val;

	val = atomic_fetchadd_int(&ref->refcount, -1);
	if (val == 1)
		deconstruct(ref->priv, priv2);


The intended lifecycle for something would be :

struct thing {
   struct kref ref;

struct thing *thingy = kmalloc(sizeof(struct thing), M_AWESOME);

kref_init(&thingy->ref, thingy, 1);
. ..
. ..
kref_dec(&thingy->ref, kfree, M_AWESOME);
. ..
kref_dec(&thingy->ref, kfree, M_AWESOME);
    Object is freed! (The deconstructor is called on the 1 -> 0
transition (the last one out turns off the lights))

Since "an object cannot synchronize its own visibility", kref_inc and
kref_dec must be synchronized at a higher level; directly using them
invites races (imagine entering a kref_inc ; you compute the address
of the refcount; then a concurrent kref_dec frees the structure. then
you go ahead and LOCK ADD. oops.)

Aggelos Economopoulos suggested on IRC the rename from kern_ref to
kref, suggested moving the deconstructor from a per-ref field to an
argument to kref_dec, and that references only needed one priv pointer
(the original had two, to support kfree).

Any criticisms or thoughts would be very welcome!

-- vs

[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]