On 10.02.2017 19:06, Joe Savage wrote: > Add an example application implementing lock-free IPv4 fragmentation > and reassembly functionality using ODP's packet "concat" and "split". > > Signed-off-by: Joe Savage <joe.sav...@arm.com> > Reviewed-and-tested-by: Bill Fischofer <bill.fischo...@linaro.org> > --- > (This code contribution is provided under the terms of agreement > LES-LTM-21309) >
> diff --git a/example/ipfragreass/odp_ipfragreass_atomics.h > b/example/ipfragreass/odp_ipfragreass_atomics.h > new file mode 100644 > index 0000000..bebe3d3 > --- /dev/null > +++ b/example/ipfragreass/odp_ipfragreass_atomics.h > @@ -0,0 +1,130 @@ > +/* Copyright (c) 2017, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#ifndef ODP_FRAGREASS_PP_ATOMICS_H_ > +#define ODP_FRAGREASS_PP_ATOMICS_H_ > + > +#include <example_debug.h> > + > +#if defined(__arm__) || defined(__aarch64__) > +#if defined(__aarch64__) > +static inline __int128 lld(__int128 *var, int mo); > +static inline uint32_t scd(__int128 *var, __int128 neu, int mo); Is there any reason to have prototypes, then main function, then lld/scd implementation? What about moving lld/scd upwards, so that there would be no extra prototypes? > +static inline bool arm_atomic_strong_compare_exchange_16(__int128 *var, > + __int128 *exp, > + __int128 neu, > + int mo_success, > + int mo_failure > + EXAMPLE_UNUSED) > +{ > + register __int128 old; > + register __int128 expected = *exp; > + int ll_mo, sc_mo; > + > + ll_mo = (mo_success != __ATOMIC_RELAXED && > + mo_success != __ATOMIC_RELEASE) ? __ATOMIC_ACQUIRE > + : __ATOMIC_RELAXED; > + sc_mo = (mo_success == __ATOMIC_RELEASE || > + mo_success == __ATOMIC_ACQ_REL || > + mo_success == __ATOMIC_SEQ_CST) ? __ATOMIC_RELEASE > + : __ATOMIC_RELAXED; > + > + /* > + * To prevent spurious failures and ensure atomicity, we must write some > + * value back -- whether it's the value we wanted to write, or the value > + * that is currently there. Repeat until we perform a successful write. > + */ > + do { > + old = lld(var, ll_mo); > + } while (scd(var, old == expected ? neu : old, sc_mo)); > + > + *exp = old; > + return (old == expected); > +} > + > +static inline __int128 lld(__int128 *var, int mo) > +{ > + __int128 old; > + > + if (mo == __ATOMIC_ACQUIRE) > + __asm__ volatile("ldaxp %0, %H0, [%1]" : "=&r" (old) > + : "r" (var) : "memory"); > + else /* mo == __ATOMIC_RELAXED */ > + __asm__ volatile("ldxp %0, %H0, [%1]" : "=&r" (old) > + : "r" (var) : ); > + return old; > +} > + > +static inline uint32_t scd(__int128 *var, __int128 neu, int mo) > +{ > + uint32_t ret; > + > + if (mo == __ATOMIC_RELEASE) > + __asm__ volatile("stlxp %w0, %1, %H1, [%2]" : "=&r" (ret) > + : "r" (neu), "r" (var) : "memory"); > + else /* mo == __ATOMIC_RELAXED */ > + __asm__ volatile("stxp %w0, %1, %H1, [%2]" : "=&r" (ret) > + : "r" (neu), "r" (var) : ); > + return ret; > +} -- With best wishes Dmitry