From 80904539e63681b2dca74e3978effb17f0c071b0 Mon Sep 17 00:00:00 2001 From: patacongo Date: Fri, 25 Jan 2013 19:15:05 +0000 Subject: Add logic to keep track of members of a task group git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5563 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/sched/group_join.c | 103 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 11 deletions(-) (limited to 'nuttx/sched/group_join.c') diff --git a/nuttx/sched/group_join.c b/nuttx/sched/group_join.c index 987c1ba87..9dcea6599 100644 --- a/nuttx/sched/group_join.c +++ b/nuttx/sched/group_join.c @@ -41,8 +41,11 @@ #include #include +#include #include +#include + #include "os_internal.h" #ifdef HAVE_TASK_GROUP @@ -50,6 +53,9 @@ /***************************************************************************** * Pre-processor Definitions *****************************************************************************/ +/* Is this worth making a configuration option? */ + +#define GROUP_REALLOC_MEMBERS 4 /***************************************************************************** * Private Types @@ -68,19 +74,21 @@ *****************************************************************************/ /***************************************************************************** - * Name: group_join + * Name: group_bind * * Description: - * Copy the group structure reference from one TCB to another, incrementing - * the refrence count on the group. This function is called when a pthread - * is produced within the task group so that the pthread can share the - * resources of the task group. + * A thread joins the group when it is created. This is a two step process, + * first, the group must bound to the new threads TCB. group_bind() does + * this (at the return from group_join, things are a little unstable: The + * group has been bound, but tg_nmembers hs not yet been incremented). + * Then, after the new thread is initialized and has a PID assigned to it, + * group_join() is called, incrementing the tg_nmembers count on the group. * * Parameters: * tcb - The TCB of the new "child" task that need to join the group. * * Return Value: - * None + * 0 (OK) on success; a negated errno value on failure. * * Assumptions: * - The parent task from which the group will be inherited is the task at @@ -90,18 +98,91 @@ * *****************************************************************************/ -void group_join(FAR _TCB *tcb) +int group_bind(FAR _TCB *tcb) { FAR _TCB *ptcb = (FAR _TCB *)g_readytorun.head; DEBUGASSERT(ptcb && tcb && ptcb->group && !tcb->group); - /* Copy the group reference from the parent to the child, incrementing the - * reference count. - */ + /* Copy the group reference from the parent to the child */ tcb->group = ptcb->group; - ptcb->group->tg_crefs++; + return OK; +} + +/***************************************************************************** + * Name: group_join + * + * Description: + * A thread joins the group when it is created. This is a two step process, + * first, the group must bound to the new threads TCB. group_bind() does + * this (at the return from group_join, things are a little unstable: The + * group has been bound, but tg_nmembers hs not yet been incremented). + * Then, after the new thread is initialized and has a PID assigned to it, + * group_join() is called, incrementing the tg_nmembers count on the group. + * + * Parameters: + * tcb - The TCB of the new "child" task that need to join the group. + * + * Return Value: + * 0 (OK) on success; a negated errno value on failure. + * + * Assumptions: + * - The parent task from which the group will be inherited is the task at + * the thead of the ready to run list. + * - Called during thread creation in a safe context. No special precautions + * are required here. + * + *****************************************************************************/ + +int group_join(FAR _TCB *tcb) +{ +#ifdef HAVE_GROUP_MEMBERS + FAR struct task_group_s *group; + + DEBUGASSERT(tcb && tcb->group && + tcb->group->tg_nmembers < UINT8_MAX); + + /* Get the group from the TCB */ + + group = tcb->group; + + /* Will we need to extend the size of the array of groups? */ + + if (group->tg_nmembers >= group->tg_mxmembers) + { + FAR pid_t *newmembers; + unsigned int newmax; + + /* Yes... reallocate the array of members */ + + newmax = group->tg_mxmembers + GROUP_REALLOC_MEMBERS; + if (newmax > UINT8_MAX) + { + newmax = UINT8_MAX; + } + + newmembers = (FAR pid_t *) + krealloc(group->tg_members, sizeof(pid_t) * newmax); + + if (!newmembers) + { + return -ENOMEM; + } + + /* Save the new number of members in the reallocated members array */ + + group->tg_members = newmembers; + group->tg_mxmembers = newmax; + } + + /* Assign this new pid to the group. */ + + group->tg_members[group->tg_nmembers] = tcb->pid; +#endif + + group->tg_nmembers++; + return OK; } #endif /* HAVE_TASK_GROUP */ -- cgit v1.2.3