atomicity.h revision 117397
1117397Skan/* Low-level functions for atomic operations. PA-RISC version. -*- C++ -*- 2117397Skan Copyright 2002 Free Software Foundation, Inc. 3117397Skan This file is part of the GNU C Library. 4117397Skan 5117397Skan The GNU C Library is free software; you can redistribute it and/or 6117397Skan modify it under the terms of the GNU Library General Public License as 7117397Skan published by the Free Software Foundation; either version 2 of the 8117397Skan License, or (at your option) any later version. 9117397Skan 10117397Skan The GNU C Library is distributed in the hope that it will be useful, 11117397Skan but WITHOUT ANY WARRANTY; without even the implied warranty of 12117397Skan MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13117397Skan Library General Public License for more details. 14117397Skan 15117397Skan You should have received a copy of the GNU Library General Public 16117397Skan License along with the GNU C Library; see the file COPYING.LIB. If not, 17117397Skan write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18117397Skan Boston, MA 02111-1307, USA. */ 19117397Skan 20117397Skan#ifndef _BITS_ATOMICITY_H 21117397Skan#define _BITS_ATOMICITY_H 1 22117397Skan 23117397Skantypedef int _Atomic_word; 24117397Skan 25117397Skantemplate <int __inst> 26117397Skanstruct __Atomicity_lock 27117397Skan{ 28117397Skan static volatile int _S_atomicity_lock; 29117397Skan}; 30117397Skan 31117397Skantemplate <int __inst> 32117397Skanvolatile int 33117397Skan__Atomicity_lock<__inst>::_S_atomicity_lock __attribute__ ((aligned (16))) = 1; 34117397Skan 35117397Skan/* Because of the lack of weak support when using the hpux 36117397Skan som linker, we explicitly instantiate the atomicity lock 37117397Skan in src/misc-inst.cc when _GLIBCPP_INST_ATOMICITY_LOCK 38117397Skan is defined. */ 39117397Skan#ifndef _GLIBCPP_INST_ATOMICITY_LOCK 40117397Skantemplate volatile int __Atomicity_lock<0>::_S_atomicity_lock; 41117397Skan#endif 42117397Skan 43117397Skanstatic inline int 44117397Skan__attribute__ ((__unused__)) 45117397Skan__exchange_and_add (volatile _Atomic_word* __mem, int __val) 46117397Skan{ 47117397Skan _Atomic_word result; 48117397Skan int tmp; 49117397Skan volatile int& lock = __Atomicity_lock<0>::_S_atomicity_lock; 50117397Skan 51117397Skan __asm__ __volatile__ ("ldcw 0(%1),%0\n\t" 52117397Skan "cmpib,<>,n 0,%0,.+20\n\t" 53117397Skan "ldw 0(%1),%0\n\t" 54117397Skan "cmpib,= 0,%0,.-4\n\t" 55117397Skan "nop\n\t" 56117397Skan "b,n .-20" 57117397Skan : "=&r" (tmp) 58117397Skan : "r" (&lock)); 59117397Skan 60117397Skan result = *__mem; 61117397Skan *__mem = result + __val; 62117397Skan /* Reset lock with PA 2.0 "ordered" store. */ 63117397Skan __asm__ __volatile__ ("stw,ma %1,0(%0)" 64117397Skan : : "r" (&lock), "r" (tmp) : "memory"); 65117397Skan return result; 66117397Skan} 67117397Skan 68117397Skanstatic inline void 69117397Skan__attribute__ ((__unused__)) 70117397Skan__atomic_add (_Atomic_word* __mem, int __val) 71117397Skan{ 72117397Skan int tmp; 73117397Skan volatile int& lock = __Atomicity_lock<0>::_S_atomicity_lock; 74117397Skan 75117397Skan __asm__ __volatile__ ("ldcw 0(%1),%0\n\t" 76117397Skan "cmpib,<>,n 0,%0,.+20\n\t" 77117397Skan "ldw 0(%1),%0\n\t" 78117397Skan "cmpib,= 0,%0,.-4\n\t" 79117397Skan "nop\n\t" 80117397Skan "b,n .-20" 81117397Skan : "=&r" (tmp) 82117397Skan : "r" (&lock)); 83117397Skan 84117397Skan *__mem += __val; 85117397Skan /* Reset lock with PA 2.0 "ordered" store. */ 86117397Skan __asm__ __volatile__ ("stw,ma %1,0(%0)" 87117397Skan : : "r" (&lock), "r" (tmp) : "memory"); 88117397Skan} 89117397Skan 90117397Skan#endif 91