Skip to content

Commit

Permalink
sched/signal: reclaim unused sigaction blocks
Browse files Browse the repository at this point in the history
This adds logic to reclaim unused sigaction blocks to reduce footprint
after running ostest.

Signed-off-by: Yanfeng Liu <[email protected]>
  • Loading branch information
yf13 committed May 27, 2024
1 parent 0bad215 commit 92c6a16
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 9 deletions.
111 changes: 103 additions & 8 deletions sched/signal/sig_action.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <sched.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>

#include <nuttx/irq.h>
#include <nuttx/queue.h>
Expand All @@ -50,12 +51,53 @@ static spinlock_t g_sigaction_spin;
* Private Functions
****************************************************************************/

/****************************************************************************
* Name: nxsig_add_freeaction
*
* Description:
* Insert a signal action entry to the address-sorted free list
*
****************************************************************************/

static void nxsig_add_free(FAR sigactq_t *sigact)
{
FAR sigactq_t *prev;
FAR sigactq_t *next;
irqstate_t flags;

flags = spin_lock_irqsave(&g_sigaction_spin);

if (g_sigfreeaction.head == NULL ||
(uintptr_t)sigact > (uintptr_t)g_sigfreeaction.tail)
{
sq_addlast((FAR sq_entry_t *)sigact, &g_sigfreeaction);
}
else if ((uintptr_t)sigact < (uintptr_t)g_sigfreeaction.head)
{
sq_addfirst((FAR sq_entry_t *)sigact, &g_sigfreeaction);
}
else
{
prev = (FAR sigactq_t *)g_sigfreeaction.head;
next = prev->flink;
while ((uintptr_t)next < (uintptr_t)sigact)
{
prev = next;
next = prev->flink;
}

sq_addafter((FAR sq_entry_t *)prev, (FAR sq_entry_t *)sigact,
&g_sigfreeaction);
}

spin_unlock_irqrestore(&g_sigaction_spin, flags);
}

/****************************************************************************
* Name: nxsig_alloc_actionblock
*
* Description:
* Allocate a block of signal actions and place them
* on the free list.
* Allocate a block of signal actions and place them in the free list.
*
****************************************************************************/

Expand All @@ -67,14 +109,16 @@ static void nxsig_alloc_actionblock(void)

/* Allocate a block of signal actions */

sigact = kmm_malloc((sizeof(sigactq_t)) * NUM_SIGNAL_ACTIONS);
sigact = kmm_zalloc((sizeof(sigactq_t)) * NUM_SIGNAL_ACTIONS);
if (sigact != NULL)
{
sigact->sob = 1; /* mark the first entry only */
nxsig_add_free(sigact);
flags = spin_lock_irqsave(&g_sigaction_spin);

for (i = 0; i < NUM_SIGNAL_ACTIONS; i++)
for (i = 1; i < NUM_SIGNAL_ACTIONS; i++)
{
sq_addlast((FAR sq_entry_t *)sigact++, &g_sigfreeaction);
sq_addafter((FAR sq_entry_t *)(sigact + i - 1),
(FAR sq_entry_t *)(sigact + i), &g_sigfreeaction);
}

spin_unlock_irqrestore(&g_sigaction_spin, flags);
Expand Down Expand Up @@ -407,11 +451,62 @@ int sigaction(int signo, FAR const struct sigaction *act,

void nxsig_release_action(FAR sigactq_t *sigact)
{
FAR sigactq_t *prev;
FAR sigactq_t *next;
irqstate_t flags;
int i;

/* Just put it back on the free list */
/* Put back to the free list */

nxsig_add_free(sigact);

/* Scan the list for complete blocks */

flags = spin_lock_irqsave(&g_sigaction_spin);
sq_addlast((FAR sq_entry_t *)sigact, &g_sigfreeaction);

prev = NULL;
sigact = (FAR sigactq_t *)g_sigfreeaction.head;

next_sob:

while (sigact && !sigact->sob) /* Seek for SOB entry */
{
prev = sigact;
sigact = sigact->flink;
}

if (sigact && sigact->flink)
{
/* Check following entries */

for (
next = sigact->flink, i = 1;
next == sigact + i && i < NUM_SIGNAL_ACTIONS;
next = next->flink, i++);

if (i == NUM_SIGNAL_ACTIONS) /* Got complete block */
{
for (; i > 0; i--) /* Detach entries from list */
{
if (!prev)
{
sq_remfirst(&g_sigfreeaction);
}
else
{
sq_remafter((FAR sq_entry_t *)prev, &g_sigfreeaction);
}
}

kmm_free(sigact); /* Free the block */
}

if (g_sigfreeaction.head && next)
{
sigact = next;
goto next_sob;
}
}

spin_unlock_irqrestore(&g_sigaction_spin, flags);
}
3 changes: 2 additions & 1 deletion sched/signal/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ struct sigactq
{
FAR struct sigactq *flink; /* Forward link */
struct sigaction act; /* Sigaction data */
uint8_t signo; /* Signal associated with action */
uint8_t signo:7; /* Signal associated with action */
uint8_t sob:1; /* Flag depicting start entry of a block */
};
typedef struct sigactq sigactq_t;

Expand Down

0 comments on commit 92c6a16

Please sign in to comment.