Update TODO. Provide do-nothing stubs for mutex attribute interfaces if features not enabled. pthread_cond includes a signaling semaphore and should call sem_setprotocol.

This commit is contained in:
Gregory Nutt 2016-11-05 11:06:52 -06:00
parent 6f1c5e7b43
commit 796969f6b6
9 changed files with 81 additions and 50 deletions

16
TODO
View File

@ -216,7 +216,7 @@ o Task/Scheduler (sched/)
Status: Open
Priority: Medium-ish
Title: ISSUES WITH PRIORITY INHERITANCE WHEN SEMAPHORE USED AS IPC
Title: ISSUES WITH PRIORITY INHERITANCE WHEN SEMAPHORE/MUTX IS USED AS IPC
Description: Semaphores have multiple uses. The typical usage is where
the semaphore is used as lock on one or more resources. In
this typical case, priority inheritance works perfectly: The
@ -264,6 +264,20 @@ o Task/Scheduler (sched/)
The fix is to call sem_setprotocol(SEM_PRIO_NONE) immediately
after the sem_init() call so that there will be no priority
inheritance operations on this semaphore used for signalling.
NOTE also that in NuttX, pthread mutexes are build on top of
binary semaphores. As a result, the above recommendation also
applies when pthread mutexes are used for inter-thread
signaling. That is, a mutex that is used for signaling should
be initialize like this (simplified, no error checking here):
pthread_mutexattr_t attr;
pthread_mutex_t mutex;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_PRIO_NONE);
pthread_mutex_init(&mutex, &attr);
Status: Open
Priority: High. If you have priority inheritance enabled and you use
semaphores for signalling events, then you *must* call

View File

@ -39,7 +39,7 @@
#include <semaphore.h>
#include <nuttx/sermaphore.h>
#include <nuttx/semaphore.h>
#include "up_internal.h"

View File

@ -96,12 +96,10 @@
* An implementation is allowed to map this mutex to one of the other mutex types.
*/
#ifdef CONFIG_MUTEX_TYPES
# define PTHREAD_MUTEX_NORMAL 0
# define PTHREAD_MUTEX_ERRORCHECK 1
# define PTHREAD_MUTEX_RECURSIVE 2
# define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
#endif
#define PTHREAD_MUTEX_NORMAL 0
#define PTHREAD_MUTEX_ERRORCHECK 1
#define PTHREAD_MUTEX_RECURSIVE 2
#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
/* Valid ranges for the pthread stacksize attribute */
@ -389,10 +387,12 @@ int pthread_mutexattr_getpshared(FAR const pthread_mutexattr_t *attr,
FAR int *pshared);
int pthread_mutexattr_setpshared(FAR pthread_mutexattr_t *attr,
int pshared);
#ifdef CONFIG_MUTEX_TYPES
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type);
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
#endif
int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr,
FAR int *protocol);
int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr,
int protocol);
/* The following routines create, delete, lock and unlock mutexes. */
@ -403,15 +403,6 @@ 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);

View File

@ -35,27 +35,24 @@
# Add the pthread C files to the build
CSRCS += pthread_attr_init.c pthread_attr_destroy.c \
pthread_attr_setschedpolicy.c pthread_attr_getschedpolicy.c \
pthread_attr_setinheritsched.c pthread_attr_getinheritsched.c \
pthread_attr_setstacksize.c pthread_attr_getstacksize.c \
pthread_attr_setschedparam.c pthread_attr_getschedparam.c \
pthread_barrierattr_init.c pthread_barrierattr_destroy.c \
pthread_barrierattr_getpshared.c pthread_barrierattr_setpshared.c \
pthread_condattr_init.c pthread_condattr_destroy.c \
pthread_mutexattr_init.c pthread_mutexattr_destroy.c \
pthread_mutexattr_getpshared.c pthread_mutexattr_setpshared.c
CSRCS += pthread_attr_init.c pthread_attr_destroy.c
CSRCS += pthread_attr_setschedpolicy.c pthread_attr_getschedpolicy.c
CSRCS += pthread_attr_setinheritsched.c pthread_attr_getinheritsched.c
CSRCS += pthread_attr_setstacksize.c pthread_attr_getstacksize.c
CSRCS += pthread_attr_setschedparam.c pthread_attr_getschedparam.c
CSRCS += pthread_barrierattr_init.c pthread_barrierattr_destroy.c
CSRCS += pthread_barrierattr_getpshared.c pthread_barrierattr_setpshared.c
CSRCS += pthread_condattr_init.c pthread_condattr_destroy.c
CSRCS += pthread_mutexattr_init.c pthread_mutexattr_destroy.c
CSRCS += pthread_mutexattr_getpshared.c pthread_mutexattr_setpshared.c
CSRCS += pthread_mutexattr_setprotocol.c pthread_mutexattr_getprotocol.c
CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c
ifeq ($(CONFIG_SMP),y)
CSRCS += pthread_attr_getaffinity.c pthread_attr_setaffinity.c
endif
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)

View File

@ -68,6 +68,11 @@ int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr,
{
DEBUGASSERT(attr != NULL && protocol != NULL);
#ifdef CONFIG_PRIORITY_INHERITANCE
linfo("Returning %d\n", attr->proto);
return attr->proto;
#else
linfo("Returning %d\n", PTHREAD_PRIO_NONE);
return PTHREAD_PRIO_NONE;
#endif
}

View File

@ -41,8 +41,6 @@
#include <pthread.h>
#include <errno.h>
#ifdef CONFIG_MUTEX_TYPES
/****************************************************************************
* Public Functions
****************************************************************************/
@ -67,13 +65,15 @@
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)
{
if (attr && type)
if (attr != NULL && type != NULL)
{
#ifdef CONFIG_MUTEX_TYPES
*type = attr->type;
#else
*type = PTHREAD_MUTEX_NORMAL;
#endif
return 0;
}
return EINVAL;
}
#endif /* CONFIG_MUTEX_TYPES */

View File

@ -69,6 +69,7 @@ int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr,
linfo("attr=0x%p protocol=%d\n", attr, protocol);
DEBUGASSERT(attr != NULL);
#ifdef CONFIG_PRIORITY_INHERITANCE
if (protocol >= PTHREAD_PRIO_NONE && protocol <= PTHREAD_PRIO_PROTECT)
{
attr->proto = protocol;
@ -76,4 +77,14 @@ int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr,
}
return EINVAL;
#else
if (protocol == PTHREAD_PRIO_NONE)
{
return OK;
}
return ENOSYS;
#endif
}

View File

@ -41,8 +41,6 @@
#include <pthread.h>
#include <errno.h>
#ifdef CONFIG_MUTEX_TYPES
/****************************************************************************
* Public Functions
****************************************************************************/
@ -69,10 +67,17 @@ int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
{
if (attr && type >= PTHREAD_MUTEX_NORMAL && type <= PTHREAD_MUTEX_RECURSIVE)
{
#ifdef CONFIG_MUTEX_TYPES
attr->type = type;
#else
if (type != PTHREAD_MUTEX_NORMAL)
{
return ENOSYS;
}
#endif
return OK;
}
return EINVAL;
}
#endif /* CONFIG_MUTEX_TYPES */

View File

@ -1,7 +1,7 @@
/****************************************************************************
* sched/pthread/pthread_condinit.c
*
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2009, 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -40,9 +40,12 @@
#include <nuttx/config.h>
#include <pthread.h>
#include <semaphore.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/semaphore.h>
#include "pthread/pthread.h"
/****************************************************************************
@ -71,23 +74,28 @@ int pthread_cond_init(FAR pthread_cond_t *cond, FAR const pthread_condattr_t *at
sinfo("cond=0x%p attr=0x%p\n", cond, attr);
if (!cond)
if (cond == NULL)
{
ret = EINVAL;
}
/* Initialize the semaphore contained in the condition structure
* with initial count = 0
/* Initialize the semaphore contained in the condition structure with
* initial count = 0
*/
else if (sem_init((FAR sem_t *)&cond->sem, 0, 0) != OK)
{
ret = EINVAL;
}
else
{
/* The contained semaphore is used for signaling and, hence, should
* not have priority inheritance enabled.
*/
sem_setprotocol(&cond->sem, SEM_PRIO_NONE);
}
sinfo("Returning %d\n", ret);
return ret;
}