mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 00:14:22 +08:00
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:
@@ -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).
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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];
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user