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 <yfliu2008@qq.com>
This commit is contained in:
parent
ab693f8aee
commit
2827703b0c
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,6 @@
|
||||
* allocate in a block
|
||||
*/
|
||||
|
||||
#define NUM_SIGNAL_ACTIONS 4
|
||||
#define NUM_PENDING_ACTIONS 4
|
||||
#define NUM_SIGNALS_PENDING 4
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user