diff --git a/include/nuttx/rwsem.h b/include/nuttx/rwsem.h index e098da97528..cfac54c988e 100644 --- a/include/nuttx/rwsem.h +++ b/include/nuttx/rwsem.h @@ -142,6 +142,19 @@ void down_write(FAR rw_semaphore_t *rwsem); void up_write(FAR rw_semaphore_t *rwsem); +/**************************************************************************** + * Name: downgrade_write + * + * Description: + * Down grade write lock to read lock on a read-write-lock object. + * + * Input Parameters: + * rwsem - Pointer to the read-write-lock descriptor. + * + ****************************************************************************/ + +void downgrade_write(FAR rw_semaphore_t *rwsem); + /**************************************************************************** * Name: init_rwsem * diff --git a/sched/semaphore/sem_rw.c b/sched/semaphore/sem_rw.c index f9561599c4c..1c2a34ad6d5 100644 --- a/sched/semaphore/sem_rw.c +++ b/sched/semaphore/sem_rw.c @@ -286,6 +286,33 @@ void up_write(FAR rw_semaphore_t *rwsem) nxmutex_unlock(&rwsem->protected); } +/**************************************************************************** + * Name: downgrade_write + * + * Description: + * Downgrade write lock to read lock on a read-write-lock object. + * + * Input Parameters: + * rwsem - Pointer to the read-write-lock descriptor. + * + ****************************************************************************/ + +void downgrade_write(FAR rw_semaphore_t *rwsem) +{ + nxmutex_lock(&rwsem->protected); + + DEBUGASSERT(rwsem->writer == 1); + DEBUGASSERT(rwsem->reader == 0); + DEBUGASSERT(rwsem->holder == _SCHED_GETTID()); + + rwsem->writer = 0; + rwsem->reader++; + rwsem->holder = RWSEM_NO_HOLDER; + + up_wait(rwsem); + nxmutex_unlock(&rwsem->protected); +} + /**************************************************************************** * Name: init_rwsem *