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
|
* Included Files
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/mutex.h>
|
#include <nuttx/semaphore.h>
|
||||||
|
#include <nuttx/spinlock.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Type Definitions
|
* Public Type Definitions
|
||||||
@ -33,11 +34,11 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
mutex_t protected; /* Protecting Locks for Read/Write Locked Tables */
|
spinlock_t protected;
|
||||||
sem_t waiting; /* Reader/writer Waiting queue */
|
sem_t waiting;
|
||||||
int waiter; /* Waiter Count */
|
int waiter;
|
||||||
int writer; /* Writer Count */
|
int writer;
|
||||||
int reader; /* Reader Count */
|
int reader;
|
||||||
} rw_semaphore_t;
|
} rw_semaphore_t;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/rwsem.h>
|
#include <nuttx/rwsem.h>
|
||||||
|
#include <nuttx/irq.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* 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)
|
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)
|
if (rwsem->writer > 0)
|
||||||
{
|
{
|
||||||
nxmutex_unlock(&rwsem->protected);
|
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +77,7 @@ int down_read_trylock(FAR rw_semaphore_t *rwsem)
|
|||||||
|
|
||||||
rwsem->reader++;
|
rwsem->reader++;
|
||||||
|
|
||||||
nxmutex_unlock(&rwsem->protected);
|
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -97,14 +99,14 @@ void down_read(FAR rw_semaphore_t *rwsem)
|
|||||||
* block and wait for the write-lock to be unlocked.
|
* 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)
|
while (rwsem->writer > 0)
|
||||||
{
|
{
|
||||||
rwsem->waiter++;
|
rwsem->waiter++;
|
||||||
nxmutex_unlock(&rwsem->protected);
|
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||||
nxsem_wait(&rwsem->waiting);
|
nxsem_wait(&rwsem->waiting);
|
||||||
nxmutex_lock(&rwsem->protected);
|
flags = spin_lock_irqsave(&rwsem->protected);
|
||||||
rwsem->waiter--;
|
rwsem->waiter--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +116,7 @@ void down_read(FAR rw_semaphore_t *rwsem)
|
|||||||
|
|
||||||
rwsem->reader++;
|
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)
|
void up_read(FAR rw_semaphore_t *rwsem)
|
||||||
{
|
{
|
||||||
nxmutex_lock(&rwsem->protected);
|
irqstate_t flags = spin_lock_irqsave(&rwsem->protected);
|
||||||
|
|
||||||
DEBUGASSERT(rwsem->reader > 0);
|
DEBUGASSERT(rwsem->reader > 0);
|
||||||
|
|
||||||
@ -141,7 +143,7 @@ void up_read(FAR rw_semaphore_t *rwsem)
|
|||||||
up_wait(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)
|
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)
|
if (rwsem->writer > 0 || rwsem->reader > 0)
|
||||||
{
|
{
|
||||||
nxmutex_unlock(&rwsem->protected);
|
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +174,7 @@ int down_write_trylock(FAR rw_semaphore_t *rwsem)
|
|||||||
|
|
||||||
rwsem->writer++;
|
rwsem->writer++;
|
||||||
|
|
||||||
nxmutex_unlock(&rwsem->protected);
|
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -190,14 +192,14 @@ int down_write_trylock(FAR rw_semaphore_t *rwsem)
|
|||||||
|
|
||||||
void down_write(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)
|
while (rwsem->reader > 0 || rwsem->writer > 0)
|
||||||
{
|
{
|
||||||
rwsem->waiter++;
|
rwsem->waiter++;
|
||||||
nxmutex_unlock(&rwsem->protected);
|
spin_unlock_irqrestore(&rwsem->protected, flags);
|
||||||
nxsem_wait(&rwsem->waiting);
|
nxsem_wait(&rwsem->waiting);
|
||||||
nxmutex_lock(&rwsem->protected);
|
flags = spin_lock_irqsave(&rwsem->protected);
|
||||||
rwsem->waiter--;
|
rwsem->waiter--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +207,7 @@ void down_write(FAR rw_semaphore_t *rwsem)
|
|||||||
|
|
||||||
rwsem->writer++;
|
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)
|
void up_write(FAR rw_semaphore_t *rwsem)
|
||||||
{
|
{
|
||||||
nxmutex_lock(&rwsem->protected);
|
irqstate_t flags = spin_lock_irqsave(&rwsem->protected);
|
||||||
|
|
||||||
DEBUGASSERT(rwsem->writer > 0);
|
DEBUGASSERT(rwsem->writer > 0);
|
||||||
|
|
||||||
@ -229,7 +231,7 @@ void up_write(FAR rw_semaphore_t *rwsem)
|
|||||||
|
|
||||||
up_wait(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 */
|
/* Initialize structure information */
|
||||||
|
|
||||||
ret = nxmutex_init(&rwsem->protected);
|
spin_lock_init(&rwsem->protected);
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = nxsem_init(&rwsem->waiting, 0, 0);
|
ret = nxsem_init(&rwsem->waiting, 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nxmutex_destroy(&rwsem->protected);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,6 +289,5 @@ void destroy_rwsem(FAR rw_semaphore_t *rwsem)
|
|||||||
DEBUGASSERT(rwsem->waiter == 0 && rwsem->reader == 0 &&
|
DEBUGASSERT(rwsem->waiter == 0 && rwsem->reader == 0 &&
|
||||||
rwsem->writer == 0);
|
rwsem->writer == 0);
|
||||||
|
|
||||||
nxmutex_destroy(&rwsem->protected);
|
|
||||||
nxsem_destroy(&rwsem->waiting);
|
nxsem_destroy(&rwsem->waiting);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user