|
9 | 9 | *
|
10 | 10 | *
|
11 | 11 | * IDENTIFICATION
|
12 |
| - * $Header: /cvsroot/pgsql/src/include/storage/s_lock.h,v 1.76 2000/12/29 21:31:20 tgl Exp $ |
| 12 | + * $Header: /cvsroot/pgsql/src/include/storage/s_lock.h,v 1.77 2000/12/30 02:34:56 tgl Exp $ |
13 | 13 | *
|
14 | 14 | *-------------------------------------------------------------------------
|
15 | 15 | */
|
@@ -291,50 +291,56 @@ tas(volatile slock_t *s_lock)
|
291 | 291 |
|
292 | 292 | #if defined(__alpha)
|
293 | 293 |
|
294 |
| -#if defined(__osf__) |
295 | 294 | /*
|
296 |
| - *OSF/1 (Alpha AXP) |
297 |
| - * |
298 |
| - *Note that slock_t on the Alpha AXP is msemaphore instead of char |
299 |
| - *(see storage/ipc.h). |
| 295 | + *Correct multi-processor locking methods are explained in section 5.5.3 |
| 296 | + * of the Alpha AXP Architecture Handbook, which at this writing can be |
| 297 | + *found at ftp://ftp.netbsd.org/pub/NetBSD/misc/dec-docs/index.html. |
| 298 | + *For gcc we implement the handbook's code directly with inline assembler. |
300 | 299 | */
|
301 |
| -#include<alpha/builtins.h> |
302 |
| -#if0 |
303 |
| -#defineTAS(lock) (msem_lock((lock), MSEM_IF_NOWAIT) < 0) |
304 |
| -#defineS_UNLOCK(lock) msem_unlock((lock), 0) |
305 |
| -#defineS_INIT_LOCK(lock)msem_init((lock), MSEM_UNLOCKED) |
306 |
| -#defineS_LOCK_FREE(lock) (!(lock)->msem_state) |
307 |
| -#else |
308 |
| -#defineTAS(lock) (__INTERLOCKED_TESTBITSS_QUAD((lock),0)) |
309 |
| -#endif |
310 |
| - |
311 |
| -#else/* i.e. not __osf__ */ |
| 300 | +#if defined(__GNUC__) |
312 | 301 |
|
313 |
| -#defineTAS(lock) tas(lock) |
314 |
| -#defineS_UNLOCK(lock) do { __asm__("mb"); *(lock) = 0; } while (0) |
| 302 | +#defineTAS(lock)tas(lock) |
| 303 | +#defineS_UNLOCK(lock)do { __asm__ volatile("mb"); *(lock) = 0; } while (0) |
315 | 304 |
|
316 | 305 | static __inline__int
|
317 | 306 | tas(volatileslock_t*lock)
|
318 | 307 | {
|
319 |
| - registerslock_t_res; |
320 |
| - |
321 |
| -__asm__(" ldq $0, %0 \n\ |
322 |
| - bne $0, 3f \n\ |
323 |
| - ldq_l $0, %0 \n\ |
324 |
| - bne $0, 3f \n\ |
325 |
| - or $31, 1, $0 \n\ |
326 |
| - stq_c $0, %0 \n\ |
327 |
| - beq $0, 2f \n\ |
328 |
| - bis $31, $31, %1 \n\ |
329 |
| - mb \n\ |
330 |
| - jmp $31, 4f \n\ |
331 |
| - 2: or $31, 1, $0 \n\ |
332 |
| - 3: bis $0, $0, %1 \n\ |
333 |
| - 4: nop ":"=m"(*lock),"=r"(_res): :"0"); |
| 308 | +registerslock_t_res; |
| 309 | + |
| 310 | +__asm__volatile |
| 311 | +("ldq $0, %0\n\ |
| 312 | +bne $0, 2f\n\ |
| 313 | +ldq_l %1, %0\n\ |
| 314 | +bne %1, 2f\n\ |
| 315 | +mov 1, $0\n\ |
| 316 | +stq_c $0, %0\n\ |
| 317 | +beq $0, 2f\n\ |
| 318 | +mb\n\ |
| 319 | +br 3f\n\ |
| 320 | + 2: mov 1, %1\n\ |
| 321 | + 3: \n" :"=m"(*lock),"=r"(_res) : :"0"); |
334 | 322 |
|
335 | 323 | return (int)_res;
|
336 | 324 | }
|
337 |
| -#endif/* __osf__ */ |
| 325 | + |
| 326 | +#else/* !defined(__GNUC__) */ |
| 327 | + |
| 328 | +/* |
| 329 | + * The Tru64 compiler doesn't support gcc-style inline asm, but it does |
| 330 | + * have some builtin functions that accomplish much the same results. |
| 331 | + * For simplicity, slock_t is defined as long (ie, quadword) on Alpha |
| 332 | + * regardless of the compiler in use. LOCK_LONG and UNLOCK_LONG only |
| 333 | + * operate on an int (ie, longword), but that's OK as long as we define |
| 334 | + * S_INIT_LOCK to zero out the whole quadword. |
| 335 | + */ |
| 336 | + |
| 337 | +#include<alpha/builtins.h> |
| 338 | + |
| 339 | +#defineS_INIT_LOCK(lock) (*(lock) = 0) |
| 340 | +#defineTAS(lock) (__LOCK_LONG_RETRY((lock), 1) == 0) |
| 341 | +#defineS_UNLOCK(lock) __UNLOCK_LONG(lock) |
| 342 | + |
| 343 | +#endif/* defined(__GNUC__) */ |
338 | 344 |
|
339 | 345 | #endif/* __alpha */
|
340 | 346 |
|
|