Обертывание атомарного типа и обеспечение того, чтобы он оставался атомным - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть несколько уникальный и интересный (и ужасный) сценарий, который заставляет меня делать некоторые хитрые вещи.Проблема заключается в следующем:

  1. Нам необходим атомарный тип для синхронизации без блокировки между потоком реального времени и потоком фоновой загрузки.
  2. Тип (к сожалению)должен компилироваться на:

    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, могут возникнуть проблемы с порядком обращений катомный объект?

В качестве дополнительного вопроса, учитывая ограничения, есть ли лучший способ сделать это?

1 Ответ

0 голосов
/ 26 февраля 2019

Ядро, которое имеет c ++ 11, но не может собрать boost::atomic

boost::atomic<T> тип только для заголовка, вы можете использовать его без создания библиотеки boost::atomic.

Вы можете использовать boost::atomic<T> напрямую и безоговорочно на обеих платформах (при условии, что ваши платформы поддерживаются).

Есть несколько битов библиотеки boost::atomic, которые требуют сборки, см. srcи test каталогов в https://github.com/boostorg/atomic, однако, использование boost::atomic<T> не требует их.

...