[libcamera-devel,v1,0/5] cam: Move request processing to main thread
mbox series

Message ID 20201113063815.10288-1-laurent.pinchart@ideasonboard.com
Headers show
Series
  • cam: Move request processing to main thread
Related show

Message

Laurent Pinchart Nov. 13, 2020, 6:38 a.m. UTC
Hello,

This patch series improves the cam application by moving request
processing to the main thread to avoid blocking the camera manager
thread (in which the request completion signal is emitted) for extended
periods of time. This helps meeting the realtime constraints of pipeline
handlers.

Note that move requesting processing to a different thread isn't a
magical solution, if the average processing time for a request is larger
than the frame interval, a request queue underrun will still occur. It
however helps handling random delays in request processing.

Included in the series is a move to libevent to implement the cam event
loop. The event loop is currently based on the libcamera event
dispatcher for historical reasons. The event dispatcher API exposed by
libcamera is incomplete, as thread support is internal to libcamera.
Instead of reimplementing the missing parts in the cam event loop, or
exposing thread support in the libcamera public API, moving to libevent
allows making the event dispatcher implementation fully private (in
patch 3/5). It isn't the job of libcamera to provide such generic APIs.

Laurent Pinchart (5):
  test: Get event dispatcher from current thread
  cam: Use libevent to implement event loop
  libcamera: Move EventDispatcher to internal API
  cam: event_loop: Add deferred calls support
  cam: Move request processing to main thread

 include/libcamera/camera_manager.h            |  4 --
 .../{ => internal}/event_dispatcher.h         |  0
 .../internal/event_dispatcher_poll.h          |  2 +-
 .../libcamera/{ => internal}/event_notifier.h |  0
 include/libcamera/internal/meson.build        |  3 +
 include/libcamera/{ => internal}/timer.h      |  0
 include/libcamera/meson.build                 |  3 -
 src/cam/capture.cpp                           |  9 +++
 src/cam/capture.h                             |  1 +
 src/cam/event_loop.cpp                        | 63 ++++++++++++++++---
 src/cam/event_loop.h                          | 24 ++++---
 src/cam/main.cpp                              | 16 ++---
 src/cam/meson.build                           | 13 +++-
 src/libcamera/camera_manager.cpp              | 44 +------------
 src/libcamera/device_enumerator_udev.cpp      |  3 +-
 src/libcamera/event_dispatcher.cpp            |  2 +-
 src/libcamera/event_dispatcher_poll.cpp       |  5 +-
 src/libcamera/event_notifier.cpp              |  4 +-
 src/libcamera/ipc_unixsocket.cpp              |  3 +-
 src/libcamera/pipeline/rkisp1/timeline.h      |  3 +-
 src/libcamera/process.cpp                     |  3 +-
 .../proxy/worker/ipa_proxy_linux_worker.cpp   |  2 +-
 src/libcamera/thread.cpp                      |  3 +-
 src/libcamera/timer.cpp                       |  4 +-
 src/libcamera/v4l2_device.cpp                 |  3 +-
 src/libcamera/v4l2_videodevice.cpp            |  2 +-
 test/camera/buffer_import.cpp                 |  8 +--
 test/camera/capture.cpp                       |  9 ++-
 test/event-dispatcher.cpp                     |  5 +-
 test/event-thread.cpp                         |  5 +-
 test/event.cpp                                |  7 +--
 test/hotplug-cameras.cpp                      |  4 +-
 test/ipa/ipa_interface_test.cpp               |  6 +-
 test/ipc/unixsocket.cpp                       |  5 +-
 test/log/log_process.cpp                      |  4 +-
 test/object-invoke.cpp                        |  2 +-
 test/process/process_test.cpp                 |  5 +-
 test/timer-thread.cpp                         |  5 +-
 test/timer.cpp                                |  5 +-
 test/v4l2_videodevice/buffer_sharing.cpp      |  4 +-
 test/v4l2_videodevice/capture_async.cpp       |  4 +-
 test/v4l2_videodevice/v4l2_m2mdevice.cpp      |  4 +-
 42 files changed, 159 insertions(+), 142 deletions(-)
 rename include/libcamera/{ => internal}/event_dispatcher.h (100%)
 rename include/libcamera/{ => internal}/event_notifier.h (100%)
 rename include/libcamera/{ => internal}/timer.h (100%)

Comments

Kieran Bingham Nov. 16, 2020, 11:47 a.m. UTC | #1
Hi Laurent,

On 13/11/2020 06:38, Laurent Pinchart wrote:
> Hello,
> 
> This patch series improves the cam application by moving request
> processing to the main thread to avoid blocking the camera manager
> thread (in which the request completion signal is emitted) for extended
> periods of time. This helps meeting the realtime constraints of pipeline
> handlers.
> 
> Note that move requesting processing to a different thread isn't a
> magical solution, if the average processing time for a request is larger
> than the frame interval, a request queue underrun will still occur. It
> however helps handling random delays in request processing.
> 
> Included in the series is a move to libevent to implement the cam event
> loop. The event loop is currently based on the libcamera event
> dispatcher for historical reasons. The event dispatcher API exposed by
> libcamera is incomplete, as thread support is internal to libcamera.
> Instead of reimplementing the missing parts in the cam event loop, or
> exposing thread support in the libcamera public API, moving to libevent
> allows making the event dispatcher implementation fully private (in
> patch 3/5). It isn't the job of libcamera to provide such generic APIs.

This series breaks simple-cam.

Will you plan to update that too?
If not I'll handle it, just let me know.

--
Thanks

Kieran


> Laurent Pinchart (5):
>   test: Get event dispatcher from current thread
>   cam: Use libevent to implement event loop
>   libcamera: Move EventDispatcher to internal API
>   cam: event_loop: Add deferred calls support
>   cam: Move request processing to main thread
> 
>  include/libcamera/camera_manager.h            |  4 --
>  .../{ => internal}/event_dispatcher.h         |  0
>  .../internal/event_dispatcher_poll.h          |  2 +-
>  .../libcamera/{ => internal}/event_notifier.h |  0
>  include/libcamera/internal/meson.build        |  3 +
>  include/libcamera/{ => internal}/timer.h      |  0
>  include/libcamera/meson.build                 |  3 -
>  src/cam/capture.cpp                           |  9 +++
>  src/cam/capture.h                             |  1 +
>  src/cam/event_loop.cpp                        | 63 ++++++++++++++++---
>  src/cam/event_loop.h                          | 24 ++++---
>  src/cam/main.cpp                              | 16 ++---
>  src/cam/meson.build                           | 13 +++-
>  src/libcamera/camera_manager.cpp              | 44 +------------
>  src/libcamera/device_enumerator_udev.cpp      |  3 +-
>  src/libcamera/event_dispatcher.cpp            |  2 +-
>  src/libcamera/event_dispatcher_poll.cpp       |  5 +-
>  src/libcamera/event_notifier.cpp              |  4 +-
>  src/libcamera/ipc_unixsocket.cpp              |  3 +-
>  src/libcamera/pipeline/rkisp1/timeline.h      |  3 +-
>  src/libcamera/process.cpp                     |  3 +-
>  .../proxy/worker/ipa_proxy_linux_worker.cpp   |  2 +-
>  src/libcamera/thread.cpp                      |  3 +-
>  src/libcamera/timer.cpp                       |  4 +-
>  src/libcamera/v4l2_device.cpp                 |  3 +-
>  src/libcamera/v4l2_videodevice.cpp            |  2 +-
>  test/camera/buffer_import.cpp                 |  8 +--
>  test/camera/capture.cpp                       |  9 ++-
>  test/event-dispatcher.cpp                     |  5 +-
>  test/event-thread.cpp                         |  5 +-
>  test/event.cpp                                |  7 +--
>  test/hotplug-cameras.cpp                      |  4 +-
>  test/ipa/ipa_interface_test.cpp               |  6 +-
>  test/ipc/unixsocket.cpp                       |  5 +-
>  test/log/log_process.cpp                      |  4 +-
>  test/object-invoke.cpp                        |  2 +-
>  test/process/process_test.cpp                 |  5 +-
>  test/timer-thread.cpp                         |  5 +-
>  test/timer.cpp                                |  5 +-
>  test/v4l2_videodevice/buffer_sharing.cpp      |  4 +-
>  test/v4l2_videodevice/capture_async.cpp       |  4 +-
>  test/v4l2_videodevice/v4l2_m2mdevice.cpp      |  4 +-
>  42 files changed, 159 insertions(+), 142 deletions(-)
>  rename include/libcamera/{ => internal}/event_dispatcher.h (100%)
>  rename include/libcamera/{ => internal}/event_notifier.h (100%)
>  rename include/libcamera/{ => internal}/timer.h (100%)
>
Laurent Pinchart Nov. 16, 2020, 12:35 p.m. UTC | #2
Hi Kieran,

On Mon, Nov 16, 2020 at 11:47:49AM +0000, Kieran Bingham wrote:
> On 13/11/2020 06:38, Laurent Pinchart wrote:
> > Hello,
> > 
> > This patch series improves the cam application by moving request
> > processing to the main thread to avoid blocking the camera manager
> > thread (in which the request completion signal is emitted) for extended
> > periods of time. This helps meeting the realtime constraints of pipeline
> > handlers.
> > 
> > Note that move requesting processing to a different thread isn't a
> > magical solution, if the average processing time for a request is larger
> > than the frame interval, a request queue underrun will still occur. It
> > however helps handling random delays in request processing.
> > 
> > Included in the series is a move to libevent to implement the cam event
> > loop. The event loop is currently based on the libcamera event
> > dispatcher for historical reasons. The event dispatcher API exposed by
> > libcamera is incomplete, as thread support is internal to libcamera.
> > Instead of reimplementing the missing parts in the cam event loop, or
> > exposing thread support in the libcamera public API, moving to libevent
> > allows making the event dispatcher implementation fully private (in
> > patch 3/5). It isn't the job of libcamera to provide such generic APIs.
> 
> This series breaks simple-cam.
> 
> Will you plan to update that too?
> If not I'll handle it, just let me know.

If you can handle it, that would be nice. Otherwise I'll do so. Sorry
about the breakage :-S

Regarding the event loop implementation in simple-cam, should we just
copy the one from cam ?

> > Laurent Pinchart (5):
> >   test: Get event dispatcher from current thread
> >   cam: Use libevent to implement event loop
> >   libcamera: Move EventDispatcher to internal API
> >   cam: event_loop: Add deferred calls support
> >   cam: Move request processing to main thread
> > 
> >  include/libcamera/camera_manager.h            |  4 --
> >  .../{ => internal}/event_dispatcher.h         |  0
> >  .../internal/event_dispatcher_poll.h          |  2 +-
> >  .../libcamera/{ => internal}/event_notifier.h |  0
> >  include/libcamera/internal/meson.build        |  3 +
> >  include/libcamera/{ => internal}/timer.h      |  0
> >  include/libcamera/meson.build                 |  3 -
> >  src/cam/capture.cpp                           |  9 +++
> >  src/cam/capture.h                             |  1 +
> >  src/cam/event_loop.cpp                        | 63 ++++++++++++++++---
> >  src/cam/event_loop.h                          | 24 ++++---
> >  src/cam/main.cpp                              | 16 ++---
> >  src/cam/meson.build                           | 13 +++-
> >  src/libcamera/camera_manager.cpp              | 44 +------------
> >  src/libcamera/device_enumerator_udev.cpp      |  3 +-
> >  src/libcamera/event_dispatcher.cpp            |  2 +-
> >  src/libcamera/event_dispatcher_poll.cpp       |  5 +-
> >  src/libcamera/event_notifier.cpp              |  4 +-
> >  src/libcamera/ipc_unixsocket.cpp              |  3 +-
> >  src/libcamera/pipeline/rkisp1/timeline.h      |  3 +-
> >  src/libcamera/process.cpp                     |  3 +-
> >  .../proxy/worker/ipa_proxy_linux_worker.cpp   |  2 +-
> >  src/libcamera/thread.cpp                      |  3 +-
> >  src/libcamera/timer.cpp                       |  4 +-
> >  src/libcamera/v4l2_device.cpp                 |  3 +-
> >  src/libcamera/v4l2_videodevice.cpp            |  2 +-
> >  test/camera/buffer_import.cpp                 |  8 +--
> >  test/camera/capture.cpp                       |  9 ++-
> >  test/event-dispatcher.cpp                     |  5 +-
> >  test/event-thread.cpp                         |  5 +-
> >  test/event.cpp                                |  7 +--
> >  test/hotplug-cameras.cpp                      |  4 +-
> >  test/ipa/ipa_interface_test.cpp               |  6 +-
> >  test/ipc/unixsocket.cpp                       |  5 +-
> >  test/log/log_process.cpp                      |  4 +-
> >  test/object-invoke.cpp                        |  2 +-
> >  test/process/process_test.cpp                 |  5 +-
> >  test/timer-thread.cpp                         |  5 +-
> >  test/timer.cpp                                |  5 +-
> >  test/v4l2_videodevice/buffer_sharing.cpp      |  4 +-
> >  test/v4l2_videodevice/capture_async.cpp       |  4 +-
> >  test/v4l2_videodevice/v4l2_m2mdevice.cpp      |  4 +-
> >  42 files changed, 159 insertions(+), 142 deletions(-)
> >  rename include/libcamera/{ => internal}/event_dispatcher.h (100%)
> >  rename include/libcamera/{ => internal}/event_notifier.h (100%)
> >  rename include/libcamera/{ => internal}/timer.h (100%)