Line 0
Link Here
|
|
|
1 |
/* Licensed to the Apache Software Foundation (ASF) under one or more |
2 |
* contributor license agreements. See the NOTICE file distributed with |
3 |
* this work for additional information regarding copyright ownership. |
4 |
* The ASF licenses this file to You under the Apache License, Version 2.0 |
5 |
* (the "License"); you may not use this file except in compliance with |
6 |
* the License. You may obtain a copy of the License at |
7 |
* |
8 |
* http://www.apache.org/licenses/LICENSE-2.0 |
9 |
* |
10 |
* Unless required by applicable law or agreed to in writing, software |
11 |
* distributed under the License is distributed on an "AS IS" BASIS, |
12 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 |
* See the License for the specific language governing permissions and |
14 |
* limitations under the License. |
15 |
*/ |
16 |
|
17 |
#include "apr_arch_atomic.h" |
18 |
|
19 |
#ifdef USE_ATOMICS_PPC |
20 |
|
21 |
#ifdef PPC405_ERRATA |
22 |
# define PPC405_ERR77_SYNC " sync\n" |
23 |
#else |
24 |
# define PPC405_ERR77_SYNC |
25 |
#endif |
26 |
|
27 |
APR_DECLARE(apr_status_t) apr_atomic_init(apr_pool_t *p) |
28 |
{ |
29 |
return APR_SUCCESS; |
30 |
} |
31 |
|
32 |
APR_DECLARE(apr_uint32_t) apr_atomic_read32(volatile apr_uint32_t *mem) |
33 |
{ |
34 |
return *mem; |
35 |
} |
36 |
|
37 |
APR_DECLARE(void) apr_atomic_set32(volatile apr_uint32_t *mem, apr_uint32_t val) |
38 |
{ |
39 |
*mem = val; |
40 |
} |
41 |
|
42 |
APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val) |
43 |
{ |
44 |
apr_uint32_t prev, temp; |
45 |
|
46 |
asm volatile ("loop_%=:\n" /* lost reservation */ |
47 |
" lwarx %0,0,%3\n" /* load and reserve */ |
48 |
" add %1,%0,%4\n" /* add val and prev */ |
49 |
PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ |
50 |
" stwcx. %1,0,%3\n" /* store new value */ |
51 |
" bne- loop_%=\n" /* loop if lost */ |
52 |
: "=&r" (prev), "=&r" (temp), "=m" (*mem) |
53 |
: "b" (mem), "r" (val) |
54 |
: "cc", "memory"); |
55 |
|
56 |
return prev; |
57 |
} |
58 |
|
59 |
APR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val) |
60 |
{ |
61 |
apr_uint32_t temp; |
62 |
|
63 |
asm volatile ("loop_%=:\n" /* lost reservation */ |
64 |
" lwarx %0,0,%2\n" /* load and reserve */ |
65 |
" subf %0,%3,%0\n" /* subtract val */ |
66 |
PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ |
67 |
" stwcx. %0,0,%2\n" /* store new value */ |
68 |
" bne- loop_%=\n" /* loop if lost */ |
69 |
: "=&r" (temp), "=m" (*mem) |
70 |
: "b" (mem), "r" (val) |
71 |
: "cc", "memory"); |
72 |
} |
73 |
|
74 |
APR_DECLARE(apr_uint32_t) apr_atomic_inc32(volatile apr_uint32_t *mem) |
75 |
{ |
76 |
apr_uint32_t prev; |
77 |
|
78 |
asm volatile ("loop_%=:\n" /* lost reservation */ |
79 |
" lwarx %0,0,%2\n" /* load and reserve */ |
80 |
" addi %0,%0,1\n" /* add immediate */ |
81 |
PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ |
82 |
" stwcx. %0,0,%2\n" /* store new value */ |
83 |
" bne- loop_%=\n" /* loop if lost */ |
84 |
" subi %0,%0,1\n" /* return old value */ |
85 |
: "=&b" (prev), "=m" (*mem) |
86 |
: "b" (mem), "m" (*mem) |
87 |
: "cc", "memory"); |
88 |
|
89 |
return prev; |
90 |
} |
91 |
|
92 |
APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem) |
93 |
{ |
94 |
apr_uint32_t prev; |
95 |
|
96 |
asm volatile ("loop_%=:\n" /* lost reservation */ |
97 |
" lwarx %0,0,%2\n" /* load and reserve */ |
98 |
" subi %0,%0,1\n" /* subtract immediate */ |
99 |
PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ |
100 |
" stwcx. %0,0,%2\n" /* store new value */ |
101 |
" bne- loop_%=\n" /* loop if lost */ |
102 |
: "=&b" (prev), "=m" (*mem) |
103 |
: "b" (mem), "m" (*mem) |
104 |
: "cc", "memory"); |
105 |
|
106 |
return prev; |
107 |
} |
108 |
|
109 |
APR_DECLARE(apr_uint32_t) apr_atomic_cas32(volatile apr_uint32_t *mem, apr_uint32_t with, |
110 |
apr_uint32_t cmp) |
111 |
{ |
112 |
apr_uint32_t prev; |
113 |
|
114 |
asm volatile ("loop_%=:\n" /* lost reservation */ |
115 |
" lwarx %0,0,%1\n" /* load and reserve */ |
116 |
" cmpw %0,%3\n" /* compare operands */ |
117 |
" bne- exit_%=\n" /* skip if not equal */ |
118 |
PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ |
119 |
" stwcx. %2,0,%1\n" /* store new value */ |
120 |
" bne- loop_%=\n" /* loop if lost */ |
121 |
"exit_%=:\n" /* not equal */ |
122 |
: "=&r" (prev) |
123 |
: "b" (mem), "r" (with), "r" (cmp) |
124 |
: "cc", "memory"); |
125 |
|
126 |
return prev; |
127 |
} |
128 |
|
129 |
APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint32_t val) |
130 |
{ |
131 |
apr_uint32_t prev; |
132 |
|
133 |
asm volatile ("loop_%=:\n" /* lost reservation */ |
134 |
" lwarx %0,0,%1\n" /* load and reserve */ |
135 |
PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ |
136 |
" stwcx. %2,0,%1\n" /* store new value */ |
137 |
" bne- loop_%=" /* loop if lost */ |
138 |
: "=&r" (prev) |
139 |
: "b" (mem), "r" (val) |
140 |
: "cc", "memory"); |
141 |
|
142 |
return prev; |
143 |
} |
144 |
|
145 |
APR_DECLARE(void*) apr_atomic_casptr(volatile void **mem, void *with, const void *cmp) |
146 |
{ |
147 |
void *prev; |
148 |
#if APR_SIZEOF_VOIDP == 4 |
149 |
asm volatile ("loop_%=:\n" /* lost reservation */ |
150 |
" lwarx %0,0,%1\n" /* load and reserve */ |
151 |
" cmpw %0,%3\n" /* compare operands */ |
152 |
" bne- exit_%=\n" /* skip if not equal */ |
153 |
PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ |
154 |
" stwcx. %2,0,%1\n" /* store new value */ |
155 |
" bne- loop_%=\n" /* loop if lost */ |
156 |
"exit_%=:\n" /* not equal */ |
157 |
: "=&r" (prev) |
158 |
: "b" (mem), "r" (with), "r" (cmp) |
159 |
: "cc", "memory"); |
160 |
#elif APR_SIZEOF_VOIDP == 8 |
161 |
asm volatile ("loop_%=:\n" /* lost reservation */ |
162 |
" ldarx %0,0,%1\n" /* load and reserve */ |
163 |
" cmpd %0,%3\n" /* compare operands */ |
164 |
" bne- exit_%=\n" /* skip if not equal */ |
165 |
PPC405_ERR77_SYNC /* ppc405 Erratum 77 */ |
166 |
" stdcx. %2,0,%1\n" /* store new value */ |
167 |
" bne- loop_%=\n" /* loop if lost */ |
168 |
"exit_%=:\n" /* not equal */ |
169 |
: "=&r" (prev) |
170 |
: "b" (mem), "r" (with), "r" (cmp) |
171 |
: "cc", "memory"); |
172 |
#else |
173 |
#error APR_SIZEOF_VOIDP value not supported |
174 |
#endif |
175 |
return prev; |
176 |
} |
177 |
|
178 |
#endif /* USE_ATOMICS_PPC */ |