atomicity.h revision 267654
14Srgrimes// Low-level functions for atomic operations: PA-RISC version  -*- C++ -*-
223452Sjoerg
323452Sjoerg// Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
4624Srgrimes//
523452Sjoerg// This file is part of the GNU ISO C++ Library.  This library is free
623452Sjoerg// software; you can redistribute it and/or modify it under the
723452Sjoerg// terms of the GNU General Public License as published by the
823452Sjoerg// Free Software Foundation; either version 2, or (at your option)
923452Sjoerg// any later version.
1023452Sjoerg
1123452Sjoerg// This library is distributed in the hope that it will be useful,
1223452Sjoerg// but WITHOUT ANY WARRANTY; without even the implied warranty of
1323452Sjoerg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1423452Sjoerg// GNU General Public License for more details.
1523452Sjoerg
1623452Sjoerg// You should have received a copy of the GNU General Public License along
1723452Sjoerg// with this library; see the file COPYING.  If not, write to the Free
1823452Sjoerg// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
1923452Sjoerg// USA.
2023452Sjoerg
2123452Sjoerg// As a special exception, you may use this file as part of a free software
2223452Sjoerg// library without restriction.  Specifically, if other files instantiate
2323452Sjoerg// templates or use macros or inline functions from this file, or you compile
2423452Sjoerg// this file and link it with other files to produce an executable, this
2523452Sjoerg// file does not by itself cause the resulting executable to be covered by
2623452Sjoerg// the GNU General Public License.  This exception does not however
2723452Sjoerg// invalidate any other reasons why the executable file might be covered by
2823452Sjoerg// the GNU General Public License.
2923452Sjoerg
3023452Sjoerg#include <bits/c++config.h>
3123452Sjoerg#include <ext/atomicity.h>
3223452Sjoerg
334Srgrimes_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
344Srgrimes
3523452Sjoerg  template<int _Inst>
3623452Sjoerg    struct _Atomicity_lock
3723452Sjoerg    {
3823452Sjoerg      static volatile int _S_atomicity_lock;
3923452Sjoerg    };
4023452Sjoerg
4123452Sjoerg  template<int _Inst>
4223452Sjoerg  volatile int
4323452Sjoerg  _Atomicity_lock<_Inst>::_S_atomicity_lock __attribute__ ((aligned (16))) = 1;
4423452Sjoerg
454Srgrimes  // Because of the lack of weak support when using the hpux som
4623452Sjoerg  // linker, we explicitly instantiate the atomicity lock.
4723452Sjoerg  template volatile int _Atomicity_lock<0>::_S_atomicity_lock;
4823452Sjoerg
4923452Sjoerg  int
504Srgrimes  __attribute__ ((__unused__))
514Srgrimes  __exchange_and_add(volatile _Atomic_word* __mem, int __val)
5223452Sjoerg  {
534Srgrimes    _Atomic_word result;
5423452Sjoerg    int tmp;
5523452Sjoerg    volatile int& lock = _Atomicity_lock<0>::_S_atomicity_lock;
5623452Sjoerg
5723452Sjoerg    __asm__ __volatile__ ("ldcw 0(%1),%0\n\t"
5823452Sjoerg			  "cmpib,<>,n 0,%0,.+20\n\t"
5923452Sjoerg			  "ldw 0(%1),%0\n\t"
6023452Sjoerg			  "cmpib,= 0,%0,.-4\n\t"
614Srgrimes			  "nop\n\t"
6223452Sjoerg			  "b,n .-20"
6323452Sjoerg			  : "=&r" (tmp)
6418444Sbde			  : "r" (&lock)
6523452Sjoerg			  : "memory");
6623452Sjoerg
6723452Sjoerg    result = *__mem;
6823452Sjoerg    *__mem = result + __val;
6923452Sjoerg    __asm__ __volatile__ ("stw %1,0(%0)"
7023452Sjoerg			  : : "r" (&lock), "r" (tmp) : "memory");
7123452Sjoerg    return result;
7223452Sjoerg  }
7323452Sjoerg
7423452Sjoerg  void
7523452Sjoerg  __attribute__ ((__unused__))
7623452Sjoerg  __atomic_add(volatile _Atomic_word* __mem, int __val)
7723452Sjoerg  {
7823452Sjoerg    int tmp;
7923452Sjoerg    volatile int& lock = _Atomicity_lock<0>::_S_atomicity_lock;
8023452Sjoerg
8123452Sjoerg    __asm__ __volatile__ ("ldcw 0(%1),%0\n\t"
8223452Sjoerg			  "cmpib,<>,n 0,%0,.+20\n\t"
8323452Sjoerg			  "ldw 0(%1),%0\n\t"
8423452Sjoerg			  "cmpib,= 0,%0,.-4\n\t"
8523452Sjoerg			  "nop\n\t"
8623452Sjoerg			  "b,n .-20"
8718444Sbde			  : "=&r" (tmp)
8823452Sjoerg			  : "r" (&lock)
8923452Sjoerg			  : "memory");
9023452Sjoerg
914Srgrimes    *__mem += __val;
9223452Sjoerg    __asm__ __volatile__ ("stw %1,0(%0)"
9323452Sjoerg			  : : "r" (&lock), "r" (tmp) : "memory");
9423452Sjoerg  }
9523452Sjoerg
9623452Sjoerg_GLIBCXX_END_NAMESPACE
9723452Sjoerg