6666 * Portions Copyright (c) 1996-2005, 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.140 2005/08/29 00:41:34 tgl Exp $
69+ * $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.141 2005/10/11 20:01:30 tgl Exp $
7070 *
7171 *-------------------------------------------------------------------------
7272 */
108108 */
109109
110110
111- #if defined( __i386__ ) || defined( __x86_64__ ) /* AMD Opteron */
111+ #ifdef __i386__
112112#define HAS_TEST_AND_SET
113113
114114typedef unsignedchar slock_t ;
@@ -120,7 +120,11 @@ tas(volatile slock_t *lock)
120120{
121121registerslock_t _res = 1 ;
122122
123- /* Use a non-locking test before asserting the bus lock */
123+ /*
124+ * Use a non-locking test before asserting the bus lock. Note that the
125+ * extra test appears to be a small loss on some x86 platforms and a small
126+ * win on others; it's by no means clear that we should keep it.
127+ */
124128__asm__ __volatile__(
125129"cmpb$0,%1\n"
126130"jne1f\n"
@@ -165,7 +169,49 @@ spin_delay(void)
165169" rep; nop\n" );
166170}
167171
168- #endif /* __i386__ || __x86_64__ */
172+ #endif /* __i386__ */
173+
174+
175+ #ifdef __x86_64__ /* AMD Opteron, Intel EM64T */
176+ #define HAS_TEST_AND_SET
177+
178+ typedef unsignedchar slock_t ;
179+
180+ #define TAS (lock ) tas(lock)
181+
182+ static __inline__int
183+ tas (volatile slock_t * lock )
184+ {
185+ registerslock_t _res = 1 ;
186+
187+ /*
188+ * On Opteron, using a non-locking test before the locking instruction
189+ * is a huge loss. On EM64T, it appears to be a wash or small loss,
190+ * so we needn't bother to try to distinguish the sub-architectures.
191+ */
192+ __asm__ __volatile__(
193+ "lock\n"
194+ "xchgb%0,%1\n"
195+ :"+q" (_res ),"+m" (* lock )
196+ :
197+ :"memory" ,"cc" );
198+ return (int )_res ;
199+ }
200+
201+ #define SPIN_DELAY () spin_delay()
202+
203+ static __inline__void
204+ spin_delay (void )
205+ {
206+ /*
207+ * Adding a PAUSE in the spin delay loop is demonstrably a no-op on
208+ * Opteron, but it may be of some use on EM64T, so we keep it.
209+ */
210+ __asm__ __volatile__(
211+ " rep; nop\n" );
212+ }
213+
214+ #endif /* __x86_64__ */
169215
170216
171217#if defined(__ia64__ )|| defined(__ia64 )