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:
Gregory Nutt
2016-02-11 08:06:33 -06:00
parent 0a7e136a5a
commit 49227fa554
9 changed files with 232 additions and 202 deletions
+3
View File
@@ -11480,4 +11480,7 @@
* arch/arm/sim/up_head.c and up_simsmp.c: Add multi-CPU support to the * 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 simulation to support SMP investigation.. Currently crashes when CONFIG_SMP
is enabled as expected (2016-02-10). 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).
+7
View File
@@ -150,6 +150,7 @@
# define TCB_FLAG_SCHED_OTHER (3 << TCB_FLAG_POLICY_SHIFT) /* Other scheding policy */ # 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_CPU_ASSIGNED (1 << 6) /* Bit 6: Assigned to a CPU */
#define TCB_FLAG_EXIT_PROCESSING (1 << 7) /* Bit 7: Exitting */ #define TCB_FLAG_EXIT_PROCESSING (1 << 7) /* Bit 7: Exitting */
/* Bits 8-15: Available */
/* Values for struct task_group tg_flags */ /* 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_ADDRENV (1 << 1) /* Bit 1: Group has an address environment */
#define GROUP_FLAG_PRIVILEGED (1 << 2) /* Bit 2: Group is privileged */ #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 */ #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 */ /* 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_PTHREAD (1 << CHILD_FLAG_TTYPE_SHIFT) /* User pthread */
# define CHILD_FLAG_TTYPE_KERNEL (2 << CHILD_FLAG_TTYPE_SHIFT) /* Kernel thread */ # 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 */ #define CHILD_FLAG_EXITED (1 << 0) /* Bit 2: The child thread has exit'ed */
/* Bits 3-7: Available */
/* Sporadic scheduler flags */ /* Sporadic scheduler flags */
#define SPORADIC_FLAG_ALLOCED (1 << 0) /* Bit 0: Timer is allocated */ #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_MAIN (1 << 1) /* Bit 1: The main timer */
#define SPORADIC_FLAG_REPLENISH (1 << 2) /* Bit 2: Replenishment cycle */ #define SPORADIC_FLAG_REPLENISH (1 << 2) /* Bit 2: Replenishment cycle */
/* Bits 3-7: Available */
/******************************************************************************** /********************************************************************************
* Public Type Definitions * Public Type Definitions
@@ -191,6 +195,9 @@ enum tstate_e
TSTATE_TASK_INVALID = 0, /* INVALID - The TCB is uninitialized */ TSTATE_TASK_INVALID = 0, /* INVALID - The TCB is uninitialized */
TSTATE_TASK_PENDING, /* READY_TO_RUN - Pending preemption unlock */ TSTATE_TASK_PENDING, /* READY_TO_RUN - Pending preemption unlock */
TSTATE_TASK_READYTORUN, /* READY-TO-RUN - But not running */ 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_RUNNING, /* READY_TO_RUN - And running */
TSTATE_TASK_INACTIVE, /* BLOCKED - Initialized but not yet activated */ TSTATE_TASK_INACTIVE, /* BLOCKED - Initialized but not yet activated */
+67 -17
View File
@@ -203,8 +203,8 @@ volatile pid_t g_lastpid;
/* The following hash table is used for two things: /* The following hash table is used for two things:
* *
* 1. This hash table greatly speeds the determination of * 1. This hash table greatly speeds the determination of a new unique
* a new unique process ID for a task, and * process ID for a task, and
* 2. Is used to quickly map a process ID into a TCB. * 2. Is used to quickly map a process ID into a TCB.
* It has the side effects of using more memory and limiting * 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]; struct pidhash_s g_pidhash[CONFIG_MAX_TASKS];
/* This is a table of task lists. This table is indexed by /* This is a table of task lists. This table is indexed by the task stat
* the task state enumeration type (tstate_t) and provides * enumeration type (tstate_t) and provides a pointer to the associated
* a pointer to the associated static task list (if there * static task list (if there is one) as well as a a set of attribute flags
* is one) as well as a boolean indication as to if the list * indicating properities of the list, for example, if the list is an
* is an ordered list or not. * ordered list or not.
*/ */
const struct tasklist_s g_tasklisttable[NUM_TASK_STATES] = const struct tasklist_s g_tasklisttable[NUM_TASK_STATES] =
{ {
{ NULL, false }, /* TSTATE_TASK_INVALID */ { /* TSTATE_TASK_INVALID */
{ &g_pendingtasks, true }, /* TSTATE_TASK_PENDING */ NULL,
{ &g_readytorun, true }, /* TSTATE_TASK_READYTORUN */ 0
{ &g_readytorun, true }, /* TSTATE_TASK_RUNNING */ },
{ &g_inactivetasks, false }, /* TSTATE_TASK_INACTIVE */ { /* TSTATE_TASK_PENDING */
{ &g_waitingforsemaphore, true } /* TSTATE_WAIT_SEM */ &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 #ifndef CONFIG_DISABLE_SIGNALS
, ,
{ &g_waitingforsignal, false } /* TSTATE_WAIT_SIG */ { /* TSTATE_WAIT_SIG */
&g_waitingforsignal,
0
}
#endif #endif
#ifndef CONFIG_DISABLE_MQUEUE #ifndef CONFIG_DISABLE_MQUEUE
, ,
{ &g_waitingformqnotempty, true }, /* TSTATE_WAIT_MQNOTEMPTY */ { /* TSTATE_WAIT_MQNOTEMPTY */
{ &g_waitingformqnotfull, true } /* TSTATE_WAIT_MQNOTFULL */ &g_waitingformqnotempty,
TLIST_ATTR_PRIORITIZED
},
{ /* TSTATE_WAIT_MQNOTFULL */
&g_waitingformqnotfull,
TLIST_ATTR_PRIORITIZED
}
#endif #endif
#ifdef CONFIG_PAGING #ifdef CONFIG_PAGING
, ,
{ &g_waitingforfill, true } /* TSTATE_WAIT_PAGEFILL */ { /* TSTATE_WAIT_PAGEFILL */
&g_waitingforfill,
TLIST_ATTR_PRIORITIZED
}
#endif #endif
}; };
@@ -360,7 +401,16 @@ void os_start(void)
bzero((void *)&g_idletcb, sizeof(struct task_tcb_s)); bzero((void *)&g_idletcb, sizeof(struct task_tcb_s));
g_idletcb.cmn.task_state = TSTATE_TASK_RUNNING; g_idletcb.cmn.task_state = TSTATE_TASK_RUNNING;
g_idletcb.cmn.entry.main = (main_t)os_start; 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; g_idletcb.cmn.flags = TCB_FLAG_TTYPE_KERNEL;
#endif
/* Set the IDLE task name */ /* Set the IDLE task name */
+37 -14
View File
@@ -62,21 +62,44 @@
* tasks built into the design). * tasks built into the design).
*/ */
#define MAX_TASKS_MASK (CONFIG_MAX_TASKS-1) #define MAX_TASKS_MASK (CONFIG_MAX_TASKS-1)
#define PIDHASH(pid) ((pid) & MAX_TASKS_MASK) #define PIDHASH(pid) ((pid) & MAX_TASKS_MASK)
/* These are macros to access the current CPU and the current task on a CPU. /* 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. * These macros are intended to support a future SMP implementation.
*/ */
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
# define current_task(cpu) ((FAR struct tcb_s *)g_assignedtasks[cpu].head) # define current_task(cpu) ((FAR struct tcb_s *)g_assignedtasks[cpu].head)
# define this_cpu() up_cpundx() # define this_cpu() up_cpundx()
#else #else
# define current_task(cpu) ((FAR struct tcb_s *)g_readytorun.head) # define current_task(cpu) ((FAR struct tcb_s *)g_readytorun.head)
# define this_cpu() (0) # 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 #endif
#define this_task() (current_task(this_cpu()))
/**************************************************************************** /****************************************************************************
* Public Type Definitions * Public Type Definitions
@@ -102,15 +125,14 @@ struct pidhash_s
#endif #endif
}; };
/* This structure defines an element of the g_tasklisttable[]. /* This structure defines an element of the g_tasklisttable[]. This table
* This table is used to map a task_state enumeration to the * is used to map a task_state enumeration to the corresponding task list.
* corresponding task list.
*/ */
struct tasklist_s struct tasklist_s
{ {
DSEG volatile dq_queue_t *list; /* Pointer to the task list */ 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]; 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 * 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 * static task list (if there is one) as well as a a set of attribute flags
* if the list is an ordered list or not. * 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]; extern const struct tasklist_s g_tasklisttable[NUM_TASK_STATES];
+13 -32
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* sched/sched/sched_addblocked.c * 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> * 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
@@ -44,26 +44,6 @@
#include "sched/sched.h" #include "sched/sched.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Variables
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@@ -90,29 +70,30 @@
void sched_addblocked(FAR struct tcb_s *btcb, tstate_t task_state) 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 */ /* Make sure that we received a valid blocked state */
ASSERT(task_state >= FIRST_BLOCKED_STATE && DEBUGASSERT(task_state >= FIRST_BLOCKED_STATE &&
task_state <= LAST_BLOCKED_STATE); task_state <= LAST_BLOCKED_STATE);
/* Add the TCB to the blocked task list associated with this 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
*/
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 */ /* Add the task to a prioritized list */
sched_addprioritized(btcb, sched_addprioritized(btcb, tasklist);
(FAR dq_queue_t *)g_tasklisttable[task_state].list);
} }
else else
{ {
/* Add the task to a non-prioritized list */ /* Add the task to a non-prioritized list */
dq_addlast((FAR dq_entry_t *)btcb, dq_addlast((FAR dq_entry_t *)btcb, tasklist);
(FAR dq_queue_t *)g_tasklisttable[task_state].list);
} }
/* Make sure the TCB's state corresponds to the list */ /* Make sure the TCB's state corresponds to the list */
+4 -26
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* sched/sched/sched_removeblocked.c * 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> * 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
@@ -44,26 +44,6 @@
#include "sched/sched.h" #include "sched/sched.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Variables
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@@ -93,15 +73,14 @@ void sched_removeblocked(FAR struct tcb_s *btcb)
/* Make sure the TCB is in a valid blocked state */ /* Make sure the TCB is in a valid blocked state */
ASSERT(task_state >= FIRST_BLOCKED_STATE && DEBUGASSERT(task_state >= FIRST_BLOCKED_STATE &&
task_state <= LAST_BLOCKED_STATE); task_state <= LAST_BLOCKED_STATE);
/* Remove the TCB from the blocked task list associated /* Remove the TCB from the blocked task list associated
* with this state * with this state
*/ */
dq_rem((FAR dq_entry_t *)btcb, dq_rem((FAR dq_entry_t *)btcb, TLIST_BLOCKED(task_state));
(FAR dq_queue_t *)g_tasklisttable[task_state].list);
/* Make sure the TCB's state corresponds to not being in /* Make sure the TCB's state corresponds to not being in
* any list * any list
@@ -109,4 +88,3 @@ void sched_removeblocked(FAR struct tcb_s *btcb)
btcb->task_state = TSTATE_TASK_INVALID; btcb->task_state = TSTATE_TASK_INVALID;
} }
+14 -35
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* sched/sched/sched_setpriority.c * 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> * 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
@@ -46,30 +46,6 @@
#include "sched/sched.h" #include "sched/sched.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Variables
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@@ -104,6 +80,7 @@
int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority) int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority)
{ {
FAR struct tcb_s *rtcb = this_task(); FAR struct tcb_s *rtcb = this_task();
FAR dq_queue_t *tasklist;
tstate_t task_state; tstate_t task_state;
irqstate_t saved_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; task_state = tcb->task_state;
switch (task_state) switch (task_state)
{ {
/* CASE 1. The task is running or ready-to-run and a context switch /* CASE 1. The task is and a context switch may be caused by the
* may be caused by the re-prioritization * re-prioritization
*/ */
case TSTATE_TASK_RUNNING: case TSTATE_TASK_RUNNING:
@@ -155,11 +132,14 @@ int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority)
} }
break; break;
/* CASE 2. The task is running or ready-to-run and a context switch /* CASE 2. The task is ready-to-run (but not running) and a context
* may be caused by the re-prioritization * switch may be caused by the re-prioritization
*/ */
case TSTATE_TASK_READYTORUN: 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 /* A context switch will occur if the new priority of the ready-to
* run task is (strictly) greater than the current running task * 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 */ /* Put it back into the ready-to-run task list */
ASSERT(!sched_addreadytorun(tcb)); DEBUGASSERT(!sched_addreadytorun(tcb));
} }
break; 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. */ /* 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 */ /* Remove the TCB from the prioritized task list */
dq_rem((FAR dq_entry_t *)tcb, dq_rem((FAR dq_entry_t *)tcb, tasklist);
(FAR dq_queue_t *)g_tasklisttable[task_state].list);
/* Change the task priority */ /* Change the task priority */
@@ -215,8 +195,7 @@ int sched_setpriority(FAR struct tcb_s *tcb, int sched_priority)
* position * position
*/ */
sched_addprioritized(tcb, sched_addprioritized(tcb, tasklist);
(FAR dq_queue_t *)g_tasklisttable[task_state].list);
} }
/* CASE 3b. The task resides in a non-prioritized list. */ /* CASE 3b. The task resides in a non-prioritized list. */
+69 -50
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* sched/task/task_restart.c * 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> * 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
@@ -80,6 +80,7 @@ int task_restart(pid_t pid)
{ {
FAR struct tcb_s *rtcb; FAR struct tcb_s *rtcb;
FAR struct task_tcb_s *tcb; FAR struct task_tcb_s *tcb;
FAR dq_queue_t *tasklist;
irqstate_t state; irqstate_t state;
int status; int status;
@@ -100,84 +101,102 @@ int task_restart(pid_t pid)
return ERROR; 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); set_errno(ENOSYS);
#ifndef CONFIG_DISABLE_PTHREAD return ERROR;
if (!tcb || (tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD) }
#else
if (!tcb)
#endif #endif
{
/* There is no TCB with this pid or, if there is, it is not a
* task.
*/
set_errno(ESRCH); /* We are restarting some other task than ourselves */
return ERROR; /* 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 #ifdef HAVE_GROUP_MEMBERS
(void)group_killchildren(tcb); (void)group_killchildren(tcb);
#endif #endif
/* Remove the TCB from whatever list it is in. At this point, the /* Remove the TCB from whatever list it is in. After this point, the TCB
* TCB should no longer be accessible to the system * should no longer be accessible to the system
*/ */
state = irqsave(); #ifdef CONFIG_SMP
dq_rem((FAR dq_entry_t *)tcb, tasklist = TLIST_HEAD(tcb->cmn.task_state, tcb->cmn.cpu);
(FAR dq_queue_t *)g_tasklisttable[tcb->cmn.task_state].list); #else
tcb->cmn.task_state = TSTATE_TASK_INVALID; tasklist = TLIST_HEAD(tcb->cmn.task_state);
irqrestore(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 #ifdef CONFIG_PRIORITY_INHERITANCE
tcb->cmn.base_priority = tcb->init_priority; tcb->cmn.base_priority = tcb->init_priority;
# if CONFIG_SEM_NNESTPRIO > 0 # if CONFIG_SEM_NNESTPRIO > 0
tcb->cmn.npend_reprio = 0; tcb->cmn.npend_reprio = 0;
# endif # endif
#endif #endif
/* Re-initialize the processor-specific portion of the TCB /* Re-initialize the processor-specific portion of the TCB. This will
* This will reset the entry point and the start-up parameters * 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); dq_addfirst((FAR dq_entry_t *)tcb, (FAR dq_queue_t *)&g_inactivetasks);
tcb->cmn.task_state = TSTATE_TASK_INACTIVE; tcb->cmn.task_state = TSTATE_TASK_INACTIVE;
/* Activate the task */ /* Activate the task */
status = task_activate((FAR struct tcb_s *)tcb); status = task_activate((FAR struct tcb_s *)tcb);
if (status != OK) if (status != OK)
{ {
(void)task_delete(pid); (void)task_delete(pid);
set_errno(-status); set_errno(-status);
return ERROR; return ERROR;
}
} }
sched_unlock(); sched_unlock();
+18 -28
View File
@@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* sched/task/task_terminate.c * 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> * 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
@@ -53,30 +53,6 @@
#endif #endif
#include "task/task.h" #include "task/task.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Variables
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@@ -124,6 +100,7 @@
int task_terminate(pid_t pid, bool nonblocking) int task_terminate(pid_t pid, bool nonblocking)
{ {
FAR struct tcb_s *dtcb; FAR struct tcb_s *dtcb;
FAR dq_queue_t *tasklist;
irqstate_t saved_state; irqstate_t saved_state;
/* Make sure the task does not become ready-to-run while we are futzing with /* 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; 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 */ /* Verify our internal sanity */
if (dtcb->task_state == TSTATE_TASK_RUNNING || 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); 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(); saved_state = irqsave();
dq_rem((FAR dq_entry_t *)dtcb, dq_rem((FAR dq_entry_t *)dtcb, tasklist);
(FAR dq_queue_t *)g_tasklisttable[dtcb->task_state].list);
dtcb->task_state = TSTATE_TASK_INVALID; dtcb->task_state = TSTATE_TASK_INVALID;
irqrestore(saved_state); irqrestore(saved_state);