diff options
Diffstat (limited to 'nuttx/sched/pthread_create.c')
-rw-r--r-- | nuttx/sched/pthread_create.c | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/nuttx/sched/pthread_create.c b/nuttx/sched/pthread_create.c index f4d0d8fdf..e37c06892 100644 --- a/nuttx/sched/pthread_create.c +++ b/nuttx/sched/pthread_create.c @@ -251,6 +251,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, #if CONFIG_RR_INTERVAL > 0 int policy; #endif + int errcode; pid_t pid; /* If attributes were not supplied, use the default attributes */ @@ -268,6 +269,12 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, return ENOMEM; } + /* Join the parent's task group */ + +#ifdef HAVE_TASK_GROUP + group_join(ptcb); +#endif + /* Share the address environment of the parent task. NOTE: Only tasks * created throught the nuttx/binfmt loaders may have an address * environment. @@ -277,8 +284,8 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, ret = up_addrenv_share((FAR const _TCB *)g_readytorun.head, ptcb); if (ret < 0) { - sched_releasetcb(ptcb); - return -ret; + errcode = -ret; + goto errout_with_tcb; } #endif @@ -287,8 +294,8 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, ret = sched_setuppthreadfiles(ptcb); if (ret != OK) { - sched_releasetcb(ptcb); - return ret; + errcode = ret; + goto errout_with_tcb; } /* Share the parent's envionment */ @@ -300,8 +307,8 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, pjoin = (FAR join_t*)kzalloc(sizeof(join_t)); if (!pjoin) { - sched_releasetcb(ptcb); - return ENOMEM; + errcode = ENOMEM; + goto errout_with_tcb; } /* Allocate the stack for the TCB */ @@ -309,9 +316,8 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, ret = up_create_stack(ptcb, attr->stacksize); if (ret != OK) { - sched_releasetcb(ptcb); - sched_free(pjoin); - return ENOMEM; + errcode = ENOMEM; + goto errout_with_join; } /* Should we use the priority and scheduler specified in the @@ -360,9 +366,8 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, TCB_FLAG_TTYPE_PTHREAD); if (ret != OK) { - sched_releasetcb(ptcb); - sched_free(pjoin); - return EBUSY; + errcode = EBUSY; + goto errout_with_join; } /* Configure the TCB for a pthread receiving on parameter @@ -440,10 +445,18 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, dq_rem((FAR dq_entry_t*)ptcb, (dq_queue_t*)&g_inactivetasks); (void)sem_destroy(&pjoin->data_sem); (void)sem_destroy(&pjoin->exit_sem); - sched_releasetcb(ptcb); - sched_free(pjoin); - ret = EIO; + + errcode = EIO; + goto errout_with_join; } return ret; + +errout_with_join: + sched_free(pjoin); + ptcb->joininfo = NULL; + +errout_with_tcb: + sched_releasetcb(ptcb); + return errcode; } |