mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 20:08:15 +08:00
video_framebuff: Replace critical section with spinlock
to avoid th global big lock and improve the performance. Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
@@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <syslog.h>
|
|
||||||
|
|
||||||
#include <nuttx/irq.h>
|
#include <nuttx/irq.h>
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
@@ -173,7 +172,7 @@ void video_framebuff_queue_container(video_framebuff_t *fbuf,
|
|||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&fbuf->lock_queue);
|
||||||
if (fbuf->vbuf_top != NULL)
|
if (fbuf->vbuf_top != NULL)
|
||||||
{
|
{
|
||||||
fbuf->vbuf_tail->next = tgt;
|
fbuf->vbuf_tail->next = tgt;
|
||||||
@@ -198,7 +197,7 @@ void video_framebuff_queue_container(video_framebuff_t *fbuf,
|
|||||||
tgt->next = NULL;
|
tgt->next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&fbuf->lock_queue, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
vbuf_container_t *video_framebuff_dq_valid_container(video_framebuff_t *fbuf)
|
vbuf_container_t *video_framebuff_dq_valid_container(video_framebuff_t *fbuf)
|
||||||
@@ -206,13 +205,13 @@ vbuf_container_t *video_framebuff_dq_valid_container(video_framebuff_t *fbuf)
|
|||||||
vbuf_container_t *ret = NULL;
|
vbuf_container_t *ret = NULL;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&fbuf->lock_queue);
|
||||||
if (fbuf->vbuf_top != NULL && fbuf->vbuf_top != fbuf->vbuf_next)
|
if (fbuf->vbuf_top != NULL && fbuf->vbuf_top != fbuf->vbuf_next)
|
||||||
{
|
{
|
||||||
ret = dequeue_vbuf_unsafe(fbuf);
|
ret = dequeue_vbuf_unsafe(fbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&fbuf->lock_queue, flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,9 +221,9 @@ video_framebuff_get_vacant_container(video_framebuff_t *fbuf)
|
|||||||
vbuf_container_t *ret;
|
vbuf_container_t *ret;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&fbuf->lock_queue);
|
||||||
ret = fbuf->vbuf_next;
|
ret = fbuf->vbuf_next;
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&fbuf->lock_queue, flags);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -233,17 +232,18 @@ void video_framebuff_capture_done(video_framebuff_t *fbuf)
|
|||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&fbuf->lock_queue);
|
||||||
if (fbuf->vbuf_next != NULL)
|
if (fbuf->vbuf_next != NULL)
|
||||||
{
|
{
|
||||||
fbuf->vbuf_next = fbuf->vbuf_next->next;
|
fbuf->vbuf_next = fbuf->vbuf_next->next;
|
||||||
if (fbuf->vbuf_next == fbuf->vbuf_top) /* RING mode case. */
|
if (fbuf->vbuf_next == fbuf->vbuf_top) /* RING mode case. */
|
||||||
{
|
{
|
||||||
syslog(LOG_WARNING, "video buffer is overflow.\n");
|
|
||||||
fbuf->vbuf_top = fbuf->vbuf_top->next;
|
fbuf->vbuf_top = fbuf->vbuf_top->next;
|
||||||
fbuf->vbuf_tail = fbuf->vbuf_tail->next;
|
fbuf->vbuf_tail = fbuf->vbuf_tail->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&fbuf->lock_queue, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void video_framebuff_change_mode(video_framebuff_t *fbuf,
|
void video_framebuff_change_mode(video_framebuff_t *fbuf,
|
||||||
@@ -251,7 +251,7 @@ void video_framebuff_change_mode(video_framebuff_t *fbuf,
|
|||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&fbuf->lock_queue);
|
||||||
if (fbuf->mode != mode)
|
if (fbuf->mode != mode)
|
||||||
{
|
{
|
||||||
if (fbuf->vbuf_tail)
|
if (fbuf->vbuf_tail)
|
||||||
@@ -270,7 +270,7 @@ void video_framebuff_change_mode(video_framebuff_t *fbuf,
|
|||||||
fbuf->mode = mode;
|
fbuf->mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&fbuf->lock_queue, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
vbuf_container_t *video_framebuff_pop_curr_container(video_framebuff_t *fbuf)
|
vbuf_container_t *video_framebuff_pop_curr_container(video_framebuff_t *fbuf)
|
||||||
@@ -278,12 +278,12 @@ vbuf_container_t *video_framebuff_pop_curr_container(video_framebuff_t *fbuf)
|
|||||||
vbuf_container_t *ret = NULL;
|
vbuf_container_t *ret = NULL;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = spin_lock_irqsave(&fbuf->lock_queue);
|
||||||
if (fbuf->vbuf_top != NULL)
|
if (fbuf->vbuf_top != NULL)
|
||||||
{
|
{
|
||||||
ret = dequeue_vbuf_unsafe(fbuf);
|
ret = dequeue_vbuf_unsafe(fbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
spin_unlock_irqrestore(&fbuf->lock_queue, flags);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,9 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <sys/videoio.h>
|
#include <sys/videoio.h>
|
||||||
|
|
||||||
#include <nuttx/mutex.h>
|
#include <nuttx/mutex.h>
|
||||||
|
#include <nuttx/spinlock.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
@@ -43,6 +45,7 @@ typedef struct vbuf_container_s vbuf_container_t;
|
|||||||
struct video_framebuff_s
|
struct video_framebuff_s
|
||||||
{
|
{
|
||||||
enum v4l2_buf_mode mode;
|
enum v4l2_buf_mode mode;
|
||||||
|
spinlock_t lock_queue;
|
||||||
mutex_t lock_empty;
|
mutex_t lock_empty;
|
||||||
int container_size;
|
int container_size;
|
||||||
vbuf_container_t *vbuf_alloced;
|
vbuf_container_t *vbuf_alloced;
|
||||||
|
|||||||
Reference in New Issue
Block a user