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.

This commit is contained in:
Gregory Nutt 2016-11-02 09:05:18 -06:00
parent 14e06a3ce3
commit 92d3022411
18 changed files with 465 additions and 51 deletions

View File

@ -61,12 +61,13 @@
struct inode; struct inode;
struct nsem_inode_s struct nsem_inode_s
{ {
sem_t ns_sem; /* The contained semaphore */
/* Inode payload unique to named semaphores. ns_inode must appear first /* Inode payload unique to named semaphores. ns_inode must appear first
* in this structure in order to support casting between type sem_t and * in this structure in order to support casting between type sem_t and
* types of struct nsem_inode_s. */ * types of struct nsem_inode_s. */
FAR struct inode *ns_inode; /* Containing inode */ FAR struct inode *ns_inode; /* Containing inode */
sem_t ns_sem; /* The semaphore */
}; };
#endif #endif

View File

@ -135,6 +135,12 @@
#define PTHREAD_BARRIER_SERIAL_THREAD 0x1000 #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 /* Definitions to map some non-standard, BSD thread management interfaces to
* the non-standard Linux-like prctl() interface. Since these are simple * 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 * 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 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 #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 #endif
@ -222,11 +231,11 @@ typedef struct pthread_mutexattr_s pthread_mutexattr_t;
struct pthread_mutex_s struct pthread_mutex_s
{ {
int pid; /* ID of the holder of the mutex */ int pid; /* ID of the holder of the mutex */
sem_t sem; /* Semaphore underlying the implementation of the mutex */ sem_t sem; /* Semaphore underlying the implementation of the mutex */
#ifdef CONFIG_MUTEX_TYPES #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 */
int nlocks; /* The number of recursive locks held */ int nlocks; /* The number of recursive locks held */
#endif #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_trylock(FAR pthread_mutex_t *mutex);
int pthread_mutex_unlock(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 */ /* Operations on condition variables */
int pthread_condattr_init(FAR pthread_condattr_t *attr); int pthread_condattr_init(FAR pthread_condattr_t *attr);

View File

@ -57,6 +57,17 @@ extern "C"
* Pre-processor Definitions * 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 * Public Type Declarations
****************************************************************************/ ****************************************************************************/
@ -92,6 +103,7 @@ struct sem_s
*/ */
#ifdef CONFIG_PRIORITY_INHERITANCE #ifdef CONFIG_PRIORITY_INHERITANCE
uint8_t flags; /* See PRIOINHERIT_FLAGS_* definitions */
# if CONFIG_SEM_PREALLOCHOLDERS > 0 # if CONFIG_SEM_PREALLOCHOLDERS > 0
FAR struct semholder_s *hhead; /* List of holders of semaphore counts */ FAR struct semholder_s *hhead; /* List of holders of semaphore counts */
# else # else
@ -106,9 +118,9 @@ typedef struct sem_s sem_t;
#ifdef CONFIG_PRIORITY_INHERITANCE #ifdef CONFIG_PRIORITY_INHERITANCE
# if CONFIG_SEM_PREALLOCHOLDERS > 0 # if CONFIG_SEM_PREALLOCHOLDERS > 0
# define SEM_INITIALIZER(c) {(c), NULL} /* semcount, hhead */ # define SEM_INITIALIZER(c) {(c), 0, NULL} /* semcount, flags, hhead */
# else # else
# define SEM_INITIALIZER(c) {(c), SEMHOLDER_INITIALIZER} /* semcount, holder */ # define SEM_INITIALIZER(c) {(c), 0, SEMHOLDER_INITIALIZER} /* semcount, flags, holder */
# endif # endif
#else #else
# define SEM_INITIALIZER(c) {(c)} /* semcount */ # define SEM_INITIALIZER(c) {(c)} /* semcount */
@ -141,6 +153,13 @@ int sem_close(FAR sem_t *sem);
int sem_unlink(FAR const char *name); int sem_unlink(FAR const char *name);
#endif #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 #undef EXTERN
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -91,15 +91,23 @@
#define SYS_sem_trywait (CONFIG_SYS_RESERVED+18) #define SYS_sem_trywait (CONFIG_SYS_RESERVED+18)
#define SYS_sem_wait (CONFIG_SYS_RESERVED+19) #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 */ /* Named semaphores */
#ifdef CONFIG_FS_NAMED_SEMAPHORES #ifdef CONFIG_FS_NAMED_SEMAPHORES
# define SYS_sem_open (CONFIG_SYS_RESERVED+20) # define SYS_sem_open __SYS_named_sem
# define SYS_sem_close (CONFIG_SYS_RESERVED+21) # define SYS_sem_close (__SYS_named_sem+1)
# define SYS_sem_unlink (CONFIG_SYS_RESERVED+22) # define SYS_sem_unlink (__SYS_named_sem+2)
# define __SYS_task_create (CONFIG_SYS_RESERVED+23) # define __SYS_task_create (__SYS_named_sem+3)
#else #else
# define __SYS_task_create (CONFIG_SYS_RESERVED+20) # define __SYS_task_create __SYS_named_sem
#endif #endif
/* Task creation APIs based on global entry points cannot be use with /* Task creation APIs based on global entry points cannot be use with

View File

@ -54,6 +54,10 @@ ifeq ($(CONFIG_MUTEX_TYPES),y)
CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c
endif endif
ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
CSRCS += pthread_mutexattr_setprotocol.c pthread_mutexattr_getprotocol.c
endif
ifeq ($(CONFIG_BUILD_PROTECTED),y) ifeq ($(CONFIG_BUILD_PROTECTED),y)
CSRCS += pthread_startup.c CSRCS += pthread_startup.c
endif endif

View File

@ -52,8 +52,7 @@
* Function: pthread_attr_destroy * Function: pthread_attr_destroy
* *
* Description: * Description:
* An attributes object can be deleted when it is no longer * An attributes object can be deleted when it is no longer needed.
* needed.
* *
* Parameters: * Parameters:
* attr * attr

View File

@ -55,7 +55,6 @@
* *
* Parameters: * Parameters:
* attr * attr
* pshared
* *
* Return Value: * Return Value:
* 0 if successful. Otherwise, an error code. * 0 if successful. Otherwise, an error code.

View File

@ -0,0 +1,73 @@
/****************************************************************************
* libc/pthread/pthread_mutexattr_getprotocol.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <pthread.h>
#include <assert.h>
#include <debug.h>
/****************************************************************************
* 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;
}

View File

@ -0,0 +1,79 @@
/****************************************************************************
* libc/pthread/pthread_mutexattr_setprotocol.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <pthread.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
/****************************************************************************
* 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;
}

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* libc/sem/sem_init.c * 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 <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -44,26 +44,6 @@
#include <semaphore.h> #include <semaphore.h>
#include <errno.h> #include <errno.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
@ -108,6 +88,7 @@ int sem_init(FAR sem_t *sem, int pshared, unsigned int value)
/* Initialize to support priority inheritance */ /* Initialize to support priority inheritance */
#ifdef CONFIG_PRIORITY_INHERITANCE #ifdef CONFIG_PRIORITY_INHERITANCE
sem->flags = 0;
# if CONFIG_SEM_PREALLOCHOLDERS > 0 # if CONFIG_SEM_PREALLOCHOLDERS > 0
sem->hhead = NULL; sem->hhead = NULL;
# else # else

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* sched/pthread/pthread_mutexinit.c * 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 <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * 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; int pshared = 0;
#ifdef CONFIG_MUTEX_TYPES #ifdef CONFIG_MUTEX_TYPES
uint8_t type = PTHREAD_MUTEX_DEFAULT; uint8_t type = PTHREAD_MUTEX_DEFAULT;
#endif #endif
int ret = OK; #ifdef CONFIG_PRIORITY_INHERITANCE
uint8_t proto = PTHREAD_PRIO_INHERIT;
#endif
int ret = OK;
int status; int status;
sinfo("mutex=0x%p attr=0x%p\n", mutex, attr); 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) if (attr)
{ {
pshared = attr->pshared; pshared = attr->pshared;
#ifdef CONFIG_PRIORITY_INHERITANCE
proto = attr->proto;
#endif
#ifdef CONFIG_MUTEX_TYPES #ifdef CONFIG_MUTEX_TYPES
type = attr->type; type = attr->type;
#endif #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); status = sem_init((FAR sem_t *)&mutex->sem, pshared, 1);
if (status != OK) 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 */ /* Set up attributes unique to the mutex type */
#ifdef CONFIG_MUTEX_TYPES #ifdef CONFIG_MUTEX_TYPES

View File

@ -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_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_timedwait.c sem_timeout.c sem_post.c sem_recover.c
CSRCS += sem_reset.c sem_waitirq.c CSRCS += sem_reset.c sem_waitirq.c
ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
CSRCS += sem_initialize.c sem_holder.c CSRCS += sem_initialize.c sem_holder.c
CSRCS += sem_setprotocol.c sem_getprotocol.c
endif endif
ifeq ($(CONFIG_SPINLOCK),y) ifeq ($(CONFIG_SPINLOCK),y)

View File

@ -0,0 +1,85 @@
/****************************************************************************
* sched/semaphore/sem_getprotocol.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <semaphore.h>
#include <assert.h>
#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 */

View File

@ -790,7 +790,7 @@ void sem_initholders(void)
* Name: sem_destroyholder * Name: sem_destroyholder
* *
* Description: * 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. * it is destroyed.
* *
* Parameters: * Parameters:
@ -855,17 +855,25 @@ void sem_addholder_tcb(FAR struct tcb_s *htcb, FAR sem_t *sem)
{ {
FAR struct semholder_s *pholder; 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 ((sem->flags & PRIOINHERIT_FLAGS_DISABLE) == 0)
if (pholder != NULL)
{ {
/* Then set the holder and increment the number of counts held by this /* Find or allocate a container for this new holder */
* holder
*/
pholder->htcb = htcb; pholder = sem_findorallocateholder(sem, htcb);
pholder->counts++; if (pholder != NULL)
{
/* Then set the holder and increment the number of counts held by this
* holder
*/
pholder->htcb = htcb;
pholder->counts++;
}
} }
} }

View File

@ -0,0 +1,110 @@
/****************************************************************************
* sched/semaphore/sem_setprotocol.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <semaphore.h>
#include <assert.h>
#include <errno.h>
#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 */

View File

@ -117,7 +117,9 @@
"sem_close","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR sem_t*" "sem_close","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR sem_t*"
"sem_destroy","semaphore.h","","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_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_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_timedwait","semaphore.h","","int","FAR sem_t*","FAR const struct timespec *"
"sem_trywait","semaphore.h","","int","FAR sem_t*" "sem_trywait","semaphore.h","","int","FAR sem_t*"
"sem_unlink","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR const char*" "sem_unlink","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR const char*"

Can't render this file because it has a wrong number of fields in line 2.

View File

@ -61,12 +61,17 @@ SYSCALL_LOOKUP(uname, 1, STUB_uname)
/* Semaphores */ /* 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_post, 1, STUB_sem_post)
SYSCALL_LOOKUP(sem_timedwait, 2, STUB_sem_timedwait) SYSCALL_LOOKUP(sem_timedwait, 2, STUB_sem_timedwait)
SYSCALL_LOOKUP(sem_trywait, 1, STUB_sem_trywait) SYSCALL_LOOKUP(sem_trywait, 1, STUB_sem_trywait)
SYSCALL_LOOKUP(sem_wait, 1, STUB_sem_wait) 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 */ /* Named semaphores */
#ifdef CONFIG_FS_NAMED_SEMAPHORES #ifdef CONFIG_FS_NAMED_SEMAPHORES

View File

@ -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_close(int nbr, uintptr_t parm1);
uintptr_t STUB_sem_destroy(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 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 parm3, uintptr_t parm4, uintptr_t parm5, uintptr_t parm6);
uintptr_t STUB_sem_post(int nbr, uintptr_t parm1); 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_timedwait(int nbr, uintptr_t parm1, uintptr_t parm2);
uintptr_t STUB_sem_trywait(int nbr, uintptr_t parm1); uintptr_t STUB_sem_trywait(int nbr, uintptr_t parm1);
uintptr_t STUB_sem_unlink(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_sem_wait(int nbr, uintptr_t parm1);
uintptr_t STUB_pgalloc(int nbr, uintptr_t parm1, uintptr_t parm2); 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 STUB_task_create(int nbr, uintptr_t parm1, uintptr_t parm2,
uintptr_t parm3, uintptr_t parm4, uintptr_t parm5); uintptr_t parm3, uintptr_t parm4, uintptr_t parm5);