Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1098677

Browse files
committed
Adjust TAS assembly as per recent discussions: use "+m"(*lock) everywhere
to reference the spinlock variable, and specify "memory" as a clobberoperand to be sure gcc does not try to keep shared-memory values inregisters across a spinlock acquisition. Also tighten the S/390 asmsequence, which was apparently written with only minimal study of thegcc asm documentation. I have personally tested i386, ia64, ppc, hppa,and s390 variants --- there is some small chance that I broke the others,but I doubt it.
1 parentc1d9dec commit1098677

File tree

1 file changed

+79
-101
lines changed

1 file changed

+79
-101
lines changed

‎src/include/storage/s_lock.h

Lines changed: 79 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
6767
* Portions Copyright (c) 1994, Regents of the University of California
6868
*
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 $
7070
*
7171
*-------------------------------------------------------------------------
7272
*/
@@ -85,16 +85,26 @@
8585
* Other compilers use __cpu or __cpu__ so we test for both in those cases.
8686
*/
8787

88-
/*
89-
* Standard gcc asm formatis:
90-
*
88+
/*----------
89+
* Standard gcc asm format(assuming "volatile slock_t *lock"):
90+
9191
__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+
*----------
98108
*/
99109

100110

@@ -117,8 +127,9 @@ tas(volatile slock_t *lock)
117127
"lock\n"
118128
"xchgb%0,%1\n"
119129
"1: \n"
120-
:"=q"(_res),"=m"(*lock)
121-
:"0"(_res));
130+
:"+q"(_res),"+m"(*lock)
131+
:
132+
:"memory","cc");
122133
return (int)_res;
123134
}
124135

@@ -128,8 +139,7 @@ static __inline__ void
128139
spin_delay(void)
129140
{
130141
__asm__ __volatile__(
131-
" rep; nop\n"
132-
: : :"memory");
142+
" rep; nop\n");
133143
}
134144

135145
#endif/* __i386__ || __x86_64__ */
@@ -150,10 +160,9 @@ tas(volatile slock_t *lock)
150160

151161
__asm__ __volatile__(
152162
"xchg4 %0=%1,%2\n"
153-
:"=r"(ret),"=m"(*lock)
154-
:"r"(1),"1"(*lock)
163+
:"=r"(ret),"+m"(*lock)
164+
:"r"(1)
155165
:"memory");
156-
157166
return (int)ret;
158167
}
159168

@@ -173,46 +182,18 @@ tas(volatile slock_t *lock)
173182
registerslock_t_res=1;
174183

175184
__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");
179189
return (int)_res;
180190
}
181191

182192
#endif/* __arm__ */
183193

184194

185-
#if defined(__s390__)&& !defined(__s390x__)
186-
/* S/390 Linux */
187-
#defineHAS_TEST_AND_SET
188-
189-
typedefunsignedintslock_t;
190-
191-
#defineTAS(lock) tas(lock)
192-
193-
static __inline__int
194-
tas(volatileslock_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) */
216197
#defineHAS_TEST_AND_SET
217198

218199
typedefunsignedintslock_t;
@@ -222,22 +203,17 @@ typedef unsigned int slock_t;
222203
static __inline__int
223204
tas(volatileslock_t*lock)
224205
{
225-
int_res;
206+
int_res=0;
226207

227208
__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;
238214
}
239215

240-
#endif/* __s390x__ */
216+
#endif/*__s390__ ||__s390x__ */
241217

242218

243219
#if defined(__sparc__)
@@ -250,12 +226,13 @@ typedef unsigned char slock_t;
250226
static __inline__int
251227
tas(volatileslock_t*lock)
252228
{
253-
registerslock_t_res=1;
229+
registerslock_t_res;
254230

255231
__asm__ __volatile__(
256232
"ldstub[%2], %0\n"
257-
:"=r"(_res),"=m"(*lock)
258-
:"r"(lock));
233+
:"=r"(_res),"+m"(*lock)
234+
:"r"(lock)
235+
:"memory");
259236
return (int)_res;
260237
}
261238

@@ -283,11 +260,11 @@ tas(volatile slock_t *lock)
283260
int_res;
284261

285262
__asm__ __volatile__(
286-
"lwarx %0,0,%2\n"
263+
"lwarx %0,0,%3\n"
287264
"cmpwi %0,0\n"
288265
"bne 1f\n"
289266
"addi %0,%0,1\n"
290-
"stwcx. %0,0,%2\n"
267+
"stwcx. %0,0,%3\n"
291268
"beq 2f \n"
292269
"1:li %1,1\n"
293270
"b3f\n"
@@ -296,10 +273,9 @@ tas(volatile slock_t *lock)
296273
"li %1,0\n"
297274
"3:\n"
298275

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");
303279
return_res;
304280
}
305281

@@ -330,10 +306,9 @@ tas(volatile slock_t *lock)
330306
"clrl%0\n"
331307
"tas%1\n"
332308
"sne%0\n"
333-
:"=d"(rv),"=m"(*lock)
334-
:"1"(*lock)
335-
:"cc");
336-
309+
:"=d"(rv),"+m"(*lock)
310+
:
311+
:"memory","cc");
337312
returnrv;
338313
}
339314

@@ -357,13 +332,13 @@ tas(volatile slock_t *lock)
357332
registerint_res;
358333

359334
__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)
365340
:"r"(lock)
366-
:"r0");
341+
:"memory");
367342
return_res;
368343
}
369344

@@ -383,9 +358,11 @@ tas(volatile slock_t *lock)
383358
registerint_res;
384359

385360
__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");
389366
return_res;
390367
}
391368

@@ -404,37 +381,37 @@ tas(volatile slock_t *lock)
404381
typedefunsigned longslock_t;
405382

406383
#defineTAS(lock) tas(lock)
407-
#defineS_UNLOCK(lock)\
408-
do \
409-
{\
410-
__asm__ __volatile__ ("mb \n"); \
411-
*((volatile slock_t *) (lock)) = 0; \
412-
} while (0)
413384

414385
static __inline__int
415386
tas(volatileslock_t*lock)
416387
{
417388
registerslock_t_res;
418389

419390
__asm____volatile__(
420-
"ldq$0, %0\n"
391+
"ldq$0, %1\n"
421392
"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"
424395
"mov1, $0\n"
425-
"stq_c$0, %0\n"
396+
"stq_c$0, %1\n"
426397
"beq$0, 2f\n"
427398
"mb\n"
428399
"br3f\n"
429-
"2:mov1, %1\n"
400+
"2:mov1, %0\n"
430401
"3:\n"
431-
:"=m"(*lock),"=r"(_res)
402+
:"=&r"(_res),"+m"(*lock)
432403
:
433-
:"0");
434-
404+
:"memory","0");
435405
return (int)_res;
436406
}
437407

408+
#defineS_UNLOCK(lock)\
409+
do \
410+
{\
411+
__asm__ __volatile__ ("mb \n"); \
412+
*((volatile slock_t *) (lock)) = 0; \
413+
} while (0)
414+
438415
#endif/* __alpha || __alpha__ */
439416

440417

@@ -540,8 +517,9 @@ tas(volatile slock_t *lock)
540517

541518
__asm__ __volatile__(
542519
"ldcwx0(0,%2),%0\n"
543-
:"=r"(lockval),"=m"(*lockword)
544-
:"r"(lockword));
520+
:"=r"(lockval),"+m"(*lockword)
521+
:"r"(lockword)
522+
:"memory");
545523
return (lockval==0);
546524
}
547525

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp