Спин-ожидание атома, чтобы стать определенной ценностью - PullRequest
3 голосов
/ 02 апреля 2019

Я хочу подождать, пока атомное значение не станет определенным значением, а затем получить память memory_order_release 'с магазином.

Я думал, что с оптимизацией

#include <stdatomic.h>

void wait_for_flag_to_become2(_Atomic unsigned char *xp)
{
    while(2!=atomic_load_explicit(xp,memory_order_acquire));
}
void wait_for_flag_to_become2_(_Atomic unsigned char *xp)
{
    while(2!=atomic_load_explicit(xp,memory_order_relaxed)){}
    atomic_thread_fence(memory_order_acquire);
}

сгенерирует тот же код и будет напоминать последнюю функцию, но на платформах, где выходные сборки отличаются, они не делают.

Являются ли эти две функции семантически эквивалентными и являются различиями в выходной сборкеиз-за простой неудачи в оптимизации, или они фактически не семантически эквивалентны?


https://gcc.godbolt.org/z/hNcf-i

power64-at12, gcc8:

wait_for_flag_to_become2:
        .quad   .L.wait_for_flag_to_become2,.TOC.@tocbase,0
.L.wait_for_flag_to_become2:
.L2:
        lbz 9,0(3)
        cmpw 7,9,9
        bne- 7,$+4
        isync
        rlwinm 9,9,0,0xff
        cmplwi 7,9,2
        bne 7,.L2
        blr
        .long 0
        .byte 0,0,0,0,0,0,0,0
wait_for_flag_to_become2_:
        .quad   .L.wait_for_flag_to_become2_,.TOC.@tocbase,0
.L.wait_for_flag_to_become2_:
.L6:
        lbz 9,0(3)
        cmplwi 7,9,2
        bne 7,.L6
        lwsync
        blr
        .long 0
        .byte 0,0,0,0,0,0,0,0

ARM64, gcc 8.2:

wait_for_flag_to_become2:
.L2:
        ldarb   w1, [x0]
        and     w1, w1, 255
        cmp     w1, 2
        bne     .L2
        ret
wait_for_flag_to_become2_:
.L5:
        ldrb    w1, [x0]
        and     w1, w1, 255
        cmp     w1, 2
        bne     .L5
        dmb     ishld
        ret
...