* [Qemu-devel] [PATCH 1/2] object: introduce Qref to abstract the refcnt interface
@ 2013-07-15 2:49 Liu Ping Fan
2013-07-15 2:49 ` [Qemu-devel] [PATCH 2/2] object: Object apply the refcnt interface by Qref Liu Ping Fan
2013-07-15 11:38 ` [Qemu-devel] [PATCH 1/2] object: introduce Qref to abstract the refcnt interface Paolo Bonzini
0 siblings, 2 replies; 3+ messages in thread
From: Liu Ping Fan @ 2013-07-15 2:49 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, Richard Henderson
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 <pingfank@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
--
1.8.1.4
^ permalink raw reply related [flat|nested] 3+ messages in thread* [Qemu-devel] [PATCH 2/2] object: Object apply the refcnt interface by Qref
2013-07-15 2:49 [Qemu-devel] [PATCH 1/2] object: introduce Qref to abstract the refcnt interface Liu Ping Fan
@ 2013-07-15 2:49 ` Liu Ping Fan
2013-07-15 11:38 ` [Qemu-devel] [PATCH 1/2] object: introduce Qref to abstract the refcnt interface Paolo Bonzini
1 sibling, 0 replies; 3+ messages in thread
From: Liu Ping Fan @ 2013-07-15 2:49 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, Richard Henderson
Signed-off-by: Liu Ping Fan <pingfank@linux.vnet.ibm.com>
---
include/qom/object.h | 2 +-
qom/object.c | 15 +++++----------
2 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/include/qom/object.h b/include/qom/object.h
index 2e165fb..8426dd1 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -389,7 +389,7 @@ struct Object
ObjectClass *class;
ObjectFree *free;
QTAILQ_HEAD(, ObjectProperty) properties;
- uint32_t ref;
+ Qref ref;
Object *parent;
};
diff --git a/qom/object.c b/qom/object.c
index b2479d1..736d4ba 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -388,15 +388,15 @@ static void object_deinit(Object *obj, TypeImpl *type)
}
}
-static void object_finalize(void *data)
+static void object_finalize(Qref *qref)
{
- Object *obj = data;
+ Object *obj = container_of(qref, Object, ref);
TypeImpl *ti = obj->class->type;
object_deinit(obj, ti);
object_property_del_all(obj);
- g_assert(obj->ref == 0);
+ g_assert(qref->count == 0);
if (obj->free) {
obj->free(obj);
}
@@ -683,17 +683,12 @@ GSList *object_class_get_list(const char *implements_type,
void object_ref(Object *obj)
{
- atomic_inc(&obj->ref);
+ qref_get(&obj->ref);
}
void object_unref(Object *obj)
{
- g_assert(obj->ref > 0);
-
- /* parent always holds a reference to its children */
- if (atomic_fetch_dec(&obj->ref) == 1) {
- object_finalize(obj);
- }
+ qref_put(&obj->ref, object_finalize);
}
void object_property_add(Object *obj, const char *name, const char *type,
--
1.8.1.4
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [Qemu-devel] [PATCH 1/2] object: introduce Qref to abstract the refcnt interface
2013-07-15 2:49 [Qemu-devel] [PATCH 1/2] object: introduce Qref to abstract the refcnt interface Liu Ping Fan
2013-07-15 2:49 ` [Qemu-devel] [PATCH 2/2] object: Object apply the refcnt interface by Qref Liu Ping Fan
@ 2013-07-15 11:38 ` Paolo Bonzini
1 sibling, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2013-07-15 11:38 UTC (permalink / raw)
To: Liu Ping Fan; +Cc: qemu-devel, Richard Henderson
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 <pingfank@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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2013-07-15 11:38 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-15 2:49 [Qemu-devel] [PATCH 1/2] object: introduce Qref to abstract the refcnt interface Liu Ping Fan
2013-07-15 2:49 ` [Qemu-devel] [PATCH 2/2] object: Object apply the refcnt interface by Qref Liu Ping Fan
2013-07-15 11:38 ` [Qemu-devel] [PATCH 1/2] object: introduce Qref to abstract the refcnt interface Paolo Bonzini
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.