From: Heesub Shin Date: Thu, 6 Apr 2017 01:11:40 +0000 (+0900) Subject: kernel/semaphore: add macros for sem_get/setprotocol() X-Git-Tag: 1.1_Public_Release~614^2~111 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0a4d5211a302226c65d7975b00a95f58a3d4c0e3;p=rtos%2Ftinyara.git kernel/semaphore: add macros for sem_get/setprotocol() Provide macros for sem_setprotocol() and sem_getprotocol() if priority inheritance is not enabled. More SEM_PRIO_* definitions to include/tinyara/semaphore.h. All credits should go to Gregory Nutt who wrote the original patch. Change-Id: Id0f931210629e5b15db5c659b914794662f04adc Signed-off-by: Gregory Nutt [Shin: backported 97bf82ee from NuttX] Signed-off-by: Heesub Shin --- diff --git a/os/include/pthread.h b/os/include/pthread.h index 4506a84..1530a58 100644 --- a/os/include/pthread.h +++ b/os/include/pthread.h @@ -64,18 +64,19 @@ * Included Files ********************************************************************************/ -#include /* Default settings */ +#include /* Default settings */ #include /* Compiler settings, noreturn_function */ -#include /* Needed for general types */ -#include /* Needed by pthread_[set|get]name_np */ +#include /* Needed for general types */ +#include /* Needed by pthread_[set|get]name_np */ -#include /* C99 fixed width integer types */ -#include /* C99 boolean types */ -#include /* For getpid */ -#include /* Needed for sem_t */ -#include /* Needed for sigset_t */ -#include /* Needed for struct timespec */ +#include /* C99 fixed width integer types */ +#include /* C99 boolean types */ +#include /* For getpid */ +#include /* Needed for sigset_t */ +#include /* Needed for struct timespec */ + +#include /* For sem_t and SEM_PRIO_* defines */ /******************************************************************************** * Pre-processor Definitions @@ -136,9 +137,7 @@ #define PTHREAD_INHERIT_SCHED 0 #define PTHREAD_EXPLICIT_SCHED 1 -#define PTHREAD_PRIO_NONE 0 -#define PTHREAD_PRIO_INHERIT 1 -#define PTHREAD_PRIO_PROTECT 2 +/* Default priority */ #define PTHREAD_DEFAULT_PRIORITY 100 @@ -163,7 +162,7 @@ #define PTHREAD_BARRIER_SERIAL_THREAD 0x1000 -/* Values for protocol attribute */ +/* Values for protocol mutex attribute */ #define PTHREAD_PRIO_NONE SEM_PRIO_NONE #define PTHREAD_PRIO_INHERIT SEM_PRIO_INHERIT diff --git a/os/include/semaphore.h b/os/include/semaphore.h index d9594af..3ab6263 100644 --- a/os/include/semaphore.h +++ b/os/include/semaphore.h @@ -69,23 +69,10 @@ #include #include -#ifdef __cplusplus -#define EXTERN extern "C" -extern "C" { -#else -#define EXTERN extern -#endif - /**************************************************************************** * 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 @@ -160,6 +147,14 @@ typedef struct sem_s sem_t; * Public Variables ****************************************************************************/ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/os/include/tinyara/semaphore.h b/os/include/tinyara/semaphore.h index 3f25428..733a286 100644 --- a/os/include/tinyara/semaphore.h +++ b/os/include/tinyara/semaphore.h @@ -66,6 +66,12 @@ * Pre-processor Definitions ****************************************************************************/ +/* Values for protocol attribute */ + +#define SEM_PRIO_NONE 0 +#define SEM_PRIO_INHERIT 1 +#define SEM_PRIO_PROTECT 2 + /**************************************************************************** * Public Data ****************************************************************************/ @@ -158,6 +164,8 @@ int sem_reset(FAR sem_t *sem, int16_t count); #ifdef CONFIG_PRIORITY_INHERITANCE int sem_getprotocol(FAR sem_t *sem, FAR int *protocol); +#else +#define sem_getprotocol(s,p) do { *(p) == SEM_PRIO_NONE); } while (0) #endif /**************************************************************************** @@ -166,6 +174,25 @@ int sem_getprotocol(FAR sem_t *sem, FAR int *protocol); * Description: * Set semaphore protocol attribute. * + * One particularly important use of this function is when a semaphore + * is used for inter-task communication like: + * + * TASK A TASK B + * sem_init(sem, 0, 0); + * sem_wait(sem); + * sem_post(sem); + * Awakens as holder + * + * In this case priority inheritance can interfere with the operation of + * the semaphore. The problem is that when TASK A is restarted it is a + * holder of the semaphore. However, it never calls sem_post(sem) so it + * becomes *permanently* a holder of the semaphore and may have its + * priority boosted when any other task tries to acquire the semaphore. + * + * 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. + * * Parameters: * sem - A pointer to the semaphore whose attributes are to be * modified @@ -179,6 +206,8 @@ int sem_getprotocol(FAR sem_t *sem, FAR int *protocol); #ifdef CONFIG_PRIORITY_INHERITANCE int sem_setprotocol(FAR sem_t *sem, int protocol); +#else +#define sem_setprotocol(s,p) DEBUGASSERT((p) == SEM_PRIO_NONE); #endif #undef EXTERN diff --git a/os/kernel/semaphore/sem_setprotocol.c b/os/kernel/semaphore/sem_setprotocol.c index 127cf11..85ba240 100644 --- a/os/kernel/semaphore/sem_setprotocol.c +++ b/os/kernel/semaphore/sem_setprotocol.c @@ -75,6 +75,25 @@ * Description: * Set semaphore protocol attribute. * + * One particularly important use of this furnction is when a semaphore + * is used for inter-task communication like: + * + * TASK A TASK B + * sem_init(sem, 0, 0); + * sem_wait(sem); + * sem_post(sem); + * Awakens as holder + * + * In this case priority inheritance can interfere with the operation of + * the semaphore. The problem is that when TASK A is restarted it is a + * holder of the semaphore. However, it never calls sem_post(sem) so it + * becomes *permanently* a holder of the semaphore and may have its + * priority boosted when any other task tries to acquire the semaphore. + * + * 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. + * * Parameters: * sem - A pointer to the semaphore whose attributes are to be * modified