> <snip> > > > /** > > * @internal Enqueue several objects on the RTS ring. > > diff --git a/lib/librte_ring/rte_ring_rts_c11_mem.h > > b/lib/librte_ring/rte_ring_rts_c11_mem.h > > new file mode 100644 > > index 000000000..b72901497 > > --- /dev/null > > +++ b/lib/librte_ring/rte_ring_rts_c11_mem.h > > @@ -0,0 +1,198 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * > > + * Copyright (c) 2010-2017 Intel Corporation > > + * Copyright (c) 2007-2009 Kip Macy km...@freebsd.org > > + * All rights reserved. > > + * Derived from FreeBSD's bufring.h > > + * Used as BSD-3 Licensed with permission from Kip Macy. > > + */ > > + > > +#ifndef _RTE_RING_RTS_C11_MEM_H_ > > +#define _RTE_RING_RTS_C11_MEM_H_ > > + > > +/** > > + * @file rte_ring_rts_c11_mem.h > > + * It is not recommended to include this file directly, > > + * include <rte_ring.h> instead. > > + * Contains internal helper functions for Relaxed Tail Sync (RTS) ring > > mode. > > + * For more information please refer to <rte_ring_rts.h>. > > + */ > > + > > +/** > > + * @internal This function updates tail values. > > + */ > > +static __rte_always_inline void > > +__rte_ring_rts_update_tail(struct rte_ring_rts_headtail *ht) { > > + union rte_ring_ht_poscnt h, ot, nt; > > + > > + /* > > + * If there are other enqueues/dequeues in progress that > > + * might preceded us, then don't update tail with new value. > > + */ > > + > > + ot.raw = __atomic_load_n(&ht->tail.raw, __ATOMIC_ACQUIRE); > This can be RELAXED. This thread is reading the value that it updated > earlier, so it should be able to see the value it updated.
It serves as a hoist barrier, to make sure that we read tail before head (see below). > > + > > + do { > > + /* on 32-bit systems we have to do atomic read here */ > > + h.raw = __atomic_load_n(&ht->head.raw, > > __ATOMIC_RELAXED); > > + > > + nt.raw = ot.raw; > > + if (++nt.val.cnt == h.val.cnt) > > + nt.val.pos = h.val.pos; > > + > > + } while (__atomic_compare_exchange_n(&ht->tail.raw, &ot.raw, > > nt.raw, > > + 0, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE) == 0); } > > + > > +/** > > + * @internal This function waits till head/tail distance wouldn't > > + * exceed pre-defined max value. > > + */ > > +static __rte_always_inline void > > +__rte_ring_rts_head_wait(const struct rte_ring_rts_headtail *ht, > > + union rte_ring_ht_poscnt *h) > > +{ > > + uint32_t max; > > + > > + max = ht->htd_max; > > + h->raw = __atomic_load_n(&ht->head.raw, __ATOMIC_ACQUIRE); > > + > > + while (h->val.pos - ht->tail.val.pos > max) { > > + rte_pause(); > > + h->raw = __atomic_load_n(&ht->head.raw, > > __ATOMIC_ACQUIRE); > > + } > > +} > > +