66
66
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
67
67
* Portions Copyright (c) 1994, Regents of the University of California
68
68
*
69
- * $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.125 2004/01/03 05:47:44 tgl Exp $
69
+ * $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.126 2004/06/19 23:02:32 tgl Exp $
70
70
*
71
71
*-------------------------------------------------------------------------
72
72
*/
85
85
* Other compilers use __cpu or __cpu__ so we test for both in those cases.
86
86
*/
87
87
88
- /*
89
- * Standard gcc asm formatis :
90
- *
88
+ /*----------
89
+ * Standard gcc asm format(assuming "volatile slock_t *lock") :
90
+
91
91
__asm__ __volatile__(
92
- "command\n"
93
- "command\n"
94
- "command\n"
95
- :"=r"(_res)return value, in register
96
- :"r"(lock)argument, 'lock pointer', in register
97
- :"r0");inline code uses this register
92
+ "instruction\n"
93
+ "instruction\n"
94
+ "instruction\n"
95
+ :"=r"(_res), "+m"(*lock)// return register, in/out lock value
96
+ :"r"(lock)// lock pointer, in input register
97
+ :"memory", "cc");// show clobbered registers here
98
+
99
+ * The output-operands list (after first colon) should always include
100
+ * "+m"(*lock), whether or not the asm code actually refers to this
101
+ * operand directly. This ensures that gcc believes the value in the
102
+ * lock variable is used and set by the asm code. Also, the clobbers
103
+ * list (after third colon) should always include "memory"; this prevents
104
+ * gcc from thinking it can cache the values of shared-memory fields
105
+ * across the asm code. Add "cc" if your asm code changes the condition
106
+ * code register, and also list any temp registers the code uses.
107
+ *----------
98
108
*/
99
109
100
110
@@ -117,8 +127,9 @@ tas(volatile slock_t *lock)
117
127
"lock\n"
118
128
"xchgb%0,%1\n"
119
129
"1: \n"
120
- :"=q" (_res ),"=m" (* lock )
121
- :"0" (_res ));
130
+ :"+q" (_res ),"+m" (* lock )
131
+ :
132
+ :"memory" ,"cc" );
122
133
return (int )_res ;
123
134
}
124
135
@@ -128,8 +139,7 @@ static __inline__ void
128
139
spin_delay (void )
129
140
{
130
141
__asm__ __volatile__(
131
- " rep; nop\n"
132
- : : :"memory" );
142
+ " rep; nop\n" );
133
143
}
134
144
135
145
#endif /* __i386__ || __x86_64__ */
@@ -150,10 +160,9 @@ tas(volatile slock_t *lock)
150
160
151
161
__asm__ __volatile__(
152
162
"xchg4 %0=%1,%2\n"
153
- :"=r" (ret ),"= m" (* lock )
154
- :"r" (1 ), "1" ( * lock )
163
+ :"=r" (ret ),"+ m" (* lock )
164
+ :"r" (1 )
155
165
:"memory" );
156
-
157
166
return (int )ret ;
158
167
}
159
168
@@ -173,46 +182,18 @@ tas(volatile slock_t *lock)
173
182
registerslock_t _res = 1 ;
174
183
175
184
__asm__ __volatile__(
176
- "swpb %0, %0, [%3]\n"
177
- :"=r" (_res ),"=m" (* lock )
178
- :"0" (_res ),"r" (lock ));
185
+ "swpb %0, %0, [%2]\n"
186
+ :"+r" (_res ),"+m" (* lock )
187
+ :"r" (lock )
188
+ :"memory" );
179
189
return (int )_res ;
180
190
}
181
191
182
192
#endif /* __arm__ */
183
193
184
194
185
- #if defined(__s390__ )&& !defined(__s390x__ )
186
- /* S/390 Linux */
187
- #define HAS_TEST_AND_SET
188
-
189
- typedef unsignedint slock_t ;
190
-
191
- #define TAS (lock ) tas(lock)
192
-
193
- static __inline__int
194
- tas (volatile slock_t * lock )
195
- {
196
- int _res ;
197
-
198
- __asm____volatile__(
199
- "la1,1\n"
200
- "l 2,%2\n"
201
- "slr 0,0\n"
202
- "cs 0,1,0(2)\n"
203
- "lr %1,0\n"
204
- :"=m" (lock ),"=d" (_res )
205
- :"m" (lock )
206
- :"0" ,"1" ,"2" );
207
-
208
- return (_res );
209
- }
210
-
211
- #endif /* __s390__ */
212
-
213
-
214
- #if defined(__s390x__ )
215
- /* S/390x Linux (64-bit zSeries) */
195
+ #if defined(__s390__ )|| defined(__s390x__ )
196
+ /* S/390 and S/390x Linux (32- and 64-bit zSeries) */
216
197
#define HAS_TEST_AND_SET
217
198
218
199
typedef unsignedint slock_t ;
@@ -222,22 +203,17 @@ typedef unsigned int slock_t;
222
203
static __inline__int
223
204
tas (volatile slock_t * lock )
224
205
{
225
- int _res ;
206
+ int _res = 0 ;
226
207
227
208
__asm____volatile__(
228
- "la1,1\n"
229
- "lg 2,%2\n"
230
- "slr 0,0\n"
231
- "cs 0,1,0(2)\n"
232
- "lr %1,0\n"
233
- :"=m" (lock ),"=d" (_res )
234
- :"m" (lock )
235
- :"0" ,"1" ,"2" );
236
-
237
- return (_res );
209
+ "cs %0,%3,0(%2)\n"
210
+ :"+d" (_res ),"+m" (* lock )
211
+ :"a" (lock ),"d" (1 )
212
+ :"memory" ,"cc" );
213
+ return _res ;
238
214
}
239
215
240
- #endif /* __s390x__ */
216
+ #endif /*__s390__ || __s390x__ */
241
217
242
218
243
219
#if defined(__sparc__ )
@@ -250,12 +226,13 @@ typedef unsigned char slock_t;
250
226
static __inline__int
251
227
tas (volatile slock_t * lock )
252
228
{
253
- registerslock_t _res = 1 ;
229
+ registerslock_t _res ;
254
230
255
231
__asm__ __volatile__(
256
232
"ldstub[%2], %0\n"
257
- :"=r" (_res ),"=m" (* lock )
258
- :"r" (lock ));
233
+ :"=r" (_res ),"+m" (* lock )
234
+ :"r" (lock )
235
+ :"memory" );
259
236
return (int )_res ;
260
237
}
261
238
@@ -283,11 +260,11 @@ tas(volatile slock_t *lock)
283
260
int _res ;
284
261
285
262
__asm__ __volatile__(
286
- "lwarx %0,0,%2 \n"
263
+ "lwarx %0,0,%3 \n"
287
264
"cmpwi %0,0\n"
288
265
"bne 1f\n"
289
266
"addi %0,%0,1\n"
290
- "stwcx. %0,0,%2 \n"
267
+ "stwcx. %0,0,%3 \n"
291
268
"beq 2f \n"
292
269
"1:li %1,1\n"
293
270
"b3f\n"
@@ -296,10 +273,9 @@ tas(volatile slock_t *lock)
296
273
"li %1,0\n"
297
274
"3:\n"
298
275
299
- :"=&r" (_t ),"=r" (_res )
300
- :"r" (lock )
301
- :"cc" ,"memory"
302
- );
276
+ :"=&r" (_t ),"=r" (_res ),"+m" (* lock )
277
+ :"r" (lock )
278
+ :"memory" ,"cc" );
303
279
return _res ;
304
280
}
305
281
@@ -330,10 +306,9 @@ tas(volatile slock_t *lock)
330
306
"clrl%0\n"
331
307
"tas%1\n"
332
308
"sne%0\n"
333
- :"=d" (rv ),"=m" (* lock )
334
- :"1" (* lock )
335
- :"cc" );
336
-
309
+ :"=d" (rv ),"+m" (* lock )
310
+ :
311
+ :"memory" ,"cc" );
337
312
return rv ;
338
313
}
339
314
@@ -357,13 +332,13 @@ tas(volatile slock_t *lock)
357
332
registerint _res ;
358
333
359
334
__asm__ __volatile__(
360
- "movl $1,r0 \n"
361
- "bbssi$0, (%1 ), 1f\n"
362
- "clrlr0 \n"
363
- "1:movlr0, %0 \n"
364
- :"=r" (_res )
335
+ "movl $1,%0 \n"
336
+ "bbssi$0, (%2 ), 1f\n"
337
+ "clrl%0 \n"
338
+ "1: \n"
339
+ :"=& r" (_res ), "+m" ( * lock )
365
340
:"r" (lock )
366
- :"r0 " );
341
+ :"memory " );
367
342
return _res ;
368
343
}
369
344
@@ -383,9 +358,11 @@ tas(volatile slock_t *lock)
383
358
registerint _res ;
384
359
385
360
__asm__ __volatile__(
386
- "sbitb0, %0\n"
387
- "sfsd%1\n"
388
- :"=m" (* lock ),"=r" (_res ));
361
+ "sbitb0, %1\n"
362
+ "sfsd%0\n"
363
+ :"=r" (_res ),"+m" (* lock )
364
+ :
365
+ :"memory" );
389
366
return _res ;
390
367
}
391
368
@@ -404,37 +381,37 @@ tas(volatile slock_t *lock)
404
381
typedef unsigned long slock_t ;
405
382
406
383
#define TAS (lock ) tas(lock)
407
- #define S_UNLOCK (lock )\
408
- do \
409
- {\
410
- __asm__ __volatile__ ("mb \n"); \
411
- *((volatile slock_t *) (lock)) = 0; \
412
- } while (0)
413
384
414
385
static __inline__int
415
386
tas (volatile slock_t * lock )
416
387
{
417
388
registerslock_t _res ;
418
389
419
390
__asm____volatile__(
420
- "ldq$0, %0 \n"
391
+ "ldq$0, %1 \n"
421
392
"bne$0, 2f\n"
422
- "ldq_l%1 , %0 \n"
423
- "bne%1 , 2f\n"
393
+ "ldq_l%0 , %1 \n"
394
+ "bne%0 , 2f\n"
424
395
"mov1, $0\n"
425
- "stq_c$0, %0 \n"
396
+ "stq_c$0, %1 \n"
426
397
"beq$0, 2f\n"
427
398
"mb\n"
428
399
"br3f\n"
429
- "2:mov1, %1 \n"
400
+ "2:mov1, %0 \n"
430
401
"3:\n"
431
- :"=m" ( * lock ),"=r" ( _res )
402
+ :"=&r" ( _res ),"+m" ( * lock )
432
403
:
433
- :"0" );
434
-
404
+ :"memory" ,"0" );
435
405
return (int )_res ;
436
406
}
437
407
408
+ #define S_UNLOCK (lock )\
409
+ do \
410
+ {\
411
+ __asm__ __volatile__ ("mb \n"); \
412
+ *((volatile slock_t *) (lock)) = 0; \
413
+ } while (0)
414
+
438
415
#endif /* __alpha || __alpha__ */
439
416
440
417
@@ -540,8 +517,9 @@ tas(volatile slock_t *lock)
540
517
541
518
__asm__ __volatile__(
542
519
"ldcwx0(0,%2),%0\n"
543
- :"=r" (lockval ),"=m" (* lockword )
544
- :"r" (lockword ));
520
+ :"=r" (lockval ),"+m" (* lockword )
521
+ :"r" (lockword )
522
+ :"memory" );
545
523
return (lockval == 0 );
546
524
}
547
525