summaryrefslogtreecommitdiff
path: root/nuttx/sched
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/sched')
-rw-r--r--nuttx/sched/group_internal.h6
-rw-r--r--nuttx/sched/group_setupidlefiles.c4
-rw-r--r--nuttx/sched/group_setupstreams.c12
-rw-r--r--nuttx/sched/group_setuptaskfiles.c19
-rw-r--r--nuttx/sched/os_internal.h4
-rw-r--r--nuttx/sched/os_start.c22
-rw-r--r--nuttx/sched/pthread_create.c60
-rw-r--r--nuttx/sched/pthread_getspecific.c7
-rw-r--r--nuttx/sched/pthread_internal.h3
-rw-r--r--nuttx/sched/pthread_setspecific.c7
-rw-r--r--nuttx/sched/sched_releasetcb.c9
-rw-r--r--nuttx/sched/task_create.c16
-rw-r--r--nuttx/sched/task_exithook.c17
-rw-r--r--nuttx/sched/task_init.c14
-rw-r--r--nuttx/sched/task_restart.c43
-rw-r--r--nuttx/sched/task_setup.c119
-rw-r--r--nuttx/sched/task_start.c8
-rw-r--r--nuttx/sched/task_starthook.c19
-rw-r--r--nuttx/sched/task_vfork.c8
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;
}