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