1 // Low-level functions for atomic operations: PA-RISC version -*- C++ -*- 2 3 // Copyright (C) 2002-2024 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 #include <bits/c++config.h> 26 #include <ext/atomicity.h> 27 28 /* Perform ldcw operation in cache when possible. */ 29 #ifndef _PA_LDCW_INSN 30 # ifdef _PA_RISC2_0 31 # define _PA_LDCW_INSN "ldcw,co" 32 # else 33 # define _PA_LDCW_INSN "ldcw" 34 # endif 35 #endif 36 37 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 38 { 39 _GLIBCXX_BEGIN_NAMESPACE_VERSION 40 41 template<int _Inst> 42 struct _Atomicity_lock 43 { 44 static volatile int _S_atomicity_lock; 45 }; 46 47 template<int _Inst> 48 volatile int 49 _Atomicity_lock<_Inst>::_S_atomicity_lock __attribute__ ((aligned (16))) = 1; 50 51 // Because of the lack of weak support when using the hpux som 52 // linker, we explicitly instantiate the atomicity lock. 53 template volatile int _Atomicity_lock<0>::_S_atomicity_lock; 54 55 int 56 __attribute__ ((__unused__)) 57 __exchange_and_add(volatile _Atomic_word* __mem, int __val) throw () 58 { 59 _Atomic_word result; 60 int tmp; 61 volatile int& lock = _Atomicity_lock<0>::_S_atomicity_lock; 62 63 __asm__ __volatile__ (_PA_LDCW_INSN " 0(%1),%0\n\t" 64 "cmpib,<>,n 0,%0,.+20\n\t" 65 "ldw,ma 0(%1),%0\n\t" 66 "cmpib,<> 0,%0,.-12\n\t" 67 "nop\n\t" 68 "b,n .-12" 69 : "=&r" (tmp) 70 : "r" (&lock) 71 : "memory"); 72 73 result = *__mem; 74 *__mem = result + __val; 75 __asm__ __volatile__ ("stw,ma %1,0(%0)" 76 : : "r" (&lock), "r" (tmp) : "memory"); 77 return result; 78 } 79 80 void 81 __attribute__ ((__unused__)) 82 __atomic_add(volatile _Atomic_word* __mem, int __val) throw () 83 { 84 int tmp; 85 volatile int& lock = _Atomicity_lock<0>::_S_atomicity_lock; 86 87 __asm__ __volatile__ (_PA_LDCW_INSN " 0(%1),%0\n\t" 88 "cmpib,<>,n 0,%0,.+20\n\t" 89 "ldw,ma 0(%1),%0\n\t" 90 "cmpib,<> 0,%0,.-12\n\t" 91 "nop\n\t" 92 "b,n .-12" 93 : "=&r" (tmp) 94 : "r" (&lock) 95 : "memory"); 96 97 *__mem += __val; 98 __asm__ __volatile__ ("stw,ma %1,0(%0)" 99 : : "r" (&lock), "r" (tmp) : "memory"); 100 } 101 102 _GLIBCXX_END_NAMESPACE_VERSION 103 } // namespace 104