У меня есть несколько уникальный и интересный (и ужасный) сценарий, который заставляет меня делать некоторые хитрые вещи.Проблема заключается в следующем:
- Нам необходим атомарный тип для синхронизации без блокировки между потоком реального времени и потоком фоновой загрузки.
Тип (к сожалению)должен компилироваться на:
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
Это класс, который будет перенаправлять на тип atomic
справильный API.К счастью, реализация boost
и std
почти совпадает.
Затем в каждом из отдельных файлов ОС что-то вроде этого:
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);
Для того, чтобы разобраться с концепцией порядка памяти, существуетсуществует аналогичная система с файлом, который необходимо делегировать каждой из реализаций ОС с использованием препроцессора.В реализации, например.Ядро, у нас есть это:
Nucleus / MemoryOrder.hpp
#include <memory>
namespace osal {
using std::memory_order;
using std::memory_order_relaxed;
...
}
Очевидно, что эквивалентный using boost::...
будет в файле QNX (к счастью, они снова совпадают)!).
Вопрос
Кажется, это работает.Я могу сделать атом и делать операции над ним.У меня есть беспокойство:
Это все еще атомарно?
Теперь, когда мы ввели косвенное обращение в API, могут возникнуть проблемы с порядком обращений катомный объект?
В качестве дополнительного вопроса, учитывая ограничения, есть ли лучший способ сделать это?