Beispiel #1
0
int group_allocate(FAR _TCB *tcb)
{
  int ret;

  DEBUGASSERT(tcb && !tcb->group);

  /* Allocate the group structure and assign it to the TCB */

  tcb->group = (FAR struct task_group_s *)kzalloc(sizeof(struct task_group_s));
  if (!tcb->group)
    {
      return -ENOMEM;
    }

  /* Assign the group a unique ID.  If g_gidcounter were to wrap before we
   * finish with task creation, that would be a problem.
   */

#ifdef HAVE_GROUP_MEMBERS
  group_assigngid(tcb->group);
#endif

  /* Duplicate the parent tasks envionment */

  ret = env_dup(tcb->group);
  if (ret < 0)
    {
      kfree(tcb->group);
      tcb->group = NULL;
      return ret;
    }

  return OK;
}
int group_allocate(FAR struct task_tcb_s *tcb)
{
  FAR struct task_group_s *group;
  int ret;

  DEBUGASSERT(tcb && !tcb->cmn.group);

  /* Allocate the group structure and assign it to the TCB */

  group = (FAR struct task_group_s *)kzalloc(sizeof(struct task_group_s));
  if (!group)
    {
      return -ENOMEM;
    }

#if CONFIG_NFILE_STREAMS > 0 && defined(CONFIG_NUTTX_KERNEL) && \
    defined(CONFIG_MM_KERNEL_HEAP)

  /* In a flat, single-heap build.  The stream list is allocated with the
   * group structure.  But in a kernel build with a kernel allocator, it
   * must be separately allocated using a user-space allocator.
   */

  group->tg_streamlist = (FAR struct streamlist *)
    kuzalloc(sizeof(struct streamlist));

  if (!group->tg_streamlist)
    {
      kfree(group);
      return -ENOMEM;
    }

#endif

  /* Attach the group to the TCB */

  tcb->cmn.group = group;

#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
  /* Assign the group a unique ID.  If g_gidcounter were to wrap before we
   * finish with task creation, that would be a problem.
   */

  group_assigngid(group);
#endif

  /* Duplicate the parent tasks environment */

  ret = env_dup(group);
  if (ret < 0)
    {
#if CONFIG_NFILE_STREAMS > 0 && defined(CONFIG_NUTTX_KERNEL) && \
    defined(CONFIG_MM_KERNEL_HEAP)
      kufree(group->tg_streamlist);
#endif
      kfree(group);
      tcb->cmn.group = NULL;
      return ret;
    }

  /* Initialize the pthread join semaphore */

#ifndef CONFIG_DISABLE_PTHREAD
  (void)sem_init(&group->tg_joinsem, 0, 1);
#endif

  return OK;
}
int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype)
{
  FAR struct task_group_s *group;
  int ret;

  DEBUGASSERT(tcb && !tcb->cmn.group);

  /* Allocate the group structure and assign it to the TCB */

  group = (FAR struct task_group_s *)kmm_zalloc(sizeof(struct task_group_s));
  if (!group)
    {
      return -ENOMEM;
    }

#if CONFIG_NFILE_STREAMS > 0 && (defined(CONFIG_BUILD_PROTECTED) || \
    defined(CONFIG_BUILD_KERNEL)) && defined(CONFIG_MM_KERNEL_HEAP)
  /* If this group is being created for a privileged thread, then all elements
   * of the group must be created for privileged access.
   */

  if ((ttype & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)
    {
      group->tg_flags |= GROUP_FLAG_PRIVILEGED;
    }

  /* In a flat, single-heap build.  The stream list is allocated with the
   * group structure.  But in a kernel build with a kernel allocator, it
   * must be separately allocated using a user-space allocator.
   */

  group->tg_streamlist = (FAR struct streamlist *)
    group_zalloc(group, sizeof(struct streamlist));

  if (!group->tg_streamlist)
    {
      kmm_free(group);
      return -ENOMEM;
    }

#endif

  /* Attach the group to the TCB */

  tcb->cmn.group = group;

#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
  /* Assign the group a unique ID.  If g_gidcounter were to wrap before we
   * finish with task creation, that would be a problem.
   */

  group_assigngid(group);
#endif

  /* Duplicate the parent tasks environment */

  ret = env_dup(group);
  if (ret < 0)
    {
#if CONFIG_NFILE_STREAMS > 0 && (defined(CONFIG_BUILD_PROTECTED) || \
    defined(CONFIG_BUILD_KERNEL)) && defined(CONFIG_MM_KERNEL_HEAP)
      group_free(group, group->tg_streamlist);
#endif
      kmm_free(group);
      tcb->cmn.group = NULL;
      return ret;
    }

  /* Initialize the pthread join semaphore */

#ifndef CONFIG_DISABLE_PTHREAD
  (void)sem_init(&group->tg_joinsem, 0, 1);
#endif

  return OK;
}