From eb308b9a2ee32eb1b882baaa0ab78bab8446411b Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Thu, 6 Apr 2017 09:31:18 +0900 Subject: [PATCH] kernel/semaphore: add new APIs for priority inheritance This commit introduces new APIs, pthread_mutexattr_get/set_protocol and non-standard sem_get/set_protocol, which allow to enable or disable priority inheritance on a single semaphore. Backported from NuttX. All credits should go to Gregory Nutt who wrote the original patch. Change-Id: I05c62a6a4ee6fbdb00b0478bf8ef8cfe44487f92 Signed-off-by: Gregory Nutt [Shin: backported 92d30224 from the upstream] Signed-off-by: Heesub Shin --- lib/libc/pthread/Make.defs | 4 + lib/libc/pthread/pthread_attrdestroy.c | 3 +- lib/libc/pthread/pthread_mutexattr_getprotocol.c | 90 ++++++++++++++++ lib/libc/pthread/pthread_mutexattr_setprotocol.c | 96 +++++++++++++++++ lib/libc/pthread/pthread_mutexattrdestroy.c | 1 - lib/libc/semaphore/sem_init.c | 23 +---- os/include/pthread.h | 29 ++++-- os/include/semaphore.h | 22 +++- os/include/sys/syscall.h | 18 +++- os/include/tinyara/semaphore.h | 4 +- os/kernel/pthread/pthread_mutexinit.c | 22 +++- os/kernel/semaphore/Make.defs | 3 + os/kernel/semaphore/sem_getprotocol.c | 99 ++++++++++++++++++ os/kernel/semaphore/sem_holder.c | 29 ++++-- os/kernel/semaphore/sem_setprotocol.c | 126 +++++++++++++++++++++++ os/syscall/syscall.csv | 2 + os/syscall/syscall_lookup.h | 7 +- os/syscall/syscall_stublookup.c | 2 + 18 files changed, 526 insertions(+), 54 deletions(-) create mode 100644 lib/libc/pthread/pthread_mutexattr_getprotocol.c create mode 100644 lib/libc/pthread/pthread_mutexattr_setprotocol.c create mode 100644 os/kernel/semaphore/sem_getprotocol.c create mode 100644 os/kernel/semaphore/sem_setprotocol.c diff --git a/lib/libc/pthread/Make.defs b/lib/libc/pthread/Make.defs index 8bfe2a3..c463822 100644 --- a/lib/libc/pthread/Make.defs +++ b/lib/libc/pthread/Make.defs @@ -73,6 +73,10 @@ ifeq ($(CONFIG_MUTEX_TYPES),y) CSRCS += pthread_mutexattrsettype.c pthread_mutexattrgettype.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/lib/libc/pthread/pthread_attrdestroy.c b/lib/libc/pthread/pthread_attrdestroy.c index e8b52ce..1adb1fb 100644 --- a/lib/libc/pthread/pthread_attrdestroy.c +++ b/lib/libc/pthread/pthread_attrdestroy.c @@ -89,8 +89,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/lib/libc/pthread/pthread_mutexattr_getprotocol.c b/lib/libc/pthread/pthread_mutexattr_getprotocol.c new file mode 100644 index 0000000..ca0eba8 --- /dev/null +++ b/lib/libc/pthread/pthread_mutexattr_getprotocol.c @@ -0,0 +1,90 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ +/**************************************************************************** + * lib/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/lib/libc/pthread/pthread_mutexattr_setprotocol.c b/lib/libc/pthread/pthread_mutexattr_setprotocol.c new file mode 100644 index 0000000..17da81f --- /dev/null +++ b/lib/libc/pthread/pthread_mutexattr_setprotocol.c @@ -0,0 +1,96 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ +/**************************************************************************** + * lib/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/lib/libc/pthread/pthread_mutexattrdestroy.c b/lib/libc/pthread/pthread_mutexattrdestroy.c index d51a41c..f1cd2fb 100644 --- a/lib/libc/pthread/pthread_mutexattrdestroy.c +++ b/lib/libc/pthread/pthread_mutexattrdestroy.c @@ -92,7 +92,6 @@ * * Parameters: * attr - * pshared * * Return Value: * 0 if successful. Otherwise, an error code. diff --git a/lib/libc/semaphore/sem_init.c b/lib/libc/semaphore/sem_init.c index 2ace638..5c88821 100644 --- a/lib/libc/semaphore/sem_init.c +++ b/lib/libc/semaphore/sem_init.c @@ -18,7 +18,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 @@ -62,26 +62,6 @@ #include /**************************************************************************** - * Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** * Public Functions ****************************************************************************/ @@ -124,6 +104,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/os/include/pthread.h b/os/include/pthread.h index 86cd666..4506a84 100644 --- a/os/include/pthread.h +++ b/os/include/pthread.h @@ -163,6 +163,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 @@ -248,9 +254,12 @@ typedef struct pthread_cond_s pthread_cond_t; * @brief Structure of pthread mutex attr configuration */ struct pthread_mutexattr_s { - uint8_t pshared; /* PTHREAD_PROCESS_PRIVATE or PTHREAD_PROCESS_SHARED */ + 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 */ + uint8_t type; /* Type of the mutex. See PTHREAD_MUTEX_* definitions */ #endif }; typedef struct pthread_mutexattr_s pthread_mutexattr_t; @@ -260,11 +269,11 @@ typedef struct pthread_mutexattr_s pthread_mutexattr_t; * @brief Structure of pthread mutex configuration */ 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 }; typedef struct pthread_mutex_s pthread_mutex_t; @@ -516,6 +525,14 @@ 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 + /* A thread can create and delete condition variables. */ /** * @ingroup PTHREAD_KERNEL diff --git a/os/include/semaphore.h b/os/include/semaphore.h index 057584c..ede02a3 100644 --- a/os/include/semaphore.h +++ b/os/include/semaphore.h @@ -80,6 +80,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 ****************************************************************************/ @@ -119,6 +130,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 @@ -136,9 +148,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 */ @@ -224,6 +236,12 @@ 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/os/include/sys/syscall.h b/os/include/sys/syscall.h index bbeb053..acfb022 100644 --- a/os/include/sys/syscall.h +++ b/os/include/sys/syscall.h @@ -107,15 +107,23 @@ #define SYS_sem_trywait (CONFIG_SYS_RESERVED+17) #define SYS_sem_wait (CONFIG_SYS_RESERVED+18) +#ifdef CONFIG_PRIORITY_INHERITANCE +#define SYS_sem_getprotocol (CONFIG_SYS_RESERVED+19) +#define SYS_sem_setprotocol (CONFIG_SYS_RESERVED+20) +#define __SYS_named_sem (CONFIG_SYS_RESERVED+21) +#else +#define __SYS_named_sem (CONFIG_SYS_RESERVED+19) +#endif + /* Named semaphores */ #ifdef CONFIG_FS_NAMED_SEMAPHORES -#define SYS_sem_open (CONFIG_SYS_RESERVED+19) -#define SYS_sem_close (CONFIG_SYS_RESERVED+20) -#define SYS_sem_unlink (CONFIG_SYS_RESERVED+21) -#define __SYS_task_create (CONFIG_SYS_RESERVED+22) +#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+19) +#define __SYS_task_create (__SYS_named_sem) #endif /* Task creation APIs based on global entry points cannot be use with diff --git a/os/include/tinyara/semaphore.h b/os/include/tinyara/semaphore.h index 1a6cc1f..4e57f4e 100644 --- a/os/include/tinyara/semaphore.h +++ b/os/include/tinyara/semaphore.h @@ -75,11 +75,11 @@ struct inode; struct nsem_inode_s { + sem_t ns_sem; /* The contained semaphore */ + /* Inode payload unique to named semaphores */ FAR struct inode *ns_inode; /* Containing inode */ - sem_t ns_sem; /* The semaphore */ - }; #endif diff --git a/os/kernel/pthread/pthread_mutexinit.c b/os/kernel/pthread/pthread_mutexinit.c index 6acc635..28778e4 100644 --- a/os/kernel/pthread/pthread_mutexinit.c +++ b/os/kernel/pthread/pthread_mutexinit.c @@ -18,7 +18,7 @@ /**************************************************************************** * kernel/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 @@ -103,12 +103,16 @@ * ****************************************************************************/ -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; #endif +#ifdef CONFIG_PRIORITY_INHERITANCE + uint8_t proto = PTHREAD_PRIO_INHERIT; +#endif int ret = OK; int status; @@ -121,6 +125,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 @@ -134,9 +141,18 @@ int pthread_mutex_init(FAR pthread_mutex_t *mutex, FAR const pthread_mutexattr_t status = sem_init((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/os/kernel/semaphore/Make.defs b/os/kernel/semaphore/Make.defs index 616f241..691fc78 100644 --- a/os/kernel/semaphore/Make.defs +++ b/os/kernel/semaphore/Make.defs @@ -50,11 +50,14 @@ # ############################################################################ +# Add semaphore-related files to the build + CSRCS += sem_destroy.c sem_wait.c sem_trywait.c sem_timedwait.c CSRCS += sem_post.c sem_recover.c 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 # Include semaphore build support diff --git a/os/kernel/semaphore/sem_getprotocol.c b/os/kernel/semaphore/sem_getprotocol.c new file mode 100644 index 0000000..ee3715d --- /dev/null +++ b/os/kernel/semaphore/sem_getprotocol.c @@ -0,0 +1,99 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ +/**************************************************************************** + * ./kernel/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/os/kernel/semaphore/sem_holder.c b/os/kernel/semaphore/sem_holder.c index 127fd9f..eb1cfe7 100644 --- a/os/kernel/semaphore/sem_holder.c +++ b/os/kernel/semaphore/sem_holder.c @@ -756,8 +756,8 @@ void sem_initholders(void) * Name: sem_destroyholder * * Description: - * Called from sem_destroy() to handle any holders of a semaphore when - * it is destroyed. + * Called from sem_destroyholder() to handle any holders of a semaphore + * when it is destroyed. * * Parameters: * sem - A reference to the semaphore being destroyed @@ -818,16 +818,23 @@ 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 */ - - pholder = sem_findorallocateholder(sem, htcb); - if (pholder != NULL) { - /* Then set the holder and increment the number of counts held by this - * 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->htcb = htcb; - pholder->counts++; + if ((sem->flags & PRIOINHERIT_FLAGS_DISABLE) == 0) { + /* Find or allocate a container for this new holder */ + 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/os/kernel/semaphore/sem_setprotocol.c b/os/kernel/semaphore/sem_setprotocol.c new file mode 100644 index 0000000..fce2738 --- /dev/null +++ b/os/kernel/semaphore/sem_setprotocol.c @@ -0,0 +1,126 @@ +/**************************************************************************** + * + * Copyright 2017 Samsung Electronics All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + * + ****************************************************************************/ +/**************************************************************************** + * kernel/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/os/syscall/syscall.csv b/os/syscall/syscall.csv index 2774aa9..ade159d 100644 --- a/os/syscall/syscall.csv +++ b/os/syscall/syscall.csv @@ -112,7 +112,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/os/syscall/syscall_lookup.h b/os/syscall/syscall_lookup.h index 313bc67..f2e9500 100644 --- a/os/syscall/syscall_lookup.h +++ b/os/syscall/syscall_lookup.h @@ -77,12 +77,17 @@ SYSCALL_LOOKUP(set_errno, 1, STUB_set_errno) /* 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/os/syscall/syscall_stublookup.c b/os/syscall/syscall_stublookup.c index f5dc49d..c7fa943 100644 --- a/os/syscall/syscall_stublookup.c +++ b/os/syscall/syscall_stublookup.c @@ -97,9 +97,11 @@ uintptr_t STUB_sched_yield(int nbr); 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); -- 2.7.4