driver/sensor: using standard recursive mutex api

Signed-off-by: Jiuzhu Dong <dongjiuzhu1@xiaomi.com>
This commit is contained in:
Jiuzhu Dong 2022-06-14 11:33:13 +08:00 committed by Xiang Xiao
parent 38393cfc94
commit 78eb832e23

View File

@ -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);