Skip to content

Commit

Permalink
sched/signal: reclaim dynamic sigactions
Browse files Browse the repository at this point in the history
This adds support of pre- and dynamic allocations of sigactions.
Current never-return behavior can be acheived by setting
SIG_ALLOC_ACTIONS to a number larger than 1.

Signed-off-by: Yanfeng Liu <[email protected]>
  • Loading branch information
yf13 committed Jun 18, 2024
1 parent c885ba7 commit 0be97b4
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 8 deletions.
14 changes: 14 additions & 0 deletions sched/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 14 additions & 7 deletions sched/signal/sig_action.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ static void nxsig_alloc_actionblock(void)

/* 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);
}
Expand Down Expand Up @@ -100,7 +100,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)
{
Expand Down Expand Up @@ -409,9 +409,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);
}
}
14 changes: 14 additions & 0 deletions sched/signal/sig_initialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ struct sigpool_s

sq_queue_t g_sigfreeaction;

#if CONFIG_SIG_PREALLOC_ACTIONS > 0
sigactq_t g_sigactions[CONFIG_SIG_PREALLOC_ACTIONS];
#endif

/* The g_sigpendingaction data structure is a list of available pending
* signal action structures.
*/
Expand Down Expand Up @@ -155,6 +159,9 @@ static void *nxsig_init_pendingsignalblock(FAR sq_queue_t *siglist,
void nxsig_initialize(void)
{
FAR void *sigpool = &g_sigpool;
#if CONFIG_SIG_PREALLOC_ACTIONS > 0
int i;
#endif

sched_trace_begin();

Expand All @@ -166,6 +173,13 @@ void nxsig_initialize(void)
sq_init(&g_sigpendingsignal);
sq_init(&g_sigpendingirqsignal);

#if CONFIG_SIG_PREALLOC_ACTIONS > 0
for (i = 0; i < CONFIG_SIG_PREALLOC_ACTIONS; i++)
{
sq_addlast((FAR sq_entry_t *)(g_sigactions + i), &g_sigfreeaction);
}
#endif

sigpool = nxsig_init_block(&g_sigpendingaction, sigpool,
NUM_PENDING_ACTIONS, SIG_ALLOC_FIXED);
sigpool = nxsig_init_block(&g_sigpendingirqaction, sigpool,
Expand Down
10 changes: 9 additions & 1 deletion sched/signal/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
* allocate in a block
*/

#define NUM_SIGNAL_ACTIONS 4
#define NUM_PENDING_ACTIONS 4
#define NUM_SIGNALS_PENDING 4

Expand Down Expand Up @@ -111,6 +110,15 @@ typedef struct sigq_s sigq_t;

extern sq_queue_t g_sigfreeaction;

#if CONFIG_SIG_PREALLOC_ACTIONS > 0
extern sigactq_t g_sigactions[CONFIG_SIG_PREALLOC_ACTIONS];
#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

/* The g_sigpendingaction data structure is a list of available pending
* signal action structures.
*/
Expand Down

0 comments on commit 0be97b4

Please sign in to comment.