Skip to content
Snippets Groups Projects
Commit a08ed46a authored by Rainer Kartmann's avatar Rainer Kartmann
Browse files

Merge branch...

Merge branch '56-add-maxcount-to-countingsemaphore-allowing-usage-as-binary-semaphore' into 'master'

Resolve "Add maxCount to CountingSemaphore (allowing usage as binary semaphore)"

Closes #56

See merge request Simox/simox!56
parents 45deef2e 28fa5e53
No related branches found
No related tags found
No related merge requests found
......@@ -7,14 +7,22 @@ namespace simox::threads
CountingSemaphore::CountingSemaphore()
{}
CountingSemaphore::CountingSemaphore(unsigned int count) : _count(count)
CountingSemaphore::CountingSemaphore(unsigned int count) :
_count(count)
{}
CountingSemaphore::CountingSemaphore(unsigned int count, unsigned int maxCount) :
_count(count), _maxCount(maxCount)
{}
void CountingSemaphore::notify()
{
std::lock_guard<std::mutex> lock(_mutex);
++_count;
if (!_maxCount || _count < *_maxCount)
{
++_count;
}
_condition.notify_one();
}
......
......@@ -2,6 +2,7 @@
#include <condition_variable>
#include <mutex>
#include <optional>
namespace simox::threads
......@@ -14,33 +15,52 @@ namespace simox::threads
* Notifiying the semaphore increments the count and allows threads to enter.
* A thread can wait until it may enter. When it enters, it decrements
* the internal count.
* An optional max count can limit the value of count (useful e.g. when your
* buffer has a limited number of items).
*
* Can be used e.g. in a Producer-Consumer pattern.
* The producer signals new jobs via `notify()`, while the consumer waits
* A counting semaphore can be used e.g. in Producer-Consumer patterns.
* The producer signals new jobs/items via `notify()`, while the consumer waits
* for new jobs via `wait()`.
*/
class CountingSemaphore
{
public:
/// Construct an initially blocking semaphore (initial count 0).
/// Construct an initially blocking semaphore (initial count 0) without max count.
CountingSemaphore();
/// Construct a semaphore with the given count.
/**
* @brief Construct a semaphore with the given initial count without max count.
* @param count The initial count (0 to block initially).
*/
CountingSemaphore(unsigned int count);
/**
* @brief Construct a semaphore with the given initial count and max count.
* @param count The initial count (0 to block initially).
* @param maxCount An optional count limit (1 for a binary semaphore).
*/
CountingSemaphore(unsigned int count, unsigned int maxCount);
/**
* @brief Signal that one waiting thread may continue.
*
* Also known as `post()` or `signal()`.
* Increments the count by 1, if it is below the optional max count.
*/
void notify();
/**
* @brief Wait until a thread may enter.
*
* Decrements the count when resuming.
*/
void wait();
/**
* @brief Try to enter. If the semaphore is currently blocking, return false.
* @brief Try to enter.
*
* If the semaphore is currently blocking, return false.
* If the semaphore is free (count > 0), decrement the count and return true.
*
* @return True if entering was successful, false if semaphore was blocking.
*/
bool try_wait();
......@@ -56,6 +76,9 @@ namespace simox::threads
/// The current count. Waiting threads may enter when > 0.
unsigned int _count = 0;
/// An optional maximal count. All `notifiy()`s increasing the counter above maxCount are ignored.
std::optional<unsigned int> _maxCount = std::nullopt;
};
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment