Q: How to use gcc atomic builtins? In my program I was trying to update a value from multiple threads. I know how to use mutex (pthread_mutex_lock(), pthread_mutex_unlock()) to do this, but I just learned about gcc atomic builtins so I would like to have a try.
shared value A;
void each_working_thread() {
    thread local variable B;
    if (is_valid(A,B))
        __sync_sub_and_fetch(A,B);
    else 
        throw error;
}

where is_valid() is a const function that return boolean. 
Is this correct, or the value of A could be updated by another thread during is_valid() ? 

A: I assume is_valid(A, B) can change depending on A.
In which case, this is not safe - consider the following sequence:


*

*Thread 1 calls is_valid(A, B) and gets true

*Thread 2 calls is_valid(A, B) and gets true

*Thread 1 calls __sync_sub_and_fetch(A, B) changes A, and the new value of A means is_valid(A, B) is now false.

*Thread 2 calls __sync_sub_and_fetch(A, B) even though it shouldn't because is_valid(A, B) is now false.


You may be interested in the compare-exchange operation. In this case you can write something like:
int oldValueOfA, newValueOfA;
do {
    oldValueOfA = A;
    __sync_synchronize(); // memory barrier; makes sure A doesn't get accessed after this line
    if (!is_valid(oldValueOfA, B))
        throw error;
    newValueOfA = oldValueOfA - B;
} while(!__sync_bool_compare_and_swap(&A, oldValueOfA, newValueOfA));

You can't make the two operations atomic, but you can detect if they weren't atomic and then you can try again.
This works because if A doesn't still contain oldValueOfA, __sync_bool_compare_and_swap does nothing and returns false. Otherwise, it sets it to newValueOfA and returns true. So if it returns true, you know nobody else changed A while you were busy calling is_valid. And if it returns false, then you haven't actually done anything yet, so you're free to go back and try again.
Note that is_valid might be called several times; this is relevant if it has side effects (like printing a message on the screen). In that case you should just use a mutex.

A: That probably is not thread safe, depending on what exactly is_valid does.
The point of that specific builtin is just to perform an atomic subtraction.
Consider this code
A = A - B;

This is not thread safe because it requires at least 2 atomic steps - the A - B, and then the assignment back to A. The builtin for this solves that one scenario.
