1*404b540aSrobert // Low-level functions for atomic operations: x86, x >= 3 version -*- C++ -*- 2*404b540aSrobert 3*404b540aSrobert // Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. 4*404b540aSrobert // 5*404b540aSrobert // This file is part of the GNU ISO C++ Library. This library is free 6*404b540aSrobert // software; you can redistribute it and/or modify it under the 7*404b540aSrobert // terms of the GNU General Public License as published by the 8*404b540aSrobert // Free Software Foundation; either version 2, or (at your option) 9*404b540aSrobert // any later version. 10*404b540aSrobert 11*404b540aSrobert // This library is distributed in the hope that it will be useful, 12*404b540aSrobert // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*404b540aSrobert // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*404b540aSrobert // GNU General Public License for more details. 15*404b540aSrobert 16*404b540aSrobert // You should have received a copy of the GNU General Public License along 17*404b540aSrobert // with this library; see the file COPYING. If not, write to the Free 18*404b540aSrobert // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19*404b540aSrobert // USA. 20*404b540aSrobert 21*404b540aSrobert // As a special exception, you may use this file as part of a free software 22*404b540aSrobert // library without restriction. Specifically, if other files instantiate 23*404b540aSrobert // templates or use macros or inline functions from this file, or you compile 24*404b540aSrobert // this file and link it with other files to produce an executable, this 25*404b540aSrobert // file does not by itself cause the resulting executable to be covered by 26*404b540aSrobert // the GNU General Public License. This exception does not however 27*404b540aSrobert // invalidate any other reasons why the executable file might be covered by 28*404b540aSrobert // the GNU General Public License. 29*404b540aSrobert 30*404b540aSrobert #include <ext/atomicity.h> 31*404b540aSrobert 32*404b540aSrobert _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) 33*404b540aSrobert 34*404b540aSrobert template<int __inst> 35*404b540aSrobert struct _Atomicity_lock 36*404b540aSrobert { 37*404b540aSrobert static volatile _Atomic_word _S_atomicity_lock; 38*404b540aSrobert }; 39*404b540aSrobert 40*404b540aSrobert template<int __inst> 41*404b540aSrobert volatile _Atomic_word _Atomicity_lock<__inst>::_S_atomicity_lock = 0; 42*404b540aSrobert 43*404b540aSrobert template volatile _Atomic_word _Atomicity_lock<0>::_S_atomicity_lock; 44*404b540aSrobert 45*404b540aSrobert _Atomic_word 46*404b540aSrobert __attribute__ ((__unused__)) __exchange_and_add(volatile _Atomic_word * __mem,int __val)47*404b540aSrobert __exchange_and_add(volatile _Atomic_word* __mem, int __val) 48*404b540aSrobert { 49*404b540aSrobert register _Atomic_word __result, __tmp = 1; 50*404b540aSrobert 51*404b540aSrobert // Obtain the atomic exchange/add spin lock. 52*404b540aSrobert do 53*404b540aSrobert { 54*404b540aSrobert __asm__ __volatile__ ("xchg{l} {%0,%1|%1,%0}" 55*404b540aSrobert : "=m" (_Atomicity_lock<0>::_S_atomicity_lock), 56*404b540aSrobert "+r" (__tmp) 57*404b540aSrobert : "m" (_Atomicity_lock<0>::_S_atomicity_lock)); 58*404b540aSrobert } 59*404b540aSrobert while (__tmp); 60*404b540aSrobert 61*404b540aSrobert __result = *__mem; 62*404b540aSrobert *__mem += __val; 63*404b540aSrobert 64*404b540aSrobert // Release spin lock. 65*404b540aSrobert _Atomicity_lock<0>::_S_atomicity_lock = 0; 66*404b540aSrobert 67*404b540aSrobert return __result; 68*404b540aSrobert } 69*404b540aSrobert 70*404b540aSrobert void 71*404b540aSrobert __attribute__ ((__unused__)) __atomic_add(volatile _Atomic_word * __mem,int __val)72*404b540aSrobert __atomic_add(volatile _Atomic_word* __mem, int __val) 73*404b540aSrobert { __exchange_and_add(__mem, __val); } 74*404b540aSrobert 75*404b540aSrobert _GLIBCXX_END_NAMESPACE 76