TCB: Increase the size of the scheduling policy field from 1 to 2 bits to allow additional, planned scheduling policies

This commit is contained in:
Gregory Nutt 2015-07-23 09:58:41 -06:00
parent bb30fa039f
commit 146bdc3c93
10 changed files with 105 additions and 54 deletions

View File

@ -10751,4 +10751,6 @@
Includes some small improvements. From Max Neklyudov (2015-07-21).
* arch/arm/src/stm32 and include/stm32: Add support for the STMicro
STM32 F446. From David Sidrane (2015-07-22).
* include/nuttx/sched.h, sched/, and fs/procfs: Increase the size of
the scheduling policy field from 1 to 2 bits to allow additional,
planned scheduling policies (2015-07-23).

View File

@ -1,7 +1,7 @@
/****************************************************************************
* fs/procfs/fs_procfsproc.c
*
* Copyright (C) 2013-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2013-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -79,7 +79,7 @@
#define STATUS_LINELEN 32
/****************************************************************************
* Private Types
* Private Type Definitions
****************************************************************************/
/* This enumeration identifies all of the task/thread nodes that can be
* accessed via the procfs file system.
@ -130,6 +130,15 @@ struct proc_dir_s
pid_t pid; /* ID of task/thread for attributes */
};
/****************************************************************************
* Private Data
****************************************************************************/
static FAR const char *g_policy[4] =
{
"SCHED_FIFO", "SCHED_RR", "SCHED_SPORADIC", "SCHED_OTHER"
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@ -351,6 +360,7 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile,
FAR struct tcb_s *tcb, FAR char *buffer,
size_t buflen, off_t offset)
{
FAR const char *policy;
FAR const char *name;
size_t remaining;
size_t linesize;
@ -431,10 +441,11 @@ static ssize_t proc_status(FAR struct proc_file_s *procfile,
return totalsize;
}
/* Show the scheduler */
/* Show the scheduler policy */
policy = g_policy[(tcb->flags & TCB_FLAG_POLICY_MASK) >> TCB_FLAG_POLICY_SHIFT];
linesize = snprintf(procfile->line, STATUS_LINELEN, "%-12s%s\n", "Scheduler:",
tcb->flags & TCB_FLAG_ROUND_ROBIN ? "SCHED_RR" : "SCHED_FIFO");
policy);
copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining, &offset);
totalsize += copysize;

View File

@ -1,7 +1,7 @@
/********************************************************************************
* include/nuttx/sched.h
*
* Copyright (C) 2007-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -134,8 +134,13 @@
# define TCB_FLAG_TTYPE_KERNEL (2 << TCB_FLAG_TTYPE_SHIFT) /* Kernel thread */
#define TCB_FLAG_NONCANCELABLE (1 << 2) /* Bit 2: Pthread is non-cancelable */
#define TCB_FLAG_CANCEL_PENDING (1 << 3) /* Bit 3: Pthread cancel is pending */
#define TCB_FLAG_ROUND_ROBIN (1 << 4) /* Bit 4: Round robin sched enabled */
#define TCB_FLAG_EXIT_PROCESSING (1 << 5) /* Bit 5: Exitting */
#define TCB_FLAG_POLICY_SHIFT (4) /* Bit 4-5: Scheduling policy */
#define TCB_FLAG_POLICY_MASK (3 << TCB_FLAG_POLICY_SHIFT)
# define TCB_FLAG_SCHED_FIFO (0 << TCB_FLAG_POLICY_SHIFT) /* FIFO scheding policy */
# define TCB_FLAG_SCHED_RR (1 << TCB_FLAG_POLICY_SHIFT) /* Round robin scheding policy */
# define TCB_FLAG_SCHED_SPORADIC (2 << TCB_FLAG_POLICY_SHIFT) /* Sporadic scheding policy */
# define TCB_FLAG_SCHED_OTHER (3 << TCB_FLAG_POLICY_SHIFT) /* Other scheding policy */
#define TCB_FLAG_EXIT_PROCESSING (1 << 6) /* Bit 6: Exitting */
/* Values for struct task_group tg_flags */
@ -472,11 +477,11 @@ struct tcb_s
entry_t entry; /* Entry Point into the thread */
uint8_t sched_priority; /* Current priority of the thread */
#ifdef CONFIG_PRIORITY_INHERITANCE
# if CONFIG_SEM_NNESTPRIO > 0
#if defined(CONFIG_PRIORITY_INHERITANCE) && CONFIG_PRIORITY_INHERITANCE > 0
uint8_t npend_reprio; /* Number of nested reprioritizations */
uint8_t pend_reprios[CONFIG_SEM_NNESTPRIO];
# endif
#endif
#if defined(CONFIG_PRIORITY_INHERITANCE)
uint8_t base_priority; /* "Normal" priority of the thread */
#endif
@ -485,8 +490,10 @@ struct tcb_s
int16_t lockcount; /* 0=preemptable (not-locked) */
#if CONFIG_RR_INTERVAL > 0
int timeslice; /* RR timeslice interval remaining */
int32_t timeslice; /* RR timeslice OR Sporadic */
/* replenishment interval remaining */
#endif
FAR struct wdog_s *waitdog; /* All timed waits used this wdog */
/* Stack-Related Fields *******************************************************/

View File

@ -1,7 +1,7 @@
/********************************************************************************
* include/sched.h
*
* Copyright (C) 2007-2009, 2011, 2013 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2011, 2013, 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -56,7 +56,7 @@
#define SCHED_FIFO 1 /* FIFO per priority scheduling policy */
#define SCHED_RR 2 /* Round robin scheduling policy */
#define SCHED_SPORADIC 3 /* Not supported */
#define SCHED_SPORADIC 3 /* Sporadic scheduling policy */
#define SCHED_OTHER 4 /* Not supported */
/* Pthread definitions **********************************************************/

View File

@ -379,18 +379,37 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
ptcb->joininfo = (FAR void *)pjoin;
#if CONFIG_RR_INTERVAL > 0
/* If round robin scheduling is selected, set the appropriate flag
* in the TCB.
*/
/* Set the appropriate scheduling policy in the TCB */
if (policy == SCHED_RR)
ptcb->cmn.flags &= TCB_FLAG_POLICY_MASK;
switch (policy)
{
ptcb->cmn.flags |= TCB_FLAG_ROUND_ROBIN;
ptcb->cmn.timeslice = MSEC2TICK(CONFIG_RR_INTERVAL);
}
default:
DEBUGPANIC();
case SCHED_FIFO:
ptcb->cmn.flags |= TCB_FLAG_SCHED_FIFO;
break;
#if CONFIG_RR_INTERVAL > 0
case SCHED_RR:
ptcb->cmn.flags |= TCB_FLAG_SCHED_RR;
ptcb->cmn.timeslice = MSEC2TICK(CONFIG_RR_INTERVAL);
break;
#endif
#ifdef CONFIG_SCHED_SPORADIC
case SCHED_SPORADIC:
ptcb->cmn.flags |= TCB_FLAG_SCHED_SPORADIC;
break;
#endif
#if 0 /* Not supported */
case SCHED_OTHER:
ptcb->cmn.flags |= TCB_FLAG_SCHED_OTHER;
break;
#endif
}
/* Get the assigned pid before we start the task (who knows what
* could happen to ptcb after this!). Copy this ID into the join structure
* as well.

View File

@ -1,7 +1,7 @@
/************************************************************************
* sched/sched/sched_getscheduler.c
*
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
* Copyright (C) 2007, 2009, 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -100,9 +100,10 @@
int sched_getscheduler(pid_t pid)
{
struct tcb_s *tcb;
FAR struct tcb_s *tcb;
int policy;
/* Verify that the pid corresponds to a real task */
/* Verify that the PID corresponds to a real task */
if (!pid)
{
@ -118,15 +119,11 @@ int sched_getscheduler(pid_t pid)
set_errno(ESRCH);
return ERROR;
}
#if CONFIG_RR_INTERVAL > 0
else if ((tcb->flags & TCB_FLAG_ROUND_ROBIN) != 0)
{
return SCHED_RR;
}
#endif
else
{
return SCHED_FIFO;
}
}
/* Return the scheduling policy from the TCB. NOTE that the user-
* interpretable values are 1 based; the TCB values are zero-based.
*/
policy = (tcb->flags & TCB_FLAG_POLICY_MASK) >> TCB_FLAG_POLICY_SHIFT;
return policy + 1;
}

View File

@ -1,7 +1,7 @@
/************************************************************************
* sched/sched/sched_processtimer.c
*
* Copyright (C) 2007, 2009, 2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2007, 2009, 2014-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -97,7 +97,7 @@ static inline void sched_process_timeslice(void)
* scheduling.
*/
if ((rtcb->flags & TCB_FLAG_ROUND_ROBIN) != 0)
if ((rtcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_RR)
{
/* Yes, check if decrementing the timeslice counter
* would cause the timeslice to expire

View File

@ -1,7 +1,7 @@
/****************************************************************************
* sched/sched/sched_setscheduler.c
*
* Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2007, 2009, 2012, 2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -148,27 +148,42 @@ int sched_setscheduler(pid_t pid, int policy,
sched_lock();
#if CONFIG_RR_INTERVAL > 0
/* Further, disable timer interrupts while we set up scheduling policy. */
saved_state = irqsave();
if (policy == SCHED_RR)
tcb->flags &= TCB_FLAG_POLICY_MASK;
switch (policy)
{
/* Set round robin scheduling */
default:
DEBUGPANIC();
case SCHED_FIFO:
tcb->flags |= TCB_FLAG_SCHED_FIFO;
#if CONFIG_RR_INTERVAL > 0
tcb->timeslice = 0;
#endif
break;
tcb->flags |= TCB_FLAG_ROUND_ROBIN;
tcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL);
}
else
{
/* Set FIFO scheduling */
#if CONFIG_RR_INTERVAL > 0
case SCHED_RR:
tcb->flags |= TCB_FLAG_SCHED_RR;
tcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL);
break;
#endif
tcb->flags &= ~TCB_FLAG_ROUND_ROBIN;
tcb->timeslice = 0;
#ifdef CONFIG_SCHED_SPORADIC
case SCHED_SPORADIC:
tcb->flags |= TCB_FLAG_SCHED_SPORADIC;
break;
#endif
#if 0 /* Not supported */
case SCHED_OTHER:
tcb->flags |= TCB_FLAG_SCHED_OTHER;
break;
#endif
}
irqrestore(saved_state);
#endif
/* Set the new priority */

View File

@ -252,7 +252,7 @@ sched_process_timeslice(unsigned int ticks, bool noswitches)
* scheduling.
*/
if ((rtcb->flags & TCB_FLAG_ROUND_ROBIN) != 0)
if ((rtcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_RR)
{
/* Now much can we decrement the timeslice delay? If 'ticks'
* is greater than the timeslice value, then we ignore any
@ -331,7 +331,7 @@ sched_process_timeslice(unsigned int ticks, bool noswitches)
* supports round robin scheduling.
*/
if ((rtcb->flags & TCB_FLAG_ROUND_ROBIN) != 0)
if ((rtcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_RR)
{
/* The new task at the head of the ready to run
* list does not support round robin scheduling.

View File

@ -132,7 +132,7 @@ int sched_unlock(void)
* timer for the next time slice.
*/
if ((rtcb->flags & TCB_FLAG_ROUND_ROBIN) != 0 &&
if ((rtcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_RR &&
rtcb->timeslice == 0)
{
/* Yes.. that is the situation. But one more thing. The call