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

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


The following commit(s) were added to refs/heads/master by this push:
     new 2827703b0c sched/signal: reclaim dynamic sigactions
2827703b0c is described below

commit 2827703b0c57f9fc74817c95928e14ee485900d7
Author: Yanfeng Liu <[email protected]>
AuthorDate: Wed May 29 14:55:19 2024 +0800

    sched/signal: reclaim dynamic sigactions
    
    This adds pre-allocation and dynamic allocations for sigactions.
    Current behavior can be acheived by setting SIG_ALLOC_ACTIONS to
    a number larger than 1.
    
    Signed-off-by: Yanfeng Liu <[email protected]>
---
 sched/Kconfig             | 14 ++++++++++++
 sched/signal/sig_action.c | 57 +++++++++++++++++++++++++++++++++++++++++------
 sched/signal/signal.h     |  1 -
 3 files changed, 64 insertions(+), 8 deletions(-)

diff --git a/sched/Kconfig b/sched/Kconfig
index 635cbbb9ba..1601dbcd53 100644
--- a/sched/Kconfig
+++ b/sched/Kconfig
@@ -1548,6 +1548,20 @@ endmenu # RTOS hooks
 
 menu "Signal Configuration"
 
+config SIG_PREALLOC_ACTIONS
+       int "Number of pre-allocated sigactions"
+       default 4
+       ---help---
+               The number of pre-allocated sigaction structures.
+
+config SIG_ALLOC_ACTIONS
+       int "Num of sigactions to allocate per time"
+       default 1
+       ---help---
+               The number of sigactions to allocate per time. Note that
+               if this number is larger than 1, the allocation won't be
+               returned to the heap but kept in a free list for reuse.
+
 config SIG_PREALLOC_IRQ_ACTIONS
        int "Number of pre-allocated irq actions"
        default 4 if DEFAULT_SMALL
diff --git a/sched/signal/sig_action.c b/sched/signal/sig_action.c
index 934a668224..3467279bab 100644
--- a/sched/signal/sig_action.c
+++ b/sched/signal/sig_action.c
@@ -40,12 +40,31 @@
 #include "group/group.h"
 #include "signal/signal.h"
 
+/****************************************************************************
+ * Preprocessor definitions
+ ****************************************************************************/
+
+/* judges if a sigaction instance is a preallocated one */
+
+#if CONFIG_SIG_PREALLOC_ACTIONS > 0
+#  define IS_PREALLOC_ACTION(x) ( \
+          (uintptr_t)(x) >= (uintptr_t)g_sigactions && \
+          (uintptr_t)(x) < ((uintptr_t)g_sigactions) + sizeof(g_sigactions))
+#else
+#  define IS_PREALLOC_ACTION(x) false
+#endif
+
 /****************************************************************************
  * Private Data
  ****************************************************************************/
 
 static spinlock_t g_sigaction_spin;
 
+#if CONFIG_SIG_PREALLOC_ACTIONS > 0
+static sigactq_t  g_sigactions[CONFIG_SIG_PREALLOC_ACTIONS];
+static bool       g_sigactions_used = false;
+#endif
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -65,14 +84,31 @@ static void nxsig_alloc_actionblock(void)
   irqstate_t flags;
   int i;
 
+  /* Use pre-allocated instances only once */
+
+#if CONFIG_SIG_PREALLOC_ACTIONS > 0
+  flags = spin_lock_irqsave(&g_sigaction_spin);
+  if (!g_sigactions_used)
+    {
+      for (i = 0; i < CONFIG_SIG_PREALLOC_ACTIONS; i++)
+        {
+          sq_addlast((FAR sq_entry_t *)(g_sigactions + i), &g_sigfreeaction);
+        }
+
+      g_sigactions_used = true;
+    }
+
+  spin_unlock_irqrestore(&g_sigaction_spin, flags);
+#endif
+
   /* Allocate a block of signal actions */
 
-  sigact = kmm_malloc((sizeof(sigactq_t)) * NUM_SIGNAL_ACTIONS);
+  sigact = kmm_malloc((sizeof(sigactq_t)) * CONFIG_SIG_ALLOC_ACTIONS);
   if (sigact != NULL)
     {
       flags = spin_lock_irqsave(&g_sigaction_spin);
 
-      for (i = 0; i < NUM_SIGNAL_ACTIONS; i++)
+      for (i = 0; i < CONFIG_SIG_ALLOC_ACTIONS; i++)
         {
           sq_addlast((FAR sq_entry_t *)sigact++, &g_sigfreeaction);
         }
@@ -100,7 +136,7 @@ static FAR sigactq_t *nxsig_alloc_action(void)
   sigact = (FAR sigactq_t *)sq_remfirst(&g_sigfreeaction);
   spin_unlock_irqrestore(&g_sigaction_spin, flags);
 
-  /* Check if we got one. */
+  /* Check if we got one via loop as not in critical section now */
 
   while (!sigact)
     {
@@ -409,9 +445,16 @@ void nxsig_release_action(FAR sigactq_t *sigact)
 {
   irqstate_t flags;
 
-  /* Just put it back on the free list */
+  if (CONFIG_SIG_ALLOC_ACTIONS > 1 || IS_PREALLOC_ACTION(sigact))
+    {
+      /* Non-preallocated instances will never return to heap! */
 
-  flags = spin_lock_irqsave(&g_sigaction_spin);
-  sq_addlast((FAR sq_entry_t *)sigact, &g_sigfreeaction);
-  spin_unlock_irqrestore(&g_sigaction_spin, flags);
+      flags = spin_lock_irqsave(&g_sigaction_spin);
+      sq_addlast((FAR sq_entry_t *)sigact, &g_sigfreeaction);
+      spin_unlock_irqrestore(&g_sigaction_spin, flags);
+    }
+  else
+    {
+      kmm_free(sigact);
+    }
 }
diff --git a/sched/signal/signal.h b/sched/signal/signal.h
index 0553b8e3b0..5165d6804f 100644
--- a/sched/signal/signal.h
+++ b/sched/signal/signal.h
@@ -42,7 +42,6 @@
  * allocate in a block
  */
 
-#define NUM_SIGNAL_ACTIONS       4
 #define NUM_PENDING_ACTIONS      4
 #define NUM_SIGNALS_PENDING      4
 

Reply via email to