Divide struct tcb_s into structs task_tcb_s and pthread_tcb_s

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5611 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2013-02-04 21:24:00 +00:00
parent b48009644f
commit 7b3ec4e146
22 changed files with 332 additions and 176 deletions
+6
View File
@@ -4124,4 +4124,10 @@
* includes/nuttx/sched.h and Lots of files: Change name of _TCB to * includes/nuttx/sched.h and Lots of files: Change name of _TCB to
struct tcb_s so that (1) it is consitent with other NuttX naming and struct tcb_s so that (1) it is consitent with other NuttX naming and
so that (2) the naming can handle some upcoming changes. so that (2) the naming can handle some upcoming changes.
* includes/nuttx/sched.h and sched/: There are three TCB structures:
struct tcb_s is a generic common version, struct task_tcb_s is a
version for tasks and kernel threads and pthread_tcb_s is a version
for pthreads. By dividing the TCB structure into these variants,
pthreads do not have to be burdened by task-specific data structures
(and vice versa).
+9 -9
View File
@@ -134,7 +134,7 @@ static void exec_ctors(FAR void *arg)
int exec_module(FAR const struct binary_s *binp) int exec_module(FAR const struct binary_s *binp)
{ {
FAR struct tcb_s *tcb; FAR struct task_tcb_s *tcb;
#ifndef CONFIG_CUSTOM_STACK #ifndef CONFIG_CUSTOM_STACK
FAR uint32_t *stack; FAR uint32_t *stack;
#endif #endif
@@ -156,7 +156,7 @@ int exec_module(FAR const struct binary_s *binp)
/* Allocate a TCB for the new task. */ /* 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) if (!tcb)
{ {
err = ENOMEM; err = ENOMEM;
@@ -198,17 +198,17 @@ int exec_module(FAR const struct binary_s *binp)
*/ */
#ifdef CONFIG_PIC #ifdef CONFIG_PIC
tcb->dspace = binp->alloc[0]; tcb->cmn.dspace = binp->alloc[0];
/* Re-initialize the task's initial state to account for the new PIC base */ /* Re-initialize the task's initial state to account for the new PIC base */
up_initial_state(tcb); up_initial_state(&tcb->cmn);
#endif #endif
/* Assign the address environment to the task */ /* Assign the address environment to the task */
#ifdef CONFIG_ADDRENV #ifdef CONFIG_ADDRENV
ret = up_addrenv_assign(binp->addrenv, tcb); ret = up_addrenv_assign(binp->addrenv, &tcb->cmn);
if (ret < 0) if (ret < 0)
{ {
err = -ret; err = -ret;
@@ -228,7 +228,7 @@ int exec_module(FAR const struct binary_s *binp)
/* Get the assigned pid before we start the task */ /* Get the assigned pid before we start the task */
pid = tcb->pid; pid = tcb->cmn.pid;
/* Then activate the task at the provided priority */ /* Then activate the task at the provided priority */
@@ -244,11 +244,11 @@ int exec_module(FAR const struct binary_s *binp)
errout_with_stack: errout_with_stack:
#ifndef CONFIG_CUSTOM_STACK #ifndef CONFIG_CUSTOM_STACK
tcb->stack_alloc_ptr = NULL; tcb->cmn.stack_alloc_ptr = NULL;
sched_releasetcb(tcb); sched_releasetcb(&tcb->cmn);
kfree(stack); kfree(stack);
#else #else
sched_releasetcb(tcb); sched_releasetcb(&tcb->cmn);
#endif #endif
goto errout; goto errout;
+63 -24
View File
@@ -387,8 +387,9 @@ struct task_group_s
#endif #endif
/* struct tcb_s ******************************************************************/ /* struct tcb_s ******************************************************************/
/* This is the common part of the task control block (TCB). Each task or thread /* This is the common part of the task control block (TCB). The TCB is the heart
* is represented by a TCB. The TCB is the heart of the NuttX task-control logic. * of the NuttX task-control logic. Each task or thread is represented by a TCB
* that includes these common definitions.
*/ */
struct tcb_s struct tcb_s
@@ -419,12 +420,6 @@ struct tcb_s
start_t start; /* Thread start function */ start_t start; /* Thread start function */
entry_t entry; /* Entry Point into the thread */ entry_t entry; /* Entry Point into the thread */
#ifdef CONFIG_SCHED_STARTHOOK
starthook_t starthook; /* Task startup function */
FAR void *starthookarg; /* The argument passed to the function */
#endif
uint8_t sched_priority; /* Current priority of the thread */ uint8_t sched_priority; /* Current priority of the thread */
#ifdef CONFIG_PRIORITY_INHERITANCE #ifdef CONFIG_PRIORITY_INHERITANCE
@@ -439,19 +434,10 @@ struct tcb_s
uint16_t flags; /* Misc. general status flags */ uint16_t flags; /* Misc. general status flags */
int16_t lockcount; /* 0=preemptable (not-locked) */ int16_t lockcount; /* 0=preemptable (not-locked) */
#ifndef CONFIG_DISABLE_PTHREAD
FAR void *joininfo; /* Detach-able info to support join */
#endif
#if CONFIG_RR_INTERVAL > 0 #if CONFIG_RR_INTERVAL > 0
int timeslice; /* RR timeslice interval remaining */ int timeslice; /* RR timeslice interval remaining */
#endif #endif
/* Values needed to restart a task ********************************************/
uint8_t init_priority; /* Initial priority of the task */
char *argv[CONFIG_MAX_TASK_ARGS+1]; /* Name+start-up parameters */
/* Stack-Related Fields *******************************************************/ /* Stack-Related Fields *******************************************************/
#ifndef CONFIG_CUSTOM_STACK #ifndef CONFIG_CUSTOM_STACK
@@ -470,12 +456,6 @@ struct tcb_s
FAR struct dspace_s *dspace; /* Allocated area for .bss and .data */ FAR struct dspace_s *dspace; /* Allocated area for .bss and .data */
#endif #endif
/* POSIX Thread Specific Data *************************************************/
#if !defined(CONFIG_DISABLE_PTHREAD) && CONFIG_NPTHREAD_KEYS > 0
FAR void *pthread_data[CONFIG_NPTHREAD_KEYS];
#endif
/* POSIX Semaphore Control Fields *********************************************/ /* POSIX Semaphore Control Fields *********************************************/
sem_t *waitsem; /* Semaphore ID waiting on */ sem_t *waitsem; /* Semaphore ID waiting on */
@@ -512,6 +492,65 @@ struct tcb_s
#endif #endif
}; };
/* struct task_tcb_s *************************************************************/
/* This is the particular form of the task control block (TCB) structure used by
* tasks (and kernel threads). There are two TCB forms: one for pthreads and
* one for tasks. Both share the common TCB fields (which must appear at the
* top of the structure) plus additional fields unique to tasks and threads.
* Having separate structures for tasks and pthreads adds some complexity, but
* saves memory in that it prevents pthreads from being burdened with the
* overhead required for tasks (and vice versa).
*/
struct task_tcb_s
{
/* Common TCB fields **********************************************************/
struct tcb_s cmn; /* Common TCB fields */
/* Task Management Fields *****************************************************/
#ifdef CONFIG_SCHED_STARTHOOK
starthook_t starthook; /* Task startup function */
FAR void *starthookarg; /* The argument passed to the function */
#endif
/* Values needed to restart a task ********************************************/
uint8_t init_priority; /* Initial priority of the task */
char *argv[CONFIG_MAX_TASK_ARGS+1]; /* Name+start-up parameters */
};
/* struct pthread_tcb_s **********************************************************/
/* This is the particular form of the task control block (TCB) structure used by
* pthreads. There are two TCB forms: one for pthreads and one for tasks. Both
* share the common TCB fields (which must appear at the top of the structure)
* plus additional fields unique to tasks and threads. Having separate structures
* for tasks and pthreads adds some complexity, but saves memory in that it
* prevents pthreads from being burdened with the overhead required for tasks
* (and vice versa).
*/
#ifndef CONFIG_DISABLE_PTHREAD
struct pthread_tcb_s
{
/* Common TCB fields **********************************************************/
struct tcb_s cmn; /* Common TCB fields */
/* Task Management Fields *****************************************************/
pthread_addr_t arg; /* Startup argument */
FAR void *joininfo; /* Detach-able info to support join */
/* POSIX Thread Specific Data *************************************************/
#if CONFIG_NPTHREAD_KEYS > 0
FAR void *pthread_data[CONFIG_NPTHREAD_KEYS];
#endif
};
#endif /* !CONFIG_DISABLE_PTHREAD */
/* This is the callback type used by sched_foreach() */ /* This is the callback type used by sched_foreach() */
typedef void (*sched_foreach_t)(FAR struct tcb_s *tcb, FAR void *arg); typedef void (*sched_foreach_t)(FAR struct tcb_s *tcb, FAR void *arg);
@@ -556,7 +595,7 @@ FAR struct socketlist *sched_getsockets(void);
/* Setup up a start hook */ /* Setup up a start hook */
#ifdef CONFIG_SCHED_STARTHOOK #ifdef CONFIG_SCHED_STARTHOOK
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);
#endif #endif
/* Internal vfork support.The overall sequence is: /* Internal vfork support.The overall sequence is:
+3 -3
View File
@@ -122,10 +122,10 @@ void group_removechildren(FAR struct task_group_s *group);
/* Group data resource configuration */ /* Group data resource configuration */
#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
int group_setupidlefiles(FAR struct tcb_s *tcb); int group_setupidlefiles(FAR struct task_tcb_s *tcb);
int group_setuptaskfiles(FAR struct tcb_s *tcb); int group_setuptaskfiles(FAR struct task_tcb_s *tcb);
#if CONFIG_NFILE_STREAMS > 0 #if CONFIG_NFILE_STREAMS > 0
int group_setupstreams(FAR struct tcb_s *tcb); int group_setupstreams(FAR struct task_tcb_s *tcb);
#endif #endif
#endif #endif
+2 -2
View File
@@ -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 #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 #endif
#if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_DEV_CONSOLE) #if CONFIG_NFILE_DESCRIPTORS > 0 && defined(CONFIG_DEV_CONSOLE)
int fd; int fd;
+6 -6
View File
@@ -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 */ /* 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 /* 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. * 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) * fd = 2 is stderr (write-only, append)
*/ */
(void)fs_fdopen(0, O_RDONLY, tcb); (void)fs_fdopen(0, O_RDONLY, (FAR struct tcb_s *)tcb);
(void)fs_fdopen(1, O_WROK|O_CREAT, tcb); (void)fs_fdopen(1, O_WROK|O_CREAT, (FAR struct tcb_s *)tcb);
(void)fs_fdopen(2, O_WROK|O_CREAT, tcb); (void)fs_fdopen(2, O_WROK|O_CREAT, (FAR struct tcb_s *)tcb);
return OK; return OK;
} }
+11 -8
View File
@@ -85,7 +85,7 @@
****************************************************************************/ ****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_FDCLONE_DISABLE) #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 */ /* 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; FAR struct file *child;
int i; 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 /* Duplicate the file descriptors. This will be either all of the
* file descriptors or just the first three (stdin, stdout, and stderr) * 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 */ /* Get pointers to the parent and child task file lists */
parent = rtcb->group->tg_filelist.fl_files; 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 */ /* 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) #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 */ /* 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. * task.
*/ */
DEBUGASSERT(tcb && tcb->group && rtcb->group); DEBUGASSERT(tcb && tcb->cmn.group && rtcb->group);
/* Get pointers to the parent and child task socket lists */ /* Get pointers to the parent and child task socket lists */
parent = rtcb->group->tg_socketlist.sl_sockets; 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 */ /* 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 #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); DEBUGASSERT(group);
#endif #endif
#ifndef CONFIG_DISABLE_PTHREAD
DEBUGASSERT((tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD);
#endif
#if CONFIG_NFILE_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0
/* Initialize file descriptors for the TCB */ /* Initialize file descriptors for the TCB */
+2 -2
View File
@@ -257,9 +257,9 @@ int os_bringup(void);
void weak_function task_initialize(void); void weak_function task_initialize(void);
#endif #endif
void task_start(void); 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); 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); void task_exithook(FAR struct tcb_s *tcb, int status);
int task_deletecurrent(void); int task_deletecurrent(void);
+11 -11
View File
@@ -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 * 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 */ /* 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 */ /* 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; g_pidhash[ PIDHASH(0)].pid = 0;
/* Initialize a TCB for this thread of execution. NOTE: The default /* 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. * that has pid == 0 and sched_priority == 0.
*/ */
bzero((void*)&g_idletcb, sizeof(struct tcb_s)); bzero((void*)&g_idletcb, sizeof(struct task_tcb_s));
g_idletcb.task_state = TSTATE_TASK_RUNNING; g_idletcb.cmn.task_state = TSTATE_TASK_RUNNING;
g_idletcb.entry.main = (main_t)os_start; g_idletcb.cmn.entry.main = (main_t)os_start;
#if CONFIG_TASK_NAME_SIZE > 0 #if CONFIG_TASK_NAME_SIZE > 0
strncpy(g_idletcb.name, g_idlename, CONFIG_TASK_NAME_SIZE-1); strncpy(g_idletcb.cmn.name, g_idlename, CONFIG_TASK_NAME_SIZE-1);
g_idletcb.argv[0] = g_idletcb.name; g_idletcb.argv[0] = g_idletcb.cmn.name;
#else #else
g_idletcb.argv[0] = (char*)g_idlename; g_idletcb.argv[0] = (char*)g_idlename;
#endif /* CONFIG_TASK_NAME_SIZE */ #endif /* CONFIG_TASK_NAME_SIZE */
@@ -289,7 +289,7 @@ void os_start(void)
/* Initialize the processor-specific portion of the TCB */ /* 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 /* Initialize the semaphore facility(if in link). This has to be done
* very early because many subsystems depend upon fully functional * 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. */ /* Allocate the IDLE group and suppress child status. */
#ifdef HAVE_TASK_GROUP #ifdef HAVE_TASK_GROUP
(void)group_allocate(&g_idletcb); (void)group_allocate(&g_idletcb.cmn);
#endif #endif
/* Initialize the interrupt handling subsystem (if included) */ /* Initialize the interrupt handling subsystem (if included) */
@@ -456,8 +456,8 @@ void os_start(void)
*/ */
#ifdef HAVE_TASK_GROUP #ifdef HAVE_TASK_GROUP
(void)group_initialize(&g_idletcb); (void)group_initialize(&g_idletcb.cmn);
g_idletcb.group->tg_flags = GROUP_FLAG_NOCLDWAIT; g_idletcb.cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT;
#endif #endif
/* Create initial tasks and bring-up the system */ /* Create initial tasks and bring-up the system */
+19 -41
View File
@@ -99,48 +99,26 @@ static const char g_pthreadname[] = "<pthread>";
* *
* Input Parameters: * Input Parameters:
* tcb - Address of the new task's TCB * tcb - Address of the new task's TCB
* name - Name of the new task (not used) * arg - The argument to provide to the pthread on startup.
* 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.
* *
* Return Value: * Return Value:
* None * 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 #if CONFIG_TASK_NAME_SIZE > 0
/* Copy the pthread name into the TCB */ /* Copy the pthread name into the TCB */
strncpy(tcb->name, g_pthreadname, CONFIG_TASK_NAME_SIZE); strncpy(tcb->cmn.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;
#endif /* CONFIG_TASK_NAME_SIZE */ #endif /* CONFIG_TASK_NAME_SIZE */
/* For pthreads, args are strictly pass-by-value; that actual /* For pthreads, args are strictly pass-by-value; that actual
* type wrapped by pthread_addr_t is unknown. * type wrapped by pthread_addr_t is unknown.
*/ */
tcb->argv[1] = (char*)arg; tcb->arg = arg;
/* Nullify the remaining, unused argument storage */
for (i = 2; i < CONFIG_MAX_TASK_ARGS+1; i++)
{
tcb->argv[i] = NULL;
}
} }
/**************************************************************************** /****************************************************************************
@@ -189,8 +167,8 @@ static inline void pthread_addjoininfo(FAR struct task_group_s *group,
static void pthread_start(void) static void pthread_start(void)
{ {
FAR struct tcb_s *ptcb = (FAR struct tcb_s*)g_readytorun.head; FAR struct pthread_tcb_s *ptcb = (FAR struct pthread_tcb_s*)g_readytorun.head;
FAR struct task_group_s *group = ptcb->group; FAR struct task_group_s *group = ptcb->cmn.group;
FAR struct join_s *pjoin = (FAR struct join_s*)ptcb->joininfo; FAR struct join_s *pjoin = (FAR struct join_s*)ptcb->joininfo;
pthread_addr_t exit_status; pthread_addr_t exit_status;
@@ -214,7 +192,7 @@ static void pthread_start(void)
* available to the pthread. * 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 */ /* 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, int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr,
pthread_startroutine_t start_routine, pthread_addr_t arg) 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; FAR struct join_s *pjoin;
int priority; int priority;
#if CONFIG_RR_INTERVAL > 0 #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. */ /* 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) if (!ptcb)
{ {
return ENOMEM; return ENOMEM;
@@ -277,7 +255,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr,
*/ */
#ifdef HAVE_TASK_GROUP #ifdef HAVE_TASK_GROUP
ret = group_bind(ptcb); ret = group_bind((FAR struct tcb_s *)ptcb);
if (ret < 0) if (ret < 0)
{ {
errcode = ENOMEM; errcode = ENOMEM;
@@ -291,7 +269,8 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr,
*/ */
#ifdef CONFIG_ADDRENV #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) if (ret < 0)
{ {
errcode = -ret; errcode = -ret;
@@ -310,7 +289,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr,
/* Allocate the stack for the TCB */ /* 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) if (ret != OK)
{ {
errcode = ENOMEM; errcode = ENOMEM;
@@ -359,8 +338,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr,
/* Initialize the task control block */ /* Initialize the task control block */
ret = task_schedsetup(ptcb, priority, pthread_start, (main_t)start_routine, ret = pthread_schedsetup(ptcb, priority, pthread_start, start_routine);
TCB_FLAG_TTYPE_PTHREAD);
if (ret != OK) if (ret != OK)
{ {
errcode = EBUSY; errcode = EBUSY;
@@ -376,7 +354,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr,
/* Join the parent's task group */ /* Join the parent's task group */
#ifdef HAVE_TASK_GROUP #ifdef HAVE_TASK_GROUP
ret = group_join(ptcb); ret = group_join((FAR struct tcb_s *)ptcb);
if (ret < 0) if (ret < 0)
{ {
errcode = ENOMEM; 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. */ /* 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 /* If round robin scheduling is selected, set the appropriate flag
* in the TCB. * in the TCB.
@@ -405,7 +383,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr,
* as well. * as well.
*/ */
pid = (int)ptcb->pid; pid = (int)ptcb->cmn.pid;
pjoin->thread = (pthread_t)pid; pjoin->thread = (pthread_t)pid;
/* Initialize the semaphores in the join structure to zero. */ /* 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(); sched_lock();
if (ret == OK) if (ret == OK)
{ {
ret = task_activate(ptcb); ret = task_activate((FAR struct tcb_s *)ptcb);
} }
if (ret == OK) if (ret == OK)
@@ -465,6 +443,6 @@ errout_with_join:
ptcb->joininfo = NULL; ptcb->joininfo = NULL;
errout_with_tcb: errout_with_tcb:
sched_releasetcb(ptcb); sched_releasetcb((FAR struct tcb_s *)ptcb);
return errcode; return errcode;
} }
+4 -3
View File
@@ -104,11 +104,12 @@
FAR void *pthread_getspecific(pthread_key_t key) FAR void *pthread_getspecific(pthread_key_t key)
{ {
#if CONFIG_NPTHREAD_KEYS > 0 #if CONFIG_NPTHREAD_KEYS > 0
FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; FAR struct pthread_tcb_s *rtcb = (FAR struct pthread_tcb_s*)g_readytorun.head;
FAR struct task_group_s *group = rtcb->group; FAR struct task_group_s *group = rtcb->cmn.group;
FAR void *ret = NULL; 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. */ /* Check if the key is valid. */
+3
View File
@@ -46,6 +46,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <pthread.h> #include <pthread.h>
#include <sched.h>
#include <nuttx/compiler.h> #include <nuttx/compiler.h>
@@ -96,6 +97,8 @@ extern "C"
struct task_group_s; /* Forward reference */ struct task_group_s; /* Forward reference */
void weak_function pthread_initialize(void); 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); int pthread_completejoin(pid_t pid, FAR void *exit_value);
void pthread_destroyjoin(FAR struct task_group_s *group, void pthread_destroyjoin(FAR struct task_group_s *group,
FAR struct join_s *pjoin); FAR struct join_s *pjoin);
+4 -3
View File
@@ -115,11 +115,12 @@
int pthread_setspecific(pthread_key_t key, FAR void *value) int pthread_setspecific(pthread_key_t key, FAR void *value)
{ {
#if CONFIG_NPTHREAD_KEYS > 0 #if CONFIG_NPTHREAD_KEYS > 0
FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; FAR struct pthread_tcb_s *rtcb = (FAR struct pthread_tcb_s*)g_readytorun.head;
FAR struct task_group_s *group = rtcb->group; FAR struct task_group_s *group = rtcb->cmn.group;
int ret = EINVAL; int ret = EINVAL;
DEBUGASSERT(group); DEBUGASSERT(group &&
(rtcb->cmn.flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD);
/* Check if the key is valid. */ /* Check if the key is valid. */
+6 -3
View File
@@ -155,11 +155,14 @@ int sched_releasetcb(FAR struct tcb_s *tcb)
* start/re-start. * 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]);
} }
} }
+8 -8
View File
@@ -106,14 +106,14 @@ static int thread_create(const char *name, uint8_t ttype, int priority,
main_t entry, FAR char * const argv[]) main_t entry, FAR char * const argv[])
#endif #endif
{ {
FAR struct tcb_s *tcb; FAR struct task_tcb_s *tcb;
pid_t pid; pid_t pid;
int errcode; int errcode;
int ret; int ret;
/* Allocate a TCB for the new task. */ /* 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) if (!tcb)
{ {
errcode = ENOMEM; errcode = ENOMEM;
@@ -123,7 +123,7 @@ static int thread_create(const char *name, uint8_t ttype, int priority,
/* Allocate a new task group */ /* Allocate a new task group */
#ifdef HAVE_TASK_GROUP #ifdef HAVE_TASK_GROUP
ret = group_allocate(tcb); ret = group_allocate((FAR struct tcb_s *)tcb);
if (ret < 0) if (ret < 0)
{ {
errcode = -ret; errcode = -ret;
@@ -145,7 +145,7 @@ static int thread_create(const char *name, uint8_t ttype, int priority,
/* Allocate the stack for the TCB */ /* Allocate the stack for the TCB */
#ifndef CONFIG_CUSTOM_STACK #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) if (ret != OK)
{ {
errcode = -ret; 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 */ /* Now we have enough in place that we can join the group */
#ifdef HAVE_TASK_GROUP #ifdef HAVE_TASK_GROUP
ret = group_initialize(tcb); ret = group_initialize((FAR struct tcb_s *)tcb);
if (ret < 0) if (ret < 0)
{ {
errcode = -ret; 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 */ /* Get the assigned pid before we start the task */
pid = (int)tcb->pid; pid = (int)tcb->cmn.pid;
/* Activate the task */ /* Activate the task */
ret = task_activate(tcb); ret = task_activate((FAR struct tcb_s *)tcb);
if (ret != OK) if (ret != OK)
{ {
errcode = get_errno(); errcode = get_errno();
@@ -197,7 +197,7 @@ static int thread_create(const char *name, uint8_t ttype, int priority,
return pid; return pid;
errout_with_tcb: errout_with_tcb:
sched_releasetcb(tcb); sched_releasetcb((FAR struct tcb_s *)tcb);
errout: errout:
set_errno(errcode); set_errno(errcode);
+12 -5
View File
@@ -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. * 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); 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. * 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 #ifdef CONFIG_SCHED_CHILD_STATUS
/* Save the exit status now of the main thread */ /* 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) if (group)
{ {
/* Only tasks return valid status. Record the exit status when the /* Only tasks (and kernel threads) return valid status. Record the
* task exists. The group, however, may still be executing. * 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 /* Report the exit status. We do not nullify tg_statloc here
* because we want to prent other tasks from registering for * because we want to prent other tasks from registering for
+11 -3
View File
@@ -120,9 +120,17 @@ int task_init(FAR struct tcb_s *tcb, const char *name, int priority,
main_t entry, FAR char * const argv[]) main_t entry, FAR char * const argv[])
#endif #endif
{ {
FAR struct task_tcb_s *ttcb = (FAR struct task_tcb_s *)tcb;
int errcode; int errcode;
int ret; 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 */ /* Create a new task group */
#ifdef HAVE_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 */ /* Associate file descriptors with the new task */
#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
ret = group_setuptaskfiles(tcb); ret = group_setuptaskfiles(ttcb);
if (ret < 0) if (ret < 0)
{ {
errcode = -ret; errcode = -ret;
@@ -153,7 +161,7 @@ int task_init(FAR struct tcb_s *tcb, const char *name, int priority,
/* Initialize the task control block */ /* 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); TCB_FLAG_TTYPE_TASK);
if (ret < OK) 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 */ /* 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 */ /* Now we have enough in place that we can join the group */
+28 -15
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* sched/task_restart.c * 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> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -38,9 +38,13 @@
****************************************************************************/ ****************************************************************************/
#include <nuttx/config.h> #include <nuttx/config.h>
#include <sys/types.h> #include <sys/types.h>
#include <sched.h> #include <sched.h>
#include <errno.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include "os_internal.h" #include "os_internal.h"
#include "sig_internal.h" #include "sig_internal.h"
@@ -97,7 +101,7 @@
int task_restart(pid_t pid) int task_restart(pid_t pid)
{ {
FAR struct tcb_s *rtcb; FAR struct tcb_s *rtcb;
FAR struct tcb_s *tcb; FAR struct task_tcb_s *tcb;
irqstate_t state; irqstate_t state;
int status; int status;
@@ -109,11 +113,12 @@ int task_restart(pid_t pid)
/* Check if the task to restart is the calling task */ /* 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)) if ((pid == 0) || (pid == rtcb->pid))
{ {
/* Not implemented */ /* Not implemented */
set_errno(ENOSYS);
return ERROR; return ERROR;
} }
@@ -123,11 +128,18 @@ int task_restart(pid_t pid)
{ {
/* Find for the TCB associated with matching 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) 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; return ERROR;
} }
@@ -136,24 +148,25 @@ int task_restart(pid_t pid)
*/ */
state = irqsave(); state = irqsave();
dq_rem((FAR dq_entry_t*)tcb, (dq_queue_t*)g_tasklisttable[tcb->task_state].list); dq_rem((FAR dq_entry_t*)tcb,
tcb->task_state = TSTATE_TASK_INVALID; (dq_queue_t*)g_tasklisttable[tcb->cmn.task_state].list);
tcb->cmn.task_state = TSTATE_TASK_INVALID;
irqrestore(state); irqrestore(state);
/* Deallocate anything left in the TCB's queues */ /* 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 */ /* 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 */ /* Reset the base task priority and the number of pending reprioritizations */
#ifdef CONFIG_PRIORITY_INHERITANCE #ifdef CONFIG_PRIORITY_INHERITANCE
tcb->base_priority = tcb->init_priority; tcb->cmn.base_priority = tcb->init_priority;
# if CONFIG_SEM_NNESTPRIO > 0 # if CONFIG_SEM_NNESTPRIO > 0
tcb->npend_reprio = 0; tcb->npend_reprio = 0;
# endif # endif
#endif #endif
@@ -161,20 +174,20 @@ int task_restart(pid_t pid)
* This will reset the entry point and the start-up parameters * 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 */ /* Add the task to the inactive task list */
dq_addfirst((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks); 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 */ /* Activate the task */
status = task_activate(tcb); status = task_activate((FAR struct tcb_s *)tcb);
if (status != OK) if (status != OK)
{ {
dq_rem((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks); dq_rem((FAR dq_entry_t*)tcb, (dq_queue_t*)&g_inactivetasks);
sched_releasetcb(tcb); sched_releasetcb((FAR struct tcb_s *)tcb);
return ERROR; return ERROR;
} }
} }
+100 -19
View File
@@ -49,6 +49,7 @@
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include "os_internal.h" #include "os_internal.h"
#include "pthread_internal.h"
#include "group_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. * the same task group.
*/ */
#ifndef CONFIG_DISABLE_PTHREAD
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_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 /* 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. * 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 #endif
/**************************************************************************** /****************************************************************************
* Public Functions * Name: thread_schedsetup
****************************************************************************/
/****************************************************************************
* Name: task_schedsetup
* *
* Description: * Description:
* This functions initializes a Task Control Block (TCB) in preparation * This functions initializes the common portions of the Task Control Block
* for starting a new thread. * (TCB) in preparation for starting a new thread.
* *
* task_schedsetup() is called from task_init(), task_start(), and * thread_schedsetup() is called from task_schedsetup() and
* pthread_create(); * pthread_schedsetup().
* *
* Input Parameters: * Input Parameters:
* tcb - Address of the new task's TCB * tcb - Address of the new task's TCB
* priority - Priority of the new task * priority - Priority of the new task
* entry - Entry point of a new task * start - Thread startup rotuine
* main - Application start point of the new task * entry - Thred user entry point
* ttype - Type of the new thread: task, pthread, or kernel thread * ttype - Type of the new thread: task, pthread, or kernel thread
* *
* Return Value: * 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, static int thread_schedsetup(FAR struct tcb_s *tcb, int priority,
uint8_t ttype) start_t start, FAR void *entry, uint8_t ttype)
{ {
int ret; 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 */ /* Save task priority and entry point in the TCB */
tcb->init_priority = (uint8_t)priority;
tcb->sched_priority = (uint8_t)priority; tcb->sched_priority = (uint8_t)priority;
#ifdef CONFIG_PRIORITY_INHERITANCE #ifdef CONFIG_PRIORITY_INHERITANCE
tcb->base_priority = (uint8_t)priority; tcb->base_priority = (uint8_t)priority;
#endif #endif
tcb->start = start; tcb->start = start;
tcb->entry.main = main; tcb->entry.main = (main_t)entry;
/* Save the thrad type. This setting will be needed in /* Save the thrad type. This setting will be needed in
* up_initial_state() is called. * up_initial_state() is called.
@@ -388,6 +386,88 @@ int task_schedsetup(FAR struct tcb_s *tcb, int priority, start_t start, main_t m
return ret; return ret;
} }
/****************************************************************************
* 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 * Name: task_argsetup
* *
@@ -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; int i;
@@ -423,16 +504,16 @@ int task_argsetup(FAR struct tcb_s *tcb, const char *name, FAR char * const argv
if (!name) if (!name)
{ {
name = (char *)g_noname; name = (FAR char *)g_noname;
} }
/* Copy the name into the TCB */ /* 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 */ /* Save the name as the first argument */
tcb->argv[0] = tcb->name; tcb->argv[0] = tcb->cmn.name;
#else #else
/* Save the name as the first argument */ /* Save the name as the first argument */
+5 -3
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* sched/task_start.c * 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> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -91,9 +91,11 @@
void task_start(void) 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; int argc;
DEBUGASSERT((tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_PTHREAD);
/* Execute the start hook if one has been registered */ /* Execute the start hook if one has been registered */
#ifdef CONFIG_SCHED_STARTHOOK #ifdef CONFIG_SCHED_STARTHOOK
@@ -119,5 +121,5 @@ void task_start(void)
* the task returns. * the task returns.
*/ */
exit(tcb->entry.main(argc, tcb->argv)); exit(tcb->cmn.entry.main(argc, tcb->argv));
} }
+15 -4
View File
@@ -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> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * 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->starthook = starthook;
tcb->starthookarg = arg; tcb->starthookarg = arg;
} }
+4 -4
View File
@@ -108,7 +108,7 @@
FAR struct tcb_s *task_vforksetup(start_t retaddr) FAR struct tcb_s *task_vforksetup(start_t retaddr)
{ {
struct tcb_s *parent = (FAR struct tcb_s *)g_readytorun.head; struct tcb_s *parent = (FAR struct tcb_s *)g_readytorun.head;
struct tcb_s *child; struct task_tcb_s *child;
int priority; int priority;
int ret; int ret;
@@ -116,7 +116,7 @@ FAR struct tcb_s *task_vforksetup(start_t retaddr)
/* Allocate a TCB for the child task. */ /* 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) if (!child)
{ {
set_errno(ENOMEM); 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); svdbg("parent=%p, returning child=%p\n", parent, child);
return child; return (FAR struct tcb_s *)child;
errout_with_tcb: errout_with_tcb:
sched_releasetcb(child); sched_releasetcb((FAR struct tcb_s *)child);
set_errno(-ret); set_errno(-ret);
return NULL; return NULL;
} }