From 146bdc3c93d7803810f9479913aa831e71765999 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 23 Jul 2015 09:58:41 -0600 Subject: [PATCH] TCB: Increase the size of the scheduling policy field from 1 to 2 bits to allow additional, planned scheduling policies --- ChangeLog | 4 ++- fs/procfs/fs_procfsproc.c | 19 ++++++++++--- include/nuttx/sched.h | 21 ++++++++++----- include/sched.h | 4 +-- sched/pthread/pthread_create.c | 35 ++++++++++++++++++------ sched/sched/sched_getscheduler.c | 25 ++++++++---------- sched/sched/sched_processtimer.c | 4 +-- sched/sched/sched_setscheduler.c | 41 ++++++++++++++++++++--------- sched/sched/sched_timerexpiration.c | 4 +-- sched/sched/sched_unlock.c | 2 +- 10 files changed, 105 insertions(+), 54 deletions(-) diff --git a/ChangeLog b/ChangeLog index 899b9babb3..f703c10365 100755 --- a/ChangeLog +++ b/ChangeLog @@ -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). diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c index 2e1a514298..869d00f9b4 100644 --- a/fs/procfs/fs_procfsproc.c +++ b/fs/procfs/fs_procfsproc.c @@ -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 * * 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; diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index fa08107116..fac3e81368 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -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 * * 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 *******************************************************/ diff --git a/include/sched.h b/include/sched.h index a0f296e14b..f4590aca2d 100644 --- a/include/sched.h +++ b/include/sched.h @@ -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 * * 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 **********************************************************/ diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index 70fb902591..5ce91934c5 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -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. diff --git a/sched/sched/sched_getscheduler.c b/sched/sched/sched_getscheduler.c index 9bf29a0f3a..58714df155 100644 --- a/sched/sched/sched_getscheduler.c +++ b/sched/sched/sched_getscheduler.c @@ -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 * * 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; +} diff --git a/sched/sched/sched_processtimer.c b/sched/sched/sched_processtimer.c index 3c31a25598..8e2340973b 100644 --- a/sched/sched/sched_processtimer.c +++ b/sched/sched/sched_processtimer.c @@ -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 * * 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 diff --git a/sched/sched/sched_setscheduler.c b/sched/sched/sched_setscheduler.c index c73c9bd382..817b5de181 100644 --- a/sched/sched/sched_setscheduler.c +++ b/sched/sched/sched_setscheduler.c @@ -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 * * 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 */ diff --git a/sched/sched/sched_timerexpiration.c b/sched/sched/sched_timerexpiration.c index e990f0b571..3ad7608854 100644 --- a/sched/sched/sched_timerexpiration.c +++ b/sched/sched/sched_timerexpiration.c @@ -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. diff --git a/sched/sched/sched_unlock.c b/sched/sched/sched_unlock.c index 2673d32af6..15b161245c 100644 --- a/sched/sched/sched_unlock.c +++ b/sched/sched/sched_unlock.c @@ -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