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/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);
|
||||||
|
Loading…
Reference in New Issue
Block a user