Il 15/07/2013 04:49, Liu Ping Fan ha scritto: > Qref is similar to kref. It hides the refcnt detail and provides > a common interface. And this patch is based on the idiom of refcnt, > and adopts some optimization about memory model, which finally > falls back on gcc implementation. > > Signed-off-by: Liu Ping Fan <pingf...@linux.vnet.ibm.com> > --- > include/qom/object.h | 34 ++++++++++++++++++++++++++++++++++ > 1 file changed, 34 insertions(+) > > diff --git a/include/qom/object.h b/include/qom/object.h > index 23fc048..2e165fb 100644 > --- a/include/qom/object.h > +++ b/include/qom/object.h > @@ -18,6 +18,7 @@ > #include <stdint.h> > #include <stdbool.h> > #include "qemu/queue.h" > +#include "qemu/osdep.h" > > struct Visitor; > struct Error; > @@ -363,6 +364,10 @@ struct ObjectClass > ObjectUnparent *unparent; > }; > > +typedef struct Qref { > + int32_t count; > +} Qref; > + > /** > * Object: > * > @@ -1133,5 +1138,34 @@ int object_child_foreach(Object *obj, int (*fn)(Object > *child, void *opaque), > */ > Object *container_get(Object *root, const char *path); > > +static inline void qref_get(Qref *qref) > +{ > +#ifdef __ATOMIC_RELAXED > + __atomic_fetch_add(&qref->count, 1, __ATOMIC_RELAXED); > +#else > + __sync_fetch_and_add(&qref->count, 1); > +#endif > +} > + > +typedef void (*ReleaseFn)(Qref *); > > +static inline void qref_put(Qref *qref, ReleaseFn release) > +{ > + int32_t i; > + > +#ifdef __ATOMIC_RELAXED > + i = __atomic_fetch_add(&qref->count, -1, __ATOMIC_RELAXED); > + g_assert(i > 0); > + if (unlikely(i == 1)) { > + __atomic_thread_fence(__ATOMIC_SEQ_CST); > + release(qref); > + } > +#else > + i = __sync_fetch_and_add(&qref->count, -1); > + g_assert(i > 0); > + if (unlikely(i == 1)) { > + release(qref); > + } > +#endif > +} > #endif >
I don't think this should depend on QOM, so include/qom/object.h is not the right place to put it. I suggested a different way in the other thread. Also, get/put is not used (except in a couple places for historical reasons) in QEMU. Paolo