1/** \file 2 * \brief compare and set (cas) implementations 3 */ 4 5/* 6 * Copyright (c) 2009, ETH Zurich. 7 * All rights reserved. 8 * 9 * This file is distributed under the terms in the attached LICENSE file. 10 * If you do not find this file, copies can be found by writing to: 11 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 12 */ 13 14#ifndef CAS_H_ 15#define CAS_H_ 16 17#include <stdint.h> 18#include <stdbool.h> 19 20/* 21 * \brief compare and set. If the value at address 22 * equals old, set it to new otherwise don't write to address. 23 * Returns the actual previous value at the address. 24 */ 25static inline uintptr_t cas_ret_act(volatile uintptr_t *address, uintptr_t old, 26 uintptr_t new) 27{ 28 register uintptr_t res; 29 __asm volatile("lock; cmpxchgq %2,%0 \n\t" 30 : "+m" (*address), "=a" (res) 31 : "r" (new), "a" (old) 32 : "memory"); 33 return res; 34} 35 36/* 37 * \brief compare and set. If the value at address 38 * equals old, set it to new and return true, 39 * otherwise don't write to address and return false 40 */ 41static inline bool cas(volatile uintptr_t *address, uintptr_t old, 42 uintptr_t new) 43{ 44 register bool res; 45 __asm volatile("lock; cmpxchgq %2,%0 \n\t" 46 "setz %1 \n\t" 47 : "+m" (*address), "=q" (res) 48 : "r" (new), "a" (old) 49 : "memory"); 50 return res; 51} 52 53#endif /* CAS_H_ */ 54