add holder for mutex

Signed-off-by: lilei19 <lilei19@xiaomi.com>
This commit is contained in:
lilei19
2023-01-17 19:15:34 +08:00
committed by Xiang Xiao
parent 64dd7e6376
commit fc176addeb
13 changed files with 504 additions and 153 deletions
+8 -8
View File
@@ -174,13 +174,13 @@ void _raise_r(struct _reent *r)
void _lock_init(_lock_t *lock) void _lock_init(_lock_t *lock)
{ {
nxmutex_init(&g_nxlock_common); nxmutex_init(&g_nxlock_common);
nxsem_get_value(&g_nxlock_common, lock); nxsem_get_value(&g_nxlock_common.sem, lock);
} }
void _lock_init_recursive(_lock_t *lock) void _lock_init_recursive(_lock_t *lock)
{ {
nxmutex_init(&g_nxlock_recursive); nxmutex_init(&g_nxlock_recursive);
nxsem_get_value(&g_nxlock_recursive, lock); nxsem_get_value(&g_nxlock_recursive.sem, lock);
} }
void _lock_close(_lock_t *lock) void _lock_close(_lock_t *lock)
@@ -198,39 +198,39 @@ void _lock_close_recursive(_lock_t *lock)
void _lock_acquire(_lock_t *lock) void _lock_acquire(_lock_t *lock)
{ {
nxmutex_lock(&g_nxlock_common); nxmutex_lock(&g_nxlock_common);
nxsem_get_value(&g_nxlock_common, lock); nxsem_get_value(&g_nxlock_common.sem, lock);
} }
void _lock_acquire_recursive(_lock_t *lock) void _lock_acquire_recursive(_lock_t *lock)
{ {
nxmutex_lock(&g_nxlock_recursive); nxmutex_lock(&g_nxlock_recursive);
nxsem_get_value(&g_nxlock_recursive, lock); nxsem_get_value(&g_nxlock_recursive.sem, lock);
} }
int _lock_try_acquire(_lock_t *lock) int _lock_try_acquire(_lock_t *lock)
{ {
nxmutex_trylock(&g_nxlock_common); nxmutex_trylock(&g_nxlock_common);
nxsem_get_value(&g_nxlock_common, lock); nxsem_get_value(&g_nxlock_common.sem, lock);
return 0; return 0;
} }
int _lock_try_acquire_recursive(_lock_t *lock) int _lock_try_acquire_recursive(_lock_t *lock)
{ {
nxmutex_trylock(&g_nxlock_recursive); nxmutex_trylock(&g_nxlock_recursive);
nxsem_get_value(&g_nxlock_recursive, lock); nxsem_get_value(&g_nxlock_recursive.sem, lock);
return 0; return 0;
} }
void _lock_release(_lock_t *lock) void _lock_release(_lock_t *lock)
{ {
nxmutex_unlock(&g_nxlock_common); nxmutex_unlock(&g_nxlock_common);
nxsem_get_value(&g_nxlock_common, lock); nxsem_get_value(&g_nxlock_common.sem, lock);
} }
void _lock_release_recursive(_lock_t *lock) void _lock_release_recursive(_lock_t *lock)
{ {
nxmutex_unlock(&g_nxlock_recursive); nxmutex_unlock(&g_nxlock_recursive);
nxsem_get_value(&g_nxlock_recursive, lock); nxsem_get_value(&g_nxlock_recursive.sem, lock);
} }
struct _reent *__getreent(void) struct _reent *__getreent(void)
+19 -19
View File
@@ -1028,12 +1028,12 @@ static int alt1250_open(FAR struct file *filep)
if (ret == OK) if (ret == OK)
{ {
nxsem_init(&dev->waitlist.lock, 0, 1); nxmutex_init(&dev->waitlist.lock);
nxsem_init(&dev->replylist.lock, 0, 1); nxmutex_init(&dev->replylist.lock);
nxsem_init(&dev->evtmaplock, 0, 1); nxmutex_init(&dev->evtmaplock);
nxsem_init(&dev->pfdlock, 0, 1); nxmutex_init(&dev->pfdlock);
nxsem_init(&dev->senddisablelock, 0, 1); nxmutex_init(&dev->senddisablelock);
nxsem_init(&dev->select_inst.stat_lock, 0, 1); nxmutex_init(&dev->select_inst.stat_lock);
sq_init(&dev->waitlist.queue); sq_init(&dev->waitlist.queue);
sq_init(&dev->replylist.queue); sq_init(&dev->replylist.queue);
@@ -1048,12 +1048,12 @@ static int alt1250_open(FAR struct file *filep)
m_err("thread create failed: %d\n", errno); m_err("thread create failed: %d\n", errno);
ret = -errno; ret = -errno;
nxsem_destroy(&dev->waitlist.lock); nxmutex_destroy(&dev->waitlist.lock);
nxsem_destroy(&dev->replylist.lock); nxmutex_destroy(&dev->replylist.lock);
nxsem_destroy(&dev->evtmaplock); nxmutex_destroy(&dev->evtmaplock);
nxsem_destroy(&dev->pfdlock); nxmutex_destroy(&dev->pfdlock);
nxsem_destroy(&dev->senddisablelock); nxmutex_destroy(&dev->senddisablelock);
nxsem_destroy(&dev->select_inst.stat_lock); nxmutex_destroy(&dev->select_inst.stat_lock);
nxmutex_lock(&dev->refslock); nxmutex_lock(&dev->refslock);
dev->crefs--; dev->crefs--;
@@ -1103,12 +1103,12 @@ static int alt1250_close(FAR struct file *filep)
if (ret == OK) if (ret == OK)
{ {
nxsem_destroy(&dev->waitlist.lock); nxmutex_destroy(&dev->waitlist.lock);
nxsem_destroy(&dev->replylist.lock); nxmutex_destroy(&dev->replylist.lock);
nxsem_destroy(&dev->evtmaplock); nxmutex_destroy(&dev->evtmaplock);
nxsem_destroy(&dev->pfdlock); nxmutex_destroy(&dev->pfdlock);
nxsem_destroy(&dev->senddisablelock); nxmutex_destroy(&dev->senddisablelock);
nxsem_destroy(&dev->select_inst.stat_lock); nxmutex_destroy(&dev->select_inst.stat_lock);
altmdm_fin(); altmdm_fin();
pthread_join(dev->recvthread, NULL); pthread_join(dev->recvthread, NULL);
@@ -1286,7 +1286,7 @@ FAR void *alt1250_register(FAR const char *devpath,
priv->spi = dev; priv->spi = dev;
priv->lower = lower; priv->lower = lower;
nxsem_init(&priv->refslock, 0, 1); nxmutex_init(&priv->refslock);
ret = register_driver(devpath, &g_alt1250fops, 0666, priv); ret = register_driver(devpath, &g_alt1250fops, 0666, priv);
if (ret < 0) if (ret < 0)
+1 -1
View File
@@ -510,7 +510,7 @@ int usrsock_request(FAR struct iovec *iov, unsigned int iovcnt)
/* Set outstanding request for daemon to handle. */ /* Set outstanding request for daemon to handle. */
net_sem_wait_uninterruptible(&dev->devlock); net_mutex_lock(&dev->devlock);
if (usrsockdev_is_opened(dev)) if (usrsockdev_is_opened(dev))
{ {
+7 -6
View File
@@ -29,6 +29,7 @@
#include <nuttx/fs/ioctl.h> #include <nuttx/fs/ioctl.h>
#include <nuttx/spi/spi.h> #include <nuttx/spi/spi.h>
#include <nuttx/queue.h> #include <nuttx/queue.h>
#include <nuttx/mutex.h>
#include <semaphore.h> #include <semaphore.h>
#include <debug.h> #include <debug.h>
#include <nuttx/irq.h> #include <nuttx/irq.h>
@@ -285,7 +286,7 @@ typedef struct alt_evtbuf_inst_s
uint16_t altcid; uint16_t altcid;
FAR void **outparam; FAR void **outparam;
size_t outparamlen; size_t outparamlen;
sem_t stat_lock; mutex_t stat_lock;
alt_evtbuf_state_t stat; alt_evtbuf_state_t stat;
} alt_evtbuf_inst_t; } alt_evtbuf_inst_t;
@@ -323,25 +324,25 @@ typedef struct altcom_fd_set_s altcom_fd_set;
struct alt_queue_s struct alt_queue_s
{ {
sq_queue_t queue; sq_queue_t queue;
sem_t lock; mutex_t lock;
}; };
struct alt1250_dev_s struct alt1250_dev_s
{ {
FAR struct spi_dev_s *spi; FAR struct spi_dev_s *spi;
FAR const struct alt1250_lower_s *lower; FAR const struct alt1250_lower_s *lower;
sem_t refslock; mutex_t refslock;
uint8_t crefs; uint8_t crefs;
struct alt_queue_s waitlist; struct alt_queue_s waitlist;
struct alt_queue_s replylist; struct alt_queue_s replylist;
uint64_t evtbitmap; uint64_t evtbitmap;
sem_t evtmaplock; mutex_t evtmaplock;
sem_t pfdlock; mutex_t pfdlock;
FAR struct pollfd *pfd; FAR struct pollfd *pfd;
pthread_t recvthread; pthread_t recvthread;
FAR struct alt_evtbuffer_s *evtbuff; FAR struct alt_evtbuffer_s *evtbuff;
uint32_t discardcnt; uint32_t discardcnt;
sem_t senddisablelock; mutex_t senddisablelock;
bool senddisable; bool senddisable;
FAR alt_container_t *select_container; FAR alt_container_t *select_container;
struct alt_evtbuf_inst_s select_inst; struct alt_evtbuf_inst_s select_inst;
+312 -95
View File
File diff suppressed because it is too large Load Diff
+47
View File
@@ -35,6 +35,7 @@
#include <semaphore.h> #include <semaphore.h>
#include <nuttx/queue.h> #include <nuttx/queue.h>
#include <nuttx/mutex.h>
#ifdef CONFIG_MM_IOB #ifdef CONFIG_MM_IOB
# include <nuttx/mm/iob.h> # include <nuttx/mm/iob.h>
#endif #endif
@@ -392,6 +393,30 @@ void net_unlock(void);
int net_sem_timedwait(sem_t *sem, unsigned int timeout); int net_sem_timedwait(sem_t *sem, unsigned int timeout);
/****************************************************************************
* Name: net_mutex_timedlock
*
* Description:
* Atomically wait for mutex (or a timeout) while temporarily releasing
* the lock on the network.
*
* Caution should be utilized. Because the network lock is relinquished
* during the wait, there could be changes in the network state that occur
* before the lock is recovered. Your design should account for this
* possibility.
*
* Input Parameters:
* mutex - A reference to the mutex to be taken.
* timeout - The relative time to wait until a timeout is declared.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int net_mutex_timedlock(mutex_t *mutex, unsigned int timeout);
/**************************************************************************** /****************************************************************************
* Name: net_sem_wait * Name: net_sem_wait
* *
@@ -414,6 +439,28 @@ int net_sem_timedwait(sem_t *sem, unsigned int timeout);
int net_sem_wait(sem_t *sem); int net_sem_wait(sem_t *sem);
/****************************************************************************
* Name: net_mutex_lock
*
* Description:
* Atomically wait for mutex while temporarily releasing the network lock.
*
* Caution should be utilized. Because the network lock is relinquished
* during the wait, there could be changes in the network state that occur
* before the lock is recovered. Your design should account for this
* possibility.
*
* Input Parameters:
* mutex - A reference to the mutex to be taken.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int net_mutex_lock(mutex_t *mutex);
/**************************************************************************** /****************************************************************************
* Name: net_sem_timedwait_uninterruptible * Name: net_sem_timedwait_uninterruptible
* *
+6 -6
View File
@@ -40,21 +40,21 @@
#ifdef CONFIG_PRIORITY_INHERITANCE #ifdef CONFIG_PRIORITY_INHERITANCE
# if CONFIG_SEM_PREALLOCHOLDERS > 0 # if CONFIG_SEM_PREALLOCHOLDERS > 0
/* semcount, waitlist, flags, hhead */ /* semcount, flags, waitlist, hhead */
# define NXSEM_INITIALIZER(c, f) \ # define NXSEM_INITIALIZER(c, f) \
{(c), SEM_WAITLIST_INITIALIZER, (f), NULL} {(c), (f), SEM_WAITLIST_INITIALIZER, NULL}
# else # else
/* semcount, waitlist, flags, holder[2] */ /* semcount, flags, waitlist, holder[2] */
# define NXSEM_INITIALIZER(c, f) \ # define NXSEM_INITIALIZER(c, f) \
{(c), SEM_WAITLIST_INITIALIZER, (f), {SEMHOLDER_INITIALIZER, SEMHOLDER_INITIALIZER}} {(c), (f), SEM_WAITLIST_INITIALIZER, {SEMHOLDER_INITIALIZER, SEMHOLDER_INITIALIZER}}
# endif # endif
#else /* CONFIG_PRIORITY_INHERITANCE */ #else /* CONFIG_PRIORITY_INHERITANCE */
/* semcount, waitlist */ /* semcount, flags, waitlist */
# define NXSEM_INITIALIZER(c, f) \ # define NXSEM_INITIALIZER(c, f) \
{(c), SEM_WAITLIST_INITIALIZER} {(c), (f), SEM_WAITLIST_INITIALIZER}
#endif /* CONFIG_PRIORITY_INHERITANCE */ #endif /* CONFIG_PRIORITY_INHERITANCE */
/* Most internal nxsem_* interfaces are not available in the user space in /* Most internal nxsem_* interfaces are not available in the user space in
+11 -9
View File
@@ -42,6 +42,7 @@
#define SEM_PRIO_INHERIT 1 #define SEM_PRIO_INHERIT 1
#define SEM_PRIO_PROTECT 2 #define SEM_PRIO_PROTECT 2
#define SEM_PRIO_MASK 3 #define SEM_PRIO_MASK 3
#define SEM_PRIO_MUTEX 4
/* Value returned by sem_open() in the event of a failure. */ /* Value returned by sem_open() in the event of a failure. */
@@ -99,14 +100,15 @@ struct sem_s
volatile int16_t semcount; /* >0 -> Num counts available */ volatile int16_t semcount; /* >0 -> Num counts available */
/* <0 -> Num tasks waiting for semaphore */ /* <0 -> Num tasks waiting for semaphore */
dq_queue_t waitlist;
/* If priority inheritance is enabled, then we have to keep track of which /* If priority inheritance is enabled, then we have to keep track of which
* tasks hold references to the semaphore. * tasks hold references to the semaphore.
*/ */
uint8_t flags; /* See SEM_PRIO_* definitions */
dq_queue_t waitlist;
#ifdef CONFIG_PRIORITY_INHERITANCE #ifdef CONFIG_PRIORITY_INHERITANCE
uint8_t flags; /* See PRIOINHERIT_FLAGS_* definitions */
# if CONFIG_SEM_PREALLOCHOLDERS > 0 # if CONFIG_SEM_PREALLOCHOLDERS > 0
FAR struct semholder_s *hhead; /* List of holders of semaphore counts */ FAR struct semholder_s *hhead; /* List of holders of semaphore counts */
# else # else
@@ -121,21 +123,21 @@ typedef struct sem_s sem_t;
#ifdef CONFIG_PRIORITY_INHERITANCE #ifdef CONFIG_PRIORITY_INHERITANCE
# if CONFIG_SEM_PREALLOCHOLDERS > 0 # if CONFIG_SEM_PREALLOCHOLDERS > 0
/* semcount, waitlist, flags, hhead */ /* semcount, flags, waitlist, hhead */
# define SEM_INITIALIZER(c) \ # define SEM_INITIALIZER(c) \
{(c), SEM_WAITLIST_INITIALIZER, 0, NULL} {(c), 0, SEM_WAITLIST_INITIALIZER, NULL}
# else # else
/* semcount, waitlist, flags, holder[2] */ /* semcount, flags, waitlist, holder[2] */
# define SEM_INITIALIZER(c) \ # define SEM_INITIALIZER(c) \
{(c), SEM_WAITLIST_INITIALIZER, 0, {SEMHOLDER_INITIALIZER, SEMHOLDER_INITIALIZER}} {(c), 0, SEM_WAITLIST_INITIALIZER, {SEMHOLDER_INITIALIZER, SEMHOLDER_INITIALIZER}}
# endif # endif
#else #else
/* semcount, waitlist */ /* semcount, flags, waitlist */
# define SEM_INITIALIZER(c) \ # define SEM_INITIALIZER(c) \
{(c), SEM_WAITLIST_INITIALIZER} {(c), 0, SEM_WAITLIST_INITIALIZER}
#endif #endif
# define SEM_WAITLIST(sem) (&((sem)->waitlist)) # define SEM_WAITLIST(sem) (&((sem)->waitlist))
-5
View File
@@ -54,11 +54,6 @@ int sem_getprotocol(FAR sem_t *sem, FAR int *protocol)
{ {
DEBUGASSERT(sem != NULL && protocol != NULL); DEBUGASSERT(sem != NULL && protocol != NULL);
#ifdef CONFIG_PRIORITY_INHERITANCE
*protocol = sem->flags; *protocol = sem->flags;
#else
*protocol = SEM_PRIO_NONE;
#endif
return OK; return OK;
} }
+2 -1
View File
@@ -76,8 +76,9 @@ int nxsem_init(FAR sem_t *sem, int pshared, unsigned int value)
/* Initialize to support priority inheritance */ /* Initialize to support priority inheritance */
#ifdef CONFIG_PRIORITY_INHERITANCE
sem->flags = 0; sem->flags = 0;
#ifdef CONFIG_PRIORITY_INHERITANCE
# if CONFIG_SEM_PREALLOCHOLDERS > 0 # if CONFIG_SEM_PREALLOCHOLDERS > 0
sem->hhead = NULL; sem->hhead = NULL;
# else # else
+1 -1
View File
@@ -191,7 +191,7 @@ static void work_process(FAR struct usr_wqueue_s *wqueue)
{ {
/* Wait indefinitely until work_queue has new items */ /* Wait indefinitely until work_queue has new items */
nxmutex_lock(&wqueue->wake); _SEM_WAIT(&wqueue->wake);
} }
else else
{ {
+2 -2
View File
@@ -641,7 +641,7 @@ int usrsock_do_request(FAR struct usrsock_conn_s *conn,
/* Set outstanding request for daemon to handle. */ /* Set outstanding request for daemon to handle. */
net_sem_wait_uninterruptible(&req->lock); net_mutex_lock(&req->lock);
if (++req->newxid == 0) if (++req->newxid == 0)
{ {
++req->newxid; ++req->newxid;
@@ -700,7 +700,7 @@ void usrsock_abort(void)
* requests. * requests.
*/ */
ret = net_sem_timedwait(&req->lock, 10); ret = net_mutex_timedlock(&req->lock, 10);
if (ret < 0) if (ret < 0)
{ {
if (ret != -ETIMEDOUT && ret != -EINTR) if (ret != -ETIMEDOUT && ret != -EINTR)
+88
View File
@@ -242,6 +242,69 @@ int net_sem_timedwait(sem_t *sem, unsigned int timeout)
return _net_timedwait(sem, true, timeout); return _net_timedwait(sem, true, timeout);
} }
/****************************************************************************
* Name: net_mutex_timedlock
*
* Description:
* Atomically wait for mutex (or a timeout) while temporarily releasing
* the lock on the network.
*
* Caution should be utilized. Because the network lock is relinquished
* during the wait, there could be changes in the network state that occur
* before the lock is recovered. Your design should account for this
* possibility.
*
* Input Parameters:
* mutex - A reference to the mutex to be taken.
* timeout - The relative time to wait until a timeout is declared.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int net_mutex_timedlock(mutex_t *mutex, unsigned int timeout)
{
unsigned int count;
irqstate_t flags;
int blresult;
int ret;
flags = enter_critical_section(); /* No interrupts */
sched_lock(); /* No context switches */
/* Release the network lock, remembering my count. net_breaklock will
* return a negated value if the caller does not hold the network lock.
*/
blresult = net_breaklock(&count);
/* Now take the mutex, waiting if so requested. */
if (timeout != UINT_MAX)
{
ret = nxmutex_timedlock(mutex, timeout);
}
else
{
/* Wait as long as necessary to get the lock */
ret = nxmutex_lock(mutex);
}
/* Recover the network lock at the proper count (if we held it before) */
if (blresult >= 0)
{
net_restorelock(count);
}
sched_unlock();
leave_critical_section(flags);
return ret;
}
/**************************************************************************** /****************************************************************************
* Name: net_sem_wait * Name: net_sem_wait
* *
@@ -267,6 +330,31 @@ int net_sem_wait(sem_t *sem)
return net_sem_timedwait(sem, UINT_MAX); return net_sem_timedwait(sem, UINT_MAX);
} }
/****************************************************************************
* Name: net_mutex_lock
*
* Description:
* Atomically wait for mutex while temporarily releasing the network lock.
*
* Caution should be utilized. Because the network lock is relinquished
* during the wait, there could be changes in the network state that occur
* before the lock is recovered. Your design should account for this
* possibility.
*
* Input Parameters:
* mutex - A reference to the mutex to be taken.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int net_mutex_lock(mutex_t *mutex)
{
return net_mutex_timedlock(mutex, UINT_MAX);
}
/**************************************************************************** /****************************************************************************
* Name: net_sem_timedwait_uninterruptible * Name: net_sem_timedwait_uninterruptible
* *