[libcamera-devel] [PATCH v2 1/9] libcamera: Add Semaphore class
Niklas Söderlund
niklas.soderlund at ragnatech.se
Mon Oct 28 12:06:57 CET 2019
Hi Laurent,
Thanks for your patch.
On 2019-10-28 12:49:05 +0200, Laurent Pinchart wrote:
> Add a general-purpose counting semaphore class.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
> ---
> src/libcamera/include/meson.build | 1 +
> src/libcamera/include/semaphore.h | 34 ++++++++++
> src/libcamera/meson.build | 1 +
> src/libcamera/semaphore.cpp | 103 ++++++++++++++++++++++++++++++
> 4 files changed, 139 insertions(+)
> create mode 100644 src/libcamera/include/semaphore.h
> create mode 100644 src/libcamera/semaphore.cpp
>
> diff --git a/src/libcamera/include/meson.build b/src/libcamera/include/meson.build
> index 2c74d29bd925..64c2155f90cf 100644
> --- a/src/libcamera/include/meson.build
> +++ b/src/libcamera/include/meson.build
> @@ -17,6 +17,7 @@ libcamera_headers = files([
> 'message.h',
> 'pipeline_handler.h',
> 'process.h',
> + 'semaphore.h',
> 'thread.h',
> 'utils.h',
> 'v4l2_controls.h',
> diff --git a/src/libcamera/include/semaphore.h b/src/libcamera/include/semaphore.h
> new file mode 100644
> index 000000000000..c6b286536eb3
> --- /dev/null
> +++ b/src/libcamera/include/semaphore.h
> @@ -0,0 +1,34 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2019, Google Inc.
> + *
> + * semaphore.h - General-purpose counting semaphore
> + */
> +#ifndef __LIBCAMERA_SEMAPHORE_H__
> +#define __LIBCAMERA_SEMAPHORE_H__
> +
> +#include <condition_variable>
> +
> +#include "thread.h"
> +
> +namespace libcamera {
> +
> +class Semaphore
> +{
> +public:
> + Semaphore(unsigned int n = 0);
> +
> + unsigned int available();
> + void acquire(unsigned int n = 1);
> + bool tryAcquire(unsigned int n = 1);
> + void release(unsigned int n = 1);
> +
> +private:
> + Mutex mutex_;
> + std::condition_variable cv_;
> + unsigned int available_;
> +};
> +
> +} /* namespace libcamera */
> +
> +#endif /* __LIBCAMERA_SEMAPHORE_H__ */
> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
> index d329820b9582..dab5dbff77b7 100644
> --- a/src/libcamera/meson.build
> +++ b/src/libcamera/meson.build
> @@ -27,6 +27,7 @@ libcamera_sources = files([
> 'pipeline_handler.cpp',
> 'process.cpp',
> 'request.cpp',
> + 'semaphore.cpp',
> 'signal.cpp',
> 'stream.cpp',
> 'thread.cpp',
> diff --git a/src/libcamera/semaphore.cpp b/src/libcamera/semaphore.cpp
> new file mode 100644
> index 000000000000..ce1eae4914ed
> --- /dev/null
> +++ b/src/libcamera/semaphore.cpp
> @@ -0,0 +1,103 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2019, Google Inc.
> + *
> + * semaphore.cpp - General-purpose counting semaphore
> + */
> +
> +#include "semaphore.h"
> +#include "thread.h"
> +
> +/**
> + * \file semaphore.h
> + * \brief General-purpose counting semaphore
> + */
> +
> +namespace libcamera {
> +
> +/**
> + * \class Semaphore
> + * \brief General-purpose counting semaphore
> + *
> + * A semaphore is a locking primitive that protects resources. It is created
> + * with an initial number of resources (which may be 0), and offers two
> + * primitives to acquire and release resources. The acquire() method tries to
> + * acquire a number of resources, and blocks if not enough resources are
> + * available until they get released. The release() method releases a number of
> + * resources, waking up any consumer blocked on an acquire() call.
> + */
> +
> +/**
> + * \brief Construct a semaphore with \a n resources
> + * \param[in] n The resource count
> + */
> +Semaphore::Semaphore(unsigned int n)
> + : available_(n)
> +{
> +}
> +
> +/**
> + * \brief Retrieve the number of available resources
> + * \return The number of available resources
> + */
> +unsigned int Semaphore::available()
> +{
> + MutexLocker locker(mutex_);
> + return available_;
> +}
> +
> +/**
> + * \brief Acquire \a n resources
> + * \param[in] n The resource count
> + *
> + * This method attempts to acquire \a n resources. If \a n is higher than the
> + * number of available resources, the call will block until enough resources
> + * become available.
> + */
> +void Semaphore::acquire(unsigned int n)
> +{
> + MutexLocker locker(mutex_);
> + cv_.wait(locker, [&] { return available_ >= n; });
> + available_ -= n;
> +}
> +
> +/**
> + * \brief Try to acquire \a n resources without blocking
> + * \param[in] n The resource count
> + *
> + * This method attempts to acquire \a n resources. If \a n is higher than the
> + * number of available resources, it returns false immediately without
> + * acquiring any resource. Otherwise it acquires the resources and returns
> + * true.
> + *
> + * \return True if the resources have been acquired, false otherwise
> + */
> +bool Semaphore::tryAcquire(unsigned int n)
> +{
> + MutexLocker locker(mutex_);
> + if (available_ < n)
> + return false;
> +
> + available_ -= n;
> + return true;
> +}
> +
> +/**
> + * \brief Release \a n resources
> + * \param[in] n The resource count
> + *
> + * This method releases \a n resources, increasing the available resource count
> + * by \a n. If the number of available resources becomes large enough for any
> + * consumer blocked on an acquire() call, those consumers get woken up.
> + */
> +void Semaphore::release(unsigned int n)
> +{
> + {
> + MutexLocker locker(mutex_);
> + available_ += n;
> + }
> +
> + cv_.notify_all();
> +}
> +
> +} /* namespace libcamera */
> --
> Regards,
>
> Laurent Pinchart
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
--
Regards,
Niklas Söderlund
More information about the libcamera-devel
mailing list