|
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 |
|
|