Ejemplo n.º 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;
}
Ejemplo n.º 2
0
int task_init(FAR _TCB *tcb, const char *name, int priority,
              main_t entry, const char *argv[])
#endif
{
  int ret;

 /* Associate file descriptors with the new task */

#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
  if (sched_setuptaskfiles(tcb) != OK)
    {
      return ERROR;
    }
#endif

  /* Clone the parent's task environment */

  (void)env_dup(tcb);

  /* Configure the user provided stack region */

#ifndef CONFIG_CUSTOM_STACK
  up_use_stack(tcb, stack, stack_size);
#endif

  /* Initialize the task control block */

  ret = task_schedsetup(tcb, priority, task_start, entry,
                        TCB_FLAG_TTYPE_TASK);
  if (ret == OK)
    {
      /* Setup to pass parameters to the new task */

      (void)task_argsetup(tcb, name, argv);
    }

  return ret;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
static int thread_create(const char *name, uint8_t type, int priority,
                         main_t entry, const char **argv)
#endif
{
  FAR _TCB *tcb;
  pid_t pid;
  int ret;

  /* Allocate a TCB for the new task. */

  tcb = (FAR _TCB*)kzalloc(sizeof(_TCB));
  if (!tcb)
    {
      goto errout;
    }

  /* Associate file descriptors with the new task */

#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
  ret = sched_setuptaskfiles(tcb);
  if (ret != OK)
    {
      goto errout_with_tcb;
    }
#endif

  /* Clone the parent's task environment */

  (void)env_dup(tcb);

  /* Allocate the stack for the TCB */

#ifndef CONFIG_CUSTOM_STACK
  ret = up_create_stack(tcb, stack_size);
  if (ret != OK)
    {
      goto errout_with_tcb;
    }
#endif

  /* Mark the type of this thread (this setting will be needed in
   * task_schedsetup() when up_initial_state() is called.
   */

  tcb->flags |= type;

  /* Initialize the task control block */

  ret = task_schedsetup(tcb, priority, task_start, entry);
  if (ret != OK)
    {
      goto errout_with_tcb;
    }

  /* Setup to pass parameters to the new task */

  (void)task_argsetup(tcb, name, argv);

  /* Get the assigned pid before we start the task */

  pid = (int)tcb->pid;

  /* Activate the task */

  ret = task_activate(tcb);
  if (ret != OK)
    {
      /* The TCB was added to the active task list by task_schedsetup() */

      dq_rem((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks);
      goto errout_with_tcb;
    }

  return pid;

errout_with_tcb:
  sched_releasetcb(tcb);

errout:
  errno = ENOMEM;
  return ERROR;
}