Message ID | 20191028104913.14985-2-laurent.pinchart@ideasonboard.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
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@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@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@lists.libcamera.org > https://lists.libcamera.org/listinfo/libcamera-devel
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 */
Add a general-purpose counting semaphore class. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> --- 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