drivers/serial: disable priority inheritance on some semaphores
authorHeesub Shin <heesub.shin@samsung.com>
Thu, 6 Apr 2017 01:19:54 +0000 (10:19 +0900)
committerHeesub Shin <heesub.shin@samsung.com>
Tue, 18 Apr 2017 03:02:11 +0000 (12:02 +0900)
Make sure that priority inheritance is not enabled for the signaling
semaphores used in the serial driver.

Change-Id: Icab16a77b5370016f6cadf2f29853164511dc41d
Signed-off-by: Gregory Nutt <gnutt@nuttx.org>
[Shin: backported 47b043df from NuttX]
Signed-off-by: Heesub Shin <heesub.shin@samsung.com>
os/drivers/serial/serial.c

index abddc70..7b2565c 100644 (file)
@@ -60,8 +60,6 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include <unistd.h>
-#include <semaphore.h>
-#include <tinyara/semaphore.h>
 #include <string.h>
 #include <fcntl.h>
 #include <poll.h>
@@ -70,6 +68,7 @@
 
 #include <tinyara/irq.h>
 #include <tinyara/arch.h>
+#include <tinyara/semaphore.h>
 #include <tinyara/fs/fs.h>
 #include <tinyara/serial/serial.h>
 #include <tinyara/fs/ioctl.h>
@@ -127,16 +126,6 @@ static const struct file_operations g_serialops = {
  ************************************************************************************/
 
 /************************************************************************************
- * Name: sem_reinit
- ************************************************************************************/
-
-static int sem_reinit(FAR sem_t *sem, int pshared, unsigned int value)
-{
-       sem_destroy(sem);
-       return sem_init(sem, pshared, value);
-}
-
-/************************************************************************************
  * Name: uart_takesem
  ************************************************************************************/
 
@@ -1139,22 +1128,18 @@ static int uart_close(FAR struct file *filep)
 
        irqrestore(flags);
 
-       /* We need to re-initialize the semaphores if this is the last close
+       /*
+        * We need to re-initialize the semaphores if this is the last close
         * of the device, as the close might be caused by pthread_cancel() of
         * a thread currently blocking on any of them.
-        *
-        * REVISIT:  This logic *only* works in the case where the cancelled
-        * thread had the only reference to the serial driver.  If there other
-        * references, then the this logic will not be executed and the
-        * semaphore count will still be incorrect.
         */
 
-       sem_reinit(&dev->xmitsem, 0, 0);
-       sem_reinit(&dev->recvsem, 0, 0);
-       sem_reinit(&dev->xmit.sem, 0, 1);
-       sem_reinit(&dev->recv.sem, 0, 1);
+       sem_reset(&dev->xmitsem, 0);
+       sem_reset(&dev->recvsem, 0);
+       sem_reset(&dev->xmit.sem, 1);
+       sem_reset(&dev->recv.sem, 1);
 #ifndef CONFIG_DISABLE_POLL
-       sem_reinit(&dev->pollsem, 0, 1);
+       sem_reset(&dev->pollsem, 1);
 #endif
 
        uart_givesem(&dev->closesem);
@@ -1288,6 +1273,7 @@ errout_with_sem:
 
 int uart_register(FAR const char *path, FAR uart_dev_t *dev)
 {
+       /* Initialize semaphores */
        sem_init(&dev->xmit.sem, 0, 1);
        sem_init(&dev->recv.sem, 0, 1);
        sem_init(&dev->closesem, 0, 1);
@@ -1297,6 +1283,14 @@ int uart_register(FAR const char *path, FAR uart_dev_t *dev)
        sem_init(&dev->pollsem, 0, 1);
 #endif
 
+       /*
+        * The recvsem and xmitsem are used for signaling and, hence, should
+        * not have priority inheritance enabled.
+        */
+       sem_setprotocol(&dev->xmitsem, SEM_PRIO_NONE);
+       sem_setprotocol(&dev->recvsem, SEM_PRIO_NONE);
+
+       /* Register the serial driver */
        dbg("Registering %s\n", path);
        return register_driver(path, &g_serialops, 0666, dev);
 }