From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56680) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uyx34-0002XY-5O for qemu-devel@nongnu.org; Tue, 16 Jul 2013 00:39:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Uyx33-0001iX-6J for qemu-devel@nongnu.org; Tue, 16 Jul 2013 00:39:38 -0400 Received: from mail-ie0-x233.google.com ([2607:f8b0:4001:c03::233]:50763) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uyx33-0001iO-1K for qemu-devel@nongnu.org; Tue, 16 Jul 2013 00:39:37 -0400 Received: by mail-ie0-f179.google.com with SMTP id c10so586752ieb.24 for ; Mon, 15 Jul 2013 21:39:36 -0700 (PDT) From: Liu Ping Fan Date: Tue, 16 Jul 2013 12:36:29 +0800 Message-Id: <1373949390-3642-1-git-send-email-pingfank@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH v2 1/2] refcnt: introduce Qref to abstract the refcnt interface List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org 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 --- v2: put Qref to a dedicated file. rename qref_get/_put as qref_inc/_dec --- include/qemu/refcnt.h | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 include/qemu/refcnt.h diff --git a/include/qemu/refcnt.h b/include/qemu/refcnt.h new file mode 100644 index 0000000..815534a --- /dev/null +++ b/include/qemu/refcnt.h @@ -0,0 +1,57 @@ +/* + * refcount management routine + * + * Copyright IBM, Corp. 2013 + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_REFCNT_H +#define QEMU_REFCNT_H + +#include "qemu/osdep.h" + +/* + * Qref defines the interface for thread-safe refcount management. + * As to atomic ops, it falls back on gcc implementation, and do some + * optimization if gcc supports C11 relaxed memory model, otherwise + * just using seq_cst memory model. + */ +typedef struct Qref { + int32_t count; +} Qref; + +static inline void qref_inc(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 *); + +/* When refcnt comes to zero, @release will be called */ +static inline void qref_dec(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