[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