add holder for mutex
Signed-off-by: lilei19 <lilei19@xiaomi.com>
This commit is contained in:
parent
6b89b6f945
commit
1d8af7e105
13 changed files with 510 additions and 153 deletions
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -30,27 +30,33 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <nuttx/clock.h>
|
||||||
#include <nuttx/semaphore.h>
|
#include <nuttx/semaphore.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define NXRMUTEX_NO_HOLDER (pid_t)-1
|
#define NXMUTEX_NO_HOLDER ((pid_t)-1)
|
||||||
#define NXMUTEX_INITIALIZER NXSEM_INITIALIZER(1, SEM_PRIO_INHERIT)
|
#define NXMUTEX_INITIALIZER {NXSEM_INITIALIZER(1, SEM_TYPE_MUTEX | \
|
||||||
#define NXRMUTEX_INITIALIZER {NXSEM_INITIALIZER(1, SEM_PRIO_INHERIT), \
|
SEM_PRIO_INHERIT), NXMUTEX_NO_HOLDER}
|
||||||
NXRMUTEX_NO_HOLDER, 0}
|
#define NXRMUTEX_INITIALIZER {NXMUTEX_INITIALIZER, 0}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Type Definitions
|
* Public Type Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
typedef sem_t mutex_t;
|
struct mutex_s
|
||||||
|
{
|
||||||
|
sem_t sem;
|
||||||
|
pid_t holder;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct mutex_s mutex_t;
|
||||||
|
|
||||||
struct rmutex_s
|
struct rmutex_s
|
||||||
{
|
{
|
||||||
mutex_t mutex;
|
mutex_t mutex;
|
||||||
pid_t holder;
|
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -91,14 +97,15 @@ extern "C"
|
||||||
|
|
||||||
static inline int nxmutex_init(FAR mutex_t *mutex)
|
static inline int nxmutex_init(FAR mutex_t *mutex)
|
||||||
{
|
{
|
||||||
int ret = _SEM_INIT(mutex, 0, 1);
|
int ret = _SEM_INIT(&mutex->sem, 0, 1);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
return _SEM_ERRVAL(ret);
|
return _SEM_ERRVAL(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
_SEM_SETPROTOCOL(mutex, SEM_PRIO_INHERIT);
|
mutex->holder = NXMUTEX_NO_HOLDER;
|
||||||
|
_SEM_SETPROTOCOL(&mutex->sem, SEM_TYPE_MUTEX | SEM_PRIO_INHERIT);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,16 +130,59 @@ static inline int nxmutex_init(FAR mutex_t *mutex)
|
||||||
|
|
||||||
static inline int nxmutex_destroy(FAR mutex_t *mutex)
|
static inline int nxmutex_destroy(FAR mutex_t *mutex)
|
||||||
{
|
{
|
||||||
int ret = _SEM_DESTROY(mutex);
|
int ret = _SEM_DESTROY(&mutex->sem);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
return _SEM_ERRVAL(ret);
|
return _SEM_ERRVAL(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex->holder = NXMUTEX_NO_HOLDER;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nxmutex_is_hold
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function check whether the caller hold the mutex
|
||||||
|
* referenced by 'mutex'.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* mutex - mutex descriptor.
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline bool nxmutex_is_hold(FAR mutex_t *mutex)
|
||||||
|
{
|
||||||
|
return mutex->holder == gettid();
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nxmutex_is_locked
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function get the lock state the mutex referenced by 'mutex'.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* mutex - mutex descriptor.
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline bool nxmutex_is_locked(FAR mutex_t *mutex)
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = _SEM_GETVALUE(&mutex->sem, &cnt);
|
||||||
|
|
||||||
|
return ret >= 0 && cnt < 1;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nxmutex_lock
|
* Name: nxmutex_lock
|
||||||
*
|
*
|
||||||
|
@ -157,13 +207,15 @@ static inline int nxmutex_lock(FAR mutex_t *mutex)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
DEBUGASSERT(!nxmutex_is_hold(mutex));
|
||||||
for (; ; )
|
for (; ; )
|
||||||
{
|
{
|
||||||
/* Take the semaphore (perhaps waiting) */
|
/* Take the semaphore (perhaps waiting) */
|
||||||
|
|
||||||
ret = _SEM_WAIT(mutex);
|
ret = _SEM_WAIT(&mutex->sem);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
|
mutex->holder = gettid();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,38 +252,72 @@ static inline int nxmutex_lock(FAR mutex_t *mutex)
|
||||||
|
|
||||||
static inline int nxmutex_trylock(FAR mutex_t *mutex)
|
static inline int nxmutex_trylock(FAR mutex_t *mutex)
|
||||||
{
|
{
|
||||||
int ret = _SEM_TRYWAIT(mutex);
|
int ret;
|
||||||
|
|
||||||
|
DEBUGASSERT(!nxmutex_is_hold(mutex));
|
||||||
|
ret = _SEM_TRYWAIT(&mutex->sem);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
return _SEM_ERRVAL(ret);
|
return _SEM_ERRVAL(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex->holder = gettid();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nxmutex_is_locked
|
* Name: nxmutex_timedlock
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function get the lock state the mutex referenced by 'mutex'.
|
* This function attempts to lock the mutex . If the mutex value
|
||||||
|
* is (<=) zero,then the calling task will not return until it
|
||||||
|
* successfully acquires the lock or timed out
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Input Parameters:
|
||||||
* mutex - mutex descriptor.
|
* mutex - Mutex object
|
||||||
|
* timeout - The time when mutex lock timed out
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Returned Value:
|
||||||
|
* OK The mutex successfully acquires
|
||||||
|
* EINVAL The mutex argument does not refer to a valid mutex. Or the
|
||||||
|
* thread would have blocked, and the abstime parameter specified
|
||||||
|
* a nanoseconds field value less than zero or greater than or
|
||||||
|
* equal to 1000 million.
|
||||||
|
* ETIMEDOUT The mutex could not be locked before the specified timeout
|
||||||
|
* expired.
|
||||||
|
* EDEADLK A deadlock condition was detected.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static inline bool nxmutex_is_locked(FAR mutex_t *mutex)
|
static inline int nxmutex_timedlock(FAR mutex_t *mutex, unsigned int timeout)
|
||||||
{
|
{
|
||||||
int cnt;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
struct timespec now;
|
||||||
|
struct timespec delay;
|
||||||
|
struct timespec rqtp;
|
||||||
|
|
||||||
ret = _SEM_GETVALUE(mutex, &cnt);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
DEBUGASSERT(ret == OK);
|
clock_ticks2time(MSEC2TICK(timeout), &delay);
|
||||||
|
clock_timespec_add(&now, &delay, &rqtp);
|
||||||
|
|
||||||
return cnt < 1;
|
/* Wait until we get the lock or until the timeout expires */
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ret = _SEM_CLOCKWAIT(&mutex->sem, CLOCK_MONOTONIC, &rqtp);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
ret = _SEM_ERRVAL(ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (ret == -EINTR || ret == -ECANCELED);
|
||||||
|
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
mutex->holder = gettid();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -258,7 +344,11 @@ static inline int nxmutex_unlock(FAR mutex_t *mutex)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = _SEM_POST(mutex);
|
DEBUGASSERT(nxmutex_is_hold(mutex));
|
||||||
|
|
||||||
|
mutex->holder = NXMUTEX_NO_HOLDER;
|
||||||
|
|
||||||
|
ret = _SEM_POST(&mutex->sem);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
return _SEM_ERRVAL(ret);
|
return _SEM_ERRVAL(ret);
|
||||||
|
@ -282,7 +372,72 @@ static inline int nxmutex_unlock(FAR mutex_t *mutex)
|
||||||
|
|
||||||
static inline int nxmutex_reset(FAR mutex_t *mutex)
|
static inline int nxmutex_reset(FAR mutex_t *mutex)
|
||||||
{
|
{
|
||||||
return nxsem_reset(mutex, 1);
|
int ret;
|
||||||
|
|
||||||
|
ret = nxsem_reset(&mutex->sem, 1);
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
mutex->holder = NXMUTEX_NO_HOLDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nxmutex_breaklock
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function attempts to break the mutex
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* mutex - Mutex descriptor.
|
||||||
|
* locked - Is the mutex break success
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* This is an internal OS interface and should not be used by applications.
|
||||||
|
* It follows the NuttX internal error return policy: Zero (OK) is
|
||||||
|
* returned on success. A negated errno value is returned on failure.
|
||||||
|
* Possible returned errors:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline int nxmutex_breaklock(FAR mutex_t *mutex, FAR bool *locked)
|
||||||
|
{
|
||||||
|
int ret = OK;
|
||||||
|
|
||||||
|
*locked = false;
|
||||||
|
if (nxmutex_is_hold(mutex))
|
||||||
|
{
|
||||||
|
ret = nxmutex_unlock(mutex);
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
*locked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nxmutex_restorelock
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function attempts to restore the mutex.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* mutex - mutex descriptor.
|
||||||
|
* locked - true: it's mean that the mutex is broke success
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* This is an internal OS interface and should not be used by applications.
|
||||||
|
* It follows the NuttX internal error return policy: Zero (OK) is
|
||||||
|
* returned on success. A negated errno value is returned on failure
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline int nxmutex_restorelock(FAR mutex_t *mutex, bool locked)
|
||||||
|
{
|
||||||
|
return locked ? nxmutex_lock(mutex) : OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -308,7 +463,6 @@ static inline int nxmutex_reset(FAR mutex_t *mutex)
|
||||||
static inline int nxrmutex_init(FAR rmutex_t *rmutex)
|
static inline int nxrmutex_init(FAR rmutex_t *rmutex)
|
||||||
{
|
{
|
||||||
rmutex->count = 0;
|
rmutex->count = 0;
|
||||||
rmutex->holder = NXRMUTEX_NO_HOLDER;
|
|
||||||
return nxmutex_init(&rmutex->mutex);
|
return nxmutex_init(&rmutex->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,7 +484,52 @@ static inline int nxrmutex_init(FAR rmutex_t *rmutex)
|
||||||
|
|
||||||
static inline int nxrmutex_destroy(FAR rmutex_t *rmutex)
|
static inline int nxrmutex_destroy(FAR rmutex_t *rmutex)
|
||||||
{
|
{
|
||||||
return nxmutex_destroy(&rmutex->mutex);
|
int ret = nxmutex_destroy(&rmutex->mutex);
|
||||||
|
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
rmutex->count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nxrmutex_is_hold
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function check whether the caller hold the recursive mutex
|
||||||
|
* referenced by 'rmutex'.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* rmutex - Recursive mutex descriptor.
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline bool nxrmutex_is_hold(FAR rmutex_t *rmutex)
|
||||||
|
{
|
||||||
|
return nxmutex_is_hold(&rmutex->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nxrmutex_is_locked
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function get the lock state the recursive mutex
|
||||||
|
* referenced by 'rmutex'.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* rmutex - Recursive mutex descriptor.
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline bool nxrmutex_is_locked(FAR rmutex_t *rmutex)
|
||||||
|
{
|
||||||
|
return nxmutex_is_locked(&rmutex->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -354,23 +553,17 @@ static inline int nxrmutex_destroy(FAR rmutex_t *rmutex)
|
||||||
|
|
||||||
static inline int nxrmutex_lock(FAR rmutex_t *rmutex)
|
static inline int nxrmutex_lock(FAR rmutex_t *rmutex)
|
||||||
{
|
{
|
||||||
pid_t tid = gettid();
|
int ret = OK;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (rmutex->holder == tid)
|
if (!nxrmutex_is_hold(rmutex))
|
||||||
{
|
|
||||||
DEBUGASSERT(rmutex->count < UINT_MAX);
|
|
||||||
rmutex->count++;
|
|
||||||
ret = OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
ret = nxmutex_lock(&rmutex->mutex);
|
ret = nxmutex_lock(&rmutex->mutex);
|
||||||
if (ret == OK)
|
}
|
||||||
{
|
|
||||||
rmutex->holder = tid;
|
if (ret >= 0)
|
||||||
rmutex->count = 1;
|
{
|
||||||
}
|
DEBUGASSERT(rmutex->count < UINT_MAX);
|
||||||
|
++rmutex->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -401,64 +594,64 @@ static inline int nxrmutex_lock(FAR rmutex_t *rmutex)
|
||||||
|
|
||||||
static inline int nxrmutex_trylock(FAR rmutex_t *rmutex)
|
static inline int nxrmutex_trylock(FAR rmutex_t *rmutex)
|
||||||
{
|
{
|
||||||
pid_t tid = gettid();
|
int ret = OK;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (rmutex->holder == tid)
|
if (!nxrmutex_is_hold(rmutex))
|
||||||
{
|
|
||||||
DEBUGASSERT(rmutex->count < UINT_MAX);
|
|
||||||
rmutex->count++;
|
|
||||||
ret = OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
ret = nxmutex_trylock(&rmutex->mutex);
|
ret = nxmutex_trylock(&rmutex->mutex);
|
||||||
if (ret == OK)
|
}
|
||||||
{
|
|
||||||
rmutex->holder = tid;
|
if (ret >= 0)
|
||||||
rmutex->count = 1;
|
{
|
||||||
}
|
DEBUGASSERT(rmutex->count < UINT_MAX);
|
||||||
|
++rmutex->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: nxrmutex_is_locked
|
* Name: nxrmutex_timedlock
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function get the lock state the recursive mutex
|
* This function attempts to lock the mutex . If the mutex value
|
||||||
* referenced by 'rmutex'.
|
* is (<=) zero,then the calling task will not return until it
|
||||||
|
* successfully acquires the lock or timed out
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Input Parameters:
|
||||||
* rmutex - Recursive mutex descriptor.
|
* rmutex - Rmutex object
|
||||||
|
* timeout - The time when mutex lock timed out
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Returned Value:
|
||||||
|
* OK The mutex successfully acquires
|
||||||
|
* EINVAL The mutex argument does not refer to a valid mutex. Or the
|
||||||
|
* thread would have blocked, and the abstime parameter specified
|
||||||
|
* a nanoseconds field value less than zero or greater than or
|
||||||
|
* equal to 1000 million.
|
||||||
|
* ETIMEDOUT The mutex could not be locked before the specified timeout
|
||||||
|
* expired.
|
||||||
|
* EDEADLK A deadlock condition was detected.
|
||||||
|
* ECANCELED May be returned if the thread is canceled while waiting.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static inline bool nxrmutex_is_locked(FAR rmutex_t *rmutex)
|
static inline int nxrmutex_timedlock(FAR rmutex_t *rmutex,
|
||||||
|
unsigned int timeout)
|
||||||
{
|
{
|
||||||
return rmutex->count > 0;
|
int ret = OK;
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
if (!nxrmutex_is_hold(rmutex))
|
||||||
* Name: nxrmutex_is_hold
|
{
|
||||||
*
|
ret = nxmutex_timedlock(&rmutex->mutex, timeout);
|
||||||
* Description:
|
}
|
||||||
* This function check whether the caller hold the recursive mutex
|
|
||||||
* referenced by 'rmutex'.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* rmutex - Recursive mutex descriptor.
|
|
||||||
*
|
|
||||||
* Return Value:
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static inline bool nxrmutex_is_hold(FAR rmutex_t *rmutex)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
return rmutex->holder == gettid();
|
DEBUGASSERT(rmutex->count < UINT_MAX);
|
||||||
|
++rmutex->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -484,16 +677,43 @@ static inline bool nxrmutex_is_hold(FAR rmutex_t *rmutex)
|
||||||
|
|
||||||
static inline int nxrmutex_unlock(FAR rmutex_t *rmutex)
|
static inline int nxrmutex_unlock(FAR rmutex_t *rmutex)
|
||||||
{
|
{
|
||||||
pid_t tid = gettid();
|
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
DEBUGASSERT(rmutex->holder == tid);
|
|
||||||
DEBUGASSERT(rmutex->count > 0);
|
DEBUGASSERT(rmutex->count > 0);
|
||||||
|
|
||||||
if (rmutex->count-- == 1)
|
if (--rmutex->count == 0)
|
||||||
{
|
{
|
||||||
rmutex->holder = NXRMUTEX_NO_HOLDER;
|
|
||||||
ret = nxmutex_unlock(&rmutex->mutex);
|
ret = nxmutex_unlock(&rmutex->mutex);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
++rmutex->count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: nxrmutex_reset
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function reset lock state.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* rmutex - rmutex descriptor.
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline int nxrmutex_reset(FAR rmutex_t *rmutex)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = nxmutex_reset(&rmutex->mutex);
|
||||||
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
rmutex->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -519,16 +739,18 @@ static inline int nxrmutex_unlock(FAR rmutex_t *rmutex)
|
||||||
static inline int nxrmutex_breaklock(FAR rmutex_t *rmutex,
|
static inline int nxrmutex_breaklock(FAR rmutex_t *rmutex,
|
||||||
FAR unsigned int *count)
|
FAR unsigned int *count)
|
||||||
{
|
{
|
||||||
pid_t tid = gettid();
|
int ret = OK;
|
||||||
int ret = -EPERM;
|
|
||||||
|
|
||||||
if (rmutex->holder == tid)
|
*count = 0;
|
||||||
|
if (nxrmutex_is_hold(rmutex))
|
||||||
{
|
{
|
||||||
*count = rmutex->count;
|
*count = rmutex->count;
|
||||||
rmutex->count = 0;
|
rmutex->count = 0;
|
||||||
rmutex->holder = NXRMUTEX_NO_HOLDER;
|
ret = nxmutex_unlock(&rmutex->mutex);
|
||||||
nxmutex_unlock(&rmutex->mutex);
|
if (ret < 0)
|
||||||
ret = OK;
|
{
|
||||||
|
rmutex->count = *count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -554,15 +776,15 @@ static inline int nxrmutex_breaklock(FAR rmutex_t *rmutex,
|
||||||
static inline int nxrmutex_restorelock(FAR rmutex_t *rmutex,
|
static inline int nxrmutex_restorelock(FAR rmutex_t *rmutex,
|
||||||
unsigned int count)
|
unsigned int count)
|
||||||
{
|
{
|
||||||
pid_t tid = gettid();
|
int ret = OK;
|
||||||
int ret;
|
|
||||||
|
|
||||||
DEBUGASSERT(rmutex->holder != tid);
|
if (count != 0)
|
||||||
ret = nxmutex_lock(&rmutex->mutex);
|
|
||||||
if (ret == OK)
|
|
||||||
{
|
{
|
||||||
rmutex->holder = tid;
|
ret = nxmutex_lock(&rmutex->mutex);
|
||||||
rmutex->count = count;
|
if (ret >= 0)
|
||||||
|
{
|
||||||
|
rmutex->count = count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -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
|
||||||
|
@ -397,6 +398,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
|
||||||
*
|
*
|
||||||
|
@ -419,6 +444,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
|
||||||
*
|
*
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -43,6 +43,8 @@
|
||||||
#define SEM_PRIO_PROTECT 2
|
#define SEM_PRIO_PROTECT 2
|
||||||
#define SEM_PRIO_MASK 3
|
#define SEM_PRIO_MASK 3
|
||||||
|
|
||||||
|
#define SEM_TYPE_MUTEX 4
|
||||||
|
|
||||||
/* Value returned by sem_open() in the event of a failure. */
|
/* Value returned by sem_open() in the event of a failure. */
|
||||||
|
|
||||||
#define SEM_FAILED NULL
|
#define SEM_FAILED NULL
|
||||||
|
@ -99,14 +101,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 +124,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))
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -704,7 +704,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)
|
||||||
|
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue