Project

General

Profile

« Previous | Next » 

Revision e6e5f703

Added by David Sorber almost 4 years ago

read_test: Added SynchronizedCounter class.

View differences:

software/read_test/src/Utilities/SynchronizedCounter.h
/********************************************************************
* This software is "commercial computer software" as defined in the *
* Federal Acquisition Regulations and is subject to BlackLynx *
* Inc's standard End User License Agreement. *
* *
* CONFIDENTIAL - All source code is the propriety and confidential *
* information of BlackLynx Inc. *
* *
* Copyright 2018-2020 BlackLynx Inc. *
* Unpublished -- all rights reserved under the copyright laws *
* of the United States. *
********************************************************************/
#ifndef __BLNX_SYNCHRONIZEDCOUNTER_H__
#define __BLNX_SYNCHRONIZEDCOUNTER_H__
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <iostream>
namespace BlackLynx
{
namespace SearchLynx
{
template<typename T>
class SynchronizedCounter
{
public:
static_assert(std::is_integral<T>::value,
"Template parameter must be an integral type");
SynchronizedCounter()
: m_finalized(false),
m_value(0)
{
}
SynchronizedCounter(T initValue)
: m_finalized(false),
m_value(initValue)
{
}
inline void increment()
{
std::lock_guard<std::mutex> lock(m_mutex);
++m_value;
}
inline void decrement()
{
std::lock_guard<std::mutex> lock(m_mutex);
--m_value;
}
void finalize()
{
std::lock_guard<std::mutex> lock(m_mutex);
m_finalized = true;
}
T getValue()
{
std::lock_guard<std::mutex> lock(m_mutex);
return m_value;
}
T getValue(bool& finalized)
{
std::lock_guard<std::mutex> lock(m_mutex);
finalize = m_finalized
return m_value;
}
private:
bool m_finalized;
T m_value;
std::mutex m_mutex;
};
}
}
#endif
software/read_test/src/Utilities/SynchronizedValue.h
class SynchronizedValue
{
public:
SynchronizedValue()
: m_terminateFlag(false),
m_flag(false)
{
}
SynchronizedValue(T initValue)
: m_terminateFlag(false),
m_flag(false),
m_value(initValue)
SynchronizedValue()
: m_terminateFlag(false),
m_flag(false)
{
}
SynchronizedValue(T initValue)
: m_terminateFlag(false),
m_flag(false),
m_value(initValue)
{
}
virtual ~SynchronizedValue() {}
/**
* Terminate any pending getValue() calls.
*/
void terminate()
{
m_terminateFlag = true;
m_CV.notify_all();
}
/**
* Set the value and notify any blocked getValue() calls.
*/
void setValue(T value)
{
m_value = value;
{
std::lock_guard<std::mutex> lock(m_mutex);
m_flag = true;
}
virtual ~SynchronizedValue() {}
/**
* Terminate any pending getValue() calls.
*/
void terminate()
{
m_terminateFlag = true;
m_CV.notify_all();
}
/**
* Set the value and notify any blocked getValue() calls.
*/
void setValue(T value)
m_CV.notify_all();
}
/**
* Get the value, potentially blocking until it becomes available. Note
* that the "terminated" parameter should always be checked before using
* the returned value as a call to terminate() might cause this function
* to return a default initialized value.
*
* @param terminated - indicates if a blocking wait was terminated
* @param block - (default: true) block while waiting for value to be set
*
* @return the stored value
*/
T getValue(bool& terminated, bool block=true)
{
terminated = false;
// If not blocking; return the current value without waiting if it
// hasn't yet been set
if (! block)
{
m_value = value;
{
std::lock_guard<std::mutex> lock(m_mutex);
m_flag = true;
}
m_CV.notify_all();
std::lock_guard<std::mutex> lock(m_mutex);
return m_value;
}
/**
* Get the value, potentially blocking until it becomes available. Note
* that the "terminated" parameter should always be checked before using
* the returned value as a call to terminate() might cause this function
* to return a default initialized value.
*
* @param terminated - indicates if a blocking wait was terminated
* @param block - (default: true) block while waiting for value to be set
*
* @return the stored value
*/
T getValue(bool& terminated, bool block=true)
std::unique_lock<std::mutex> muxLock(m_mutex);
while (m_flag == false)
{
terminated = false;
// If not blocking; return the current value without waiting if it
// hasn't yet been set
if (! block)
{
std::lock_guard<std::mutex> lock(m_mutex);
return m_value;
}
std::unique_lock<std::mutex> muxLock(m_mutex);
while (m_flag == false)
m_CV.wait_for(muxLock, std::chrono::milliseconds(1));
// If we've been asked to terminate, break out of the loop and abort
if (m_terminateFlag)
{
m_CV.wait_for(muxLock, std::chrono::milliseconds(1));
// If we've been asked to terminate, break out of the loop and abort
if (m_terminateFlag)
{
terminated = true;
break;
}
terminated = true;
break;
}
muxLock.unlock();
return m_value;
}
/**
* Reset the internal flag to allow the value to be set again. Note this
* function must be used with care!
*/
void reset()
{
std::lock_guard<std::mutex> lock(m_mutex);
m_flag = false;
}
void reset(T newVal)
{
std::lock_guard<std::mutex> lock(m_mutex);
m_flag = false;
m_value = newVal;
}
muxLock.unlock();
return m_value;
}
/**
* Reset the internal flag to allow the value to be set again. Note this
* function must be used with care!
*/
void reset()
{
std::lock_guard<std::mutex> lock(m_mutex);
m_flag = false;
}
void reset(T newVal)
{
std::lock_guard<std::mutex> lock(m_mutex);
m_flag = false;
m_value = newVal;
}
private:

Also available in: Unified diff