OSDN Git Service

2003-07-04 Benjamin Kosnik <bkoz@redhat.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / config / cpu / hppa / atomicity.h
1 /* Low-level functions for atomic operations.  PA-RISC version. -*- C++ -*-
2    Copyright 2002 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
20 #ifndef _GLIBCXX_ATOMICITY_H
21 #define _GLIBCXX_ATOMICITY_H    1
22
23 typedef int _Atomic_word;
24
25 template <int __inst>
26 struct __Atomicity_lock
27 {
28   static volatile int _S_atomicity_lock;
29 };
30
31 template <int __inst>
32 volatile int
33 __Atomicity_lock<__inst>::_S_atomicity_lock __attribute__ ((aligned (16))) = 1;
34
35 /* Because of the lack of weak support when using the hpux
36    som linker, we explicitly instantiate the atomicity lock
37    in src/misc-inst.cc when _GLIBCXX_INST_GLIBCXX_ATOMICITY_LOCK
38    is defined.  */
39 #ifndef _GLIBCXX_INST_GLIBCXX_ATOMICITY_LOCK
40 template volatile int __Atomicity_lock<0>::_S_atomicity_lock;
41 #endif
42
43 static inline int
44 __attribute__ ((__unused__))
45 __exchange_and_add (volatile _Atomic_word* __mem, int __val)
46 {
47   _Atomic_word result;
48   int tmp;
49   volatile int& lock = __Atomicity_lock<0>::_S_atomicity_lock;
50
51   __asm__ __volatile__ ("ldcw 0(%1),%0\n\t"
52                         "cmpib,<>,n 0,%0,.+20\n\t"
53                         "ldw 0(%1),%0\n\t"
54                         "cmpib,= 0,%0,.-4\n\t"
55                         "nop\n\t"
56                         "b,n .-20"
57                         : "=&r" (tmp)
58                         : "r" (&lock));
59
60   result = *__mem;
61   *__mem = result + __val;
62   /* Reset lock with PA 2.0 "ordered" store.  */
63   __asm__ __volatile__ ("stw,ma %1,0(%0)"
64                         : : "r" (&lock), "r" (tmp) : "memory");
65   return result;
66 }
67
68 static inline void
69 __attribute__ ((__unused__))
70 __atomic_add (_Atomic_word* __mem, int __val)
71 {
72   int tmp;
73   volatile int& lock = __Atomicity_lock<0>::_S_atomicity_lock;
74
75   __asm__ __volatile__ ("ldcw 0(%1),%0\n\t"
76                         "cmpib,<>,n 0,%0,.+20\n\t"
77                         "ldw 0(%1),%0\n\t"
78                         "cmpib,= 0,%0,.-4\n\t"
79                         "nop\n\t"
80                         "b,n .-20"
81                         : "=&r" (tmp)
82                         : "r" (&lock));
83
84   *__mem += __val;
85   /* Reset lock with PA 2.0 "ordered" store.  */
86   __asm__ __volatile__ ("stw,ma %1,0(%0)"
87                         : : "r" (&lock), "r" (tmp) : "memory");
88 }
89
90 #endif