diff --git a/ChangeLog b/ChangeLog index 2afd70cda02..efe8770b8fd 100755 --- a/ChangeLog +++ b/ChangeLog @@ -10756,3 +10756,4 @@ planned scheduling policies (2015-07-23). * pthread_create: Fix an (unlikely) error in fallback value in the event of a failure (which should never occur) (2015-07-23). +* include/, sched/, and libc/: Add support for sporadic scheduling parameters in struct sched_param, posix_spawnattr_t, and pthread_attr_t. Update all user interfaces to pass sporadic scheduling parameters. Feature is dependent on EXPERIMENTAL and no changes have yet been made to core scheduling logic (2015-07-23). diff --git a/include/nuttx/pthread.h b/include/nuttx/pthread.h index 575baed2c68..7528bbda853 100644 --- a/include/nuttx/pthread.h +++ b/include/nuttx/pthread.h @@ -51,13 +51,27 @@ /* Default pthread attribute initializer */ -#define PTHREAD_ATTR_INITIALIZER \ -{ \ - PTHREAD_STACK_DEFAULT, /* stacksize */ \ - PTHREAD_DEFAULT_PRIORITY, /* priority */ \ - SCHED_RR, /* policy */ \ - PTHREAD_EXPLICIT_SCHED, /* inheritsched */ \ -} +#ifdef CONFIG_SCHED_SPORADIC +# define PTHREAD_ATTR_INITIALIZER \ + { \ + PTHREAD_DEFAULT_PRIORITY, /* priority */ \ + SCHED_RR, /* policy */ \ + PTHREAD_EXPLICIT_SCHED, /* inheritsched */ \ + 0, /* low_priority */ \ + 0, /* max_repl */ \ + PTHREAD_STACK_DEFAULT, /* stacksize */ \ + {0, 0}, /* repl_period */ \ + {0, 0}, /* budget */ \ + } +#else +# define PTHREAD_ATTR_INITIALIZER \ + { \ + PTHREAD_DEFAULT_PRIORITY, /* priority */ \ + SCHED_RR, /* policy */ \ + PTHREAD_EXPLICIT_SCHED, /* inheritsched */ \ + PTHREAD_STACK_DEFAULT, /* stacksize */ \ + } +#endif /**************************************************************************** * Public Data diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 192dcdfb766..6ecae9c86f3 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -485,7 +485,8 @@ struct tcb_s uint8_t base_priority; /* "Normal" priority of the thread */ #endif #ifdef CONFIG_SCHED_SPORADIC - int32_t low_priority; /* Sporadic low priority */ + uint8_t low_priority; /* Sporadic low priority */ + uint8_t max_repl; /* Max. replenishments */ #endif uint8_t task_state; /* Current state of the thread */ @@ -498,7 +499,7 @@ struct tcb_s #endif #ifdef CONFIG_SCHED_SPORADIC uint32_t spstart; /* Start time of execution budget */ - uint32_t replen; /* Sporadic replenishment interval */ + uint32_t repl_period; /* Sporadic replenishment period */ uint32_t budget; /* Sporadic execution budget */ #endif diff --git a/include/pthread.h b/include/pthread.h index f2bac8cf709..7a7f1a4ec20 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -1,7 +1,7 @@ /******************************************************************************** * include/pthread.h * - * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -166,10 +166,21 @@ typedef pthread_startroutine_t pthread_func_t; struct pthread_attr_s { - size_t stacksize; /* Size of the stack allocated for the pthread */ - int16_t priority; /* Priority of the pthread */ - uint8_t policy; /* Pthread scheduler policy */ - uint8_t inheritsched; /* Inherit parent prio/policy? */ + uint8_t priority; /* Priority of the pthread */ + uint8_t policy; /* Pthread scheduler policy */ + uint8_t inheritsched; /* Inherit parent prio/policy? */ + +#ifdef CONFIG_SCHED_SPORADIC + uint8_t low_priority; /* Low scheduling priority*/ + uint8_t max_repl; /* Maximum pending replenishments */ +#endif + + size_t stacksize; /* Size of the stack allocated for the pthread */ + +#ifdef CONFIG_SCHED_SPORADIC + struct timespec repl_period; /* Replenishment period */ + struct timespec budget; /* Initial budget */ +#endif }; typedef struct pthread_attr_s pthread_attr_t; diff --git a/include/sched.h b/include/sched.h index f4590aca2d2..cb89b056640 100644 --- a/include/sched.h +++ b/include/sched.h @@ -49,7 +49,6 @@ /******************************************************************************** * Pre-processor Definitions ********************************************************************************/ - /* Task Management Definitions **************************************************/ /* POSIX-like scheduling policies */ @@ -71,7 +70,17 @@ struct sched_param { - int sched_priority; + int sched_priority; /* Base thread priority */ + +#ifdef CONFIG_SCHED_SPORADIC + int sched_ss_low_priority; /* Low scheduling priority for sporadic + * server */ + struct timespec sched_ss_repl_period; /* Replenishment period for sporadic + * server. */ + struct timespec sched_ss_init_budget; /* Initial budget for sporadic server */ + int sched_ss_max_repl; /* Maximum pending replenishments for + * sporadic server. */ +#endif }; /******************************************************************************** diff --git a/include/spawn.h b/include/spawn.h index e47bf47b244..59abfdf11d9 100644 --- a/include/spawn.h +++ b/include/spawn.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/spawn.h * - * Copyright (C) 2013 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 @@ -78,6 +78,7 @@ * because the user will be required to allocate this memory. */ +struct timespec; struct posix_spawnattr_s { /* Used by posix_spawn, posix_spawnp, and task_spawn */ @@ -85,6 +86,12 @@ struct posix_spawnattr_s uint8_t flags; /* See POSIX_SPAWN_ definitions */ uint8_t priority; /* Task scheduling priority */ uint8_t policy; /* Task scheduling policy */ + +#ifdef CONFIG_SCHED_SPORADIC + uint8_t low_priority; /* Low scheduling priority*/ + uint8_t max_repl; /* Maximum pending replenishments */ +#endif + #ifndef CONFIG_DISABLE_SIGNALS sigset_t sigmask; /* Signals to be masked */ #endif @@ -94,6 +101,12 @@ struct posix_spawnattr_s size_t stacksize; /* Task stack size */ #endif + +#ifdef CONFIG_SCHED_SPORADIC + struct timespec repl_period; /* Replenishment period */ + struct timespec budget; /* Initial budget */ +#endif + }; typedef struct posix_spawnattr_s posix_spawnattr_t; diff --git a/include/unistd.h b/include/unistd.h index a0240e9d1b0..7816fb36c38 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -68,31 +68,45 @@ /* POSIX feature set macros */ -#define POSIX_VERSION -#undef _POSIX_SAVED_IDS -#undef _POSIX_JOB_CONTROL -#define _POSIX_REALTIME_SIGNALS 1 -#define _POSIX_MESSAGE_PASSING 1 -#undef _POSIX_MAPPED_FILES -#undef _POSIX_SHARED_MEMORY_OBJECTS -#define _POSIX_PRIORITY_SCHEDULING 1 -#define _POSIX_TIMERS 1 -#undef _POSIX_MEMLOCK -#undef _POSIX_MEMLOCK_RANGE -#undef _POSIX_FSYNC -#define _POSIX_SYNCHRONIZED_IO 1 -#undef _POSIX_ASYNCHRONOUS_IO -#undef _POSIX_PRIORITIZED_IO +#define POSIX_VERSION +#undef _POSIX_SAVED_IDS +#undef _POSIX_JOB_CONTROL +#define _POSIX_REALTIME_SIGNALS 1 +#define _POSIX_MESSAGE_PASSING 1 +#undef _POSIX_MAPPED_FILES +#undef _POSIX_SHARED_MEMORY_OBJECTS +#define _POSIX_PRIORITY_SCHEDULING 1 +#define _POSIX_TIMERS 1 +#undef _POSIX_MEMLOCK +#undef _POSIX_MEMLOCK_RANGE +#undef _POSIX_FSYNC +#define _POSIX_SYNCHRONIZED_IO 1 + +#ifdef CONFIG_FS_AIO +# define _POSIX_ASYNCHRONOUS_IO 1 +#else +# undef _POSIX_ASYNCHRONOUS_IO +#endif + +#undef _POSIX_PRIORITIZED_IO + +#ifdef CONFIG_SCHED_SPORADIC +# define _POSIX_SPORADIC_SERVER 1 +# define _POSIX_THREAD_SPORADIC_SERVER 1 +#else +# undef _POSIX_SPORADIC_SERVER +# undef _POSIX_THREAD_SPORADIC_SERVER +#endif /* Execution time constants (not supported) */ -#undef _POSIX_CHOWN_RESTRICTED -#undef _POSIX_NO_TRUNC -#undef _POSIX_VDISABLE +#undef _POSIX_CHOWN_RESTRICTED +#undef _POSIX_NO_TRUNC +#undef _POSIX_VDISABLE -#define _POSIX_SYNC_IO 1 -#undef _POSIX_ASYNC_IO -#undef _POSIX_PRIO_IO +#define _POSIX_SYNC_IO 1 +#undef _POSIX_ASYNC_IO +#undef _POSIX_PRIO_IO #define fdatasync(f) fsync(f) diff --git a/libc/pthread/pthread_attrgetschedparam.c b/libc/pthread/pthread_attrgetschedparam.c index e15330d319a..ddf67a1d661 100644 --- a/libc/pthread/pthread_attrgetschedparam.c +++ b/libc/pthread/pthread_attrgetschedparam.c @@ -45,26 +45,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -98,13 +78,18 @@ int pthread_attr_getschedparam(FAR const pthread_attr_t *attr, } else { - param->sched_priority = attr->priority; + param->sched_priority = (int)attr->priority; +#ifdef CONFIG_SCHED_SPORADIC + param->sched_ss_low_priority = (int)attr->low_priority; + param->sched_ss_max_repl = (int)attr->max_repl; + param->sched_ss_repl_period.tv_sec = attr->repl_period.tv_sec; + param->sched_ss_repl_period.tv_nsec = attr->repl_period.tv_nsec; + param->sched_ss_init_budget.tv_sec = attr->budget.tv_sec; + param->sched_ss_init_budget.tv_nsec = attr->budget.tv_nsec; +#endif ret = OK; } sdbg("Returning %d\n", ret); return ret; } - - - diff --git a/libc/pthread/pthread_attrsetschedparam.c b/libc/pthread/pthread_attrsetschedparam.c index 9d85cd39dbc..0a06f1b9261 100644 --- a/libc/pthread/pthread_attrsetschedparam.c +++ b/libc/pthread/pthread_attrsetschedparam.c @@ -1,7 +1,7 @@ /**************************************************************************** * libc/pthread/pthread_attrsetschedparam.c * - * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,30 +45,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - /**************************************************************************** * Function: pthread_attr_setschedparam * @@ -86,7 +62,7 @@ ****************************************************************************/ int pthread_attr_setschedparam(FAR pthread_attr_t *attr, - FAR const struct sched_param *param) + FAR const struct sched_param *param) { int ret; @@ -98,11 +74,18 @@ int pthread_attr_setschedparam(FAR pthread_attr_t *attr, } else { - attr->priority = (short)param->sched_priority; + attr->priority = (short)param->sched_priority; +#ifdef CONFIG_SCHED_SPORADIC + attr->low_priority = (uint8_t)param->sched_ss_low_priority; + attr->max_repl = (uint8_t)param->sched_ss_max_repl; + attr->repl_period.tv_sec = param->sched_ss_repl_period.tv_sec; + attr->repl_period.tv_nsec = param->sched_ss_repl_period.tv_nsec; + attr->budget.tv_sec = param->sched_ss_init_budget.tv_sec; + attr->budget.tv_nsec = param->sched_ss_init_budget.tv_nsec; +#endif ret = OK; } + sdbg("Returning %d\n", ret); return ret; } - - diff --git a/libc/spawn/lib_psa_getschedparam.c b/libc/spawn/lib_psa_getschedparam.c index 51b2cb38e59..3a4e48d921c 100644 --- a/libc/spawn/lib_psa_getschedparam.c +++ b/libc/spawn/lib_psa_getschedparam.c @@ -1,7 +1,7 @@ /**************************************************************************** * libc/string/lib_psa_getschedparam.c * - * Copyright (C) 2013 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 @@ -70,5 +70,13 @@ int posix_spawnattr_getschedparam(FAR const posix_spawnattr_t *attr, { DEBUGASSERT(attr && param); param->sched_priority = attr->priority; +#ifdef CONFIG_SCHED_SPORADIC + param->sched_ss_low_priority = (int)attr->low_priority; + param->sched_ss_max_repl = (int)attr->max_repl; + param->sched_ss_repl_period.tv_sec = attr->repl_period.tv_sec; + param->sched_ss_repl_period.tv_nsec = attr->repl_period.tv_nsec; + param->sched_ss_init_budget.tv_sec = attr->budget.tv_sec; + param->sched_ss_init_budget.tv_nsec = attr->budget.tv_nsec; +#endif return OK; } diff --git a/libc/spawn/lib_psa_init.c b/libc/spawn/lib_psa_init.c index afa993179a8..4ee16ff6262 100644 --- a/libc/spawn/lib_psa_init.c +++ b/libc/spawn/lib_psa_init.c @@ -1,7 +1,7 @@ /**************************************************************************** * libc/string/lib_psa_init.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 @@ -88,22 +88,35 @@ int posix_spawnattr_init(posix_spawnattr_t *attr) return errno; } - attr->priority = param.sched_priority; + attr->priority = param.sched_priority; /* Set the default scheduler policy to the policy of this task */ - attr->policy = sched_getscheduler(0); + attr->policy = sched_getscheduler(0); #ifndef CONFIG_DISABLE_SIGNALS - /* Empty signal masek */ + /* Empty signal mask */ - attr->sigmask = 0; + attr->sigmask = 0; #endif +#ifdef CONFIG_SCHED_SPORADIC + /* Sporadic scheduling parameters */ + + attr->low_priority = (uint8_t)param.sched_ss_low_priority; + attr->max_repl = (uint8_t)param.sched_ss_max_repl; + attr->repl_period.tv_sec = param.sched_ss_repl_period.tv_sec; + attr->repl_period.tv_nsec = param.sched_ss_repl_period.tv_nsec; + attr->budget.tv_sec = param.sched_ss_init_budget.tv_sec; + attr->budget.tv_nsec = param.sched_ss_init_budget.tv_nsec; +#endif + + #ifndef CONFIG_ARCH_ADDRENV /* Default stack size */ - attr->stacksize = CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE; + attr->stacksize = CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE; #endif + return OK; } diff --git a/libc/spawn/lib_psa_setschedparam.c b/libc/spawn/lib_psa_setschedparam.c index 5e992e8a92b..3e29ca4937e 100644 --- a/libc/spawn/lib_psa_setschedparam.c +++ b/libc/spawn/lib_psa_setschedparam.c @@ -1,7 +1,7 @@ /**************************************************************************** * libc/string/lib_psa_setschedparam.c * - * Copyright (C) 2013 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 @@ -69,6 +69,16 @@ int posix_spawnattr_setschedparam(FAR posix_spawnattr_t *attr, FAR const struct sched_param *param) { DEBUGASSERT(attr && param && (unsigned)param->sched_priority <= 0xff); - attr->priority = (uint8_t)param->sched_priority; + + attr->priority = (uint8_t)param->sched_priority; + +#ifdef CONFIG_SCHED_SPORADIC + attr->low_priority = (uint8_t)param->sched_ss_low_priority; + attr->max_repl = (uint8_t)param->sched_ss_max_repl; + attr->repl_period.tv_sec = param->sched_ss_repl_period.tv_sec; + attr->repl_period.tv_nsec = param->sched_ss_repl_period.tv_nsec; + attr->budget.tv_sec = param->sched_ss_init_budget.tv_sec; + attr->budget.tv_nsec = param->sched_ss_init_budget.tv_nsec; +#endif return OK; } diff --git a/libc/wqueue/work_usrthread.c b/libc/wqueue/work_usrthread.c index bc679700474..0179ed3c51a 100644 --- a/libc/wqueue/work_usrthread.c +++ b/libc/wqueue/work_usrthread.c @@ -1,7 +1,7 @@ /**************************************************************************** * libc/wqueue/work_usrthread.c * - * Copyright (C) 2009-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -375,7 +375,7 @@ int work_usrstart(void) pthread_t usrwork; pthread_attr_t attr; struct sched_param param; - int status; + int ret; /* Set up the work queue lock */ @@ -386,13 +386,26 @@ int work_usrstart(void) (void)pthread_attr_init(&attr); (void)pthread_attr_setstacksize(&attr, CONFIG_LIB_USRWORKSTACKSIZE); ++#ifdef CONFIG_SCHED_SPORADIC + /* Get the current sporadic scheduling parameters. Those will not be + * modified. + */ + + ret = set_getparam(pid, ¶m); + if (ret < 0) + { + int erroode = get_errno(); + return -errcode; + } +#endif + param.sched_priority = CONFIG_LIB_USRWORKPRIORITY; (void)pthread_attr_setschedparam(&attr, ¶m); - status = pthread_create(&usrwork, &attr, work_usrthread, NULL); - if (status != 0) + ret = pthread_create(&usrwork, &attr, work_usrthread, NULL); + if (ret != 0) { - return -status; + return -ret; } /* Detach because the return value and completion status will not be diff --git a/sched/Kconfig b/sched/Kconfig index a94f2fa3071..6184c9779f4 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -310,6 +310,7 @@ config RR_INTERVAL config SCHED_SPORADIC bool "Support sporadic scheduling" default n + depends on EXPERIMENTAL ---help--- Build in additional logic to support sporadic scheduling (SCHED_SPORADIC). diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index 84a8e7585e9..efd9d10eeda 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -234,10 +234,11 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, { FAR struct pthread_tcb_s *ptcb; FAR struct join_s *pjoin; - int priority; -#if CONFIG_RR_INTERVAL > 0 - int policy; +#ifdef CONFIG_SCHED_SPORADIC + int ticks; #endif + int priority; + int policy; int errcode; pid_t pid; int ret; @@ -315,26 +316,39 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, { struct sched_param param; - /* Get the priority for this thread. */ + /* Get the priority (and any other scheduling parameters) for this + * thread. + */ ret = sched_getparam(0, ¶m); - if (ret == OK) + if (ret == ERROR) { - priority = param.sched_priority; - } - else - { - priority = PTHREAD_DEFAULT_PRIORITY; + errcode = get_errno(); + goto errout_with_join; } -#if CONFIG_RR_INTERVAL > 0 + priority = param.sched_priority; + /* Get the scheduler policy for this thread */ policy = sched_getscheduler(0); if (policy == ERROR) { - policy = SCHED_FIFO; + errcode = get_errno(); + goto errout_with_join; } + +#ifdef CONFIG_SCHED_SPORADIC + /* Save the sporadic scheduling parameters */ + + ptcb->cmn.low_priority = param.sched_ss_low_priority; + ptcb->cmn.max_repl = param.sched_ss_max_repl; + + (void)clock_time2ticks(¶m.sched_ss_repl_period, &ticks); + ptcb->cmn.repl_period = ticks; + + (void)clock_time2ticks(¶m.sched_ss_init_budget, &ticks); + ptcb->cmn.budget = ticks; #endif } else @@ -342,8 +356,19 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, /* Use the priority and scheduler from the attributes */ priority = attr->priority; -#if CONFIG_RR_INTERVAL > 0 policy = attr->policy; + +#ifdef CONFIG_SCHED_SPORADIC + /* Save the sporadic scheduling parameters */ + + ptcb->cmn.low_priority = attr->low_priority; + ptcb->cmn.max_repl = attr->max_repl; + + (void)clock_time2ticks(&attr->repl_period, &ticks); + ptcb->cmn.repl_period = ticks; + + (void)clock_time2ticks(&attr->budget, &ticks); + ptcb->cmn.budget = ticks; #endif } diff --git a/sched/pthread/pthread_getschedparam.c b/sched/pthread/pthread_getschedparam.c index 5671112b832..984902704ce 100644 --- a/sched/pthread/pthread_getschedparam.c +++ b/sched/pthread/pthread_getschedparam.c @@ -1,7 +1,7 @@ /**************************************************************************** * pthread_getschedparam.c * - * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2008, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without diff --git a/sched/pthread/pthread_setschedparam.c b/sched/pthread/pthread_setschedparam.c index e2c1704e2be..8ff54a0227b 100644 --- a/sched/pthread/pthread_setschedparam.c +++ b/sched/pthread/pthread_setschedparam.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread/pthread_setschedparam.c * - * Copyright (C) 2007, 2008, 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2008, 2012, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -118,7 +118,8 @@ * ****************************************************************************/ -int pthread_setschedparam(pthread_t thread, int policy, FAR const struct sched_param *param) +int pthread_setschedparam(pthread_t thread, int policy, + FAR const struct sched_param *param) { int ret; diff --git a/sched/pthread/pthread_setschedprio.c b/sched/pthread/pthread_setschedprio.c index c36ac00862f..7813c5df972 100644 --- a/sched/pthread/pthread_setschedprio.c +++ b/sched/pthread/pthread_setschedprio.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread/pthread_setschedprio.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 @@ -102,20 +102,30 @@ int pthread_setschedprio(pthread_t thread, int prio) struct sched_param param; int ret; - /* Set the errno to some non-zero value (failsafe) */ +#ifdef CONFIG_SCHED_SPORADIC + /* Get the current sporadic scheduling parameters. Those will not be + * modified. + */ - set_errno(EINVAL); + ret = sched_getparam((pid_t)thread, ¶m); + if (ret < 0) + { + goto errout_with_errno; + } +#endif /* Call sched_setparam() to change the priority */ param.sched_priority = prio; ret = sched_setparam((pid_t)thread, ¶m); - if (ret != OK) + if (ret >= 0) { - /* If sched_setparam() fails, return the errno */ - - ret = get_errno(); + return OK; } +#ifdef CONFIG_SCHED_SPORADIC +errout_with_errno: +#endif + ret = get_errno(); return ret; } diff --git a/sched/sched/sched_getparam.c b/sched/sched/sched_getparam.c index 1998e9b162d..a715fb74431 100644 --- a/sched/sched/sched_getparam.c +++ b/sched/sched/sched_getparam.c @@ -1,7 +1,7 @@ /************************************************************************ * sched/sched/sched_getparam.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 @@ -42,6 +42,7 @@ #include #include +#include "clock/clock.h" #include "sched/sched.h" /************************************************************************ @@ -96,7 +97,7 @@ * ************************************************************************/ -int sched_getparam (pid_t pid, struct sched_param * param) +int sched_getparam (pid_t pid, FAR struct sched_param *param) { FAR struct tcb_s *rtcb; FAR struct tcb_s *tcb; @@ -136,6 +137,16 @@ int sched_getparam (pid_t pid, struct sched_param * param) /* Return the priority of the task */ param->sched_priority = (int)tcb->sched_priority; + +#ifdef CONFIG_SCHED_SPORADIC + /* Return parameters associated with SCHED_SPORADIC */ + + param->sched_ss_low_priority = (int)tcb->low_priority; + param->sched_ss_max_repl = (int)tcb->max_repl; + + clock_ticks2time((int)tcb->repl_period, ¶m->sched_ss_repl_period); + clock_ticks2time((int)tcb->budget, ¶m->sched_ss_init_budget); +#endif } sched_unlock(); diff --git a/sched/sched/sched_setparam.c b/sched/sched/sched_setparam.c index 23bb3ca6a29..5ba08d3c97b 100644 --- a/sched/sched/sched_setparam.c +++ b/sched/sched/sched_setparam.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/sched/sched_setparam.c * - * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2013, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -45,6 +45,7 @@ #include +#include "clock/clock.h" #include "sched/sched.h" /**************************************************************************** @@ -105,7 +106,7 @@ * ****************************************************************************/ -int sched_setparam(pid_t pid, const struct sched_param *param) +int sched_setparam(pid_t pid, FAR const struct sched_param *param) { FAR struct tcb_s *rtcb; FAR struct tcb_s *tcb; @@ -148,6 +149,35 @@ int sched_setparam(pid_t pid, const struct sched_param *param) } } +#ifdef CONFIG_SCHED_SPORADIC + /* Update parameters associated with SCHED_SPORADIC */ + + if ((rtcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC) + { + int ticks; + + DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX); + + tcb->flags |= TCB_FLAG_SCHED_SPORADIC; + tcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL); + tcb->low_priority = param->sched_ss_low_priority; + tcb->max_repl = param->sched_ss_max_repl; + + (void)clock_time2ticks(¶m->sched_ss_repl_period, &ticks); + tcb->repl_period = ticks; + + (void)clock_time2ticks(¶m->sched_ss_init_budget, &ticks); + tcb->budget = ticks; + } + else + { + tcb->low_priority = 0; + tcb->max_repl = 0; + tcb->repl_period = 0; + tcb->budget = 0; + } +#endif + /* Then perform the reprioritization */ ret = sched_reprioritize(tcb, param->sched_priority); diff --git a/sched/sched/sched_setscheduler.c b/sched/sched/sched_setscheduler.c index 817b5de1810..d069f59319d 100644 --- a/sched/sched/sched_setscheduler.c +++ b/sched/sched/sched_setscheduler.c @@ -106,7 +106,7 @@ ****************************************************************************/ int sched_setscheduler(pid_t pid, int policy, - const struct sched_param *param) + FAR const struct sched_param *param) { FAR struct tcb_s *tcb; #if CONFIG_RR_INTERVAL > 0 @@ -157,22 +157,53 @@ int sched_setscheduler(pid_t pid, int policy, default: DEBUGPANIC(); case SCHED_FIFO: - tcb->flags |= TCB_FLAG_SCHED_FIFO; -#if CONFIG_RR_INTERVAL > 0 - tcb->timeslice = 0; + { + tcb->flags |= TCB_FLAG_SCHED_FIFO; +#if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC) + tcb->timeslice = 0; #endif +#ifdef CONFIG_SCHED_SPORADIC + tcb->low_priority = 0; + tcb->max_repl = 0; + tcb->repl_period = 0; + tcb->budget = 0; +#endif + } break; #if CONFIG_RR_INTERVAL > 0 case SCHED_RR: - tcb->flags |= TCB_FLAG_SCHED_RR; - tcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL); + { + tcb->flags |= TCB_FLAG_SCHED_RR; + tcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL); +#ifdef CONFIG_SCHED_SPORADIC + tcb->low_priority = 0; + tcb->max_repl = 0; + tcb->repl_period = 0; + tcb->budget = 0; +#endif + } break; #endif #ifdef CONFIG_SCHED_SPORADIC case SCHED_SPORADIC: - tcb->flags |= TCB_FLAG_SCHED_SPORADIC; + { + int ticks; + + DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX); + + tcb->flags |= TCB_FLAG_SCHED_SPORADIC; + tcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL); + tcb->low_priority = param->sched_ss_low_priority; + tcb->max_repl = param->sched_ss_max_repl; + + (void)clock_time2ticks(¶m->sched_ss_repl_period, &ticks); + tcb->repl_period = ticks; + + (void)clock_time2ticks(¶m->sched_ss_init_budget, &ticks); + tcb->budget = ticks; + } break; #endif @@ -199,4 +230,3 @@ int sched_setscheduler(pid_t pid, int policy, return OK; } } - diff --git a/sched/task/task_spawnparms.c b/sched/task/task_spawnparms.c index 20a02d083c2..32be77bd369 100644 --- a/sched/task/task_spawnparms.c +++ b/sched/task/task_spawnparms.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/task/task_spawnparms.c * - * Copyright (C) 2013 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 @@ -111,7 +111,7 @@ static inline int spawn_dup2(FAR struct spawn_dup2_file_action_s *action) int errcode = get_errno(); sdbg("ERROR: dup2 failed: %d\n", errcode); - return errcode; + return -errcode; } return OK; @@ -202,7 +202,7 @@ void spawn_semtake(FAR sem_t *sem) * * Returned Value: * Errors are not reported by this function. This is because errors - * cannot occur, but ratther that the new task has already been started + * cannot occur, but rather that the new task has already been started * so there is no graceful way to handle errors detected in this context * (unless we delete the new task and recover). * @@ -229,7 +229,22 @@ int spawn_execattrs(pid_t pid, FAR const posix_spawnattr_t *attr) if ((attr->flags & POSIX_SPAWN_SETSCHEDPARAM) != 0) { - /* Get the priority from the attrributes */ +#ifdef CONFIG_SCHED_SPORADIC + int ret; + + /* Get the current sporadic scheduling parameters. Those will not be + * modified. + */ + + ret = sched_getparam(pid, ¶m); + if (ret < 0) + { + int errcode = get_errno(); + return -errcode; + } +#endif + + /* Get the priority from the attributes */ param.sched_priority = attr->priority; @@ -265,6 +280,16 @@ int spawn_execattrs(pid_t pid, FAR const posix_spawnattr_t *attr) svdbg("Setting policy=%d priority=%d for pid=%d\n", attr->policy, param.sched_priority, pid); +#ifdef CONFIG_SCHED_SPORADIC + /* But take the sporadic scheduler parameters from the attributes */ + + param.sched_ss_low_priority = (int)attr->low_priority; + param.sched_ss_max_repl = (int)attr->max_repl; + param.sched_ss_repl_period.tv_sec = attr->repl_period.tv_sec; + param.sched_ss_repl_period.tv_nsec = attr->repl_period.tv_nsec; + param.sched_ss_init_budget.tv_sec = attr->budget.tv_sec; + param.sched_ss_init_budget.tv_nsec = attr->budget.tv_nsec; +#endif (void)sched_setscheduler(pid, attr->policy, ¶m); }