Scheduler: Replace the boolean 'prioritized' with a uint8_t bit set so that additional attributes of a list can be specified without adding more boolean values.
This commit is contained in:
parent
0a7e136a5a
commit
49227fa554
@ -11480,4 +11480,7 @@
|
||||
* arch/arm/sim/up_head.c and up_simsmp.c: Add multi-CPU support to the
|
||||
simulation to support SMP investigation.. Currently crashes when CONFIG_SMP
|
||||
is enabled as expected (2016-02-10).
|
||||
* sched/sched.h and other files: Replace the bool 'prioritized' in the task
|
||||
list table with a uint8_t bit set so that additional attributes of a task
|
||||
list can be provided without adding more booleans (2016-10-11).
|
||||
|
||||
|
@ -150,6 +150,7 @@
|
||||
# define TCB_FLAG_SCHED_OTHER (3 << TCB_FLAG_POLICY_SHIFT) /* Other scheding policy */
|
||||
#define TCB_FLAG_CPU_ASSIGNED (1 << 6) /* Bit 6: Assigned to a CPU */
|
||||
#define TCB_FLAG_EXIT_PROCESSING (1 << 7) /* Bit 7: Exitting */
|
||||
/* Bits 8-15: Available */
|
||||
|
||||
/* Values for struct task_group tg_flags */
|
||||
|
||||
@ -157,6 +158,7 @@
|
||||
#define GROUP_FLAG_ADDRENV (1 << 1) /* Bit 1: Group has an address environment */
|
||||
#define GROUP_FLAG_PRIVILEGED (1 << 2) /* Bit 2: Group is privileged */
|
||||
#define GROUP_FLAG_DELETED (1 << 3) /* Bit 3: Group has been deleted but not yet freed */
|
||||
/* Bits 4-7: Available */
|
||||
|
||||
/* Values for struct child_status_s ch_flags */
|
||||
|
||||
@ -166,12 +168,14 @@
|
||||
# define CHILD_FLAG_TTYPE_PTHREAD (1 << CHILD_FLAG_TTYPE_SHIFT) /* User pthread */
|
||||
# define CHILD_FLAG_TTYPE_KERNEL (2 << CHILD_FLAG_TTYPE_SHIFT) /* Kernel thread */
|
||||
#define CHILD_FLAG_EXITED (1 << 0) /* Bit 2: The child thread has exit'ed */
|
||||
/* Bits 3-7: Available */
|
||||
|
||||
/* Sporadic scheduler flags */
|
||||
|
||||
#define SPORADIC_FLAG_ALLOCED (1 << 0) /* Bit 0: Timer is allocated */
|
||||
#define SPORADIC_FLAG_MAIN (1 << 1) /* Bit 1: The main timer */
|
||||
#define SPORADIC_FLAG_REPLENISH (1 << 2) /* Bit 2: Replenishment cycle */
|
||||
/* Bits 3-7: Available */
|
||||
|
||||
/********************************************************************************
|
||||
* Public Type Definitions
|
||||
@ -191,6 +195,9 @@ enum tstate_e
|
||||
TSTATE_TASK_INVALID = 0, /* INVALID - The TCB is uninitialized */
|
||||
TSTATE_TASK_PENDING, /* READY_TO_RUN - Pending preemption unlock */
|
||||
TSTATE_TASK_READYTORUN, /* READY-TO-RUN - But not running */
|
||||
#ifdef CONFIG_SMP
|
||||
TSTATE_TASK_ASSIGNED, /* READY-TO-RUN - Not running, but assigned to a CPU */
|
||||
#endif
|
||||
TSTATE_TASK_RUNNING, /* READY_TO_RUN - And running */
|
||||
|
||||
TSTATE_TASK_INACTIVE, /* BLOCKED - Initialized but not yet activated */
|
||||
|
@ -203,8 +203,8 @@ volatile pid_t g_lastpid;
|
||||
|
||||
/* The following hash table is used for two things:
|
||||
*
|
||||
* 1. This hash table greatly speeds the determination of
|
||||
* a new unique process ID for a task, and
|
||||
* 1. This hash table greatly speeds the determination of a new unique
|
||||
* process ID for a task, and
|
||||
* 2. Is used to quickly map a process ID into a TCB.
|
||||
* It has the side effects of using more memory and limiting
|
||||
*
|
||||
@ -213,33 +213,74 @@ volatile pid_t g_lastpid;
|
||||
|
||||
struct pidhash_s g_pidhash[CONFIG_MAX_TASKS];
|
||||
|
||||
/* This is a table of task lists. This table is indexed by
|
||||
* the task state enumeration type (tstate_t) and provides
|
||||
* a pointer to the associated static task list (if there
|
||||
* is one) as well as a boolean indication as to if the list
|
||||
* is an ordered list or not.
|
||||
/* This is a table of task lists. This table is indexed by the task stat
|
||||
* enumeration type (tstate_t) and provides a pointer to the associated
|
||||
* static task list (if there is one) as well as a a set of attribute flags
|
||||
* indicating properities of the list, for example, if the list is an
|
||||
* ordered list or not.
|
||||
*/
|
||||
|
||||
const struct tasklist_s g_tasklisttable[NUM_TASK_STATES] =
|
||||
{
|
||||
{ NULL, false }, /* TSTATE_TASK_INVALID */
|
||||
{ &g_pendingtasks, true }, /* TSTATE_TASK_PENDING */
|
||||
{ &g_readytorun, true }, /* TSTATE_TASK_READYTORUN */
|
||||
{ &g_readytorun, true }, /* TSTATE_TASK_RUNNING */
|
||||
{ &g_inactivetasks, false }, /* TSTATE_TASK_INACTIVE */
|
||||
{ &g_waitingforsemaphore, true } /* TSTATE_WAIT_SEM */
|
||||
{ /* TSTATE_TASK_INVALID */
|
||||
NULL,
|
||||
0
|
||||
},
|
||||
{ /* TSTATE_TASK_PENDING */
|
||||
&g_pendingtasks,
|
||||
TLIST_ATTR_PRIORITIZED
|
||||
},
|
||||
{ /* TSTATE_TASK_READYTORUN */
|
||||
&g_readytorun,
|
||||
TLIST_ATTR_PRIORITIZED
|
||||
},
|
||||
#ifdef CONFIG_SMP
|
||||
{ /* TSTATE_TASK_ASSIGNED */
|
||||
g_assignedtasks,
|
||||
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_INDEXED
|
||||
},
|
||||
{ /* TSTATE_TASK_RUNNING */
|
||||
g_assignedtasks,
|
||||
TLIST_ATTR_PRIORITIZED | TLIST_ATTR_INDEXED
|
||||
},
|
||||
#else
|
||||
{ /* TSTATE_TASK_RUNNING */
|
||||
&g_readytorun,
|
||||
TLIST_ATTR_PRIORITIZED
|
||||
},
|
||||
#endif
|
||||
{ /* TSTATE_TASK_INACTIVE */
|
||||
&g_inactivetasks,
|
||||
0
|
||||
},
|
||||
{ /* TSTATE_WAIT_SEM */
|
||||
&g_waitingforsemaphore,
|
||||
TLIST_ATTR_PRIORITIZED
|
||||
}
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
,
|
||||
{ &g_waitingforsignal, false } /* TSTATE_WAIT_SIG */
|
||||
{ /* TSTATE_WAIT_SIG */
|
||||
&g_waitingforsignal,
|
||||
0
|
||||
}
|
||||
#endif
|
||||
#ifndef CONFIG_DISABLE_MQUEUE
|
||||
,
|
||||
{ &g_waitingformqnotempty, true }, /* TSTATE_WAIT_MQNOTEMPTY */
|
||||
{ &g_waitingformqnotfull, true } /* TSTATE_WAIT_MQNOTFULL */
|
||||
{ /* TSTATE_WAIT_MQNOTEMPTY */
|
||||
&g_waitingformqnotempty,
|
||||
TLIST_ATTR_PRIORITIZED
|
||||
},
|
||||
{ /* TSTATE_WAIT_MQNOTFULL */
|
||||
&g_waitingformqnotfull,
|
||||
TLIST_ATTR_PRIORITIZED
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_PAGING
|
||||
,
|
||||
{ &g_waitingforfill, true } /* TSTATE_WAIT_PAGEFILL */
|
||||
{ /* TSTATE_WAIT_PAGEFILL */
|
||||
&g_waitingforfill,
|
||||
TLIST_ATTR_PRIORITIZED
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -360,7 +401,16 @@ void os_start(void)
|
||||
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;
|
||||
|
||||
/* Set the task flags to indicate that this is a kernel thread and, if
|
||||
* configured for SMP, that this task is assigned to CPU0.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
g_idletcb.cmn.flags = (TCB_FLAG_TTYPE_KERNEL | TCB_FLAG_CPU_ASSIGNED);
|
||||
#else
|
||||
g_idletcb.cmn.flags = TCB_FLAG_TTYPE_KERNEL;
|
||||
#endif
|
||||
|
||||
/* Set the IDLE task name */
|
||||
|
||||
|
@ -62,21 +62,44 @@
|
||||
* tasks built into the design).
|
||||
*/
|
||||
|
||||
#define MAX_TASKS_MASK (CONFIG_MAX_TASKS-1)
|
||||
#define PIDHASH(pid) ((pid) & MAX_TASKS_MASK)
|
||||
#define MAX_TASKS_MASK (CONFIG_MAX_TASKS-1)
|
||||
#define PIDHASH(pid) ((pid) & MAX_TASKS_MASK)
|
||||
|
||||
/* These are macros to access the current CPU and the current task on a CPU.
|
||||
* These macros are intended to support a future SMP implementation.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
# define current_task(cpu) ((FAR struct tcb_s *)g_assignedtasks[cpu].head)
|
||||
# define this_cpu() up_cpundx()
|
||||
# define current_task(cpu) ((FAR struct tcb_s *)g_assignedtasks[cpu].head)
|
||||
# define this_cpu() up_cpundx()
|
||||
#else
|
||||
# define current_task(cpu) ((FAR struct tcb_s *)g_readytorun.head)
|
||||
# define this_cpu() (0)
|
||||
# define current_task(cpu) ((FAR struct tcb_s *)g_readytorun.head)
|
||||
# define this_cpu() (0)
|
||||
#endif
|
||||
#define this_task() (current_task(this_cpu()))
|
||||
|
||||
/* List attribute flags */
|
||||
|
||||
#define TLIST_ATTR_PRIORITIZED (1 << 0) /* Bit 0: List is prioritized */
|
||||
#define TLIST_ATTR_INDEXED (1 << 1) /* Bit 1: List is indexed by CPU */
|
||||
|
||||
#define __TLIST_ATTR(s) g_tasklisttable[s].attr
|
||||
#define TLIST_ISPRIORITIZED(s) ((__TLIST_ATTR(s) & TLIST_ATTR_PRIORITIZED) != 0)
|
||||
#define TLIST_ISINDEXED(s) ((__TLIST_ATTR(s) & TLIST_ATTR_INDEXED) != 0)
|
||||
|
||||
#define __TLIST_HEAD(s) (FAR dq_queue_t *)g_tasklisttable[s].list
|
||||
#define __TLIST_HEADINDEXED(s,c) (&(__TLIST_HEAD(s))[c])
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
# define TLIST_HEAD(s,c) \
|
||||
((TLIST_ISINDEXED(s)) ? __TLIST_HEADINDEXED(s,c) : __TLIST_HEAD(s))
|
||||
# define TLIST_READYTORUN(s,c) __TLIST_HEADINDEXED(s,c)
|
||||
# define TLIST_BLOCKED(s) __TLIST_HEAD(s)
|
||||
#else
|
||||
# define TLIST_HEAD(s) __TLIST_HEAD(s)
|
||||
# define TLIST_READYTORUN(s) __TLIST_HEAD(s)
|
||||
# define TLIST_BLOCKED(s) __TLIST_HEAD(s)
|
||||
#endif
|
||||
#define this_task() (current_task(this_cpu()))
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
@ -102,15 +125,14 @@ struct pidhash_s
|
||||
#endif
|
||||
};
|
||||
|
||||
/* This structure defines an element of the g_tasklisttable[].
|
||||
* This table is used to map a task_state enumeration to the
|
||||
* corresponding task list.
|
||||
/* This structure defines an element of the g_tasklisttable[]. This table
|
||||
* is used to map a task_state enumeration to the corresponding task list.
|
||||
*/
|
||||
|
||||
struct tasklist_s
|
||||
{
|
||||
DSEG volatile dq_queue_t *list; /* Pointer to the task list */
|
||||
bool prioritized; /* true if the list is prioritized */
|
||||
uint8_t attr; /* List attribute flags */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -255,10 +277,11 @@ extern volatile pid_t g_lastpid;
|
||||
|
||||
extern struct pidhash_s g_pidhash[CONFIG_MAX_TASKS];
|
||||
|
||||
/* This is a table of task lists. This table is indexed by the task state
|
||||
/* This is a table of task lists. This table is indexed by the task stat
|
||||
* enumeration type (tstate_t) and provides a pointer to the associated
|
||||
* static task list (if there is one) as well as a boolean indication as to
|
||||
* if the list is an ordered list or not.
|
||||
* static task list (if there is one) as well as a a set of attribute flags
|
||||
* indicating properities of the list, for example, if the list is an
|
||||
* ordered list or not.
|
||||
*/
|
||||
|
||||
extern const struct tasklist_s g_tasklisttable[NUM_TASK_STATES];
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/sched/sched_addblocked.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -44,26 +44,6 @@
|
||||
|
||||
#include "sched/sched.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -90,29 +70,30 @@
|
||||
|
||||
void sched_addblocked(FAR struct tcb_s *btcb, tstate_t task_state)
|
||||
{
|
||||
FAR dq_queue_t *tasklist;
|
||||
|
||||
/* Make sure that we received a valid blocked state */
|
||||
|
||||
ASSERT(task_state >= FIRST_BLOCKED_STATE &&
|
||||
task_state <= LAST_BLOCKED_STATE);
|
||||
DEBUGASSERT(task_state >= FIRST_BLOCKED_STATE &&
|
||||
task_state <= LAST_BLOCKED_STATE);
|
||||
|
||||
/* Add the TCB to the blocked task list associated with this state.
|
||||
* First, determine if the task is to be added to a prioritized task
|
||||
* list
|
||||
*/
|
||||
/* Add the TCB to the blocked task list associated with this state. */
|
||||
|
||||
if (g_tasklisttable[task_state].prioritized)
|
||||
tasklist = TLIST_BLOCKED(task_state);
|
||||
|
||||
/* Determine if the task is to be added to a prioritized task list. */
|
||||
|
||||
if (TLIST_ISPRIORITIZED(task_state))
|
||||
{
|
||||
/* Add the task to a prioritized list */
|
||||
|
||||
sched_addprioritized(btcb,
|
||||
(FAR dq_queue_t *)g_tasklisttable[task_state].list);
|
||||
sched_addprioritized(btcb, tasklist);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add the task to a non-prioritized list */
|
||||
|
||||
dq_addlast((FAR dq_entry_t *)btcb,
|
||||
(FAR dq_queue_t *)g_tasklisttable[task_state].list);
|
||||
dq_addlast((FAR dq_entry_t *)btcb, tasklist);
|
||||
}
|
||||
|
||||
/* Make sure the TCB's state corresponds to the list */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/sched/sched_removeblocked.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -44,26 +44,6 @@
|
||||
|
||||
#include "sched/sched.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -93,15 +73,14 @@ void sched_removeblocked(FAR struct tcb_s *btcb)
|
||||
|
||||
/* Make sure the TCB is in a valid blocked state */
|
||||
|
||||
ASSERT(task_state >= FIRST_BLOCKED_STATE &&
|
||||
task_state <= LAST_BLOCKED_STATE);
|
||||
DEBUGASSERT(task_state >= FIRST_BLOCKED_STATE &&
|
||||
task_state <= LAST_BLOCKED_STATE);
|
||||
|
||||
/* Remove the TCB from the blocked task list associated
|
||||
* with this state
|
||||
*/
|
||||
|
||||
dq_rem((FAR dq_entry_t *)btcb,
|
||||
(FAR dq_queue_t *)g_tasklisttable[task_state].list);
|
||||
dq_rem((FAR dq_entry_t *)btcb, TLIST_BLOCKED(task_state));
|
||||
|
||||
/* Make sure the TCB's state corresponds to not being in
|
||||
* any list
|
||||
@ -109,4 +88,3 @@ void sched_removeblocked(FAR struct tcb_s *btcb)
|
||||
|
||||
btcb->task_state = TSTATE_TASK_INVALID;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/sched/sched_setpriority.c
|
||||
*
|
||||
* Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009, 2013, 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -46,30 +46,6 @@
|
||||
|
||||
#include "sched/sched.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -104,6 +80,7 @@
|
||||
int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
FAR dq_queue_t *tasklist;
|
||||
tstate_t task_state;
|
||||
irqstate_t saved_state;
|
||||
|
||||
@ -127,8 +104,8 @@ int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority)
|
||||
task_state = tcb->task_state;
|
||||
switch (task_state)
|
||||
{
|
||||
/* CASE 1. The task is running or ready-to-run and a context switch
|
||||
* may be caused by the re-prioritization
|
||||
/* CASE 1. The task is and a context switch may be caused by the
|
||||
* re-prioritization
|
||||
*/
|
||||
|
||||
case TSTATE_TASK_RUNNING:
|
||||
@ -155,11 +132,14 @@ int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority)
|
||||
}
|
||||
break;
|
||||
|
||||
/* CASE 2. The task is running or ready-to-run and a context switch
|
||||
* may be caused by the re-prioritization
|
||||
/* CASE 2. The task is ready-to-run (but not running) and a context
|
||||
* switch may be caused by the re-prioritization
|
||||
*/
|
||||
|
||||
case TSTATE_TASK_READYTORUN:
|
||||
#ifdef CONFIG_SMP
|
||||
case TSTATE_TASK_ASSIGNED:
|
||||
#endif
|
||||
|
||||
/* A context switch will occur if the new priority of the ready-to
|
||||
* run task is (strictly) greater than the current running task
|
||||
@ -188,7 +168,7 @@ int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority)
|
||||
|
||||
/* Put it back into the ready-to-run task list */
|
||||
|
||||
ASSERT(!sched_addreadytorun(tcb));
|
||||
DEBUGASSERT(!sched_addreadytorun(tcb));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -200,12 +180,12 @@ int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority)
|
||||
|
||||
/* CASE 3a. The task resides in a prioritized list. */
|
||||
|
||||
if (g_tasklisttable[task_state].prioritized)
|
||||
tasklist = TLIST_BLOCKED(task_state);
|
||||
if (TLIST_ISPRIORITIZED(task_state))
|
||||
{
|
||||
/* Remove the TCB from the prioritized task list */
|
||||
|
||||
dq_rem((FAR dq_entry_t *)tcb,
|
||||
(FAR dq_queue_t *)g_tasklisttable[task_state].list);
|
||||
dq_rem((FAR dq_entry_t *)tcb, tasklist);
|
||||
|
||||
/* Change the task priority */
|
||||
|
||||
@ -215,8 +195,7 @@ int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority)
|
||||
* position
|
||||
*/
|
||||
|
||||
sched_addprioritized(tcb,
|
||||
(FAR dq_queue_t *)g_tasklisttable[task_state].list);
|
||||
sched_addprioritized(tcb, tasklist);
|
||||
}
|
||||
|
||||
/* CASE 3b. The task resides in a non-prioritized list. */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/task/task_restart.c
|
||||
*
|
||||
* Copyright (C) 2007, 2009, 2012-2013 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007, 2009, 2012-2013, 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -80,6 +80,7 @@ int task_restart(pid_t pid)
|
||||
{
|
||||
FAR struct tcb_s *rtcb;
|
||||
FAR struct task_tcb_s *tcb;
|
||||
FAR dq_queue_t *tasklist;
|
||||
irqstate_t state;
|
||||
int status;
|
||||
|
||||
@ -100,84 +101,102 @@ int task_restart(pid_t pid)
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* We are restarting some other task than ourselves */
|
||||
#ifdef CONFIG_SMP
|
||||
/* There is currently no capability to restart a task that is actively
|
||||
* running on another CPU either. This is not the calling cast so if it
|
||||
* is running, then it could only be running a a different CPU.
|
||||
*
|
||||
* Also, will need some interlocks to assure that no tasks are rescheduled
|
||||
* on any other CPU while we do this.
|
||||
*/
|
||||
|
||||
else
|
||||
#warning Missing SMP logic
|
||||
if (rtcb->task_state == TSTATE_TASK_RUNNING)
|
||||
{
|
||||
/* Find for the TCB associated with matching pid */
|
||||
/* Not implemented */
|
||||
|
||||
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)
|
||||
set_errno(ENOSYS);
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
/* There is no TCB with this pid or, if there is, it is not a
|
||||
* task.
|
||||
*/
|
||||
|
||||
set_errno(ESRCH);
|
||||
return ERROR;
|
||||
}
|
||||
/* We are restarting some other task than ourselves */
|
||||
/* Find for the TCB associated with matching pid */
|
||||
|
||||
/* Try to recover from any bad states */
|
||||
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 or, if there is, it is not a task. */
|
||||
|
||||
task_recover((FAR struct tcb_s *)tcb);
|
||||
set_errno(ESRCH);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Kill any children of this thread */
|
||||
/* Try to recover from any bad states */
|
||||
|
||||
task_recover((FAR struct tcb_s *)tcb);
|
||||
|
||||
/* Kill any children of this thread */
|
||||
|
||||
#ifdef HAVE_GROUP_MEMBERS
|
||||
(void)group_killchildren(tcb);
|
||||
(void)group_killchildren(tcb);
|
||||
#endif
|
||||
|
||||
/* Remove the TCB from whatever list it is in. At this point, the
|
||||
* TCB should no longer be accessible to the system
|
||||
*/
|
||||
/* Remove the TCB from whatever list it is in. After this point, the TCB
|
||||
* should no longer be accessible to the system
|
||||
*/
|
||||
|
||||
state = irqsave();
|
||||
dq_rem((FAR dq_entry_t *)tcb,
|
||||
(FAR dq_queue_t *)g_tasklisttable[tcb->cmn.task_state].list);
|
||||
tcb->cmn.task_state = TSTATE_TASK_INVALID;
|
||||
irqrestore(state);
|
||||
#ifdef CONFIG_SMP
|
||||
tasklist = TLIST_HEAD(tcb->cmn.task_state, tcb->cmn.cpu);
|
||||
#else
|
||||
tasklist = TLIST_HEAD(tcb->cmn.task_state);
|
||||
#endif
|
||||
|
||||
/* Deallocate anything left in the TCB's queues */
|
||||
state = irqsave();
|
||||
dq_rem((FAR dq_entry_t *)tcb, tasklist);
|
||||
tcb->cmn.task_state = TSTATE_TASK_INVALID;
|
||||
irqrestore(state);
|
||||
|
||||
sig_cleanup((FAR struct tcb_s *)tcb); /* Deallocate Signal lists */
|
||||
/* Deallocate anything left in the TCB's queues */
|
||||
|
||||
/* Reset the current task priority */
|
||||
sig_cleanup((FAR struct tcb_s *)tcb); /* Deallocate Signal lists */
|
||||
|
||||
tcb->cmn.sched_priority = tcb->init_priority;
|
||||
/* Reset the current task priority */
|
||||
|
||||
/* Reset the base task priority and the number of pending reprioritizations */
|
||||
tcb->cmn.sched_priority = tcb->init_priority;
|
||||
|
||||
/* Reset the base task priority and the number of pending reprioritizations */
|
||||
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
tcb->cmn.base_priority = tcb->init_priority;
|
||||
tcb->cmn.base_priority = tcb->init_priority;
|
||||
# if CONFIG_SEM_NNESTPRIO > 0
|
||||
tcb->cmn.npend_reprio = 0;
|
||||
tcb->cmn.npend_reprio = 0;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Re-initialize the processor-specific portion of the TCB
|
||||
* This will reset the entry point and the start-up parameters
|
||||
*/
|
||||
/* Re-initialize the processor-specific portion of the TCB. This will
|
||||
* reset the entry point and the start-up parameters
|
||||
*/
|
||||
|
||||
up_initial_state((FAR struct tcb_s *)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, (FAR dq_queue_t *)&g_inactivetasks);
|
||||
tcb->cmn.task_state = TSTATE_TASK_INACTIVE;
|
||||
dq_addfirst((FAR dq_entry_t *)tcb, (FAR dq_queue_t *)&g_inactivetasks);
|
||||
tcb->cmn.task_state = TSTATE_TASK_INACTIVE;
|
||||
|
||||
/* Activate the task */
|
||||
/* Activate the task */
|
||||
|
||||
status = task_activate((FAR struct tcb_s *)tcb);
|
||||
if (status != OK)
|
||||
{
|
||||
(void)task_delete(pid);
|
||||
set_errno(-status);
|
||||
return ERROR;
|
||||
}
|
||||
status = task_activate((FAR struct tcb_s *)tcb);
|
||||
if (status != OK)
|
||||
{
|
||||
(void)task_delete(pid);
|
||||
set_errno(-status);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* sched/task/task_terminate.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2014 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011-2014, 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -53,30 +53,6 @@
|
||||
#endif
|
||||
#include "task/task.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -124,6 +100,7 @@
|
||||
int task_terminate(pid_t pid, bool nonblocking)
|
||||
{
|
||||
FAR struct tcb_s *dtcb;
|
||||
FAR dq_queue_t *tasklist;
|
||||
irqstate_t saved_state;
|
||||
|
||||
/* Make sure the task does not become ready-to-run while we are futzing with
|
||||
@ -143,6 +120,14 @@ int task_terminate(pid_t pid, bool nonblocking)
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* We will need some interlocks to assure that no tasks are rescheduled
|
||||
* on any other CPU while we do this.
|
||||
*/
|
||||
|
||||
# warning Missing SMP logic
|
||||
#endif
|
||||
|
||||
/* Verify our internal sanity */
|
||||
|
||||
if (dtcb->task_state == TSTATE_TASK_RUNNING ||
|
||||
@ -165,11 +150,16 @@ int task_terminate(pid_t pid, bool nonblocking)
|
||||
|
||||
task_exithook(dtcb, EXIT_SUCCESS, nonblocking);
|
||||
|
||||
/* Remove the task from the OS's tasks lists. */
|
||||
/* Remove the task from the OS's task lists. */
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
tasklist = TLIST_HEAD(dtcb->task_state, dtcb->cpu);
|
||||
#else
|
||||
tasklist = TLIST_HEAD(dtcb->task_state);
|
||||
#endif
|
||||
|
||||
saved_state = irqsave();
|
||||
dq_rem((FAR dq_entry_t *)dtcb,
|
||||
(FAR dq_queue_t *)g_tasklisttable[dtcb->task_state].list);
|
||||
dq_rem((FAR dq_entry_t *)dtcb, tasklist);
|
||||
dtcb->task_state = TSTATE_TASK_INVALID;
|
||||
irqrestore(saved_state);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user