我有一个有点独特和有趣(且可怕)的场景,这迫使我去做一些棘手的事情。问题如下:
类型(不幸的是)必须在以下位置编译:
a。 QNX仅具有c ++ 03,但支持boost::atomic
。
b。具有c ++ 11但无法构建boost::atomic
这迫使我考虑同时使用boost::atomic
和std::atomic
。我要解决的方法是生成一个新类型,将所有功能转发到平台上的相关atomic
类型。这个想法是这样的:
Atomic.hpp
namespace osal { namespace detail {
template <typename T, template <class> class TAtomic >
struct AtomicImpl {
void store(T desired, memory_order order = osal::memory_order_seq_cst)
{
_atomic.store(desired, order);
}
// ... Other api
private:
AtomicImpl& operator=(const AtomicImpl& rhs);
// ... Other blocked operations
TAtomic<T> _atomic;
};
}}
#if defined QNX
#include <osal/QNX/Atomic.hpp>
#elif defined NUCLEUS
#include <osal/NUCLEUS/Atomic.hpp>
#endif
这列出了一个类,该类将使用正确的API转发到atomic
类型。幸运的是,boost
和std
实现几乎完全匹配。
然后在每个单独的OS文件中,如下所示:
Nucleus / Atomic.hpp
#include <atomic>
namespace osal
{
template <typename T> struct atomic
{
typedef detail::AtomicImpl<T, std::atomic> type;
};
}
这会使用std::atomic
创建一个原子类型,从而可以像这样使用:
osal::atomic<uint8_t>::type a;
a.store(1);
为了处理内存顺序的概念,存在一个类似的系统,该系统带有一个文件,用于使用预处理器委派给每个OS实现。在实施中,例如核,我们有这个:
Nucleus / MemoryOrder.hpp
#include <memory>
namespace osal {
using std::memory_order;
using std::memory_order_relaxed;
...
}
显然,等效的using boost::...
将位于QNX文件中(幸运的是,它们再次匹配!)。
这似乎起作用。我可以做一个原子并对其进行操作。我担心:
这仍然是原子的吗?
现在我们在API中引入了间接寻址,对原子对象的调用顺序是否会出现问题?
作为奖励问题,考虑到约束条件,是否有更好的方法来做到这一点?
答案 0 :(得分:0)
具有c ++ 11但不能构建
的核boost::atomic
boost::atomic<T>
类型仅是标题,您可以使用它而无需构建boost::atomic
库。
您可以在两个平台上直接无条件使用boost::atomic<T>
(前提是支持您的平台)。
boost::atomic
库中有一些地方需要构建,请参见https://github.com/boostorg/atomic中的src
和test
目录,但是,使用boost::atomic<T>
并不需要需要那些。