mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 22:41:07 +08:00
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:
@@ -216,7 +216,7 @@ o Task/Scheduler (sched/)
|
|||||||
Status: Open
|
Status: Open
|
||||||
Priority: Medium-ish
|
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
|
Description: Semaphores have multiple uses. The typical usage is where
|
||||||
the semaphore is used as lock on one or more resources. In
|
the semaphore is used as lock on one or more resources. In
|
||||||
this typical case, priority inheritance works perfectly: The
|
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
|
The fix is to call sem_setprotocol(SEM_PRIO_NONE) immediately
|
||||||
after the sem_init() call so that there will be no priority
|
after the sem_init() call so that there will be no priority
|
||||||
inheritance operations on this semaphore used for signalling.
|
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
|
Status: Open
|
||||||
Priority: High. If you have priority inheritance enabled and you use
|
Priority: High. If you have priority inheritance enabled and you use
|
||||||
semaphores for signalling events, then you *must* call
|
semaphores for signalling events, then you *must* call
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
|
|
||||||
#include <nuttx/sermaphore.h>
|
#include <nuttx/semaphore.h>
|
||||||
|
|
||||||
#include "up_internal.h"
|
#include "up_internal.h"
|
||||||
|
|
||||||
|
|||||||
+8
-17
@@ -96,12 +96,10 @@
|
|||||||
* An implementation is allowed to map this mutex to one of the other mutex types.
|
* 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_NORMAL 0
|
#define PTHREAD_MUTEX_ERRORCHECK 1
|
||||||
# define PTHREAD_MUTEX_ERRORCHECK 1
|
#define PTHREAD_MUTEX_RECURSIVE 2
|
||||||
# define PTHREAD_MUTEX_RECURSIVE 2
|
#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
|
||||||
# define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Valid ranges for the pthread stacksize attribute */
|
/* Valid ranges for the pthread stacksize attribute */
|
||||||
|
|
||||||
@@ -389,10 +387,12 @@ int pthread_mutexattr_getpshared(FAR const pthread_mutexattr_t *attr,
|
|||||||
FAR int *pshared);
|
FAR int *pshared);
|
||||||
int pthread_mutexattr_setpshared(FAR pthread_mutexattr_t *attr,
|
int pthread_mutexattr_setpshared(FAR pthread_mutexattr_t *attr,
|
||||||
int pshared);
|
int pshared);
|
||||||
#ifdef CONFIG_MUTEX_TYPES
|
|
||||||
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type);
|
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type);
|
||||||
int pthread_mutexattr_settype(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. */
|
/* 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_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);
|
||||||
|
|||||||
+12
-15
@@ -35,27 +35,24 @@
|
|||||||
|
|
||||||
# Add the pthread C files to the build
|
# Add the pthread C files to the build
|
||||||
|
|
||||||
CSRCS += pthread_attr_init.c pthread_attr_destroy.c \
|
CSRCS += pthread_attr_init.c pthread_attr_destroy.c
|
||||||
pthread_attr_setschedpolicy.c pthread_attr_getschedpolicy.c \
|
CSRCS += pthread_attr_setschedpolicy.c pthread_attr_getschedpolicy.c
|
||||||
pthread_attr_setinheritsched.c pthread_attr_getinheritsched.c \
|
CSRCS += pthread_attr_setinheritsched.c pthread_attr_getinheritsched.c
|
||||||
pthread_attr_setstacksize.c pthread_attr_getstacksize.c \
|
CSRCS += pthread_attr_setstacksize.c pthread_attr_getstacksize.c
|
||||||
pthread_attr_setschedparam.c pthread_attr_getschedparam.c \
|
CSRCS += pthread_attr_setschedparam.c pthread_attr_getschedparam.c
|
||||||
pthread_barrierattr_init.c pthread_barrierattr_destroy.c \
|
CSRCS += pthread_barrierattr_init.c pthread_barrierattr_destroy.c
|
||||||
pthread_barrierattr_getpshared.c pthread_barrierattr_setpshared.c \
|
CSRCS += pthread_barrierattr_getpshared.c pthread_barrierattr_setpshared.c
|
||||||
pthread_condattr_init.c pthread_condattr_destroy.c \
|
CSRCS += pthread_condattr_init.c pthread_condattr_destroy.c
|
||||||
pthread_mutexattr_init.c pthread_mutexattr_destroy.c \
|
CSRCS += pthread_mutexattr_init.c pthread_mutexattr_destroy.c
|
||||||
pthread_mutexattr_getpshared.c pthread_mutexattr_setpshared.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)
|
ifeq ($(CONFIG_SMP),y)
|
||||||
CSRCS += pthread_attr_getaffinity.c pthread_attr_setaffinity.c
|
CSRCS += pthread_attr_getaffinity.c pthread_attr_setaffinity.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_MUTEX_TYPES),y)
|
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
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
ifeq ($(CONFIG_BUILD_PROTECTED),y)
|
||||||
|
|||||||
@@ -68,6 +68,11 @@ int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr,
|
|||||||
{
|
{
|
||||||
DEBUGASSERT(attr != NULL && protocol != NULL);
|
DEBUGASSERT(attr != NULL && protocol != NULL);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||||
linfo("Returning %d\n", attr->proto);
|
linfo("Returning %d\n", attr->proto);
|
||||||
return attr->proto;
|
return attr->proto;
|
||||||
|
#else
|
||||||
|
linfo("Returning %d\n", PTHREAD_PRIO_NONE);
|
||||||
|
return PTHREAD_PRIO_NONE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,6 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef CONFIG_MUTEX_TYPES
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -67,13 +65,15 @@
|
|||||||
|
|
||||||
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)
|
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;
|
*type = attr->type;
|
||||||
|
#else
|
||||||
|
*type = PTHREAD_MUTEX_NORMAL;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_MUTEX_TYPES */
|
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr,
|
|||||||
linfo("attr=0x%p protocol=%d\n", attr, protocol);
|
linfo("attr=0x%p protocol=%d\n", attr, protocol);
|
||||||
DEBUGASSERT(attr != NULL);
|
DEBUGASSERT(attr != NULL);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||||
if (protocol >= PTHREAD_PRIO_NONE && protocol <= PTHREAD_PRIO_PROTECT)
|
if (protocol >= PTHREAD_PRIO_NONE && protocol <= PTHREAD_PRIO_PROTECT)
|
||||||
{
|
{
|
||||||
attr->proto = protocol;
|
attr->proto = protocol;
|
||||||
@@ -76,4 +77,14 @@ int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
|
#else
|
||||||
|
if (protocol == PTHREAD_PRIO_NONE)
|
||||||
|
{
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ENOSYS;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,6 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef CONFIG_MUTEX_TYPES
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* 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)
|
if (attr && type >= PTHREAD_MUTEX_NORMAL && type <= PTHREAD_MUTEX_RECURSIVE)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_MUTEX_TYPES
|
||||||
attr->type = type;
|
attr->type = type;
|
||||||
|
#else
|
||||||
|
if (type != PTHREAD_MUTEX_NORMAL)
|
||||||
|
{
|
||||||
|
return ENOSYS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_MUTEX_TYPES */
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/pthread/pthread_condinit.c
|
* 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>
|
* 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
|
||||||
@@ -40,9 +40,12 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <semaphore.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/semaphore.h>
|
||||||
|
|
||||||
#include "pthread/pthread.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);
|
sinfo("cond=0x%p attr=0x%p\n", cond, attr);
|
||||||
|
|
||||||
if (!cond)
|
if (cond == NULL)
|
||||||
{
|
{
|
||||||
ret = EINVAL;
|
ret = EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the semaphore contained in the condition structure
|
/* Initialize the semaphore contained in the condition structure with
|
||||||
* with initial count = 0
|
* initial count = 0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
else if (sem_init((FAR sem_t *)&cond->sem, 0, 0) != OK)
|
else if (sem_init((FAR sem_t *)&cond->sem, 0, 0) != OK)
|
||||||
{
|
{
|
||||||
ret = EINVAL;
|
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);
|
sinfo("Returning %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user