atomic.h

/* -*- C -*-// -------------------------------------------------------------------// MiniLock - a quick user space lock // Copyright (c) 2008 Leon Bottou. All rights reserved//// Permission is hereby granted, free of charge, to any person obtaining// a copy of this software and associated documentation files (the// "Software"), to deal in the Software without restriction, including// without limitation the rights to use, copy, modify, merge, publish,// distribute, sublicense, and/or sell copies of the Software, and to// permit persons to whom the Software is furnished to do so, subject to// the following conditions://// The above copyright notice and this permission notice shall be// included in all copies or substantial portions of the Software.//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.//// ------------------------------------------------------------------- */#ifndef ATOMIC_H#define ATOMIC_H/* ------------------------------------------------------------// These are primitives to implement very quick locks.// // Non-blocking usage:// if (atomicAcquire(&lock)) {// ... // do something protected by the lock// atomicRelease(&lock);// }//// Blocking usage:// atomicAcquireOrSpin(&lock);// // do something protected by the lock// atomicRelease(&lock);//// Rules of thumb:// - Acquire and release from the same function with // no intervening function calls.// - Do not use AcquireOrSpin for waiting a long time.// No more than a few microseconds please.//// Memory ordering:// Viewed from another processor// - load/stores performed by this cpu after the acquire // cannot appear to have happened before the acquire.// - load/stores performed by this cpu before the release // cannot appear to have happened after the release.//// Implementation:// All depends on the definitions from the initial include file.// To perform the non blocking operations:// - use intel builtins if available (icc, gcc>=4.1).// - use win32 interlocked operations (win32).// - use inline assembly code for some platforms.// - use pthreads// To perform the waiting when spinning takes to long:// - use win32 critical sections and events.// - use pthreads mutex and conditions.// This is controlled by the preprocessor symbols:// WIN32 // __GNUC__ __GNUC_MAJOR__ __GNUC_MINOR__ // __INTEL_COMPILER// and can be overriden by defining// HAVE_INTEL_ATOMIC_BUILTINS// OBEY_HAVE_INTEL_ATOMIC_BUILTINS// and by tweaking the files include in atomic.h.// ------------------------------------------------------------ */# ifdef __cplusplusextern"C" {
#endif/* { int tmp = *lock; *lock = 1; return !tmp; }. */int atomicAcquire(intvolatile *lock);
/* { while (!atomicAcquire(lock)) { spin/yield/wait } } */void atomicAcquireOrSpin(intvolatile *lock);
/* { *lock = 0; } */void atomicRelease(intvolatile *lock);
/* { *var += 1; return *var; } */int atomicIncrement(intvolatile *var);
/* { *var -= 1; return *var; } */int atomicDecrement(intvolatile *var);
/* { if (*var == oldval) { *var = newval; return TRUE; } return FALSE; } */int atomicCompareAndSwap(intvolatile *var, int oldval, int newval);
# ifdef __cplusplus}
#endif#endif