#include #include int main() { int x = 23; int success = __sync_bool_compare_and_swap(&x, 23, 34); printf("Success? %d; value = %d\n", success, x); success = __sync_bool_compare_and_swap(&x, 33, 22); printf("Success? %d; value = %d\n", success, x); int oldval = __sync_fetch_and_add(&x, 1000); printf("Changed from %d to %d atomically\n", oldval, x); int newval = __sync_add_and_fetch(&x, 1000); printf("Changed to %d (was %d at time of change) atomically\n", x, newval); __sync_synchronize(); // no visible effect; a memory barrier } typedef struct node { double payload; struct node *next; } node_t; typedef struct { node_t *head, *tail; } queue_t; void atomic_add(queue_t *q, double value) { // make node node_t *new_node = malloc(sizeof(node_t)); new_node->payload = value; new_node->next = NULL; for(;;) { // retry until success #ifdef TAIL_BEFORE_LINK node_t *p = q->tail; // first update the tail pointer if (__sync_bool_compare_and_swap(&(q->tail), p, new_node)) { // on success, update next pointer of old tail p->next = new_node; break; } #else // LINK_BEFORE_TAIL // first update the connectivity if (__sync_bool_compare_and_swap(&(q->tail->next), NULL, new_node)) { // on success, update tail q->tail = new_node; break; } #endif } }