diff options
Diffstat (limited to 'nuttx/sched')
-rw-r--r-- | nuttx/sched/group_internal.h | 6 | ||||
-rw-r--r-- | nuttx/sched/group_setupidlefiles.c | 4 | ||||
-rw-r--r-- | nuttx/sched/group_setupstreams.c | 12 | ||||
-rw-r--r-- | nuttx/sched/group_setuptaskfiles.c | 19 | ||||
-rw-r--r-- | nuttx/sched/os_internal.h | 4 | ||||
-rw-r--r-- | nuttx/sched/os_start.c | 22 | ||||
-rw-r--r-- | nuttx/sched/pthread_create.c | 60 | ||||
-rw-r--r-- | nuttx/sched/pthread_getspecific.c | 7 | ||||
-rw-r--r-- | nuttx/sched/pthread_internal.h | 3 | ||||
-rw-r--r-- | nuttx/sched/pthread_setspecific.c | 7 | ||||
-rw-r--r-- | nuttx/sched/sched_releasetcb.c | 9 | ||||
-rw-r--r-- | nuttx/sched/task_create.c | 16 | ||||
-rw-r--r-- | nuttx/sched/task_exithook.c | 17 | ||||
-rw-r--r-- | nuttx/sched/task_init.c | 14 | ||||
-rw-r--r-- | nuttx/sched/task_restart.c | 43 | ||||
-rw-r--r-- | nuttx/sched/task_setup.c | 119 | ||||
-rw-r--r-- | nuttx/sched/task_start.c | 8 | ||||
-rw-r--r-- | nuttx/sched/task_starthook.c | 19 | ||||
-rw-r--r-- | nuttx/sched/task_vfork.c | 8 |
19 files changed, 254 insertions, 143 deletions
diff --git a/nuttx/sched/group_internal.h b/nuttx/sched/group_internal.h index 8936b9bbf..e79f96e8c 100644 --- a/nuttx/sched/group_internal.h +++ b/nuttx/sched/group_internal.h @@ -122,10 +122,10 @@ void group_removechildren(FAR struct task_group_s *group); /* Group data resource configuration */ #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 -int group_setupidlefiles(FAR struct tcb_s *tcb); -int group_setuptaskfiles(FAR struct tcb_s *tcb); +int group_setupidlefiles(FAR struct task_tcb_s *tcb); +int group_setuptaskfiles(FAR struct task_tcb_s *tcb); #if CONFIG_NFILE_STREAMS > 0 -int group_setupstreams(FAR struct tcb_s *tcb); +int group_setupstreams(FAR struct task_tcb_s *tcb); #endif #endif diff --git a/nuttx/sched/group_setupidlefiles.c b/nuttx/sched/group_setupidlefiles.c index d3e00660c..25ed71c04 100644 --- a/nuttx/sched/group_setupidlefiles.c +++ b/nuttx/sched/group_setupidlefiles.c @@ -78,10 +78,10 @@ * ****************************************************************************/ -int group_setupidlefiles(FAR struct tcb_s *tcb) +int group_setupidlefiles(FAR struct task_tcb_s *tcb) { #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NFILE_DESCRIPTORS > 0 - FAR struct task_group_s *group = tcb->group; + FAR struct task_group_s *group = tcb->cmn.group; #endif #if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_DEV_CONSOLE) int fd; diff --git a/nuttx/sched/group_setupstreams.c b/nuttx/sched/group_setupstreams.c index 377ee9e97..217decd57 100644 --- a/nuttx/sched/group_setupstreams.c +++ b/nuttx/sched/group_setupstreams.c @@ -72,13 +72,13 @@ * ****************************************************************************/ -int group_setupstreams(FAR struct tcb_s *tcb) +int group_setupstreams(FAR struct task_tcb_s *tcb) { - DEBUGASSERT(tcb && tcb->group); + DEBUGASSERT(tcb && tcb->cmn.group); /* Initialize file streams for the task group */ - lib_streaminit(&tcb->group->tg_streamlist); + lib_streaminit(&tcb->cmn.group->tg_streamlist); /* fdopen to get the stdin, stdout and stderr streams. The following logic * depends on the fact that the library layer will allocate FILEs in order. @@ -88,9 +88,9 @@ int group_setupstreams(FAR struct tcb_s *tcb) * fd = 2 is stderr (write-only, append) */ - (void)fs_fdopen(0, O_RDONLY, tcb); - (void)fs_fdopen(1, O_WROK|O_CREAT, tcb); - (void)fs_fdopen(2, O_WROK|O_CREAT, tcb); + (void)fs_fdopen(0, O_RDONLY, (FAR struct tcb_s *)tcb); + (void)fs_fdopen(1, O_WROK|O_CREAT, (FAR struct tcb_s *)tcb); + (void)fs_fdopen(2, O_WROK|O_CREAT, (FAR struct tcb_s *)tcb); return OK; } diff --git a/nuttx/sched/group_setuptaskfiles.c b/nuttx/sched/group_setuptaskfiles.c index 8d1895c94..269485ea4 100644 --- a/nuttx/sched/group_setuptaskfiles.c +++ b/nuttx/sched/group_setuptaskfiles.c @@ -85,7 +85,7 @@ ****************************************************************************/ #if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_FDCLONE_DISABLE) -static inline void sched_dupfiles(FAR struct tcb_s *tcb) +static inline void sched_dupfiles(FAR struct task_tcb_s *tcb) { /* The parent task is the one at the head of the ready-to-run list */ @@ -94,7 +94,7 @@ static inline void sched_dupfiles(FAR struct tcb_s *tcb) FAR struct file *child; int i; - DEBUGASSERT(tcb && tcb->group && rtcb->group); + DEBUGASSERT(tcb && tcb->cmn.group && rtcb->group); /* Duplicate the file descriptors. This will be either all of the * file descriptors or just the first three (stdin, stdout, and stderr) @@ -105,7 +105,7 @@ static inline void sched_dupfiles(FAR struct tcb_s *tcb) /* Get pointers to the parent and child task file lists */ parent = rtcb->group->tg_filelist.fl_files; - child = tcb->group->tg_filelist.fl_files; + child = tcb->cmn.group->tg_filelist.fl_files; /* Check each file in the parent file list */ @@ -143,7 +143,7 @@ static inline void sched_dupfiles(FAR struct tcb_s *tcb) ****************************************************************************/ #if CONFIG_NSOCKET_DESCRIPTORS > 0 && !defined(CONFIG_SDCLONE_DISABLE) -static inline void sched_dupsockets(FAR struct tcb_s *tcb) +static inline void sched_dupsockets(FAR struct task_tcb_s *tcb) { /* The parent task is the one at the head of the ready-to-run list */ @@ -156,12 +156,12 @@ static inline void sched_dupsockets(FAR struct tcb_s *tcb) * task. */ - DEBUGASSERT(tcb && tcb->group && rtcb->group); + DEBUGASSERT(tcb && tcb->cmn.group && rtcb->group); /* Get pointers to the parent and child task socket lists */ parent = rtcb->group->tg_socketlist.sl_sockets; - child = tcb->group->tg_socketlist.sl_sockets; + child = tcb->cmn.group->tg_socketlist.sl_sockets; /* Check each socket in the parent socket list */ @@ -206,13 +206,16 @@ static inline void sched_dupsockets(FAR struct tcb_s *tcb) * ****************************************************************************/ -int group_setuptaskfiles(FAR struct tcb_s *tcb) +int group_setuptaskfiles(FAR struct task_tcb_s *tcb) { #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 - FAR struct task_group_s *group = tcb->group; + FAR struct task_group_s *group = tcb->cmn.group; DEBUGASSERT(group); #endif +#ifndef CONFIG_DISABLE_PTHREAD + DEBUGASSERT((tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD); +#endif #if CONFIG_NFILE_DESCRIPTORS > 0 /* Initialize file descriptors for the TCB */ diff --git a/nuttx/sched/os_internal.h b/nuttx/sched/os_internal.h index 22f69e53d..eef0d5e70 100644 --- a/nuttx/sched/os_internal.h +++ b/nuttx/sched/os_internal.h @@ -257,9 +257,9 @@ int os_bringup(void); void weak_function task_initialize(void); #endif void task_start(void); -int task_schedsetup(FAR struct tcb_s *tcb, int priority, start_t start, +int task_schedsetup(FAR struct task_tcb_s *tcb, int priority, start_t start, main_t main, uint8_t ttype); -int task_argsetup(FAR struct tcb_s *tcb, FAR const char *name, FAR char * const argv[]); +int task_argsetup(FAR struct task_tcb_s *tcb, FAR const char *name, FAR char * const argv[]); void task_exithook(FAR struct tcb_s *tcb, int status); int task_deletecurrent(void); diff --git a/nuttx/sched/os_start.c b/nuttx/sched/os_start.c index fd13865db..ace475ba1 100644 --- a/nuttx/sched/os_start.c +++ b/nuttx/sched/os_start.c @@ -204,7 +204,7 @@ const tasklist_t g_tasklisttable[NUM_TASK_STATES] = * that user init task is responsible for bringing up the rest of the system */ -static FAR struct tcb_s g_idletcb; +static FAR struct task_tcb_s g_idletcb; /* This is the name of the idle task */ @@ -262,7 +262,7 @@ void os_start(void) /* Assign the process ID of ZERO to the idle task */ - g_pidhash[ PIDHASH(0)].tcb = &g_idletcb; + g_pidhash[ PIDHASH(0)].tcb = &g_idletcb.cmn; g_pidhash[ PIDHASH(0)].pid = 0; /* Initialize a TCB for this thread of execution. NOTE: The default @@ -272,13 +272,13 @@ void os_start(void) * that has pid == 0 and sched_priority == 0. */ - bzero((void*)&g_idletcb, sizeof(struct tcb_s)); - g_idletcb.task_state = TSTATE_TASK_RUNNING; - g_idletcb.entry.main = (main_t)os_start; + bzero((void*)&g_idletcb, sizeof(struct task_tcb_s)); + g_idletcb.cmn.task_state = TSTATE_TASK_RUNNING; + g_idletcb.cmn.entry.main = (main_t)os_start; #if CONFIG_TASK_NAME_SIZE > 0 - strncpy(g_idletcb.name, g_idlename, CONFIG_TASK_NAME_SIZE-1); - g_idletcb.argv[0] = g_idletcb.name; + strncpy(g_idletcb.cmn.name, g_idlename, CONFIG_TASK_NAME_SIZE-1); + g_idletcb.argv[0] = g_idletcb.cmn.name; #else g_idletcb.argv[0] = (char*)g_idlename; #endif /* CONFIG_TASK_NAME_SIZE */ @@ -289,7 +289,7 @@ void os_start(void) /* Initialize the processor-specific portion of the TCB */ - up_initial_state(&g_idletcb); + up_initial_state(&g_idletcb.cmn); /* Initialize the semaphore facility(if in link). This has to be done * very early because many subsystems depend upon fully functional @@ -330,7 +330,7 @@ void os_start(void) /* Allocate the IDLE group and suppress child status. */ #ifdef HAVE_TASK_GROUP - (void)group_allocate(&g_idletcb); + (void)group_allocate(&g_idletcb.cmn); #endif /* Initialize the interrupt handling subsystem (if included) */ @@ -456,8 +456,8 @@ void os_start(void) */ #ifdef HAVE_TASK_GROUP - (void)group_initialize(&g_idletcb); - g_idletcb.group->tg_flags = GROUP_FLAG_NOCLDWAIT; + (void)group_initialize(&g_idletcb.cmn); + g_idletcb.cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT; #endif /* Create initial tasks and bring-up the system */ diff --git a/nuttx/sched/pthread_create.c b/nuttx/sched/pthread_create.c index 956c0aed9..70b5ceb49 100644 --- a/nuttx/sched/pthread_create.c +++ b/nuttx/sched/pthread_create.c @@ -99,48 +99,26 @@ static const char g_pthreadname[] = "<pthread>"; * * Input Parameters: * tcb - Address of the new task's TCB - * name - Name of the new task (not used) - * argv - A pointer to an array of input parameters. Up to - * CONFIG_MAX_TASK_ARG parameters may be provided. If fewer - * than CONFIG_MAX_TASK_ARG parameters are passed, the list - * should be terminated with a NULL argv[] value. If no - * parameters are required, argv may be NULL. + * arg - The argument to provide to the pthread on startup. * * Return Value: * None * ****************************************************************************/ -static void pthread_argsetup(FAR struct tcb_s *tcb, pthread_addr_t arg) +static inline void pthread_argsetup(FAR struct pthread_tcb_s *tcb, pthread_addr_t arg) { - int i; - #if CONFIG_TASK_NAME_SIZE > 0 /* Copy the pthread name into the TCB */ - strncpy(tcb->name, g_pthreadname, CONFIG_TASK_NAME_SIZE); - - /* Save the name as the first argument in the TCB */ - - tcb->argv[0] = tcb->name; -#else - /* Save the name as the first argument in the TCB */ - - tcb->argv[0] = (char *)g_pthreadname; + strncpy(tcb->cmn.name, g_pthreadname, CONFIG_TASK_NAME_SIZE); #endif /* CONFIG_TASK_NAME_SIZE */ /* For pthreads, args are strictly pass-by-value; that actual * type wrapped by pthread_addr_t is unknown. */ - tcb->argv[1] = (char*)arg; - - /* Nullify the remaining, unused argument storage */ - - for (i = 2; i < CONFIG_MAX_TASK_ARGS+1; i++) - { - tcb->argv[i] = NULL; - } + tcb->arg = arg; } /**************************************************************************** @@ -189,8 +167,8 @@ static inline void pthread_addjoininfo(FAR struct task_group_s *group, static void pthread_start(void) { - FAR struct tcb_s *ptcb = (FAR struct tcb_s*)g_readytorun.head; - FAR struct task_group_s *group = ptcb->group; + FAR struct pthread_tcb_s *ptcb = (FAR struct pthread_tcb_s*)g_readytorun.head; + FAR struct task_group_s *group = ptcb->cmn.group; FAR struct join_s *pjoin = (FAR struct join_s*)ptcb->joininfo; pthread_addr_t exit_status; @@ -214,7 +192,7 @@ static void pthread_start(void) * available to the pthread. */ - exit_status = (*ptcb->entry.pthread)((pthread_addr_t)ptcb->argv[1]); + exit_status = (*ptcb->cmn.entry.pthread)(ptcb->arg); /* The thread has returned */ @@ -247,7 +225,7 @@ static void pthread_start(void) int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, pthread_startroutine_t start_routine, pthread_addr_t arg) { - FAR struct tcb_s *ptcb; + FAR struct pthread_tcb_s *ptcb; FAR struct join_s *pjoin; int priority; #if CONFIG_RR_INTERVAL > 0 @@ -266,7 +244,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, /* Allocate a TCB for the new task. */ - ptcb = (FAR struct tcb_s*)kzalloc(sizeof(struct tcb_s)); + ptcb = (FAR struct pthread_tcb_s *)kzalloc(sizeof(struct pthread_tcb_s)); if (!ptcb) { return ENOMEM; @@ -277,7 +255,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, */ #ifdef HAVE_TASK_GROUP - ret = group_bind(ptcb); + ret = group_bind((FAR struct tcb_s *)ptcb); if (ret < 0) { errcode = ENOMEM; @@ -291,7 +269,8 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, */ #ifdef CONFIG_ADDRENV - ret = up_addrenv_share((FAR const struct tcb_s *)g_readytorun.head, ptcb); + ret = up_addrenv_share((FAR const struct tcb_s *)g_readytorun.head, + (FAR struct tcb_s *)ptcb); if (ret < 0) { errcode = -ret; @@ -310,7 +289,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, /* Allocate the stack for the TCB */ - ret = up_create_stack(ptcb, attr->stacksize); + ret = up_create_stack((FAR struct tcb_s *)ptcb, attr->stacksize); if (ret != OK) { errcode = ENOMEM; @@ -359,8 +338,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, /* Initialize the task control block */ - ret = task_schedsetup(ptcb, priority, pthread_start, (main_t)start_routine, - TCB_FLAG_TTYPE_PTHREAD); + ret = pthread_schedsetup(ptcb, priority, pthread_start, start_routine); if (ret != OK) { errcode = EBUSY; @@ -376,7 +354,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, /* Join the parent's task group */ #ifdef HAVE_TASK_GROUP - ret = group_join(ptcb); + ret = group_join((FAR struct tcb_s *)ptcb); if (ret < 0) { errcode = ENOMEM; @@ -386,7 +364,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, /* Attach the join info to the TCB. */ - ptcb->joininfo = (void*)pjoin; + ptcb->joininfo = (FAR void *)pjoin; /* If round robin scheduling is selected, set the appropriate flag * in the TCB. @@ -405,7 +383,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, * as well. */ - pid = (int)ptcb->pid; + pid = (int)ptcb->cmn.pid; pjoin->thread = (pthread_t)pid; /* Initialize the semaphores in the join structure to zero. */ @@ -421,7 +399,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, sched_lock(); if (ret == OK) { - ret = task_activate(ptcb); + ret = task_activate((FAR struct tcb_s *)ptcb); } if (ret == OK) @@ -465,6 +443,6 @@ errout_with_join: ptcb->joininfo = NULL; errout_with_tcb: - sched_releasetcb(ptcb); + sched_releasetcb((FAR struct tcb_s *)ptcb); return errcode; } diff --git a/nuttx/sched/pthread_getspecific.c b/nuttx/sched/pthread_getspecific.c index 065cb5a16..1c87c29eb 100644 --- a/nuttx/sched/pthread_getspecific.c +++ b/nuttx/sched/pthread_getspecific.c @@ -104,11 +104,12 @@ FAR void *pthread_getspecific(pthread_key_t key) { #if CONFIG_NPTHREAD_KEYS > 0 - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; - FAR struct task_group_s *group = rtcb->group; + FAR struct pthread_tcb_s *rtcb = (FAR struct pthread_tcb_s*)g_readytorun.head; + FAR struct task_group_s *group = rtcb->cmn.group; FAR void *ret = NULL; - DEBUGASSERT(group); + DEBUGASSERT(group && + (rtcb->cmn.flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD); /* Check if the key is valid. */ diff --git a/nuttx/sched/pthread_internal.h b/nuttx/sched/pthread_internal.h index 0b4adf758..aa0e8ba15 100644 --- a/nuttx/sched/pthread_internal.h +++ b/nuttx/sched/pthread_internal.h @@ -46,6 +46,7 @@ #include <stdint.h> #include <stdbool.h> #include <pthread.h> +#include <sched.h> #include <nuttx/compiler.h> @@ -96,6 +97,8 @@ extern "C" struct task_group_s; /* Forward reference */ void weak_function pthread_initialize(void); +int pthread_schedsetup(FAR struct tcb_s *tcb, int priority, start_t start, + pthread_startroutine_t entry); int pthread_completejoin(pid_t pid, FAR void *exit_value); void pthread_destroyjoin(FAR struct task_group_s *group, FAR struct join_s *pjoin); diff --git a/nuttx/sched/pthread_setspecific.c b/nuttx/sched/pthread_setspecific.c index cc792b3ce..16401fbe6 100644 --- a/nuttx/sched/pthread_setspecific.c +++ b/nuttx/sched/pthread_setspecific.c @@ -115,11 +115,12 @@ int pthread_setspecific(pthread_key_t key, FAR void *value) { #if CONFIG_NPTHREAD_KEYS > 0 - FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; - FAR struct task_group_s *group = rtcb->group; + FAR struct pthread_tcb_s *rtcb = (FAR struct pthread_tcb_s*)g_readytorun.head; + FAR struct task_group_s *group = rtcb->cmn.group; int ret = EINVAL; - DEBUGASSERT(group); + DEBUGASSERT(group && + (rtcb->cmn.flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD); /* Check if the key is valid. */ diff --git a/nuttx/sched/sched_releasetcb.c b/nuttx/sched/sched_releasetcb.c index 688c8bb93..d4d59605d 100644 --- a/nuttx/sched/sched_releasetcb.c +++ b/nuttx/sched/sched_releasetcb.c @@ -155,11 +155,14 @@ int sched_releasetcb(FAR struct tcb_s *tcb) * start/re-start. */ - if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_TASK) +#ifndef CONFIG_DISABLE_PTHREAD + if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD) +#endif { - for (i = 1; i < CONFIG_MAX_TASK_ARGS+1 && tcb->argv[i]; i++) + FAR struct task_tcb_s *ttcb = (FAR struct task_tcb_s *)tcb; + for (i = 1; i < CONFIG_MAX_TASK_ARGS+1 && ttcb->argv[i]; i++) { - sched_free((FAR void*)tcb->argv[i]); + sched_free((FAR void*)ttcb->argv[i]); } } diff --git a/nuttx/sched/task_create.c b/nuttx/sched/task_create.c index 976cca35b..30fc1354f 100644 --- a/nuttx/sched/task_create.c +++ b/nuttx/sched/task_create.c @@ -106,14 +106,14 @@ static int thread_create(const char *name, uint8_t ttype, int priority, main_t entry, FAR char * const argv[]) #endif { - FAR struct tcb_s *tcb; + FAR struct task_tcb_s *tcb; pid_t pid; int errcode; int ret; /* Allocate a TCB for the new task. */ - tcb = (FAR struct tcb_s*)kzalloc(sizeof(struct tcb_s)); + tcb = (FAR struct task_tcb_s *)kzalloc(sizeof(struct task_tcb_s)); if (!tcb) { errcode = ENOMEM; @@ -123,7 +123,7 @@ static int thread_create(const char *name, uint8_t ttype, int priority, /* Allocate a new task group */ #ifdef HAVE_TASK_GROUP - ret = group_allocate(tcb); + ret = group_allocate((FAR struct tcb_s *)tcb); if (ret < 0) { errcode = -ret; @@ -145,7 +145,7 @@ static int thread_create(const char *name, uint8_t ttype, int priority, /* Allocate the stack for the TCB */ #ifndef CONFIG_CUSTOM_STACK - ret = up_create_stack(tcb, stack_size); + ret = up_create_stack((FAR struct tcb_s *)tcb, stack_size); if (ret != OK) { errcode = -ret; @@ -169,7 +169,7 @@ static int thread_create(const char *name, uint8_t ttype, int priority, /* Now we have enough in place that we can join the group */ #ifdef HAVE_TASK_GROUP - ret = group_initialize(tcb); + ret = group_initialize((FAR struct tcb_s *)tcb); if (ret < 0) { errcode = -ret; @@ -179,11 +179,11 @@ static int thread_create(const char *name, uint8_t ttype, int priority, /* Get the assigned pid before we start the task */ - pid = (int)tcb->pid; + pid = (int)tcb->cmn.pid; /* Activate the task */ - ret = task_activate(tcb); + ret = task_activate((FAR struct tcb_s *)tcb); if (ret != OK) { errcode = get_errno(); @@ -197,7 +197,7 @@ static int thread_create(const char *name, uint8_t ttype, int priority, return pid; errout_with_tcb: - sched_releasetcb(tcb); + sched_releasetcb((FAR struct tcb_s *)tcb); errout: set_errno(errcode); diff --git a/nuttx/sched/task_exithook.c b/nuttx/sched/task_exithook.c index 20d1bd161..1c2137545 100644 --- a/nuttx/sched/task_exithook.c +++ b/nuttx/sched/task_exithook.c @@ -318,7 +318,9 @@ static inline void task_sigchild(gid_t pgid, FAR struct tcb_s *ctcb, int status) * interpretable exit Check if this is the main task that is exiting. */ - if ((ctcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_TASK) +#ifndef CONFIG_DISABLE_PTHREAD + if ((ctcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD) +#endif { task_exitstatus(pgrp, status); } @@ -363,7 +365,9 @@ static inline void task_sigchild(FAR struct tcb_s *ptcb, FAR struct tcb_s *ctcb, * that are still running. */ - if ((ctcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_TASK) +#ifndef CONFIG_DISABLE_PTHREAD + if ((ctcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD) +#endif { #ifdef CONFIG_SCHED_CHILD_STATUS /* Save the exit status now of the main thread */ @@ -480,11 +484,14 @@ static inline void task_exitwakeup(FAR struct tcb_s *tcb, int status) if (group) { - /* Only tasks return valid status. Record the exit status when the - * task exists. The group, however, may still be executing. + /* Only tasks (and kernel threads) return valid status. Record the + * exit status when the task exists. The group, however, may still + * be executing. */ - if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_TASK) +#ifndef CONFIG_DISABLE_PTHREAD + if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD) +#endif { /* Report the exit status. We do not nullify tg_statloc here * because we want to prent other tasks from registering for diff --git a/nuttx/sched/task_init.c b/nuttx/sched/task_init.c index 13f7ac8f7..802d0748d 100644 --- a/nuttx/sched/task_init.c +++ b/nuttx/sched/task_init.c @@ -120,9 +120,17 @@ int task_init(FAR struct tcb_s *tcb, const char *name, int priority, main_t entry, FAR char * const argv[]) #endif { + FAR struct task_tcb_s *ttcb = (FAR struct task_tcb_s *)tcb; int errcode; int ret; + /* Only tasks and kernel threads can be initialized in this way */ + +#ifndef CONFIG_DISABLE_PTHREAD + DEBUGASSERT(tcb && + (tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD); +#endif + /* Create a new task group */ #ifdef HAVE_TASK_GROUP @@ -137,7 +145,7 @@ int task_init(FAR struct tcb_s *tcb, const char *name, int priority, /* Associate file descriptors with the new task */ #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 - ret = group_setuptaskfiles(tcb); + ret = group_setuptaskfiles(ttcb); if (ret < 0) { errcode = -ret; @@ -153,7 +161,7 @@ int task_init(FAR struct tcb_s *tcb, const char *name, int priority, /* Initialize the task control block */ - ret = task_schedsetup(tcb, priority, task_start, entry, + ret = task_schedsetup(ttcb, priority, task_start, entry, TCB_FLAG_TTYPE_TASK); if (ret < OK) { @@ -163,7 +171,7 @@ int task_init(FAR struct tcb_s *tcb, const char *name, int priority, /* Setup to pass parameters to the new task */ - (void)task_argsetup(tcb, name, argv); + (void)task_argsetup(ttcb, name, argv); /* Now we have enough in place that we can join the group */ diff --git a/nuttx/sched/task_restart.c b/nuttx/sched/task_restart.c index 762cbec52..578585c8e 100644 --- a/nuttx/sched/task_restart.c +++ b/nuttx/sched/task_restart.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/task_restart.c * - * Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2012-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -38,9 +38,13 @@ ****************************************************************************/ #include <nuttx/config.h> + #include <sys/types.h> #include <sched.h> +#include <errno.h> + #include <nuttx/arch.h> + #include "os_internal.h" #include "sig_internal.h" @@ -97,7 +101,7 @@ int task_restart(pid_t pid) { FAR struct tcb_s *rtcb; - FAR struct tcb_s *tcb; + FAR struct task_tcb_s *tcb; irqstate_t state; int status; @@ -109,11 +113,12 @@ int task_restart(pid_t pid) /* Check if the task to restart is the calling task */ - rtcb = (FAR struct tcb_s*)g_readytorun.head; + rtcb = (FAR struct tcb_s *)g_readytorun.head; if ((pid == 0) || (pid == rtcb->pid)) { /* Not implemented */ + set_errno(ENOSYS); return ERROR; } @@ -123,11 +128,18 @@ int task_restart(pid_t pid) { /* Find for the TCB associated with matching pid */ - tcb = sched_gettcb(pid); + tcb = (FAR struct task_tcb_s *)sched_gettcb(pid); +#ifndef CONFIG_DISABLE_PTHREAD + if (!tcb || (tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD) +#else if (!tcb) +#endif { - /* There is no TCB with this pid */ + /* There is no TCB with this pid or, if there is, it is not a + * task. + */ + set_errno(ESRCH); return ERROR; } @@ -136,24 +148,25 @@ int task_restart(pid_t pid) */ state = irqsave(); - dq_rem((FAR dq_entry_t*)tcb, (dq_queue_t*)g_tasklisttable[tcb->task_state].list); - tcb->task_state = TSTATE_TASK_INVALID; + dq_rem((FAR dq_entry_t*)tcb, + (dq_queue_t*)g_tasklisttable[tcb->cmn.task_state].list); + tcb->cmn.task_state = TSTATE_TASK_INVALID; irqrestore(state); /* Deallocate anything left in the TCB's queues */ - sig_cleanup(tcb); /* Deallocate Signal lists */ + sig_cleanup((FAR struct tcb_s *)tcb); /* Deallocate Signal lists */ /* Reset the current task priority */ - tcb->sched_priority = tcb->init_priority; + tcb->cmn.sched_priority = tcb->init_priority; /* Reset the base task priority and the number of pending reprioritizations */ #ifdef CONFIG_PRIORITY_INHERITANCE - tcb->base_priority = tcb->init_priority; + tcb->cmn.base_priority = tcb->init_priority; # if CONFIG_SEM_NNESTPRIO > 0 - tcb->npend_reprio = 0; + tcb->npend_reprio = 0; # endif #endif @@ -161,20 +174,20 @@ int task_restart(pid_t pid) * This will reset the entry point and the start-up parameters */ - up_initial_state(tcb); + up_initial_state((FAR struct tcb_s *)tcb); /* Add the task to the inactive task list */ dq_addfirst((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks); - tcb->task_state = TSTATE_TASK_INACTIVE; + tcb->cmn.task_state = TSTATE_TASK_INACTIVE; /* Activate the task */ - status = task_activate(tcb); + status = task_activate((FAR struct tcb_s *)tcb); if (status != OK) { dq_rem((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks); - sched_releasetcb(tcb); + sched_releasetcb((FAR struct tcb_s *)tcb); return ERROR; } } diff --git a/nuttx/sched/task_setup.c b/nuttx/sched/task_setup.c index 4c1b957f9..a7b634dd7 100644 --- a/nuttx/sched/task_setup.c +++ b/nuttx/sched/task_setup.c @@ -49,6 +49,7 @@ #include <nuttx/arch.h> #include "os_internal.h" +#include "pthread_internal.h" #include "group_internal.h" /**************************************************************************** @@ -183,7 +184,9 @@ static inline void task_saveparent(FAR struct tcb_s *tcb, uint8_t ttype) * the same task group. */ +#ifndef CONFIG_DISABLE_PTHREAD if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD) +#endif { /* This is a new task in a new task group, we have to copy the ID from * the parent's task group structure to child's task group. @@ -290,24 +293,20 @@ static inline void task_dupdspace(FAR struct tcb_s *tcb) #endif /**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: task_schedsetup + * Name: thread_schedsetup * * Description: - * This functions initializes a Task Control Block (TCB) in preparation - * for starting a new thread. + * This functions initializes the common portions of the Task Control Block + * (TCB) in preparation for starting a new thread. * - * task_schedsetup() is called from task_init(), task_start(), and - * pthread_create(); + * thread_schedsetup() is called from task_schedsetup() and + * pthread_schedsetup(). * * Input Parameters: * tcb - Address of the new task's TCB * priority - Priority of the new task - * entry - Entry point of a new task - * main - Application start point of the new task + * start - Thread startup rotuine + * entry - Thred user entry point * ttype - Type of the new thread: task, pthread, or kernel thread * * Return Value: @@ -318,8 +317,8 @@ static inline void task_dupdspace(FAR struct tcb_s *tcb) * ****************************************************************************/ -int task_schedsetup(FAR struct tcb_s *tcb, int priority, start_t start, main_t main, - uint8_t ttype) +static int thread_schedsetup(FAR struct tcb_s *tcb, int priority, + start_t start, FAR void *entry, uint8_t ttype) { int ret; @@ -330,13 +329,12 @@ int task_schedsetup(FAR struct tcb_s *tcb, int priority, start_t start, main_t m { /* Save task priority and entry point in the TCB */ - tcb->init_priority = (uint8_t)priority; tcb->sched_priority = (uint8_t)priority; #ifdef CONFIG_PRIORITY_INHERITANCE tcb->base_priority = (uint8_t)priority; #endif tcb->start = start; - tcb->entry.main = main; + tcb->entry.main = (main_t)entry; /* Save the thrad type. This setting will be needed in * up_initial_state() is called. @@ -389,6 +387,88 @@ int task_schedsetup(FAR struct tcb_s *tcb, int priority, start_t start, main_t m } /**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: task_schedsetup + * + * Description: + * This functions initializes a Task Control Block (TCB) in preparation + * for starting a new task. + * + * task_schedsetup() is called from task_init() and task_start(). + * + * Input Parameters: + * tcb - Address of the new task's TCB + * priority - Priority of the new task + * start - Startup function (probably task_start()) + * main - Application start point of the new task + * ttype - Type of the new thread: task or kernel thread + * + * Return Value: + * OK on success; ERROR on failure. + * + * This function can only failure is it is unable to assign a new, unique + * task ID to the TCB (errno is not set). + * + ****************************************************************************/ + +int task_schedsetup(FAR struct task_tcb_s *tcb, int priority, start_t start, + main_t main, uint8_t ttype) +{ + int ret; + + /* Perform common thread setup */ + + ret = thread_schedsetup((FAR struct tcb_s *)tcb, priority, start, + (FAR void *)main, ttype); + if (ret == OK) + { + /* Save task restart priority */ + + tcb->init_priority = (uint8_t)priority; + } + + return ret; +} + +/**************************************************************************** + * Name: pthread_schedsetup + * + * Description: + * This functions initializes a Task Control Block (TCB) in preparation + * for starting a new pthread. + * + * pthread_schedsetup() is called from pthread_create(), + * + * Input Parameters: + * tcb - Address of the new task's TCB + * priority - Priority of the new task + * start - Startup function (probably pthread_start()) + * entry - Entry point of the new pthread + * ttype - Type of the new thread: task, pthread, or kernel thread + * + * Return Value: + * OK on success; ERROR on failure. + * + * This function can only failure is it is unable to assign a new, unique + * task ID to the TCB (errno is not set). + * + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_PTHREAD +int pthread_schedsetup(FAR struct tcb_s *tcb, int priority, start_t start, + pthread_startroutine_t entry) +{ + /* Perform common thread setup */ + + return thread_schedsetup(tcb, priority, start, (FAR void *)entry, + TCB_FLAG_TTYPE_PTHREAD); +} +#endif + +/**************************************************************************** * Name: task_argsetup * * Description: @@ -414,7 +494,8 @@ int task_schedsetup(FAR struct tcb_s *tcb, int priority, start_t start, main_t m * ****************************************************************************/ -int task_argsetup(FAR struct tcb_s *tcb, const char *name, FAR char * const argv[]) +int task_argsetup(FAR struct task_tcb_s *tcb, const char *name, + FAR char * const argv[]) { int i; @@ -423,16 +504,16 @@ int task_argsetup(FAR struct tcb_s *tcb, const char *name, FAR char * const argv if (!name) { - name = (char *)g_noname; + name = (FAR char *)g_noname; } /* Copy the name into the TCB */ - strncpy(tcb->name, name, CONFIG_TASK_NAME_SIZE); + strncpy(tcb->cmn.name, name, CONFIG_TASK_NAME_SIZE); /* Save the name as the first argument */ - tcb->argv[0] = tcb->name; + tcb->argv[0] = tcb->cmn.name; #else /* Save the name as the first argument */ diff --git a/nuttx/sched/task_start.c b/nuttx/sched/task_start.c index 5a66089c6..8e012b515 100644 --- a/nuttx/sched/task_start.c +++ b/nuttx/sched/task_start.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/task_start.c * - * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2010, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -91,9 +91,11 @@ void task_start(void) { - FAR struct tcb_s *tcb = (FAR struct tcb_s*)g_readytorun.head; + FAR struct task_tcb_s *tcb = (FAR struct task_tcb_s*)g_readytorun.head; int argc; + DEBUGASSERT((tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD); + /* Execute the start hook if one has been registered */ #ifdef CONFIG_SCHED_STARTHOOK @@ -119,5 +121,5 @@ void task_start(void) * the task returns. */ - exit(tcb->entry.main(argc, tcb->argv)); + exit(tcb->cmn.entry.main(argc, tcb->argv)); } diff --git a/nuttx/sched/task_starthook.c b/nuttx/sched/task_starthook.c index cf725a854..7fa0757aa 100644 --- a/nuttx/sched/task_starthook.c +++ b/nuttx/sched/task_starthook.c @@ -1,7 +1,7 @@ /**************************************************************************** - * sched/task_start.c + * sched/task_starthook.c * - * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -90,9 +90,20 @@ * ****************************************************************************/ -void task_starthook(FAR struct tcb_s *tcb, starthook_t starthook, FAR void *arg) +void task_starthook(FAR struct task_tcb_s *tcb, starthook_t starthook, + FAR void *arg) { - DEBUGASSERT(tcb); + /* Only tasks can have starthooks. The starthook will be called when the + * task is started (or restarted). + */ + +#ifndef CONFIG_DISABLE_PTHREAD + DEBUGASSERT(tcb && + (tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD); +#endif + + /* Set up the start hook */ + tcb->starthook = starthook; tcb->starthookarg = arg; } diff --git a/nuttx/sched/task_vfork.c b/nuttx/sched/task_vfork.c index f5d41bc8b..082854d60 100644 --- a/nuttx/sched/task_vfork.c +++ b/nuttx/sched/task_vfork.c @@ -108,7 +108,7 @@ FAR struct tcb_s *task_vforksetup(start_t retaddr) { struct tcb_s *parent = (FAR struct tcb_s *)g_readytorun.head; - struct tcb_s *child; + struct task_tcb_s *child; int priority; int ret; @@ -116,7 +116,7 @@ FAR struct tcb_s *task_vforksetup(start_t retaddr) /* Allocate a TCB for the child task. */ - child = (FAR struct tcb_s*)kzalloc(sizeof(struct tcb_s)); + child = (FAR struct task_tcb_s *)kzalloc(sizeof(struct task_tcb_s)); if (!child) { set_errno(ENOMEM); @@ -152,10 +152,10 @@ FAR struct tcb_s *task_vforksetup(start_t retaddr) } svdbg("parent=%p, returning child=%p\n", parent, child); - return child; + return (FAR struct tcb_s *)child; errout_with_tcb: - sched_releasetcb(child); + sched_releasetcb((FAR struct tcb_s *)child); set_errno(-ret); return NULL; } |