atomicity.h revision 132720
155682Smarkm// Low-level functions for atomic operations: x86, x >= 3 version -*- C++ -*- 2233294Sstas 3233294Sstas// Copyright (C) 2003, 2004 Free Software Foundation, Inc. 4233294Sstas// 555682Smarkm// This file is part of the GNU ISO C++ Library. This library is free 6233294Sstas// software; you can redistribute it and/or modify it under the 7233294Sstas// terms of the GNU General Public License as published by the 8233294Sstas// Free Software Foundation; either version 2, or (at your option) 955682Smarkm// any later version. 10233294Sstas 11233294Sstas// This library is distributed in the hope that it will be useful, 1255682Smarkm// but WITHOUT ANY WARRANTY; without even the implied warranty of 13233294Sstas// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14233294Sstas// GNU General Public License for more details. 15233294Sstas 1655682Smarkm// You should have received a copy of the GNU General Public License along 17233294Sstas// with this library; see the file COPYING. If not, write to the Free 18233294Sstas// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 19233294Sstas// USA. 2055682Smarkm 21233294Sstas// As a special exception, you may use this file as part of a free software 22233294Sstas// library without restriction. Specifically, if other files instantiate 23233294Sstas// templates or use macros or inline functions from this file, or you compile 24233294Sstas// this file and link it with other files to produce an executable, this 25233294Sstas// file does not by itself cause the resulting executable to be covered by 26233294Sstas// the GNU General Public License. This exception does not however 27233294Sstas// invalidate any other reasons why the executable file might be covered by 28233294Sstas// the GNU General Public License. 29233294Sstas 30233294Sstas#include <bits/atomicity.h> 31233294Sstas 3255682Smarkmnamespace __gnu_cxx 3355682Smarkm{ 3455682Smarkm template<int __inst> 3555682Smarkm struct _Atomicity_lock 3655682Smarkm { 3755682Smarkm static volatile _Atomic_word _S_atomicity_lock; 3855682Smarkm }; 3955682Smarkm 4055682Smarkm template<int __inst> 4155682Smarkm volatile _Atomic_word _Atomicity_lock<__inst>::_S_atomicity_lock = 0; 4290926Snectar 4390926Snectar template volatile _Atomic_word _Atomicity_lock<0>::_S_atomicity_lock; 4490926Snectar 4555682Smarkm _Atomic_word 46233294Sstas __attribute__ ((__unused__)) 4755682Smarkm __exchange_and_add(volatile _Atomic_word* __mem, int __val) 4855682Smarkm { 4955682Smarkm register _Atomic_word __result, __tmp = 1; 50178825Sdfr 51178825Sdfr // Obtain the atomic exchange/add spin lock. 52178825Sdfr do 53178825Sdfr { 5455682Smarkm __asm__ __volatile__ ("xchg{l} {%0,%1|%1,%0}" 5555682Smarkm : "=m" (_Atomicity_lock<0>::_S_atomicity_lock), 5655682Smarkm "+r" (__tmp) 5755682Smarkm : "m" (_Atomicity_lock<0>::_S_atomicity_lock)); 5855682Smarkm } 5955682Smarkm while (__tmp); 6055682Smarkm 6155682Smarkm __result = *__mem; 6255682Smarkm *__mem += __val; 6355682Smarkm 6455682Smarkm // Release spin lock. 6555682Smarkm _Atomicity_lock<0>::_S_atomicity_lock = 0; 6655682Smarkm 6755682Smarkm return __result; 68233294Sstas } 6955682Smarkm 7055682Smarkm void 7155682Smarkm __attribute__ ((__unused__)) 7255682Smarkm __atomic_add(volatile _Atomic_word* __mem, int __val) 7355682Smarkm { __exchange_and_add(__mem, __val); } 7455682Smarkm} // namespace __gnu_cxx 7555682Smarkm