From 92d3022411f363fce0f925a5b0a66d773e0560f9 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 2 Nov 2016 09:05:18 -0600 Subject: [PATCH] Add pthread_mutexattr_get/set_protocol and non-standard sem_get/set_protocol. These may use to enable or disable priority inheritance on a single semaphore. --- include/nuttx/semaphore.h | 3 +- include/pthread.h | 26 ++++- include/semaphore.h | 23 +++- include/sys/syscall.h | 18 ++- libc/pthread/Make.defs | 4 + libc/pthread/pthread_attr_destroy.c | 3 +- libc/pthread/pthread_mutexattr_destroy.c | 1 - libc/pthread/pthread_mutexattr_getprotocol.c | 73 ++++++++++++ libc/pthread/pthread_mutexattr_setprotocol.c | 79 +++++++++++++ libc/semaphore/sem_init.c | 23 +--- sched/pthread/pthread_mutexinit.c | 27 ++++- sched/semaphore/Make.defs | 3 + sched/semaphore/sem_getprotocol.c | 85 ++++++++++++++ sched/semaphore/sem_holder.c | 26 +++-- sched/semaphore/sem_setprotocol.c | 110 +++++++++++++++++++ syscall/syscall.csv | 2 + syscall/syscall_lookup.h | 7 +- syscall/syscall_stublookup.c | 3 + 18 files changed, 465 insertions(+), 51 deletions(-) create mode 100644 libc/pthread/pthread_mutexattr_getprotocol.c create mode 100644 libc/pthread/pthread_mutexattr_setprotocol.c create mode 100644 sched/semaphore/sem_getprotocol.c create mode 100644 sched/semaphore/sem_setprotocol.c diff --git a/include/nuttx/semaphore.h b/include/nuttx/semaphore.h index 4a5bb32d32..1d0afca38e 100644 --- a/include/nuttx/semaphore.h +++ b/include/nuttx/semaphore.h @@ -61,12 +61,13 @@ struct inode; struct nsem_inode_s { + sem_t ns_sem; /* The contained semaphore */ + /* Inode payload unique to named semaphores. ns_inode must appear first * in this structure in order to support casting between type sem_t and * types of struct nsem_inode_s. */ FAR struct inode *ns_inode; /* Containing inode */ - sem_t ns_sem; /* The semaphore */ }; #endif diff --git a/include/pthread.h b/include/pthread.h index 64228154f7..e25e63d41f 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -135,6 +135,12 @@ #define PTHREAD_BARRIER_SERIAL_THREAD 0x1000 +/* Values for protocol attribute */ + +#define PTHREAD_PRIO_NONE SEM_PRIO_NONE +#define PTHREAD_PRIO_INHERIT SEM_PRIO_INHERIT +#define PTHREAD_PRIO_PROTECT SEM_PRIO_PROTECT + /* Definitions to map some non-standard, BSD thread management interfaces to * the non-standard Linux-like prctl() interface. Since these are simple * mappings to prctl, they will return 0 on success and -1 on failure with the @@ -212,6 +218,9 @@ typedef struct pthread_cond_s pthread_cond_t; struct pthread_mutexattr_s { uint8_t pshared; /* PTHREAD_PROCESS_PRIVATE or PTHREAD_PROCESS_SHARED */ +#ifdef CONFIG_PRIORITY_INHERITANCE + uint8_t proto; /* See PTHREAD_PRIO_* definitions */ +#endif #ifdef CONFIG_MUTEX_TYPES uint8_t type; /* Type of the mutex. See PTHREAD_MUTEX_* definitions */ #endif @@ -222,11 +231,11 @@ typedef struct pthread_mutexattr_s pthread_mutexattr_t; struct pthread_mutex_s { - int pid; /* ID of the holder of the mutex */ - sem_t sem; /* Semaphore underlying the implementation of the mutex */ + int pid; /* ID of the holder of the mutex */ + sem_t sem; /* Semaphore underlying the implementation of the mutex */ #ifdef CONFIG_MUTEX_TYPES - uint8_t type; /* Type of the mutex. See PTHREAD_MUTEX_* definitions */ - int nlocks; /* The number of recursive locks held */ + uint8_t type; /* Type of the mutex. See PTHREAD_MUTEX_* definitions */ + int nlocks; /* The number of recursive locks held */ #endif }; @@ -395,6 +404,15 @@ int pthread_mutex_lock(FAR pthread_mutex_t *mutex); int pthread_mutex_trylock(FAR pthread_mutex_t *mutex); int pthread_mutex_unlock(FAR pthread_mutex_t *mutex); +#ifdef CONFIG_PRIORITY_INHERITANCE +/* Manage priority inheritance */ + +int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr, + FAR int *protocol); +int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr, + int protocol); +#endif + /* Operations on condition variables */ int pthread_condattr_init(FAR pthread_condattr_t *attr); diff --git a/include/semaphore.h b/include/semaphore.h index 142ef51ada..41db9caa8b 100644 --- a/include/semaphore.h +++ b/include/semaphore.h @@ -57,6 +57,17 @@ extern "C" * Pre-processor Definitions ****************************************************************************/ +/* Values for protocol attribute */ + +#define SEM_PRIO_NONE 0 +#define SEM_PRIO_INHERIT 1 +#define SEM_PRIO_PROTECT 2 + +/* Bit definitions for the struct sem_s flags field */ + +#define PRIOINHERIT_FLAGS_DISABLE (1 << 0) /* Bit 0: Priority inheritance + * is disabled for this semaphore. */ + /**************************************************************************** * Public Type Declarations ****************************************************************************/ @@ -92,6 +103,7 @@ struct sem_s */ #ifdef CONFIG_PRIORITY_INHERITANCE + uint8_t flags; /* See PRIOINHERIT_FLAGS_* definitions */ # if CONFIG_SEM_PREALLOCHOLDERS > 0 FAR struct semholder_s *hhead; /* List of holders of semaphore counts */ # else @@ -106,9 +118,9 @@ typedef struct sem_s sem_t; #ifdef CONFIG_PRIORITY_INHERITANCE # if CONFIG_SEM_PREALLOCHOLDERS > 0 -# define SEM_INITIALIZER(c) {(c), NULL} /* semcount, hhead */ +# define SEM_INITIALIZER(c) {(c), 0, NULL} /* semcount, flags, hhead */ # else -# define SEM_INITIALIZER(c) {(c), SEMHOLDER_INITIALIZER} /* semcount, holder */ +# define SEM_INITIALIZER(c) {(c), 0, SEMHOLDER_INITIALIZER} /* semcount, flags, holder */ # endif #else # define SEM_INITIALIZER(c) {(c)} /* semcount */ @@ -141,6 +153,13 @@ int sem_close(FAR sem_t *sem); int sem_unlink(FAR const char *name); #endif +#ifdef CONFIG_PRIORITY_INHERITANCE +/* Non-standard interfaces to manage priority inheritance */ + +int sem_getprotocol(FAR sem_t *sem, FAR int *protocol); +int sem_setprotocol(FAR sem_t *sem, int protocol); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/include/sys/syscall.h b/include/sys/syscall.h index 2fba44de34..134b2cb27d 100644 --- a/include/sys/syscall.h +++ b/include/sys/syscall.h @@ -91,15 +91,23 @@ #define SYS_sem_trywait (CONFIG_SYS_RESERVED+18) #define SYS_sem_wait (CONFIG_SYS_RESERVED+19) +#ifdef CONFIG_PRIORITY_INHERITANCE +# define SYS_sem_getprotocol (CONFIG_SYS_RESERVED+20) +# define SYS_sem_setprotocol (CONFIG_SYS_RESERVED+21) +# define __SYS_named_sem (CONFIG_SYS_RESERVED+22) +#else +# define __SYS_named_sem (CONFIG_SYS_RESERVED+20) +#endif + /* Named semaphores */ #ifdef CONFIG_FS_NAMED_SEMAPHORES -# define SYS_sem_open (CONFIG_SYS_RESERVED+20) -# define SYS_sem_close (CONFIG_SYS_RESERVED+21) -# define SYS_sem_unlink (CONFIG_SYS_RESERVED+22) -# define __SYS_task_create (CONFIG_SYS_RESERVED+23) +# define SYS_sem_open __SYS_named_sem +# define SYS_sem_close (__SYS_named_sem+1) +# define SYS_sem_unlink (__SYS_named_sem+2) +# define __SYS_task_create (__SYS_named_sem+3) #else -# define __SYS_task_create (CONFIG_SYS_RESERVED+20) +# define __SYS_task_create __SYS_named_sem #endif /* Task creation APIs based on global entry points cannot be use with diff --git a/libc/pthread/Make.defs b/libc/pthread/Make.defs index 0d783c07fd..9d343f6052 100644 --- a/libc/pthread/Make.defs +++ b/libc/pthread/Make.defs @@ -54,6 +54,10 @@ ifeq ($(CONFIG_MUTEX_TYPES),y) CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c endif +ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) +CSRCS += pthread_mutexattr_setprotocol.c pthread_mutexattr_getprotocol.c +endif + ifeq ($(CONFIG_BUILD_PROTECTED),y) CSRCS += pthread_startup.c endif diff --git a/libc/pthread/pthread_attr_destroy.c b/libc/pthread/pthread_attr_destroy.c index 084946cf72..7d39a19278 100644 --- a/libc/pthread/pthread_attr_destroy.c +++ b/libc/pthread/pthread_attr_destroy.c @@ -52,8 +52,7 @@ * Function: pthread_attr_destroy * * Description: - * An attributes object can be deleted when it is no longer - * needed. + * An attributes object can be deleted when it is no longer needed. * * Parameters: * attr diff --git a/libc/pthread/pthread_mutexattr_destroy.c b/libc/pthread/pthread_mutexattr_destroy.c index a5ada87790..62d5de4a92 100644 --- a/libc/pthread/pthread_mutexattr_destroy.c +++ b/libc/pthread/pthread_mutexattr_destroy.c @@ -55,7 +55,6 @@ * * Parameters: * attr - * pshared * * Return Value: * 0 if successful. Otherwise, an error code. diff --git a/libc/pthread/pthread_mutexattr_getprotocol.c b/libc/pthread/pthread_mutexattr_getprotocol.c new file mode 100644 index 0000000000..f7851855ac --- /dev/null +++ b/libc/pthread/pthread_mutexattr_getprotocol.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * libc/pthread/pthread_mutexattr_getprotocol.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: pthread_mutexattr_getprotocol + * + * Description: + * Return the value of the mutex protocol attribute. + * + * Parameters: + * attr - A pointer to the mutex attributes to be queried. + * protocol - The user provided location in which to store the protocol + * value. + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + ****************************************************************************/ + +int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr, + FAR int *protocol) +{ + DEBUGASSERT(attr != NULL && protocol != NULL); + + linfo("Returning %d\n", attr->proto); + return attr->proto; +} diff --git a/libc/pthread/pthread_mutexattr_setprotocol.c b/libc/pthread/pthread_mutexattr_setprotocol.c new file mode 100644 index 0000000000..621a94d1c1 --- /dev/null +++ b/libc/pthread/pthread_mutexattr_setprotocol.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * libc/pthread/pthread_mutexattr_setprotocol.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: pthread_mutexattr_setprotocol + * + * Description: + * Set mutex protocol attribute. + * + * Parameters: + * attr - A pointer to the mutex attributes to be modified + * protocol - The new protocol to use + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + ****************************************************************************/ + +int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr, + int protocol) +{ + linfo("attr=0x%p protocol=%d\n", attr, protocol); + DEBUGASSERT(attr != NULL); + + if (protocol >= PTHREAD_PRIO_NONE && protocol <= PTHREAD_PRIO_PROTECT) + { + attr->proto = protocol; + return OK; + } + + return EINVAL; +} diff --git a/libc/semaphore/sem_init.c b/libc/semaphore/sem_init.c index 861acb6cde..f4037d342c 100644 --- a/libc/semaphore/sem_init.c +++ b/libc/semaphore/sem_init.c @@ -1,7 +1,7 @@ /**************************************************************************** * libc/sem/sem_init.c * - * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,26 +44,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -108,6 +88,7 @@ int sem_init(FAR sem_t *sem, int pshared, unsigned int value) /* Initialize to support priority inheritance */ #ifdef CONFIG_PRIORITY_INHERITANCE + sem->flags = 0; # if CONFIG_SEM_PREALLOCHOLDERS > 0 sem->hhead = NULL; # else diff --git a/sched/pthread/pthread_mutexinit.c b/sched/pthread/pthread_mutexinit.c index 31d18e2f46..0c65fbc7ed 100644 --- a/sched/pthread/pthread_mutexinit.c +++ b/sched/pthread/pthread_mutexinit.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread/pthread_mutexinit.c * - * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -66,13 +66,17 @@ * ****************************************************************************/ -int pthread_mutex_init(FAR pthread_mutex_t *mutex, FAR const pthread_mutexattr_t *attr) +int pthread_mutex_init(FAR pthread_mutex_t *mutex, + FAR const pthread_mutexattr_t *attr) { int pshared = 0; #ifdef CONFIG_MUTEX_TYPES - uint8_t type = PTHREAD_MUTEX_DEFAULT; + uint8_t type = PTHREAD_MUTEX_DEFAULT; #endif - int ret = OK; +#ifdef CONFIG_PRIORITY_INHERITANCE + uint8_t proto = PTHREAD_PRIO_INHERIT; +#endif + int ret = OK; int status; sinfo("mutex=0x%p attr=0x%p\n", mutex, attr); @@ -88,6 +92,9 @@ int pthread_mutex_init(FAR pthread_mutex_t *mutex, FAR const pthread_mutexattr_t if (attr) { pshared = attr->pshared; +#ifdef CONFIG_PRIORITY_INHERITANCE + proto = attr->proto; +#endif #ifdef CONFIG_MUTEX_TYPES type = attr->type; #endif @@ -102,9 +109,19 @@ int pthread_mutex_init(FAR pthread_mutex_t *mutex, FAR const pthread_mutexattr_t status = sem_init((FAR sem_t *)&mutex->sem, pshared, 1); if (status != OK) { - ret = EINVAL; + ret = get_errno(); } +#ifdef CONFIG_PRIORITY_INHERITANCE + /* Initialize the semaphore protocol */ + + status = sem_setprotocol((FAR sem_t *)&mutex->sem, proto); + if (status != OK) + { + ret = get_errno(); + } +#endif + /* Set up attributes unique to the mutex type */ #ifdef CONFIG_MUTEX_TYPES diff --git a/sched/semaphore/Make.defs b/sched/semaphore/Make.defs index 39ba7cd2dc..70b9e356bd 100644 --- a/sched/semaphore/Make.defs +++ b/sched/semaphore/Make.defs @@ -33,12 +33,15 @@ # ############################################################################ +# Add semaphore-related files to the build + CSRCS += sem_destroy.c sem_wait.c sem_trywait.c sem_tickwait.c CSRCS += sem_timedwait.c sem_timeout.c sem_post.c sem_recover.c CSRCS += sem_reset.c sem_waitirq.c ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) CSRCS += sem_initialize.c sem_holder.c +CSRCS += sem_setprotocol.c sem_getprotocol.c endif ifeq ($(CONFIG_SPINLOCK),y) diff --git a/sched/semaphore/sem_getprotocol.c b/sched/semaphore/sem_getprotocol.c new file mode 100644 index 0000000000..f3dc169e6e --- /dev/null +++ b/sched/semaphore/sem_getprotocol.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * sched/semaphore/sem_getprotocol.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#include "semaphore/semaphore.h" + +#ifdef CONFIG_PRIORITY_INHERITANCE + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: sem_getprotocol + * + * Description: + * Return the value of the semaphore protocol attribute. + * + * Parameters: + * sem - A pointer to the semaphore whose attributes are to be + * queried. + * protocol - The user provided location in which to store the protocol + * value. + * + * Return Value: + * 0 if successful. Otherwise, -1 is returned and the errno value is set + * appropriately. + * + ****************************************************************************/ + +int sem_getprotocol(FAR sem_t *sem, FAR int *protocol) +{ + DEBUGASSERT(sem != NULL); + + if ((sem->flags & PRIOINHERIT_FLAGS_DISABLE) != 0) + { + return SEM_PRIO_NONE; + } + else + { + return SEM_PRIO_INHERIT; + } +} + +#endif /* CONFIG_PRIORITY_INHERITANCE */ diff --git a/sched/semaphore/sem_holder.c b/sched/semaphore/sem_holder.c index 769444fd99..6b9f05af3e 100644 --- a/sched/semaphore/sem_holder.c +++ b/sched/semaphore/sem_holder.c @@ -790,7 +790,7 @@ void sem_initholders(void) * Name: sem_destroyholder * * Description: - * Called from sem_destroy() to handle any holders of a semaphore when + * Called from sem_destroyholder() to handle any holders of a semaphore when * it is destroyed. * * Parameters: @@ -855,17 +855,25 @@ void sem_addholder_tcb(FAR struct tcb_s *htcb, FAR sem_t *sem) { FAR struct semholder_s *pholder; - /* Find or allocate a container for this new holder */ + /* If priority inheritance is disabled for this thread, then do not add + * the holder. If there are never holders of the semaphore, the priority + * inheritance is effectively disabled. + */ - pholder = sem_findorallocateholder(sem, htcb); - if (pholder != NULL) + if ((sem->flags & PRIOINHERIT_FLAGS_DISABLE) == 0) { - /* Then set the holder and increment the number of counts held by this - * holder - */ + /* Find or allocate a container for this new holder */ - pholder->htcb = htcb; - pholder->counts++; + pholder = sem_findorallocateholder(sem, htcb); + if (pholder != NULL) + { + /* Then set the holder and increment the number of counts held by this + * holder + */ + + pholder->htcb = htcb; + pholder->counts++; + } } } diff --git a/sched/semaphore/sem_setprotocol.c b/sched/semaphore/sem_setprotocol.c new file mode 100644 index 0000000000..c5609fdcd5 --- /dev/null +++ b/sched/semaphore/sem_setprotocol.c @@ -0,0 +1,110 @@ +/**************************************************************************** + * sched/semaphore/sem_setprotocol.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include + +#include "semaphore/semaphore.h" + +#ifdef CONFIG_PRIORITY_INHERITANCE + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: sem_setprotocol + * + * Description: + * Set semaphore protocol attribute. + * + * Parameters: + * sem - A pointer to the semaphore whose attributes are to be + * modified + * protocol - The new protocol to use + * + * Return Value: + * 0 if successful. Otherwise, -1 is returned and the errno value is set + * appropriately. + * + ****************************************************************************/ + +int sem_setprotocol(FAR sem_t *sem, int protocol) +{ + int errcode; + + DEBUGASSERT(sem != NULL); + + switch (protocol) + { + case SEM_PRIO_NONE: + /* Disable priority inheritance */ + + sem->flags |= PRIOINHERIT_FLAGS_DISABLE; + + /* Remove any current holders */ + + sem_destroyholder(sem); + return OK; + + case SEM_PRIO_INHERIT: + /* Enable priority inheritance (dangerous) */ + + sem->flags &= ~PRIOINHERIT_FLAGS_DISABLE; + return OK; + + case SEM_PRIO_PROTECT: + /* Not yet supported */ + + errcode = ENOSYS; + break; + + default: + errcode = EINVAL; + break; + } + + set_errno(errcode); + return ERROR; +} + +#endif /* CONFIG_PRIORITY_INHERITANCE */ diff --git a/syscall/syscall.csv b/syscall/syscall.csv index c1fdd2e291..b745998c4b 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -117,7 +117,9 @@ "sem_close","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR sem_t*" "sem_destroy","semaphore.h","","int","FAR sem_t*" "sem_open","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","FAR sem_t*","FAR const char*","int","..." +"sem_getprotocol","semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t*","FAR int*" "sem_post","semaphore.h","","int","FAR sem_t*" +"sem_setprotocol","semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t*","int" "sem_timedwait","semaphore.h","","int","FAR sem_t*","FAR const struct timespec *" "sem_trywait","semaphore.h","","int","FAR sem_t*" "sem_unlink","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR const char*" diff --git a/syscall/syscall_lookup.h b/syscall/syscall_lookup.h index d0f304fbad..e3506707d8 100644 --- a/syscall/syscall_lookup.h +++ b/syscall/syscall_lookup.h @@ -61,12 +61,17 @@ SYSCALL_LOOKUP(uname, 1, STUB_uname) /* Semaphores */ -SYSCALL_LOOKUP(sem_destroy, 2, STUB_sem_destroy) +SYSCALL_LOOKUP(sem_destroy, 1, STUB_sem_destroy) SYSCALL_LOOKUP(sem_post, 1, STUB_sem_post) SYSCALL_LOOKUP(sem_timedwait, 2, STUB_sem_timedwait) SYSCALL_LOOKUP(sem_trywait, 1, STUB_sem_trywait) SYSCALL_LOOKUP(sem_wait, 1, STUB_sem_wait) +#ifdef CONFIG_PRIORITY_INHERITANCE +SYSCALL_LOOKUP(sem_getprotocol, 2, STUB_sem_getprotocol) +SYSCALL_LOOKUP(sem_setprotocol, 2, STUB_sem_setprotocol) +#endif + /* Named semaphores */ #ifdef CONFIG_FS_NAMED_SEMAPHORES diff --git a/syscall/syscall_stublookup.c b/syscall/syscall_stublookup.c index 868eca6f13..996763daea 100644 --- a/syscall/syscall_stublookup.c +++ b/syscall/syscall_stublookup.c @@ -82,13 +82,16 @@ uintptr_t STUB_uname(int nbr, uintptr_t parm1); uintptr_t STUB_sem_close(int nbr, uintptr_t parm1); uintptr_t STUB_sem_destroy(int nbr, uintptr_t parm1); +uintptr_t STUB_sem_getprotocol(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_sem_open(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, uintptr_t parm4, uintptr_t parm5, uintptr_t parm6); uintptr_t STUB_sem_post(int nbr, uintptr_t parm1); +uintptr_t STUB_sem_setprotocol(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_sem_timedwait(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_sem_trywait(int nbr, uintptr_t parm1); uintptr_t STUB_sem_unlink(int nbr, uintptr_t parm1); uintptr_t STUB_sem_wait(int nbr, uintptr_t parm1); + uintptr_t STUB_pgalloc(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_task_create(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, uintptr_t parm4, uintptr_t parm5);