mirror of
https://github.com/apache/nuttx.git
synced 2025-12-08 19:02:43 +08:00
sched/group: Implement group_drop()
Implement a function for dropping references to the group structure and finally freeing the allocated memory, if the group has been marked for destruction
This commit is contained in:
committed by
Alan Carvalho de Assis
parent
8a5dc0ba12
commit
8306e0d175
@@ -80,6 +80,7 @@ int group_bind(FAR struct pthread_tcb_s *tcb);
|
||||
int group_join(FAR struct pthread_tcb_s *tcb);
|
||||
#endif
|
||||
void group_leave(FAR struct tcb_s *tcb);
|
||||
void group_drop(FAR struct task_group_s *group);
|
||||
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
|
||||
void group_add_waiter(FAR struct task_group_s *group);
|
||||
void group_del_waiter(FAR struct task_group_s *group);
|
||||
|
||||
@@ -217,23 +217,13 @@ static inline void group_release(FAR struct task_group_s *group)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
|
||||
/* If there are threads waiting for this group to be freed, then we cannot
|
||||
* yet free the memory resources. Instead just mark the group deleted
|
||||
* and wait for those threads complete their waits.
|
||||
*/
|
||||
/* Mark the group as deleted now */
|
||||
|
||||
if (group->tg_nwaiters > 0)
|
||||
{
|
||||
group->tg_flags |= GROUP_FLAG_DELETED;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Release the group container itself */
|
||||
group->tg_flags |= GROUP_FLAG_DELETED;
|
||||
|
||||
kmm_free(group);
|
||||
}
|
||||
/* Then drop the group freeing the allocated memory */
|
||||
|
||||
group_drop(group);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -390,3 +380,51 @@ void group_leave(FAR struct tcb_s *tcb)
|
||||
}
|
||||
|
||||
#endif /* HAVE_GROUP_MEMBERS */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: group_drop
|
||||
*
|
||||
* Description:
|
||||
* Release the group's memory. This function is called whenever a reference
|
||||
* to the group structure is released. It is not dependent on member count,
|
||||
* but rather external references, which include:
|
||||
* - Waiter list for waitpid()
|
||||
*
|
||||
* Input Parameters:
|
||||
* group - The group that is to be dropped
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
* Assumptions:
|
||||
* Called during task deletion or context switch in a safe context. No
|
||||
* special precautions are required here.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void group_drop(FAR struct task_group_s *group)
|
||||
{
|
||||
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
|
||||
/* If there are threads waiting for this group to be freed, then we cannot
|
||||
* yet free the memory resources. Instead just mark the group deleted
|
||||
* and wait for those threads complete their waits.
|
||||
*/
|
||||
|
||||
if (group->tg_nwaiters > 0)
|
||||
{
|
||||
/* Hold the group still */
|
||||
|
||||
sinfo("Keep group %p (waiters > 0)\n", group);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
/* Finally, if no one needs the group and it has been deleted, remove it */
|
||||
|
||||
if (group->tg_flags & GROUP_FLAG_DELETED)
|
||||
{
|
||||
/* Release the group container itself */
|
||||
|
||||
kmm_free(group);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,14 +70,7 @@ void group_del_waiter(FAR struct task_group_s *group)
|
||||
{
|
||||
DEBUGASSERT(group->tg_nwaiters > 0);
|
||||
group->tg_nwaiters--;
|
||||
if (group->tg_nwaiters == 0 && (group->tg_flags & GROUP_FLAG_DELETED) != 0)
|
||||
{
|
||||
/* Release the group container (all other resources have already been
|
||||
* freed).
|
||||
*/
|
||||
|
||||
kmm_free(group);
|
||||
}
|
||||
group_drop(group);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SCHED_WAITPID && !CONFIG_SCHED_HAVE_PARENT */
|
||||
|
||||
Reference in New Issue
Block a user