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 ee39e7a4a20 sched/group: add spinlock in group_childstatus.c
ee39e7a4a20 is described below
commit ee39e7a4a2015a4121091ab30bc081829f650997
Author: hujun5 <[email protected]>
AuthorDate: Fri May 9 09:58:47 2025 +0800
sched/group: add spinlock in group_childstatus.c
Add spinlock protection to child task pool allocation and deallocation in
group_childstatus.c. Protects g_child_pool freelist and group child list
traversal/modification operations against concurrent access in SMP systems.
Signed-off-by: hujun5 <[email protected]>
---
sched/group/group_childstatus.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/sched/group/group_childstatus.c b/sched/group/group_childstatus.c
index 1485d9a81cb..b9ce8879b05 100644
--- a/sched/group/group_childstatus.c
+++ b/sched/group/group_childstatus.c
@@ -66,6 +66,7 @@ struct child_pool_s
****************************************************************************/
static struct child_pool_s g_child_pool;
+static spinlock_t g_child_pool_lock = SP_UNLOCKED;
/****************************************************************************
* Private Functions
@@ -169,17 +170,21 @@ void task_initialize(void)
FAR struct child_status_s *group_alloc_child(void)
{
FAR struct child_status_s *ret;
+ irqstate_t flags;
/* Return the status block at the head of the free list */
+ flags = spin_lock_irqsave(&g_child_pool_lock);
ret = g_child_pool.freelist;
if (ret)
{
g_child_pool.freelist = ret->flink;
ret->flink = NULL;
+ spin_unlock_irqrestore(&g_child_pool_lock, flags);
}
else
{
+ spin_unlock_irqrestore(&g_child_pool_lock, flags);
ret = kmm_zalloc(sizeof(*ret));
}
@@ -206,12 +211,16 @@ FAR struct child_status_s *group_alloc_child(void)
void group_free_child(FAR struct child_status_s *child)
{
+ irqstate_t flags;
+
/* Return the child status structure to the free list */
if (child)
{
+ flags = spin_lock_irqsave(&g_child_pool_lock);
child->flink = g_child_pool.freelist;
g_child_pool.freelist = child;
+ spin_unlock_irqrestore(&g_child_pool_lock, flags);
}
}
@@ -271,19 +280,23 @@ FAR struct child_status_s *group_find_child(FAR struct
task_group_s *group,
pid_t pid)
{
FAR struct child_status_s *child;
+ irqstate_t flags;
DEBUGASSERT(group);
/* Find the status structure with the matching PID */
+ flags = spin_lock_irqsave(&group->tg_lock);
for (child = group->tg_children; child; child = child->flink)
{
if (child->ch_pid == pid)
{
+ spin_unlock_irqrestore(&group->tg_lock, flags);
return child;
}
}
+ spin_unlock_irqrestore(&group->tg_lock, flags);
return NULL;
}
@@ -309,17 +322,21 @@ FAR struct child_status_s *group_find_child(FAR struct
task_group_s *group,
FAR struct child_status_s *group_exit_child(FAR struct task_group_s *group)
{
FAR struct child_status_s *child;
+ irqstate_t flags;
/* Find the status structure of any child task that has exited. */
+ flags = spin_lock_irqsave(&group->tg_lock);
for (child = group->tg_children; child; child = child->flink)
{
if ((child->ch_flags & CHILD_FLAG_EXITED) != 0)
{
+ spin_unlock_irqrestore(&group->tg_lock, flags);
return child;
}
}
+ spin_unlock_irqrestore(&group->tg_lock, flags);
return NULL;
}
@@ -350,11 +367,13 @@ FAR struct child_status_s *group_remove_child(FAR struct
task_group_s *group,
{
FAR struct child_status_s *curr;
FAR struct child_status_s *prev;
+ irqstate_t flags;
DEBUGASSERT(group);
/* Find the status structure with the matching PID */
+ flags = spin_lock_irqsave(&group->tg_lock);
for (prev = NULL, curr = group->tg_children;
curr;
prev = curr, curr = curr->flink)
@@ -381,9 +400,12 @@ FAR struct child_status_s *group_remove_child(FAR struct
task_group_s *group,
}
curr->flink = NULL;
+ spin_unlock_irqrestore(&group->tg_lock, flags);
group_dump_children(group, "group_remove_child");
+ return curr;
}
+ spin_unlock_irqrestore(&group->tg_lock, flags);
return curr;
}
@@ -409,11 +431,13 @@ void group_remove_children(FAR struct task_group_s *group)
{
FAR struct child_status_s *curr;
FAR struct child_status_s *next;
+ irqstate_t flags;
/* Remove all child structures for the TCB and return them to the
* freelist.
*/
+ flags = spin_lock_irqsave(&group->tg_lock);
for (curr = group->tg_children; curr; curr = next)
{
next = curr->flink;
@@ -421,6 +445,8 @@ void group_remove_children(FAR struct task_group_s *group)
}
group->tg_children = NULL;
+ spin_unlock_irqrestore(&group->tg_lock, flags);
+
group_dump_children(group, "group_remove_children");
}