All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.