[1/3] lib/eal: add rte_atomic128_cmp_exchange compatible with MSVC

Message ID 1733848355-19048-2-git-send-email-andremue@linux.microsoft.com (mailing list archive)
State New, archived
Delegated to: David Marchand
Headers
Series enable build of lib/stack when using MSVC |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Andre Muezerie Dec. 10, 2024, 4:32 p.m. UTC
MSVC does not support inline assembly, which is used by the
implementation of rte_atomic128_cmp_exchange and is needed
by lib/stack.

Error printed by MSVC:

stack_rte_stack_lf.c.obj : error LNK2019:
    unresolved external symbol rte_atomic128_cmp_exchange referenced
    in function __rte_stack_lf_push_elems

Fix is to provide an implementation for rte_atomic128_cmp_exchange
which uses an intrinsic function, which is used when compiling with
MSVC. For other compilers the existing implementation continues to
be used.

Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
---
 lib/eal/x86/include/rte_atomic.h    |  4 ++--
 lib/eal/x86/include/rte_atomic_64.h | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+), 2 deletions(-)
  

Comments

David Marchand Jan. 24, 2025, 2:27 p.m. UTC | #1
On Tue, Dec 10, 2024 at 5:33 PM Andre Muezerie
<andremue@linux.microsoft.com> wrote:
>
> MSVC does not support inline assembly, which is used by the
> implementation of rte_atomic128_cmp_exchange and is needed
> by lib/stack.
>
> Error printed by MSVC:
>
> stack_rte_stack_lf.c.obj : error LNK2019:
>     unresolved external symbol rte_atomic128_cmp_exchange referenced
>     in function __rte_stack_lf_push_elems
>
> Fix is to provide an implementation for rte_atomic128_cmp_exchange
> which uses an intrinsic function, which is used when compiling with
> MSVC. For other compilers the existing implementation continues to
> be used.
>
> Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
> ---
>  lib/eal/x86/include/rte_atomic.h    |  4 ++--
>  lib/eal/x86/include/rte_atomic_64.h | 18 ++++++++++++++++++
>  2 files changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/lib/eal/x86/include/rte_atomic.h b/lib/eal/x86/include/rte_atomic.h
> index c72c47c83e..e8e0e4c33c 100644
> --- a/lib/eal/x86/include/rte_atomic.h
> +++ b/lib/eal/x86/include/rte_atomic.h
> @@ -288,12 +288,12 @@ static inline int rte_atomic32_dec_and_test(rte_atomic32_t *v)
>
>  #endif
>
> +#endif /* RTE_TOOLCHAIN_MSVC */
> +
>  #ifdef RTE_ARCH_I686
>  #include "rte_atomic_32.h"
>  #else
>  #include "rte_atomic_64.h"
>  #endif
>
> -#endif
> -

This partially reverts 27da6a123414 ("eal: hide legacy atomics API for MSVC").
It would be better to implement an equivalent to
rte_atomic128_cmp_exchange in the DPDK "new" stdatomic API
(rte_stdatomic.h).
  
Andre Muezerie Jan. 28, 2025, 9:25 p.m. UTC | #2
On Fri, Jan 24, 2025 at 03:27:06PM +0100, David Marchand wrote:
> On Tue, Dec 10, 2024 at 5:33 PM Andre Muezerie
> <andremue@linux.microsoft.com> wrote:
> >
> > MSVC does not support inline assembly, which is used by the
> > implementation of rte_atomic128_cmp_exchange and is needed
> > by lib/stack.
> >
> > Error printed by MSVC:
> >
> > stack_rte_stack_lf.c.obj : error LNK2019:
> >     unresolved external symbol rte_atomic128_cmp_exchange referenced
> >     in function __rte_stack_lf_push_elems
> >
> > Fix is to provide an implementation for rte_atomic128_cmp_exchange
> > which uses an intrinsic function, which is used when compiling with
> > MSVC. For other compilers the existing implementation continues to
> > be used.
> >
> > Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
> > ---
> >  lib/eal/x86/include/rte_atomic.h    |  4 ++--
> >  lib/eal/x86/include/rte_atomic_64.h | 18 ++++++++++++++++++
> >  2 files changed, 20 insertions(+), 2 deletions(-)
> >
> > diff --git a/lib/eal/x86/include/rte_atomic.h b/lib/eal/x86/include/rte_atomic.h
> > index c72c47c83e..e8e0e4c33c 100644
> > --- a/lib/eal/x86/include/rte_atomic.h
> > +++ b/lib/eal/x86/include/rte_atomic.h
> > @@ -288,12 +288,12 @@ static inline int rte_atomic32_dec_and_test(rte_atomic32_t *v)
> >
> >  #endif
> >
> > +#endif /* RTE_TOOLCHAIN_MSVC */
> > +
> >  #ifdef RTE_ARCH_I686
> >  #include "rte_atomic_32.h"
> >  #else
> >  #include "rte_atomic_64.h"
> >  #endif
> >
> > -#endif
> > -
> 
> This partially reverts 27da6a123414 ("eal: hide legacy atomics API for MSVC").
> It would be better to implement an equivalent to
> rte_atomic128_cmp_exchange in the DPDK "new" stdatomic API
> (rte_stdatomic.h).
> 
> 
> -- 
> David Marchand

Thanks for calling that out. After looking at the past commits I got a better understanding
of the reasons the atomic-related code is laid out the way it is, and I agree that we should
attempt to follow the same guidelines.

For that reason I changed the approach taken in the v2 I sent out today.

Let me know your thoughts.
--
Andre Muezerie
  

Patch

diff --git a/lib/eal/x86/include/rte_atomic.h b/lib/eal/x86/include/rte_atomic.h
index c72c47c83e..e8e0e4c33c 100644
--- a/lib/eal/x86/include/rte_atomic.h
+++ b/lib/eal/x86/include/rte_atomic.h
@@ -288,12 +288,12 @@  static inline int rte_atomic32_dec_and_test(rte_atomic32_t *v)
 
 #endif
 
+#endif /* RTE_TOOLCHAIN_MSVC */
+
 #ifdef RTE_ARCH_I686
 #include "rte_atomic_32.h"
 #else
 #include "rte_atomic_64.h"
 #endif
 
-#endif
-
 #endif /* _RTE_ATOMIC_X86_H_ */
diff --git a/lib/eal/x86/include/rte_atomic_64.h b/lib/eal/x86/include/rte_atomic_64.h
index 0a7a2131e0..26c87a2da6 100644
--- a/lib/eal/x86/include/rte_atomic_64.h
+++ b/lib/eal/x86/include/rte_atomic_64.h
@@ -182,6 +182,23 @@  static inline void rte_atomic64_clear(rte_atomic64_t *v)
 
 /*------------------------ 128 bit atomic operations -------------------------*/
 
+#ifdef RTE_TOOLCHAIN_MSVC
+static inline int
+rte_atomic128_cmp_exchange(rte_int128_t *dst,
+			   rte_int128_t *exp,
+			   const rte_int128_t *src,
+			   unsigned int weak,
+			   int success,
+			   int failure)
+{
+	return (int)_InterlockedCompareExchange128(
+		(int64_t volatile *) dst,
+		src->val[1], /* exchange high */
+		src->val[0], /* exchange low */
+		(int64_t *) exp /* comparand result */
+	);
+}
+#else
 static inline int
 rte_atomic128_cmp_exchange(rte_int128_t *dst,
 			   rte_int128_t *exp,
@@ -212,5 +229,6 @@  rte_atomic128_cmp_exchange(rte_int128_t *dst,
 
 	return res;
 }
+#endif /* RTE_TOOLCHAIN_MSVC */
 
 #endif /* _RTE_ATOMIC_X86_64_H_ */