driver/sensor: using standard recursive mutex api
Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
38393cfc94
commit
78eb832e23
@ -37,6 +37,7 @@
|
||||
#include <nuttx/list.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/mm/circbuf.h>
|
||||
#include <nuttx/mutex.h>
|
||||
#include <nuttx/sensors/sensor.h>
|
||||
|
||||
/****************************************************************************
|
||||
@ -94,9 +95,7 @@ struct sensor_upperhalf_s
|
||||
FAR struct sensor_lowerhalf_s *lower; /* The handle of lower half driver */
|
||||
struct sensor_state_s state; /* The state of sensor device */
|
||||
struct circbuf_s buffer; /* The circular buffer of sensor device */
|
||||
sem_t exclsem; /* Manages exclusive access to file operations */
|
||||
pid_t semholder; /* The current holder of the semaphore */
|
||||
int16_t semcount; /* Number of counts held */
|
||||
rmutex_t lock; /* Manages exclusive access to file operations */
|
||||
struct list_node userlist; /* List of users */
|
||||
};
|
||||
|
||||
@ -178,38 +177,6 @@ static const struct file_operations g_sensor_fops =
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void sensor_semtake(FAR struct sensor_upperhalf_s *upper)
|
||||
{
|
||||
pid_t pid = gettid();
|
||||
|
||||
if (pid == upper->semholder)
|
||||
{
|
||||
upper->semcount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
nxsem_wait_uninterruptible(&upper->exclsem);
|
||||
upper->semholder = pid;
|
||||
upper->semcount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void sensor_semgive(FAR struct sensor_upperhalf_s *upper)
|
||||
{
|
||||
DEBUGASSERT(upper->semholder == gettid());
|
||||
|
||||
if (upper->semcount > 1)
|
||||
{
|
||||
upper->semcount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
upper->semholder = INVALID_PROCESS_ID;
|
||||
upper->semcount = 0;
|
||||
nxsem_post(&upper->exclsem);
|
||||
}
|
||||
}
|
||||
|
||||
static bool sensor_in_range(unsigned long left, unsigned long value,
|
||||
unsigned long right)
|
||||
{
|
||||
@ -392,7 +359,7 @@ static int sensor_open(FAR struct file *filep)
|
||||
FAR struct sensor_user_s *user;
|
||||
int ret = 0;
|
||||
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
user = kmm_zalloc(sizeof(struct sensor_user_s));
|
||||
if (user == NULL)
|
||||
{
|
||||
@ -464,7 +431,7 @@ errout_with_open:
|
||||
errout_with_user:
|
||||
kmm_free(user);
|
||||
errout_with_sem:
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -476,13 +443,13 @@ static int sensor_close(FAR struct file *filep)
|
||||
FAR struct sensor_user_s *user = filep->f_priv;
|
||||
int ret = 0;
|
||||
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
if (lower->ops->close)
|
||||
{
|
||||
ret = lower->ops->close(lower, filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -509,7 +476,7 @@ static int sensor_close(FAR struct file *filep)
|
||||
/* The user is closed, notify to other users */
|
||||
|
||||
sensor_pollnotify(upper, POLLPRI);
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
|
||||
kmm_free(user);
|
||||
return ret;
|
||||
@ -530,19 +497,19 @@ static ssize_t sensor_read(FAR struct file *filep, FAR char *buffer,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
if (lower->ops->fetch)
|
||||
{
|
||||
if (!(filep->f_oflags & O_NONBLOCK))
|
||||
{
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
ret = nxsem_wait_uninterruptible(&user->buffersem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
}
|
||||
else if (!upper->state.nsubscribers)
|
||||
{
|
||||
@ -604,14 +571,14 @@ static ssize_t sensor_read(FAR struct file *filep, FAR char *buffer,
|
||||
}
|
||||
else
|
||||
{
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
ret = nxsem_wait_uninterruptible(&user->buffersem);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -641,7 +608,7 @@ static ssize_t sensor_read(FAR struct file *filep, FAR char *buffer,
|
||||
}
|
||||
|
||||
out:
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -669,27 +636,27 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
case SNIOC_GET_STATE:
|
||||
{
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
memcpy((FAR void *)(uintptr_t)arg,
|
||||
&upper->state, sizeof(upper->state));
|
||||
user->changed = false;
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
}
|
||||
break;
|
||||
|
||||
case SNIOC_SET_INTERVAL:
|
||||
{
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
ret = sensor_update_interval(filep, upper, user, arg);
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
}
|
||||
break;
|
||||
|
||||
case SNIOC_BATCH:
|
||||
{
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
ret = sensor_update_latency(filep, upper, user, arg);
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -731,15 +698,15 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
|
||||
case SNIOC_SET_USERPRIV:
|
||||
{
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
upper->state.priv = (FAR void *)(uintptr_t)arg;
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
}
|
||||
break;
|
||||
|
||||
case SNIOC_SET_BUFFER_NUMBER:
|
||||
{
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
if (!circbuf_is_init(&upper->buffer))
|
||||
{
|
||||
if (arg >= lower->nbuffer)
|
||||
@ -756,15 +723,15 @@ static int sensor_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
|
||||
ret = -EBUSY;
|
||||
}
|
||||
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
}
|
||||
break;
|
||||
|
||||
case SNIOC_READLAST:
|
||||
{
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
user->readlast = !!arg;
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -798,7 +765,7 @@ static int sensor_poll(FAR struct file *filep,
|
||||
int semcount;
|
||||
int ret = 0;
|
||||
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
if (setup)
|
||||
{
|
||||
/* Don't have enough space to store fds */
|
||||
@ -850,7 +817,7 @@ static int sensor_poll(FAR struct file *filep,
|
||||
}
|
||||
|
||||
errout:
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -870,7 +837,7 @@ static ssize_t sensor_push_event(FAR void *priv, FAR const void *data,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
if (!circbuf_is_init(&upper->buffer))
|
||||
{
|
||||
/* Initialize sensor buffer when data is first generated */
|
||||
@ -879,7 +846,7 @@ static ssize_t sensor_push_event(FAR void *priv, FAR const void *data,
|
||||
upper->state.esize);
|
||||
if (ret < 0)
|
||||
{
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -900,7 +867,7 @@ static ssize_t sensor_push_event(FAR void *priv, FAR const void *data,
|
||||
}
|
||||
}
|
||||
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@ -910,7 +877,7 @@ static void sensor_notify_event(FAR void *priv)
|
||||
FAR struct sensor_user_s *user;
|
||||
int semcount;
|
||||
|
||||
sensor_semtake(upper);
|
||||
nxrmutex_lock(&upper->lock);
|
||||
list_for_every_entry(&upper->userlist, user, struct sensor_user_s, node)
|
||||
{
|
||||
nxsem_get_value(&user->buffersem, &semcount);
|
||||
@ -922,7 +889,7 @@ static void sensor_notify_event(FAR void *priv)
|
||||
sensor_pollnotify_one(user, POLLIN);
|
||||
}
|
||||
|
||||
sensor_semgive(upper);
|
||||
nxrmutex_unlock(&upper->lock);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1026,8 +993,7 @@ int sensor_custom_register(FAR struct sensor_lowerhalf_s *lower,
|
||||
upper->state.nadvertisers = 1;
|
||||
}
|
||||
|
||||
upper->semholder = INVALID_PROCESS_ID;
|
||||
nxsem_init(&upper->exclsem, 0, 1);
|
||||
nxrmutex_init(&upper->lock);
|
||||
|
||||
/* Bind the lower half data structure member */
|
||||
|
||||
@ -1069,7 +1035,7 @@ int sensor_custom_register(FAR struct sensor_lowerhalf_s *lower,
|
||||
return ret;
|
||||
|
||||
drv_err:
|
||||
nxsem_destroy(&upper->exclsem);
|
||||
nxrmutex_destroy(&upper->lock);
|
||||
|
||||
kmm_free(upper);
|
||||
|
||||
@ -1132,7 +1098,7 @@ void sensor_custom_unregister(FAR struct sensor_lowerhalf_s *lower,
|
||||
sensor_rpmsg_unregister(lower);
|
||||
#endif
|
||||
|
||||
nxsem_destroy(&upper->exclsem);
|
||||
nxrmutex_destroy(&upper->lock);
|
||||
if (circbuf_is_init(&upper->buffer))
|
||||
{
|
||||
circbuf_uninit(&upper->buffer);
|
||||
|
Loading…
Reference in New Issue
Block a user