From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by dpdk.org (Postfix) with ESMTP id 5974037B3 for ; Tue, 28 Mar 2017 22:36:57 +0200 (CEST) Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga105.jf.intel.com with ESMTP; 28 Mar 2017 13:36:57 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,238,1486454400"; d="scan'208";a="80340108" Received: from sivswdev01.ir.intel.com ([10.237.217.45]) by orsmga005.jf.intel.com with ESMTP; 28 Mar 2017 13:36:55 -0700 From: Bruce Richardson To: olivier.matz@6wind.com Cc: thomas.monjalon@6wind.com, dev@dpdk.org, Bruce Richardson Date: Tue, 28 Mar 2017 21:36:06 +0100 Message-Id: <20170328203606.27457-15-bruce.richardson@intel.com> X-Mailer: git-send-email 2.8.4 In-Reply-To: <20170328203606.27457-1-bruce.richardson@intel.com> References: <20170324171008.29355-1-bruce.richardson@intel.com> <20170328203606.27457-1-bruce.richardson@intel.com> Subject: [dpdk-dev] [PATCH v4 14/14] ring: make ring struct and enq/deq macros type agnostic X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 28 Mar 2017 20:36:57 -0000 Modify the enqueue and dequeue macros to support copying any type of object by passing in the exact object type. Rather than using the "ring" structure member of rte_ring, which is of type "array of void *", instead have the macros take the start of the ring a a pointer value, thereby leaving the rte_ring structure as purely a header value. This allows it to be reused by other future ring types which can add on extra fields if they want, or even to have the actual ring elements, of whatever type stored separate from the ring header. Signed-off-by: Bruce Richardson Acked-by: Olivier Matz --- lib/librte_ring/rte_ring.h | 68 ++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h index b352dad..f0692d3 100644 --- a/lib/librte_ring/rte_ring.h +++ b/lib/librte_ring/rte_ring.h @@ -159,11 +159,7 @@ struct rte_ring { /** Ring consumer status. */ struct rte_ring_headtail cons __rte_aligned(CONS_ALIGN); - - void *ring[] __rte_cache_aligned; /**< Memory space of ring starts here. - * not volatile so need to be careful - * about compiler re-ordering */ -}; +} __rte_cache_aligned; #define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */ #define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */ @@ -290,54 +286,62 @@ void rte_ring_dump(FILE *f, const struct rte_ring *r); /* the actual enqueue of pointers on the ring. * Placed here since identical code needed in both * single and multi producer enqueue functions */ -#define ENQUEUE_PTRS() do { \ +#define ENQUEUE_PTRS(r, ring_start, prod_head, obj_table, n, obj_type) do { \ unsigned int i; \ - const uint32_t size = r->size; \ - uint32_t idx = prod_head & r->mask; \ + const uint32_t size = (r)->size; \ + uint32_t idx = prod_head & (r)->mask; \ + obj_type *ring = (void *)ring_start; \ if (likely(idx + n < size)) { \ for (i = 0; i < (n & ((~(unsigned)0x3))); i+=4, idx+=4) { \ - r->ring[idx] = obj_table[i]; \ - r->ring[idx+1] = obj_table[i+1]; \ - r->ring[idx+2] = obj_table[i+2]; \ - r->ring[idx+3] = obj_table[i+3]; \ + ring[idx] = obj_table[i]; \ + ring[idx+1] = obj_table[i+1]; \ + ring[idx+2] = obj_table[i+2]; \ + ring[idx+3] = obj_table[i+3]; \ } \ switch (n & 0x3) { \ - case 3: r->ring[idx++] = obj_table[i++]; \ - case 2: r->ring[idx++] = obj_table[i++]; \ - case 1: r->ring[idx++] = obj_table[i++]; \ + case 3: \ + ring[idx++] = obj_table[i++]; /* fallthrough */ \ + case 2: \ + ring[idx++] = obj_table[i++]; /* fallthrough */ \ + case 1: \ + ring[idx++] = obj_table[i++]; \ } \ } else { \ for (i = 0; idx < size; i++, idx++)\ - r->ring[idx] = obj_table[i]; \ + ring[idx] = obj_table[i]; \ for (idx = 0; i < n; i++, idx++) \ - r->ring[idx] = obj_table[i]; \ + ring[idx] = obj_table[i]; \ } \ -} while(0) +} while (0) /* the actual copy of pointers on the ring to obj_table. * Placed here since identical code needed in both * single and multi consumer dequeue functions */ -#define DEQUEUE_PTRS() do { \ +#define DEQUEUE_PTRS(r, ring_start, cons_head, obj_table, n, obj_type) do { \ unsigned int i; \ - uint32_t idx = cons_head & r->mask; \ - const uint32_t size = r->size; \ + uint32_t idx = cons_head & (r)->mask; \ + const uint32_t size = (r)->size; \ + obj_type *ring = (void *)ring_start; \ if (likely(idx + n < size)) { \ for (i = 0; i < (n & (~(unsigned)0x3)); i+=4, idx+=4) {\ - obj_table[i] = r->ring[idx]; \ - obj_table[i+1] = r->ring[idx+1]; \ - obj_table[i+2] = r->ring[idx+2]; \ - obj_table[i+3] = r->ring[idx+3]; \ + obj_table[i] = ring[idx]; \ + obj_table[i+1] = ring[idx+1]; \ + obj_table[i+2] = ring[idx+2]; \ + obj_table[i+3] = ring[idx+3]; \ } \ switch (n & 0x3) { \ - case 3: obj_table[i++] = r->ring[idx++]; \ - case 2: obj_table[i++] = r->ring[idx++]; \ - case 1: obj_table[i++] = r->ring[idx++]; \ + case 3: \ + obj_table[i++] = ring[idx++]; /* fallthrough */ \ + case 2: \ + obj_table[i++] = ring[idx++]; /* fallthrough */ \ + case 1: \ + obj_table[i++] = ring[idx++]; \ } \ } else { \ for (i = 0; idx < size; i++, idx++) \ - obj_table[i] = r->ring[idx]; \ + obj_table[i] = ring[idx]; \ for (idx = 0; i < n; i++, idx++) \ - obj_table[i] = r->ring[idx]; \ + obj_table[i] = ring[idx]; \ } \ } while (0) @@ -452,7 +456,7 @@ __rte_ring_do_enqueue(struct rte_ring *r, void * const *obj_table, if (n == 0) goto end; - ENQUEUE_PTRS(); + ENQUEUE_PTRS(r, &r[1], prod_head, obj_table, n, void *); rte_smp_wmb(); update_tail(&r->prod, prod_head, prod_next, is_sp); @@ -557,7 +561,7 @@ __rte_ring_do_dequeue(struct rte_ring *r, void **obj_table, if (n == 0) goto end; - DEQUEUE_PTRS(); + DEQUEUE_PTRS(r, &r[1], cons_head, obj_table, n, void *); rte_smp_rmb(); update_tail(&r->cons, cons_head, cons_next, is_sc); -- 2.9.3