You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2023/06/15 22:32:06 UTC

[nuttx] 02/02: netdev/upper: Use atomic when we have atomic support from compiler

This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit f80539b6a82b6cb7a321c4a31c6d8c275d703316
Author: Zhe Weng <we...@xiaomi.com>
AuthorDate: Wed Jun 14 16:29:15 2023 +0800

    netdev/upper: Use atomic when we have atomic support from compiler
    
    Ref: How to test atomic support https://beej.us/guide/bgc/html/split/chapter-atomics.html
    
    Signed-off-by: Zhe Weng <we...@xiaomi.com>
---
 drivers/net/netdev_upperhalf.c       | 12 ++++++++++++
 include/nuttx/net/netdev_lowerhalf.h | 26 +++++++++++++++++++++++++-
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/net/netdev_upperhalf.c b/drivers/net/netdev_upperhalf.c
index db144235d2..1a12a49599 100644
--- a/drivers/net/netdev_upperhalf.c
+++ b/drivers/net/netdev_upperhalf.c
@@ -91,19 +91,27 @@ struct netdev_upperhalf_s
 static int quota_fetch_inc(FAR struct netdev_lowerhalf_s *lower,
                            enum netpkt_type_e type)
 {
+#ifndef HAVE_ATOMIC
   irqstate_t flags = spin_lock_irqsave(NULL);
   int ret = lower->quota[type]++;
   spin_unlock_irqrestore(NULL, flags);
   return ret;
+#else
+  return atomic_fetch_add(&lower->quota[type], 1);
+#endif
 }
 
 static int quota_fetch_dec(FAR struct netdev_lowerhalf_s *lower,
                            enum netpkt_type_e type)
 {
+#ifndef HAVE_ATOMIC
   irqstate_t flags = spin_lock_irqsave(NULL);
   int ret = lower->quota[type]--;
   spin_unlock_irqrestore(NULL, flags);
   return ret;
+#else
+  return atomic_fetch_sub(&lower->quota[type], 1);
+#endif
 }
 
 /****************************************************************************
@@ -838,10 +846,14 @@ void netdev_lower_txdone(FAR struct netdev_lowerhalf_s *dev)
 int netdev_lower_quota_load(FAR struct netdev_lowerhalf_s *dev,
                             enum netpkt_type_e type)
 {
+#ifndef HAVE_ATOMIC
   irqstate_t flags = spin_lock_irqsave(NULL);
   int ret = dev->quota[type];
   spin_unlock_irqrestore(NULL, flags);
   return ret;
+#else
+  return atomic_load(&dev->quota[type]);
+#endif
 }
 
 /****************************************************************************
diff --git a/include/nuttx/net/netdev_lowerhalf.h b/include/nuttx/net/netdev_lowerhalf.h
index 958505801a..e3298ea4b6 100644
--- a/include/nuttx/net/netdev_lowerhalf.h
+++ b/include/nuttx/net/netdev_lowerhalf.h
@@ -32,6 +32,17 @@
 #include <net/if.h>
 #include <netinet/in.h>
 
+/* Compiler may not have stdatomic.h before C11 or with __STDC_NO_ATOMICS__
+ * But we can also get atomic support from libmetal.
+ */
+
+#if defined(CONFIG_OPENAMP)
+#include <metal/atomic.h>
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && \
+      !defined(__STDC_NO_ATOMICS__)
+#include <stdatomic.h>
+#endif
+
 #include <nuttx/net/ip.h>
 #include <nuttx/net/net.h>
 #include <nuttx/net/netdev.h>
@@ -50,6 +61,12 @@
 
 #define NETPKT_BUFLEN   CONFIG_IOB_BUFSIZE
 
+#if defined(CONFIG_OPENAMP) || \
+    (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && \
+    !defined(__STDC_NO_ATOMICS__))
+#define HAVE_ATOMIC
+#endif
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/
@@ -84,7 +101,14 @@ struct netdev_ops_s;
 struct netdev_lowerhalf_s
 {
   FAR const struct netdev_ops_s *ops;
-  int quota[NETPKT_TYPENUM]; /* Max # of buffer held by driver */
+
+  /* Max # of buffer held by driver */
+
+#ifdef HAVE_ATOMIC
+  atomic_int quota[NETPKT_TYPENUM];
+#else
+  int quota[NETPKT_TYPENUM];
+#endif
 
   /* The structure used by net stack.
    * Note: Do not change its fields unless you know what you are doing.