|
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 | | -#if 0 |
303 | | -#define TAS(lock) (msem_lock((lock), MSEM_IF_NOWAIT) < 0) |
304 | | -#define S_UNLOCK(lock) msem_unlock((lock), 0) |
305 | | -#define S_INIT_LOCK(lock) msem_init((lock), MSEM_UNLOCKED) |
306 | | -#define S_LOCK_FREE(lock) (!(lock)->msem_state) |
307 | | -#else |
308 | | -#define TAS(lock) (__INTERLOCKED_TESTBITSS_QUAD((lock),0)) |
309 | | -#endif |
310 | | - |
311 | | -#else /* i.e. not __osf__ */ |
| 300 | +#if defined(__GNUC__) |
312 | 301 |
|
313 | | -#define TAS(lock) tas(lock) |
314 | | -#define S_UNLOCK(lock) do { __asm__("mb"); *(lock) = 0; } while (0) |
| 302 | +#define TAS(lock) tas(lock) |
| 303 | +#define S_UNLOCK(lock) do { __asm__ volatile ("mb"); *(lock) = 0; } while (0) |
315 | 304 |
|
316 | 305 | static __inline__ int |
317 | 306 | tas(volatile slock_t *lock) |
318 | 307 | { |
319 | | - register slock_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 | + register slock_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 | +#define S_INIT_LOCK(lock) (*(lock) = 0) |
| 340 | +#define TAS(lock) (__LOCK_LONG_RETRY((lock), 1) == 0) |
| 341 | +#define S_UNLOCK(lock) __UNLOCK_LONG(lock) |
| 342 | + |
| 343 | +#endif /* defined(__GNUC__) */ |
338 | 344 |
|
339 | 345 | #endif /* __alpha */ |
340 | 346 |
|
|
0 commit comments