Repartition functionality in preparation for nested, pending reprioritization
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1591 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
8e93df66c6
commit
367beee228
17 changed files with 180 additions and 103 deletions
|
@ -109,9 +109,6 @@ void up_reprioritize_rtr(_TCB *tcb, ubyte priority)
|
|||
/* Setup up the new task priority */
|
||||
|
||||
tcb->sched_priority = (ubyte)priority;
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
tcb->base_priority = (ubyte)priority;
|
||||
#endif
|
||||
|
||||
/* Return the task to the specified blocked task list.
|
||||
* sched_addreadytorun will return TRUE if the task was
|
||||
|
|
|
@ -109,9 +109,6 @@ void up_reprioritize_rtr(FAR _TCB *tcb, ubyte priority)
|
|||
/* Setup up the new task priority */
|
||||
|
||||
tcb->sched_priority = (ubyte)priority;
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
tcb->base_priority = (ubyte)priority;
|
||||
#endif
|
||||
|
||||
/* Return the task to the specified blocked task list.
|
||||
* sched_addreadytorun will return TRUE if the task was
|
||||
|
|
|
@ -109,9 +109,6 @@ void up_reprioritize_rtr(_TCB *tcb, ubyte priority)
|
|||
/* Setup up the new task priority */
|
||||
|
||||
tcb->sched_priority = (ubyte)priority;
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
tcb->base_priority = (ubyte)priority;
|
||||
#endif
|
||||
|
||||
/* Return the task to the specified blocked task list.
|
||||
* sched_addreadytorun will return TRUE if the task was
|
||||
|
|
|
@ -109,9 +109,6 @@ void up_reprioritize_rtr(_TCB *tcb, ubyte priority)
|
|||
/* Setup up the new task priority */
|
||||
|
||||
tcb->sched_priority = (ubyte)priority;
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
tcb->base_priority = (ubyte)priority;
|
||||
#endif
|
||||
|
||||
/* Return the task to the specified blocked task list.
|
||||
* sched_addreadytorun will return TRUE if the task was
|
||||
|
|
|
@ -113,9 +113,6 @@ void up_reprioritize_rtr(FAR _TCB *tcb, ubyte priority)
|
|||
/* Setup up the new task priority */
|
||||
|
||||
tcb->sched_priority = (ubyte)priority;
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
tcb->base_priority = (ubyte)priority;
|
||||
#endif
|
||||
|
||||
/* Return the task to the specified blocked task list.
|
||||
* sched_addreadytorun will return TRUE if the task was
|
||||
|
|
|
@ -114,9 +114,6 @@ void up_reprioritize_rtr(FAR _TCB *tcb, ubyte priority)
|
|||
/* Setup up the new task priority */
|
||||
|
||||
tcb->sched_priority = (ubyte)priority;
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
tcb->base_priority = (ubyte)priority;
|
||||
#endif
|
||||
|
||||
/* Return the task to the specified blocked task list.
|
||||
* sched_addreadytorun will return TRUE if the task was
|
||||
|
|
|
@ -237,7 +237,10 @@ static void *lowpri_thread(void *parameter)
|
|||
}
|
||||
else
|
||||
{
|
||||
printf("lowpri_thread: Priority before sem_post: %d\n", sparam.sched_priority);
|
||||
printf("lowpri_thread: %s priority before sem_post: %d\n",
|
||||
sparam.sched_priority != g_highpri ? "ERROR" : "SUCCESS",
|
||||
sparam.sched_priority);
|
||||
|
||||
if (sparam.sched_priority != g_highpri)
|
||||
{
|
||||
printf(" ERROR should have been %d\n", g_highpri);
|
||||
|
@ -252,7 +255,10 @@ static void *lowpri_thread(void *parameter)
|
|||
}
|
||||
else
|
||||
{
|
||||
printf("lowpri_thread: Final priority: %d\n", sparam.sched_priority);
|
||||
printf("lowpri_thread: %s final priority: %d\n",
|
||||
sparam.sched_priority != g_lowpri ? "ERROR" : "SUCCESS",
|
||||
sparam.sched_priority);
|
||||
|
||||
if (sparam.sched_priority != g_lowpri)
|
||||
{
|
||||
printf(" ERROR should have been %d\n", g_lowpri);
|
||||
|
|
|
@ -178,6 +178,10 @@ struct _TCB
|
|||
exitfunc_t exitfunc; /* Called if exit is called. */
|
||||
ubyte sched_priority; /* Current priority of the thread */
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
# if CONFIG_SEM_NNESTPRIO > 0
|
||||
ubyte npend_reprio; /* Number of nested reprioritizations */
|
||||
ubyte pend_reprios[CONFIG_SEM_NNESTPRIO];
|
||||
# endif
|
||||
ubyte base_priority; /* "Normal" priority of the thread */
|
||||
#endif
|
||||
ubyte task_state; /* Current state of the thread */
|
||||
|
|
|
@ -50,11 +50,14 @@ TSK_SRCS = task_create.c task_init.c task_setup.c task_activate.c \
|
|||
sched_mergepending.c sched_addblocked.c sched_removeblocked.c \
|
||||
sched_free.c sched_gettcb.c sched_releasetcb.c
|
||||
|
||||
SCHED_SRCS = sched_setparam.c sched_settcbprio.c sched_getparam.c \
|
||||
SCHED_SRCS = sched_setparam.c sched_setpriority.c sched_getparam.c \
|
||||
sched_setscheduler.c sched_getscheduler.c \
|
||||
sched_yield.c sched_rrgetinterval.c sched_foreach.c \
|
||||
sched_getprioritymax.c sched_getprioritymin.c \
|
||||
sched_lock.c sched_unlock.c sched_lockcount.c
|
||||
ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
|
||||
SEM_SRCS += sched_reprioritize.c
|
||||
endif
|
||||
|
||||
ENV_SRCS = env_getenvironptr.c env_dup.c env_share.c env_release.c \
|
||||
env_findvar.c env_removevar.c \
|
||||
|
|
|
@ -252,7 +252,12 @@ extern boolean sched_addprioritized(FAR _TCB *newTcb,
|
|||
extern boolean sched_mergepending(void);
|
||||
extern void sched_addblocked(FAR _TCB *btcb, tstate_t task_state);
|
||||
extern void sched_removeblocked(FAR _TCB *btcb);
|
||||
extern int sched_settcbprio(FAR _TCB *tcb, int sched_priority);
|
||||
extern int sched_setpriority(FAR _TCB *tcb, int sched_priority);
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
extern int sched_reprioritize(FAR _TCB *tcb, int sched_priority);
|
||||
#else
|
||||
# define sched_reprioritize(tcb,sched_priority) sched_setpriority(tcb,sched_priority)
|
||||
#endif
|
||||
extern FAR _TCB *sched_gettcb(pid_t pid);
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||
|
|
128
sched/sched_reprioritize.c
Normal file
128
sched/sched_reprioritize.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
/****************************************************************************
|
||||
* sched/sched_reprioritize.c
|
||||
*
|
||||
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
#include <sched.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sched_reprioritize
|
||||
*
|
||||
* Description:
|
||||
* This function sets the priority of a specified task.
|
||||
*
|
||||
* NOTE: Setting a task's priority to the same value has a similar
|
||||
* effect to sched_yield() -- The task will be moved to after all other
|
||||
* tasks with the same priority.
|
||||
*
|
||||
* Inputs:
|
||||
* tcb - the TCB of task to reprioritize.
|
||||
* sched_priority - The new task priority
|
||||
*
|
||||
* Return Value:
|
||||
* On success, sched_setparam() returns 0 (OK). On error, -1
|
||||
* (ERROR) is returned, and errno is set appropriately.
|
||||
*
|
||||
* EINVAL The parameter 'param' is invalid or does not make
|
||||
* sense for the current scheduling policy.
|
||||
* EPERM The calling task does not have appropriate privileges.
|
||||
* ESRCH The task whose ID is pid could not be found.
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sched_reprioritize(FAR _TCB *tcb, int sched_priority)
|
||||
{
|
||||
/* This function is equivalent to sched_setpriority() BUT it also has the
|
||||
* side effect of discarding all priority inheritance history. This is
|
||||
* done only on explicit, user-initiated reprioritization.
|
||||
*/
|
||||
|
||||
int ret = sched_setpriority(tcb, sched_priority);
|
||||
if (ret == 0)
|
||||
{
|
||||
/* Reset the base_priority -- the priority that the thread would return
|
||||
* to once it posts the semaphore.
|
||||
*/
|
||||
|
||||
tcb->base_priority = (ubyte)sched_priority;
|
||||
|
||||
/* Discard any pending reprioritizations as well */
|
||||
|
||||
# if CONFIG_SEM_NNESTPRIO > 0
|
||||
tcb->npend_reprio = 0;
|
||||
# endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_PRIORITY_INHERITANCE */
|
|
@ -147,7 +147,7 @@ int sched_setparam(pid_t pid, const struct sched_param *param)
|
|||
|
||||
/* Then perform the reprioritization */
|
||||
|
||||
ret = sched_settcbprio(tcb, param->sched_priority);
|
||||
ret = sched_reprioritize(tcb, param->sched_priority);
|
||||
sched_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* sched/sched_settcbprio.c
|
||||
* sched/sched_setpriority.c
|
||||
*
|
||||
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
@ -73,7 +73,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sched_settcbprio
|
||||
* Name: sched_setpriority
|
||||
*
|
||||
* Description:
|
||||
* This function sets the priority of a specified task.
|
||||
|
@ -99,7 +99,7 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int sched_settcbprio(FAR _TCB *tcb, int sched_priority)
|
||||
int sched_setpriority(FAR _TCB *tcb, int sched_priority)
|
||||
{
|
||||
FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
|
||||
tstate_t task_state;
|
||||
|
@ -150,9 +150,6 @@ int sched_settcbprio(FAR _TCB *tcb, int sched_priority)
|
|||
/* Change the task priority */
|
||||
|
||||
tcb->sched_priority = (ubyte)sched_priority;
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
tcb->base_priority = (ubyte)sched_priority;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -186,9 +183,6 @@ int sched_settcbprio(FAR _TCB *tcb, int sched_priority)
|
|||
/* Change the task priority */
|
||||
|
||||
tcb->sched_priority = (ubyte)sched_priority;
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
tcb->base_priority = (ubyte)sched_priority;
|
||||
#endif
|
||||
|
||||
/* Put it back into the ready-to-run task list */
|
||||
|
||||
|
@ -212,9 +206,6 @@ int sched_settcbprio(FAR _TCB *tcb, int sched_priority)
|
|||
/* Change the task priority */
|
||||
|
||||
tcb->sched_priority = (ubyte)sched_priority;
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
tcb->base_priority = (ubyte)sched_priority;
|
||||
#endif
|
||||
|
||||
/* Put it back into the prioritized list at the correct
|
||||
* position
|
||||
|
@ -230,9 +221,6 @@ int sched_settcbprio(FAR _TCB *tcb, int sched_priority)
|
|||
/* Just change the task's priority */
|
||||
|
||||
tcb->sched_priority = (ubyte)sched_priority;
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
tcb->base_priority = (ubyte)sched_priority;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -240,55 +228,3 @@ int sched_settcbprio(FAR _TCB *tcb, int sched_priority)
|
|||
irqrestore(saved_state);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int sched_setparam(pid_t pid, const struct sched_param *param)
|
||||
{
|
||||
FAR _TCB *rtcb;
|
||||
FAR _TCB *tcb;
|
||||
int ret;
|
||||
|
||||
/* Verify that the requested priority is in the valid range */
|
||||
|
||||
if (!param ||
|
||||
param->sched_priority < SCHED_PRIORITY_MIN ||
|
||||
param->sched_priority > SCHED_PRIORITY_MAX)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Prohibit modifications to the head of the ready-to-run task
|
||||
* list while adjusting the priority
|
||||
*/
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Check if the task to reprioritize is the calling task */
|
||||
|
||||
rtcb = (FAR _TCB*)g_readytorun.head;
|
||||
if (pid == 0 || pid == rtcb->pid)
|
||||
{
|
||||
tcb = rtcb;
|
||||
}
|
||||
|
||||
/* The pid is not the calling task, we will have to search for it */
|
||||
|
||||
else
|
||||
{
|
||||
tcb = sched_gettcb(pid);
|
||||
if (!tcb)
|
||||
{
|
||||
/* No task with this pid was found */
|
||||
|
||||
errno = ESRCH;
|
||||
sched_unlock();
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Then perform the reprioritization */
|
||||
|
||||
ret = sched_settcbprio(tcb, param->sched_priority);
|
||||
sched_unlock();
|
||||
return ret;
|
||||
}
|
|
@ -173,7 +173,7 @@ int sched_setscheduler(pid_t pid, int policy,
|
|||
|
||||
/* Set the new priority */
|
||||
|
||||
ret = sched_settcbprio(tcb, param->sched_priority);
|
||||
ret = sched_reprioritize(tcb, param->sched_priority);
|
||||
sched_unlock();
|
||||
|
||||
if (ret != OK)
|
||||
|
|
|
@ -96,5 +96,5 @@ int sched_yield(void)
|
|||
* be rescheduled behind any other tasks at the same priority.
|
||||
*/
|
||||
|
||||
return sched_settcbprio(rtcb, rtcb->sched_priority);
|
||||
return sched_setpriority(rtcb, rtcb->sched_priority);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
/* Configuration ************************************************************/
|
||||
|
||||
#ifndef CONFIG_SEM_PREALLOCHOLDERS
|
||||
# define CONFIG_SEM_PREALLOCHOLDERS (4*CONFIG_MAX_TASKS)
|
||||
# define CONFIG_SEM_PREALLOCHOLDERS 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -229,7 +229,7 @@ static inline void sem_freeholder(sem_t *sem, FAR struct semholder_s *pholder)
|
|||
|
||||
void sem_initholders(void)
|
||||
{
|
||||
#ifdef CONFIG_SEM_PREALLOCHOLDERS
|
||||
#if CONFIG_SEM_PREALLOCHOLDERS > 0
|
||||
int i;
|
||||
|
||||
/* Put all of the pre-allocated holder structures into free list */
|
||||
|
@ -352,20 +352,19 @@ void sem_boostpriority(sem_t *sem)
|
|||
if (pholder->counts > 0)
|
||||
{
|
||||
htcb = pholder->holder;
|
||||
#if CONFIG_SEM_NNESTPRIO > 0
|
||||
# error "Missing implementation"
|
||||
#else
|
||||
if (htcb && htcb->sched_priority < rtcb->sched_priority)
|
||||
{
|
||||
/* Raise the priority of the holder of the semaphore. This
|
||||
* cannot cause a context switch because we have preemption
|
||||
* disabled. The task will be marked "pending" and the switch
|
||||
* will occur during up_block_task() processing.
|
||||
*
|
||||
* NOTE that we have to restore base_priority because
|
||||
* sched_setparam() should set both.
|
||||
*/
|
||||
|
||||
int base_priority = htcb->base_priority;
|
||||
(void)sched_settcbprio(htcb, rtcb->sched_priority);
|
||||
htcb->base_priority = base_priority;
|
||||
(void)sched_setpriority(htcb, rtcb->sched_priority);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -450,6 +449,9 @@ void sem_restorebaseprio(sem_t *sem)
|
|||
htcb = pholder->holder;
|
||||
if (htcb)
|
||||
{
|
||||
#if CONFIG_SEM_NNESTPRIO > 0
|
||||
# error "Missing implementation"
|
||||
#else
|
||||
/* Was the priority of this thread boosted? NOTE: There is
|
||||
* a logical flaw here: If the thread holds multiple semaphore
|
||||
* and has been boosted multiple times, then there is no mechanism
|
||||
|
@ -461,7 +463,7 @@ void sem_restorebaseprio(sem_t *sem)
|
|||
{
|
||||
up_reprioritize_rtr(rtcb, htcb->base_priority);
|
||||
}
|
||||
|
||||
#endif
|
||||
/* When no more counts are held, remove the holder from the list */
|
||||
|
||||
if (pholder->counts <= 0)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* mkconfig.c
|
||||
* tools/mkconfig.c
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -240,6 +240,17 @@ int main(int argc, char **argv, char **envp)
|
|||
printf("# define CONFIG_NFILE_STREAMS 3\n");
|
||||
printf("# endif\n");
|
||||
printf("#endif\n\n");
|
||||
printf("/* If priority inheritance is disabled, then do not allocate any\n");
|
||||
printf(" * associated resources.\n");
|
||||
printf(" */\n\n");
|
||||
printf("#if !defined(CONFIG_PROIRITY_INHERITANCE) || !defined(CONFIG_SEM_PREALLOCHOLDERSS)\n");
|
||||
printf("# undef CONFIG_SEM_PREALLOCHOLDERS\n");
|
||||
printf("# define CONFIG_SEM_PREALLOCHOLDERSS 0\n");
|
||||
printf("#endif\n\n");
|
||||
printf("#if !defined(CONFIG_PROIRITY_INHERITANCE) || !defined(CONFIG_SEM_NNESTPRIO)\n");
|
||||
printf("# undef CONFIG_SEM_NNESTPRIO\n");
|
||||
printf("# define CONFIG_SEM_NNESTPRIO 0\n");
|
||||
printf("#endif\n\n");
|
||||
printf("/* If no file descriptors are configured, then make certain no\n");
|
||||
printf(" * streams are configured either.\n");
|
||||
printf(" */\n\n");
|
||||
|
|
Loading…
Reference in a new issue