drivers/serial: disable priority inheritance on some semaphores
Make sure that priority inheritance is not enabled for the signaling
semaphores used in the serial driver.
[Shin: backported from NuttX]
#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>
#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>
@@ -126,16 +125,6 @@ static const struct file_operations g_serialops = {
* Private Functions
************************************************************************************/
-/************************************************************************************
- * 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);
}
