From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf1-f194.google.com (mail-pf1-f194.google.com [209.85.210.194]) by dpdk.org (Postfix) with ESMTP id 76F5BA3 for ; Tue, 19 Mar 2019 16:50:27 +0100 (CET) Received: by mail-pf1-f194.google.com with SMTP id r15so11230663pfn.9 for ; Tue, 19 Mar 2019 08:50:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=H2R6O4J5ck0msxn+mC4QZj7kGFdsMxXV9+4Kc1Jx2Oo=; b=Txb3QvLKp6et5HpVgjLGwKuvGoxSn3zM1WG2hNh3bUer9TX+9ys5MSuj802cP/p4qH vYG1atanRdVovJY6mx8r/Uq9lgVpVeYAdGHKi98Y4QSYfVJNuSMfpld+mIQljdOqeSKW AtVrnkt57PqlqWJzB9nGm/RwbjcZ5G89p6rf8Kgq+3BcKh/zox054N7+h1l5JOv18JXb 1ZsVfAQyqfdEbru5xik7cfJFUyHLFSzWa11ts8noRzr0AeGAPK9fzyZV8Cd66gTP5UFn yfTPmvHv9/bN2Vwcn7YeHUCEw2KpzQMJ2BMOJ2uvP4rl2OIK1uwAcwnqzGZisslwByPQ 1KYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=H2R6O4J5ck0msxn+mC4QZj7kGFdsMxXV9+4Kc1Jx2Oo=; b=UzgLtux6/jT+/bokluRekKd0uvaS3XUrkpLRCb7XwkPTiIl5vkcceF7BrXQSQDkINc G+LOWyjzPMCru0kOwcasFjZi5kH4mIT10FjKoL6dOr79Wun4rZHeWxJA4t7qQ1fMQcfW ib3VakYPYOttHTMc15EE+E0i3GFAY0WXXmE9p+X9vjiwav/RbcC0IO4TKaxiWY3QxUAK ItmTpwZ7JqEUJmHT2ReOVkTxNBnvjIz6CPKHSlpkQypd4ccxeAYuk8mD0vJSwYPLmbOQ q3u2wCy4oKpkiNwmtFVnEDUMPG6FMU+vN/LYIKkMgVh8DdyoqBJkI577Y5+MdV0uN/xC Nh0w== X-Gm-Message-State: APjAAAUN237YseUmjFTaqqiVJ5RuOvRIuxjyKwVKA275c4JFfReIp5mg 4Istk+UBGf8DzYC0MwK9+kwvgg== X-Google-Smtp-Source: APXvYqyghWEjit6sz34UzwMzOXGjkaKhuDXd5zxmP81BQhLbMKyaomRl+wBvM8zFPp3wQYyKsXgWWw== X-Received: by 2002:a63:c10b:: with SMTP id w11mr23709063pgf.39.1553010626512; Tue, 19 Mar 2019 08:50:26 -0700 (PDT) Received: from shemminger-XPS-13-9360 (204-195-22-127.wavecable.com. [204.195.22.127]) by smtp.gmail.com with ESMTPSA id e8sm18470534pfn.103.2019.03.19.08.50.26 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 19 Mar 2019 08:50:26 -0700 (PDT) Date: Tue, 19 Mar 2019 08:50:22 -0700 From: Stephen Hemminger To: Gage Eads Cc: dev@dpdk.org, olivier.matz@6wind.com, arybchenko@solarflare.com, bruce.richardson@intel.com, konstantin.ananyev@intel.com, jerinj@marvell.com, mczekaj@marvell.com, nd@arm.com, Ola.Liljedahl@arm.com Message-ID: <20190319085022.5a971ac2@shemminger-XPS-13-9360> In-Reply-To: <20190318213555.17345-4-gage.eads@intel.com> References: <20190306150342.2894-1-gage.eads@intel.com> <20190318213555.17345-1-gage.eads@intel.com> <20190318213555.17345-4-gage.eads@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Subject: Re: [dpdk-dev] [PATCH v7 3/6] ring: add a lock-free implementation 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, 19 Mar 2019 15:50:27 -0000 On Mon, 18 Mar 2019 16:35:52 -0500 Gage Eads wrote: > > +/* The actual enqueue of pointers on the lock-free ring, used by the > + * single-producer lock-free enqueue function. > + */ > +#define ENQUEUE_PTRS_LF(r, base, prod_head, obj_table, n) do { \ > + unsigned int i; \ > + const uint32_t size = (r)->size; \ > + size_t idx = prod_head & (r)->mask; \ > + size_t new_cnt = prod_head + size; \ > + struct rte_ring_lf_entry *ring = (struct rte_ring_lf_entry *)base; \ > + unsigned int mask = ~0x3; \ > + if (likely(idx + n < size)) { \ > + for (i = 0; i < (n & mask); i += 4, idx += 4) { \ > + ring[idx].ptr = obj_table[i]; \ > + ring[idx].cnt = (new_cnt + i) >> r->log2_size; \ > + ring[idx + 1].ptr = obj_table[i + 1]; \ > + ring[idx + 1].cnt = (new_cnt + i + 1) >> r->log2_size; \ > + ring[idx + 2].ptr = obj_table[i + 2]; \ > + ring[idx + 2].cnt = (new_cnt + i + 2) >> r->log2_size; \ > + ring[idx + 3].ptr = obj_table[i + 3]; \ > + ring[idx + 3].cnt = (new_cnt + i + 3) >> r->log2_size; \ > + } \ > + switch (n & 0x3) { \ > + case 3: \ > + ring[idx].cnt = (new_cnt + i) >> r->log2_size; \ > + ring[idx++].ptr = obj_table[i++]; /* fallthrough */ \ > + case 2: \ > + ring[idx].cnt = (new_cnt + i) >> r->log2_size; \ > + ring[idx++].ptr = obj_table[i++]; /* fallthrough */ \ > + case 1: \ > + ring[idx].cnt = (new_cnt + i) >> r->log2_size; \ > + ring[idx++].ptr = obj_table[i++]; \ > + } \ > + } else { \ > + for (i = 0; idx < size; i++, idx++) { \ > + ring[idx].cnt = (new_cnt + i) >> r->log2_size; \ > + ring[idx].ptr = obj_table[i]; \ > + } \ > + for (idx = 0; i < n; i++, idx++) { \ > + ring[idx].cnt = (new_cnt + i) >> r->log2_size; \ > + ring[idx].ptr = obj_table[i]; \ > + } \ > + } \ > +} 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 */ > @@ -314,6 +384,43 @@ void rte_ring_dump(FILE *f, const struct rte_ring *r); > } \ > } while (0) > > +/* The actual copy of pointers on the lock-free ring to obj_table. */ > +#define DEQUEUE_PTRS_LF(r, base, cons_head, obj_table, n) do { \ > + unsigned int i; \ > + size_t idx = cons_head & (r)->mask; \ > + const uint32_t size = (r)->size; \ > + struct rte_ring_lf_entry *ring = (struct rte_ring_lf_entry *)base; \ > + unsigned int mask = ~0x3; \ > + if (likely(idx + n < size)) { \ > + for (i = 0; i < (n & mask); i += 4, idx += 4) {\ > + obj_table[i] = ring[idx].ptr; \ > + obj_table[i + 1] = ring[idx + 1].ptr; \ > + obj_table[i + 2] = ring[idx + 2].ptr; \ > + obj_table[i + 3] = ring[idx + 3].ptr; \ > + } \ > + switch (n & 0x3) { \ > + case 3: \ > + obj_table[i++] = ring[idx++].ptr; /* fallthrough */ \ > + case 2: \ > + obj_table[i++] = ring[idx++].ptr; /* fallthrough */ \ > + case 1: \ > + obj_table[i++] = ring[idx++].ptr; \ > + } \ > + } else { \ > + for (i = 0; idx < size; i++, idx++) \ > + obj_table[i] = ring[idx].ptr; \ > + for (idx = 0; i < n; i++, idx++) \ > + obj_table[i] = ring[idx].ptr; \ > + } \ > +} while (0) > + Generic programming like this in C is hard to maintain. Please don't use large macros. It is better to have two copies than a single large macro. Better yet use a single inline function than can be expanded in different ways based on the pointer size. From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by dpdk.space (Postfix) with ESMTP id 1612DA00E6 for ; Tue, 19 Mar 2019 16:50:29 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 502AD239; Tue, 19 Mar 2019 16:50:28 +0100 (CET) Received: from mail-pf1-f194.google.com (mail-pf1-f194.google.com [209.85.210.194]) by dpdk.org (Postfix) with ESMTP id 76F5BA3 for ; Tue, 19 Mar 2019 16:50:27 +0100 (CET) Received: by mail-pf1-f194.google.com with SMTP id r15so11230663pfn.9 for ; Tue, 19 Mar 2019 08:50:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=H2R6O4J5ck0msxn+mC4QZj7kGFdsMxXV9+4Kc1Jx2Oo=; b=Txb3QvLKp6et5HpVgjLGwKuvGoxSn3zM1WG2hNh3bUer9TX+9ys5MSuj802cP/p4qH vYG1atanRdVovJY6mx8r/Uq9lgVpVeYAdGHKi98Y4QSYfVJNuSMfpld+mIQljdOqeSKW AtVrnkt57PqlqWJzB9nGm/RwbjcZ5G89p6rf8Kgq+3BcKh/zox054N7+h1l5JOv18JXb 1ZsVfAQyqfdEbru5xik7cfJFUyHLFSzWa11ts8noRzr0AeGAPK9fzyZV8Cd66gTP5UFn yfTPmvHv9/bN2Vwcn7YeHUCEw2KpzQMJ2BMOJ2uvP4rl2OIK1uwAcwnqzGZisslwByPQ 1KYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=H2R6O4J5ck0msxn+mC4QZj7kGFdsMxXV9+4Kc1Jx2Oo=; b=UzgLtux6/jT+/bokluRekKd0uvaS3XUrkpLRCb7XwkPTiIl5vkcceF7BrXQSQDkINc G+LOWyjzPMCru0kOwcasFjZi5kH4mIT10FjKoL6dOr79Wun4rZHeWxJA4t7qQ1fMQcfW ib3VakYPYOttHTMc15EE+E0i3GFAY0WXXmE9p+X9vjiwav/RbcC0IO4TKaxiWY3QxUAK ItmTpwZ7JqEUJmHT2ReOVkTxNBnvjIz6CPKHSlpkQypd4ccxeAYuk8mD0vJSwYPLmbOQ q3u2wCy4oKpkiNwmtFVnEDUMPG6FMU+vN/LYIKkMgVh8DdyoqBJkI577Y5+MdV0uN/xC Nh0w== X-Gm-Message-State: APjAAAUN237YseUmjFTaqqiVJ5RuOvRIuxjyKwVKA275c4JFfReIp5mg 4Istk+UBGf8DzYC0MwK9+kwvgg== X-Google-Smtp-Source: APXvYqyghWEjit6sz34UzwMzOXGjkaKhuDXd5zxmP81BQhLbMKyaomRl+wBvM8zFPp3wQYyKsXgWWw== X-Received: by 2002:a63:c10b:: with SMTP id w11mr23709063pgf.39.1553010626512; Tue, 19 Mar 2019 08:50:26 -0700 (PDT) Received: from shemminger-XPS-13-9360 (204-195-22-127.wavecable.com. [204.195.22.127]) by smtp.gmail.com with ESMTPSA id e8sm18470534pfn.103.2019.03.19.08.50.26 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 19 Mar 2019 08:50:26 -0700 (PDT) Date: Tue, 19 Mar 2019 08:50:22 -0700 From: Stephen Hemminger To: Gage Eads Cc: dev@dpdk.org, olivier.matz@6wind.com, arybchenko@solarflare.com, bruce.richardson@intel.com, konstantin.ananyev@intel.com, jerinj@marvell.com, mczekaj@marvell.com, nd@arm.com, Ola.Liljedahl@arm.com Message-ID: <20190319085022.5a971ac2@shemminger-XPS-13-9360> In-Reply-To: <20190318213555.17345-4-gage.eads@intel.com> References: <20190306150342.2894-1-gage.eads@intel.com> <20190318213555.17345-1-gage.eads@intel.com> <20190318213555.17345-4-gage.eads@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit Subject: Re: [dpdk-dev] [PATCH v7 3/6] ring: add a lock-free implementation 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Message-ID: <20190319155022._-IOeaKgQeKuvHagZ161SlLk36sgc71-lj_bbPJFljE@z> On Mon, 18 Mar 2019 16:35:52 -0500 Gage Eads wrote: > > +/* The actual enqueue of pointers on the lock-free ring, used by the > + * single-producer lock-free enqueue function. > + */ > +#define ENQUEUE_PTRS_LF(r, base, prod_head, obj_table, n) do { \ > + unsigned int i; \ > + const uint32_t size = (r)->size; \ > + size_t idx = prod_head & (r)->mask; \ > + size_t new_cnt = prod_head + size; \ > + struct rte_ring_lf_entry *ring = (struct rte_ring_lf_entry *)base; \ > + unsigned int mask = ~0x3; \ > + if (likely(idx + n < size)) { \ > + for (i = 0; i < (n & mask); i += 4, idx += 4) { \ > + ring[idx].ptr = obj_table[i]; \ > + ring[idx].cnt = (new_cnt + i) >> r->log2_size; \ > + ring[idx + 1].ptr = obj_table[i + 1]; \ > + ring[idx + 1].cnt = (new_cnt + i + 1) >> r->log2_size; \ > + ring[idx + 2].ptr = obj_table[i + 2]; \ > + ring[idx + 2].cnt = (new_cnt + i + 2) >> r->log2_size; \ > + ring[idx + 3].ptr = obj_table[i + 3]; \ > + ring[idx + 3].cnt = (new_cnt + i + 3) >> r->log2_size; \ > + } \ > + switch (n & 0x3) { \ > + case 3: \ > + ring[idx].cnt = (new_cnt + i) >> r->log2_size; \ > + ring[idx++].ptr = obj_table[i++]; /* fallthrough */ \ > + case 2: \ > + ring[idx].cnt = (new_cnt + i) >> r->log2_size; \ > + ring[idx++].ptr = obj_table[i++]; /* fallthrough */ \ > + case 1: \ > + ring[idx].cnt = (new_cnt + i) >> r->log2_size; \ > + ring[idx++].ptr = obj_table[i++]; \ > + } \ > + } else { \ > + for (i = 0; idx < size; i++, idx++) { \ > + ring[idx].cnt = (new_cnt + i) >> r->log2_size; \ > + ring[idx].ptr = obj_table[i]; \ > + } \ > + for (idx = 0; i < n; i++, idx++) { \ > + ring[idx].cnt = (new_cnt + i) >> r->log2_size; \ > + ring[idx].ptr = obj_table[i]; \ > + } \ > + } \ > +} 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 */ > @@ -314,6 +384,43 @@ void rte_ring_dump(FILE *f, const struct rte_ring *r); > } \ > } while (0) > > +/* The actual copy of pointers on the lock-free ring to obj_table. */ > +#define DEQUEUE_PTRS_LF(r, base, cons_head, obj_table, n) do { \ > + unsigned int i; \ > + size_t idx = cons_head & (r)->mask; \ > + const uint32_t size = (r)->size; \ > + struct rte_ring_lf_entry *ring = (struct rte_ring_lf_entry *)base; \ > + unsigned int mask = ~0x3; \ > + if (likely(idx + n < size)) { \ > + for (i = 0; i < (n & mask); i += 4, idx += 4) {\ > + obj_table[i] = ring[idx].ptr; \ > + obj_table[i + 1] = ring[idx + 1].ptr; \ > + obj_table[i + 2] = ring[idx + 2].ptr; \ > + obj_table[i + 3] = ring[idx + 3].ptr; \ > + } \ > + switch (n & 0x3) { \ > + case 3: \ > + obj_table[i++] = ring[idx++].ptr; /* fallthrough */ \ > + case 2: \ > + obj_table[i++] = ring[idx++].ptr; /* fallthrough */ \ > + case 1: \ > + obj_table[i++] = ring[idx++].ptr; \ > + } \ > + } else { \ > + for (i = 0; idx < size; i++, idx++) \ > + obj_table[i] = ring[idx].ptr; \ > + for (idx = 0; i < n; i++, idx++) \ > + obj_table[i] = ring[idx].ptr; \ > + } \ > +} while (0) > + Generic programming like this in C is hard to maintain. Please don't use large macros. It is better to have two copies than a single large macro. Better yet use a single inline function than can be expanded in different ways based on the pointer size.