libqi-api  2.8.7.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Classes | Namespaces | Macros | Functions
atomic.hpp File Reference
#include <boost/predef.h>
#include <atomic>
#include <qi/config.hpp>
#include <qi/macro.hpp>

Go to the source code of this file.

Classes

struct  qi::detail::StaticAtomicInt
 
struct  qi::Atomic< T >
 
class  qi::AtomicFlagLock
 

Namespaces

 qi
 Deprecated in 2.5. Use int8_t from <cstdint>.
 
 qi::detail
 

Macros

#define QI_ATOMIC_HPP_
 
#define _QI_INSTANCIATE(_, a, elem)   ::qi::detail::newAndAssign(&elem);
 
#define QI_THREADSAFE_NEW(...)   QI_ONCE(QI_VAARGS_APPLY(_QI_INSTANCIATE, _, __VA_ARGS__);)
 Safe static initialization of variables. More...
 
#define QI_ONCE(code)
 Execute code once, parallel calls are blocked until code finishes. More...
 

Functions

long qi::testAndSet (long *cond)
 
template<typename T >
void qi::detail::newAndAssign (T **ptr)
 
bool qi::tryRaiseAtomicFlag (std::atomic< bool > &b)
 
bool qi::tryLowerAtomicFlag (std::atomic< bool > &b)
 
AtomicFlagLock qi::scopelock (std::atomic_flag &f)
 model ScopeLockable std::atomic_flag: More...
 
template<typename T >
qi::src (const std::atomic< T > &x)
 

Macro Definition Documentation

#define _QI_INSTANCIATE (   _,
  a,
  elem 
)    ::qi::detail::newAndAssign(&elem);

Definition at line 325 of file atomic.hpp.

#define QI_ATOMIC_HPP_

Definition at line 9 of file atomic.hpp.

#define QI_ONCE (   code)
Value:
static qi::detail::StaticAtomicInt QI_UNIQ_DEF(atomic_guard_a) = {0}; \
static qi::detail::StaticAtomicInt QI_UNIQ_DEF(atomic_guard_b) = {0}; \
while (!QI_UNIQ_DEF(atomic_guard_a).setIfEquals(1, 1)) \
{ \
bool tok = QI_UNIQ_DEF(atomic_guard_b).setIfEquals(0, 1); \
if (tok) \
{ \
try \
{ \
code; \
} \
catch (...) \
{ \
QI_UNIQ_DEF(atomic_guard_b) = 0; \
throw; \
} \
++QI_UNIQ_DEF(atomic_guard_a); \
} \
}
#define QI_UNIQ_DEF(A)
A macro to append the line number of the parent macro usage, to define a function in or a variable an...
Definition: macro.hpp:311

Execute code once, parallel calls are blocked until code finishes.

* .. code-block:: cpp
*
*   void myFunction()
*   {
*     QI_ONCE(std::cout << "first initialization" << std::endl);
*     std::cout << "doing stuff" << std::endl;
*   }
*
* In this code, you have two guarantees:
* - "first initialization" will be written only once
* - "doing stuff" will never appear before "first initialization"
*
* `QI_ONCE` is optimized so that further calls after initialization have the less
* overhead possible.
*
* You can also put multiple instructions in a `QI_ONCE`.
*
* .. code-block:: cpp
*
*   QI_ONCE(
*       doStuff();
*       doMoreStuff();
*       );
*
* This macro is only useful in C++03 and the function above may be written in
* C++11:
*
* .. code-block:: cpp
*
*   void myFunction()
*   {
*     static std::once_flag flag;
*     std::call_once(flag,
*         [](){std::cout << "first initialization" << std::endl;});
*     std::cout << "doing stuff" << std::endl;
*   }
* 

Definition at line 420 of file atomic.hpp.

#define QI_THREADSAFE_NEW (   ...)    QI_ONCE(QI_VAARGS_APPLY(_QI_INSTANCIATE, _, __VA_ARGS__);)

Safe static initialization of variables.

* Accept a list of pointers (expected to be static function variables)
* and new them once in a thread-safe manner.
* Implementation aims for minimal overhead when initialization is done.
*
* `QI_THREADSAFE_NEW` is there to provide a safe static initialization of
* variables in C++03. Its most common use case is the following:
*
* .. code-block:: cpp
*
*   static std::vector<int> vec;
*
*   void threadSafeFunction()
*   {
*     static boost::mutex* mutex; // = 0 is optional
*     QI_THREADSAFE_NEW(mutex);
*     boost::mutex::scoped_lock l(*mutex);
*     vec.push_back(0);
*   }
*
* Using a simple `static boost::mutex` does not guarantee safe initialization in
* a multithreaded environment in C++03 (even though GCC's implementation is
* safe), that's why `QI_THREADSAFE_NEW` is needed.
*
* In C++11, the following is safe:
*
* .. code-block:: cpp
*
*   static std::vector<int> vec;
*
*   void threadSafeFunction()
*   {
*     static boost::mutex mutex;
*     boost::mutex::scoped_lock l(mutex);
*     vec.push_back(0);
*   }
* 

Definition at line 374 of file atomic.hpp.