shced:sem: replace mutex with spinlock
The overhead of spinlok is less than mutext (mutex need to call enter_critical section.) After this patch, `down_write_trylock` and `down_read_trylock` can be use in interrupt context. The instruction is protected with mutex only one instruction so using spinlock is better. Signed-off-by: TaiJu Wu <tjwu1217@gmail.com>
This commit is contained in:
parent
a7389c0057
commit
23d65cb97f
|
@ -25,7 +25,8 @@
|
|||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/mutex.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
|
@ -33,11 +34,11 @@
|
|||
|
||||
typedef struct
|
||||
{
|
||||
mutex_t protected; /* Protecting Locks for Read/Write Locked Tables */
|
||||
sem_t waiting; /* Reader/writer Waiting queue */
|
||||
int waiter; /* Waiter Count */
|
||||
int writer; /* Writer Count */
|
||||
int reader; /* Reader Count */
|
||||
spinlock_t protected;
|
||||
sem_t waiting;
|
||||
int waiter;
|
||||
int writer;
|
||||
int reader;
|
||||
} rw_semaphore_t;
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/rwsem.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <assert.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
@ -61,11 +63,11 @@ static inline void up_wait(FAR rw_semaphore_t *rwsem)
|
|||
|
||||
int down_read_trylock(FAR rw_semaphore_t *rwsem)
|
||||
{
|
||||
nxmutex_lock(&rwsem->protected);
|
||||
irqstate_t flags = spin_lock_irqsave(&rwsem->protected);
|
||||
|
||||
if (rwsem->writer > 0)
|
||||
{
|
||||
nxmutex_unlock(&rwsem->protected);
|
||||
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -75,7 +77,7 @@ int down_read_trylock(FAR rw_semaphore_t *rwsem)
|
|||
|
||||
rwsem->reader++;
|
||||
|
||||
nxmutex_unlock(&rwsem->protected);
|
||||
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -97,14 +99,14 @@ void down_read(FAR rw_semaphore_t *rwsem)
|
|||
* block and wait for the write-lock to be unlocked.
|
||||
*/
|
||||
|
||||
nxmutex_lock(&rwsem->protected);
|
||||
irqstate_t flags = spin_lock_irqsave(&rwsem->protected);
|
||||
|
||||
while (rwsem->writer > 0)
|
||||
{
|
||||
rwsem->waiter++;
|
||||
nxmutex_unlock(&rwsem->protected);
|
||||
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||
nxsem_wait(&rwsem->waiting);
|
||||
nxmutex_lock(&rwsem->protected);
|
||||
flags = spin_lock_irqsave(&rwsem->protected);
|
||||
rwsem->waiter--;
|
||||
}
|
||||
|
||||
|
@ -114,7 +116,7 @@ void down_read(FAR rw_semaphore_t *rwsem)
|
|||
|
||||
rwsem->reader++;
|
||||
|
||||
nxmutex_unlock(&rwsem->protected);
|
||||
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -130,7 +132,7 @@ void down_read(FAR rw_semaphore_t *rwsem)
|
|||
|
||||
void up_read(FAR rw_semaphore_t *rwsem)
|
||||
{
|
||||
nxmutex_lock(&rwsem->protected);
|
||||
irqstate_t flags = spin_lock_irqsave(&rwsem->protected);
|
||||
|
||||
DEBUGASSERT(rwsem->reader > 0);
|
||||
|
||||
|
@ -141,7 +143,7 @@ void up_read(FAR rw_semaphore_t *rwsem)
|
|||
up_wait(rwsem);
|
||||
}
|
||||
|
||||
nxmutex_unlock(&rwsem->protected);
|
||||
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -160,11 +162,11 @@ void up_read(FAR rw_semaphore_t *rwsem)
|
|||
|
||||
int down_write_trylock(FAR rw_semaphore_t *rwsem)
|
||||
{
|
||||
nxmutex_lock(&rwsem->protected);
|
||||
irqstate_t flags = spin_lock_irqsave(&rwsem->protected);
|
||||
|
||||
if (rwsem->writer > 0 || rwsem->reader > 0)
|
||||
{
|
||||
nxmutex_unlock(&rwsem->protected);
|
||||
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -172,7 +174,7 @@ int down_write_trylock(FAR rw_semaphore_t *rwsem)
|
|||
|
||||
rwsem->writer++;
|
||||
|
||||
nxmutex_unlock(&rwsem->protected);
|
||||
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -190,14 +192,14 @@ int down_write_trylock(FAR rw_semaphore_t *rwsem)
|
|||
|
||||
void down_write(FAR rw_semaphore_t *rwsem)
|
||||
{
|
||||
nxmutex_lock(&rwsem->protected);
|
||||
irqstate_t flags = spin_lock_irqsave(&rwsem->protected);
|
||||
|
||||
while (rwsem->reader > 0 || rwsem->writer > 0)
|
||||
{
|
||||
rwsem->waiter++;
|
||||
nxmutex_unlock(&rwsem->protected);
|
||||
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||
nxsem_wait(&rwsem->waiting);
|
||||
nxmutex_lock(&rwsem->protected);
|
||||
flags = spin_lock_irqsave(&rwsem->protected);
|
||||
rwsem->waiter--;
|
||||
}
|
||||
|
||||
|
@ -205,7 +207,7 @@ void down_write(FAR rw_semaphore_t *rwsem)
|
|||
|
||||
rwsem->writer++;
|
||||
|
||||
nxmutex_unlock(&rwsem->protected);
|
||||
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -221,7 +223,7 @@ void down_write(FAR rw_semaphore_t *rwsem)
|
|||
|
||||
void up_write(FAR rw_semaphore_t *rwsem)
|
||||
{
|
||||
nxmutex_lock(&rwsem->protected);
|
||||
irqstate_t flags = spin_lock_irqsave(&rwsem->protected);
|
||||
|
||||
DEBUGASSERT(rwsem->writer > 0);
|
||||
|
||||
|
@ -229,7 +231,7 @@ void up_write(FAR rw_semaphore_t *rwsem)
|
|||
|
||||
up_wait(rwsem);
|
||||
|
||||
nxmutex_unlock(&rwsem->protected);
|
||||
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -253,16 +255,11 @@ int init_rwsem(FAR rw_semaphore_t *rwsem)
|
|||
|
||||
/* Initialize structure information */
|
||||
|
||||
ret = nxmutex_init(&rwsem->protected);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
spin_lock_init(&rwsem->protected);
|
||||
|
||||
ret = nxsem_init(&rwsem->waiting, 0, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
nxmutex_destroy(&rwsem->protected);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -292,6 +289,5 @@ void destroy_rwsem(FAR rw_semaphore_t *rwsem)
|
|||
DEBUGASSERT(rwsem->waiter == 0 && rwsem->reader == 0 &&
|
||||
rwsem->writer == 0);
|
||||
|
||||
nxmutex_destroy(&rwsem->protected);
|
||||
nxsem_destroy(&rwsem->waiting);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue