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:
Ville Juven
2023-01-26 14:45:13 +02:00
committed by Alan Carvalho de Assis
parent 8a5dc0ba12
commit 8306e0d175
3 changed files with 55 additions and 23 deletions

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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 */