GLIB: g_atomic_int_get становится NO-OP?

В более крупном фрагменте кода я заметил, что функции g_atomic_* в glib не выполняют то, что я ожидал, поэтому я написал этот простой пример:

#include <stdlib.h>
#include "glib.h"
#include "pthread.h"
#include "stdio.h"

void *set_foo(void *ptr) {
  g_atomic_int_set(((int*)ptr), 42);
  return NULL;
}

int main(void) {
  int foo = 0;
  pthread_t other;

  if (pthread_create(&other, NULL, set_foo, &foo)== 0) {
    pthread_join(other, NULL);
    printf("Got %d\n", g_atomic_int_get(&foo));
  } else {
    printf("Thread did not run\n");
    exit(1);
  }
}

Когда я компилирую это с опцией GCC'-E' (остановка после предварительной обработки), я замечаю, что вызов g_atomic_int_get(&foo) стал:

(*(&foo))

и g_atomic_int_set(((int*)ptr), 42) стал:

((void) (*(((int*)ptr)) = (42)))

Очевидно, я ожидал некоторых атомарных операций сравнения и обмена, а не просто простых (небезопасных) назначений. Что я делаю неправильно?

Для справки моя команда компиляции выглядит так:

gcc -m64 -E -o foo.E `pkg-config --cflags glib-2.0` -O0 -g foo.c

1 ответ

Решение

Архитектура, на которой вы работаете, не требует барьера памяти для атомарных целочисленных операций set / get, поэтому преобразование допустимо.

Вот где это определено: http://git.gnome.org/browse/glib/tree/glib/gatomic.h#n60

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

Другие вопросы по тегам