MinGW 4.6.2 std :: атомный указатель

Я использую MinGW 4.6.2 в Windows XP, и я столкнулся с каким-то странным поведением с std :: atomic. Ситуация такова:

  • Thread A создает переменную std :: atomic (с параметром T * в качестве параметра шаблона).
  • Thread B изменяет его.
  • Thread A ждет изменения, затем читает переменную.

Конечным результатом является то, что значение, считанное потоком A, не является значением, заданным потоком B.

Если я удалю std :: atomic (который сохраняет переменную как указатель), она работает так, как ожидалось. И что более интересно, если я установил параметр шаблона в unsigned long и нарисую указатель на и из T *, он работает так, как ожидалось.

Я использую оператор присваивания, чтобы установить значение и элемент загрузки, чтобы получить значение.

Мне не хватает, как должен работать std :: atomic с параметром T * или это нарушение?

РЕДАКТИРОВАТЬ

Некоторый код

    #include <boost/thread.hpp>
    #include <atomic>

    using namespace std;

    void* vptr;
    std::atomic<unsigned int> aui;
    std::atomic<void*> aptr;

    void foo()
    {
        vptr = (void*) 0x123;
        aui = (unsigned int) 0x123;
        aptr = (void*) 0x123;
    }

    int main(int argc, char* argv[])
    {
        boost::thread threadA;

        vptr = nullptr;
        aui = 0;
        aptr = nullptr;

        threadA = boost::thread(foo);
        threadA.join();

        cout << vptr << " " << (void*)aui.load() << " " << aptr.load();

        return 0;
    }

Выход: 0x123 0x123 0x41d028

+2
источник поделиться
2 ответа

Я воспроизвел вашу проблему с MinGW 4.6.1 (и нашел, что исправлено в 4.7.0). Если вы не можете перейти на новый MinGW, который исправил проблему, вы должны иметь возможность исправить определение заголовка lib/gcc/mingw32/4.6.2/include/c++/bits/atomic_0.h _ATOMIC_STORE_ макрос как таковой (при условии, что заголовки в 4.6.2 достаточно похожи на 4.6.1):

#if 0 /* disable the original broken macro */
#define _ATOMIC_STORE_(__a, __n, __x)                      \
  ({typedef __typeof__(_ATOMIC_MEMBER_) __i_type;                          \
    __i_type* __p = &_ATOMIC_MEMBER_;                      \
    __typeof__(__n) __w = (__n);                           \
    __atomic_flag_base* __g = __atomic_flag_for_address(__p);          \
    __atomic_flag_wait_explicit(__g, __x);                 \
    *__p = __w;                                \
    atomic_flag_clear_explicit(__g, __x);                      \
    __w; })
#else
#define _ATOMIC_STORE_(__a, __n, __x)                      \
  ({typedef __typeof__(_ATOMIC_MEMBER_) __i_type;                          \
    __i_type* __pxx = &_ATOMIC_MEMBER_;                    \
    __typeof__(__n) __w = (__n);                           \
    __atomic_flag_base* __g = __atomic_flag_for_address(__pxx);        \
    __atomic_flag_wait_explicit(__g, __x);                 \
    *__pxx = __w;                                  \
    atomic_flag_clear_explicit(__g, __x);                      \
    __w; })
#endif

Проблема заключается в локальной переменной в макросе с именем __p, что, по-видимому, вызывает путаницу, когда макрос вызывается с переменной, также называемой __p для параметра макроса __n. Когда __n становится расширенным до __p, вместо доступа к переменной, переданной 'invoker' in, расширенный макрос обращается к локальной переменной.

+2
источник

Это может быть http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51811 - это исправлено в GCC 4.7

Можете ли вы показать код, который вызывает проблему?

0
источник

Посмотрите другие вопросы по меткам или Задайте вопрос