In looking at the VAX ASM problem, I realized that the ASM in s_lock.h
is all formatted differently, making it even more confusing. I have
applied the following patch to s_lock.h to try and clean it up.
The new standard format is:
/*
* Standard __asm__ format:
*
* __asm__(
* "command;"
* "command;"
* "command;"
* : "=r"(_res) return value, in register
* : "r"(lock) argument, 'lock pointer', in register
* : "r0"); inline code uses this register
*/
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
? config.log
? config.cache
? config.status
? GNUmakefile
? src/Makefile.custom
? src/GNUmakefile
? src/Makefile.global
? src/log
? src/crtags
? src/backend/postgres
? src/backend/catalog/global.bki
? src/backend/catalog/global.description
? src/backend/catalog/template1.bki
? src/backend/catalog/template1.description
? src/backend/port/Makefile
? src/bin/initdb/initdb
? src/bin/initlocation/initlocation
? src/bin/ipcclean/ipcclean
? src/bin/pg_config/pg_config
? src/bin/pg_ctl/pg_ctl
? src/bin/pg_dump/pg_dump
? src/bin/pg_dump/pg_restore
? src/bin/pg_dump/pg_dumpall
? src/bin/pg_id/pg_id
? src/bin/pg_passwd/pg_passwd
? src/bin/pgaccess/pgaccess
? src/bin/pgtclsh/Makefile.tkdefs
? src/bin/pgtclsh/Makefile.tcldefs
? src/bin/pgtclsh/pgtclsh
? src/bin/pgtclsh/pgtksh
? src/bin/psql/psql
? src/bin/scripts/createlang
? src/include/config.h
? src/include/stamp-h
? src/interfaces/ecpg/lib/libecpg.so.3.2.0
? src/interfaces/ecpg/preproc/ecpg
? src/interfaces/libpgeasy/libpgeasy.so.2.1
? src/interfaces/libpgtcl/libpgtcl.so.2.1
? src/interfaces/libpq/libpq.so.2.1
? src/interfaces/perl5/blib
? src/interfaces/perl5/Makefile
? src/interfaces/perl5/pm_to_blib
? src/interfaces/perl5/Pg.c
? src/interfaces/perl5/Pg.bs
? src/pl/plperl/blib
? src/pl/plperl/Makefile
? src/pl/plperl/pm_to_blib
? src/pl/plperl/SPI.c
? src/pl/plperl/plperl.bs
? src/pl/plpgsql/src/libplpgsql.so.1.0
? src/pl/tcl/Makefile.tcldefs
Index: src/include/storage/s_lock.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/storage/s_lock.h,v
retrieving revision 1.78
diff -c -r1.78 s_lock.h
*** src/include/storage/s_lock.h 2001/01/18 23:40:26 1.78
--- src/include/storage/s_lock.h 2001/01/19 02:52:49
***************
*** 35,41 ****
*
* int TAS(slock_t *lock)
* Atomic test-and-set instruction. Attempt to acquire the lock,
! * but do *not* wait. Returns 0 if successful, nonzero if unable
* to acquire the lock.
*
* TAS() is a lower-level part of the API, but is used directly in a
--- 35,41 ----
*
* int TAS(slock_t *lock)
* Atomic test-and-set instruction. Attempt to acquire the lock,
! * but do *not* wait. Returns 0 if successful, nonzero if unable
* to acquire the lock.
*
* TAS() is a lower-level part of the API, but is used directly in a
***************
*** 48,56 ****
* unsigned spins = 0;
*
* while (TAS(lock))
- * {
* S_LOCK_SLEEP(lock, spins++);
- * }
* }
*
* where S_LOCK_SLEEP() checks for timeout and sleeps for a short
--- 48,54 ----
***************
*** 87,96 ****
/* Platform-independent out-of-line support routines */
extern void s_lock(volatile slock_t *lock,
! const char *file, const int line);
extern void s_lock_sleep(unsigned spins, int microsec,
! volatile slock_t *lock,
! const char *file, const int line);
#if defined(HAS_TEST_AND_SET)
--- 85,94 ----
/* Platform-independent out-of-line support routines */
extern void s_lock(volatile slock_t *lock,
! const char *file, const int line);
extern void s_lock_sleep(unsigned spins, int microsec,
! volatile slock_t *lock,
! const char *file, const int line);
#if defined(HAS_TEST_AND_SET)
***************
*** 101,106 ****
--- 99,116 ----
* All the gcc inlines
*/
+ /*
+ * Standard __asm__ format:
+ *
+ * __asm__(
+ * "command;"
+ * "command;"
+ * "command;"
+ * : "=r"(_res) return value, in register
+ * : "r"(lock) argument, 'lock pointer', in register
+ * : "r0"); inline code uses this register
+ */
+
#if defined(__i386__)
#define TAS(lock) tas(lock)
***************
*** 110,116 ****
{
register slock_t _res = 1;
! __asm__("lock; xchgb %0,%1": "=q"(_res), "=m"(*lock):"0"(_res));
return (int) _res;
}
--- 120,130 ----
{
register slock_t _res = 1;
! __asm__(
! "lock;"
! "xchgb %0,%1;"
! : "=q"(_res), "=m"(*lock)
! : "0"(_res));
return (int) _res;
}
***************
*** 121,139 ****
#define TAS(lock) tas(lock)
static __inline__ int
! tas (volatile slock_t *lock)
{
! long int ret;
! __asm__ __volatile__(
! "xchg4 %0=%1,%2"
! : "=r"(ret), "=m"(*lock)
! : "r"(1), "1"(*lock)
! : "memory");
! return (int) ret;
}
! #endif /* __ia64__ */
#if defined(__arm__) || defined(__arm__)
--- 135,154 ----
#define TAS(lock) tas(lock)
static __inline__ int
! tas(volatile slock_t *lock)
{
! long int ret;
! __asm__ __volatile__(
! "xchg4 %0=%1,%2;"
! : "=r"(ret), "=m"(*lock)
! : "r"(1), "1"(*lock)
! : "memory");
! return (int) ret;
}
!
! #endif /* __ia64__ */
#if defined(__arm__) || defined(__arm__)
***************
*** 142,180 ****
static __inline__ int
tas(volatile slock_t *lock)
{
! register slock_t _res = 1;
! __asm__("swpb %0, %0, [%3]": "=r"(_res), "=m"(*lock):"0"(_res), "r" (lock));
! return (int) _res;
}
! #endif /* __arm__ */
#if defined(__s390__)
/*
* S/390 Linux
*/
! #define TAS(lock) tas(lock)
static inline int
tas(volatile slock_t *lock)
{
! int _res;
! __asm__ __volatile(" la 1,1\n"
! " l 2,%2\n"
! " slr 0,0\n"
! " cs 0,1,0(2)\n"
! " lr %1,0"
! : "=m" (lock), "=d" (_res)
! : "m" (lock)
! : "0", "1", "2");
! return (_res);
}
- #endif /* __s390__ */
#if defined(__sparc__)
#define TAS(lock) tas(lock)
--- 157,200 ----
static __inline__ int
tas(volatile slock_t *lock)
{
! register slock_t _res = 1;
! __asm__(
! "swpb %0, %0, [%3];"
! : "=r"(_res), "=m"(*lock)
! : "0"(_res), "r"(lock));
! return (int) _res;
}
! #endif /* __arm__ */
#if defined(__s390__)
/*
* S/390 Linux
*/
! #define TAS(lock) tas(lock)
static inline int
tas(volatile slock_t *lock)
{
! int _res;
! __asm__ __volatile(
! "la 1,1;"
! "l 2,%2;"
! "slr 0,0;"
! "cs 0,1,0(2);"
! "lr %1,0;"
! : "=m"(lock), "=d"(_res)
! : "m"(lock)
! : "0", "1", "2");
! return (_res);
}
+ #endif /* __s390__ */
+
#if defined(__sparc__)
#define TAS(lock) tas(lock)
***************
*** 183,190 ****
{
register slock_t _res = 1;
! __asm__("ldstub [%2], %0" \
! : "=r"(_res), "=m"(*lock) \
: "r"(lock));
return (int) _res;
}
--- 203,211 ----
{
register slock_t _res = 1;
! __asm__(
! "ldstub [%2], %0;"
! : "=r"(_res), "=m"(*lock)
: "r"(lock));
return (int) _res;
}
***************
*** 199,214 ****
tas(volatile slock_t *lock)
{
register int rv;
!
! __asm__ __volatile__ (
! "tas %1; sne %0"
! : "=d" (rv), "=m"(*lock)
! : "1" (*lock)
! : "cc" );
return rv;
}
! #endif /* defined(__mc68000__) && defined(__linux__) */
#if defined(NEED_VAX_TAS_ASM)
--- 220,237 ----
tas(volatile slock_t *lock)
{
register int rv;
!
! __asm__ __volatile__(
! "tas %1;"
! "sne %0;"
! : "=d"(rv), "=m"(*lock)
! : "1"(*lock)
! : "cc");
!
return rv;
}
! #endif /* defined(__mc68000__) && defined(__linux__) */
#if defined(NEED_VAX_TAS_ASM)
***************
*** 225,237 ****
{
register _res;
! __asm__(" movl $1, r0 \
! bbssi $0, (%1), 1f \
! clrl r0 \
! 1: movl r0, %0 "
! : "=r"(_res) /* return value, in register */
! : "r"(lock) /* argument, 'lock pointer', in register */
! : "r0"); /* inline code uses this register */
return (int) _res;
}
--- 248,261 ----
{
register _res;
! __asm__(
! "movl $1, r0;"
! "bbssi $0, (%1), 1f;"
! "clrl r0;"
! "1: movl r0, %0;"
! : "=r"(_res)
! : "r"(lock)
! : "r0");
return (int) _res;
}
***************
*** 244,257 ****
static __inline__ int
tas(volatile slock_t *lock)
{
! register _res;
! __asm__("sbitb 0, %0 \n\
! sfsd %1"
! : "=m"(*lock), "=r"(_res));
! return (int) _res;
}
! #endif /* NEED_NS32K_TAS_ASM */
--- 268,283 ----
static __inline__ int
tas(volatile slock_t *lock)
{
! register _res;
!
! __asm__(
! "sbitb 0, %0;"
! "sfsd %1;"
! : "=m"(*lock), "=r"(_res));
! return (int) _res;
}
! #endif /* NEED_NS32K_TAS_ASM */
***************
*** 268,274 ****
tas(volatile slock_t *s_lock)
{
/* UNIVEL wants %mem in column 1, so we don't pg_indent this file */
! %mem s_lock
pushl %ebx
movl s_lock, %ebx
movl $255, %eax
--- 294,300 ----
tas(volatile slock_t *s_lock)
{
/* UNIVEL wants %mem in column 1, so we don't pg_indent this file */
! %mem s_lock
pushl %ebx
movl s_lock, %ebx
movl $255, %eax
***************
*** 277,283 ****
popl %ebx
}
! #endif /* defined(NEED_I386_TAS_ASM) && defined(USE_UNIVEL_CC) */
#endif /* defined(__GNUC__) */
--- 303,309 ----
popl %ebx
}
! #endif /* defined(NEED_I386_TAS_ASM) && defined(USE_UNIVEL_CC) */
#endif /* defined(__GNUC__) */
***************
*** 300,329 ****
#if defined(__GNUC__)
#define TAS(lock) tas(lock)
! #define S_UNLOCK(lock) do { __asm__ volatile ("mb"); *(lock) = 0; } while (0)
static __inline__ int
tas(volatile slock_t *lock)
{
register slock_t _res;
! __asm__ volatile
! (" ldq $0, %0 \n\
! bne $0, 2f \n\
! ldq_l %1, %0 \n\
! bne %1, 2f \n\
! mov 1, $0 \n\
! stq_c $0, %0 \n\
! beq $0, 2f \n\
! mb \n\
! br 3f \n\
! 2: mov 1, %1 \n\
! 3: \n" : "=m"(*lock), "=r"(_res) : : "0");
return (int) _res;
}
! #else /* !defined(__GNUC__) */
/*
* The Tru64 compiler doesn't support gcc-style inline asm, but it does
--- 326,358 ----
#if defined(__GNUC__)
#define TAS(lock) tas(lock)
! #define S_UNLOCK(lock) do { __asm__ volatile ("mb"); *(lock) = 0; } while (0)
static __inline__ int
tas(volatile slock_t *lock)
{
register slock_t _res;
! __asm__ volatile(
! "ldq $0, %0;"
! "bne $0, 2f;"
! "ldq_l %1, %0;"
! "bne %1, 2f;"
! "mov 1, $0;"
! "stq_c $0, %0;"
! "beq $0, 2f;"
! "mb;"
! "br 3f;"
! "2: mov 1, %1;"
! "3:"
! : "=m"(*lock), "=r"(_res)
! :
! : "0");
return (int) _res;
}
! #else /* !defined(__GNUC__) */
/*
* The Tru64 compiler doesn't support gcc-style inline asm, but it does
***************
*** 337,348 ****
#include <alpha/builtins.h>
#define S_INIT_LOCK(lock) (*(lock) = 0)
! #define TAS(lock) (__LOCK_LONG_RETRY((lock), 1) == 0)
! #define S_UNLOCK(lock) __UNLOCK_LONG(lock)
! #endif /* defined(__GNUC__) */
! #endif /* __alpha */
#if defined(__hpux)
--- 366,377 ----
#include <alpha/builtins.h>
#define S_INIT_LOCK(lock) (*(lock) = 0)
! #define TAS(lock) (__LOCK_LONG_RETRY((lock), 1) == 0)
! #define S_UNLOCK(lock) __UNLOCK_LONG(lock)
! #endif /* defined(__GNUC__) */
! #endif /* __alpha */
#if defined(__hpux)
***************
*** 373,390 ****
*
* Note that slock_t under QNX is sem_t instead of char
*/
! #define TAS(lock) (sem_trywait((lock)) < 0)
! #define S_UNLOCK(lock) sem_post((lock))
! #define S_INIT_LOCK(lock) sem_init((lock), 1, 1)
! #define S_LOCK_FREE(lock) ((lock)->value)
! #endif /* __QNX__ */
#if defined(__sgi)
/*
* SGI IRIX 5
* slock_t is defined as a unsigned long. We use the standard SGI
! * mutex API.
*
* The following comment is left for historical reasons, but is probably
* not a good idea since the mutex ABI is supported.
--- 402,419 ----
*
* Note that slock_t under QNX is sem_t instead of char
*/
! #define TAS(lock) (sem_trywait((lock)) < 0)
! #define S_UNLOCK(lock) sem_post((lock))
! #define S_INIT_LOCK(lock) sem_init((lock), 1, 1)
! #define S_LOCK_FREE(lock) ((lock)->value)
! #endif /* __QNX__ */
#if defined(__sgi)
/*
* SGI IRIX 5
* slock_t is defined as a unsigned long. We use the standard SGI
! * mutex API.
*
* The following comment is left for historical reasons, but is probably
* not a good idea since the mutex ABI is supported.
***************
*** 402,408 ****
#if defined(sinix)
/*
! * SINIX / Reliant UNIX
* slock_t is defined as a struct abilock_t, which has a single unsigned long
* member. (Basically same as SGI)
*
--- 431,437 ----
#if defined(sinix)
/*
! * SINIX / Reliant UNIX
* slock_t is defined as a struct abilock_t, which has a single unsigned long
* member. (Basically same as SGI)
*
***************
*** 412,418 ****
#define S_INIT_LOCK(lock) init_lock(lock)
#define S_LOCK_FREE(lock) (stat_lock(lock) == UNLOCKED)
#endif /* sinix */
!
#if defined(_AIX)
/*
--- 441,447 ----
#define S_INIT_LOCK(lock) init_lock(lock)
#define S_LOCK_FREE(lock) (stat_lock(lock) == UNLOCKED)
#endif /* sinix */
!
#if defined(_AIX)
/*
***************
*** 440,446 ****
! #else /* !HAS_TEST_AND_SET */
/*
* Fake spinlock implementation using SysV semaphores --- slow and prone
--- 469,475 ----
! #else /* !HAS_TEST_AND_SET */
/*
* Fake spinlock implementation using SysV semaphores --- slow and prone
***************
*** 451,469 ****
typedef struct
{
/* reference to semaphore used to implement this spinlock */
! IpcSemaphoreId semId;
! int sem;
} slock_t;
extern bool s_lock_free_sema(volatile slock_t *lock);
extern void s_unlock_sema(volatile slock_t *lock);
extern void s_init_lock_sema(volatile slock_t *lock);
! extern int tas_sema(volatile slock_t *lock);
! #define S_LOCK_FREE(lock) s_lock_free_sema(lock)
! #define S_UNLOCK(lock) s_unlock_sema(lock)
! #define S_INIT_LOCK(lock) s_init_lock_sema(lock)
! #define TAS(lock) tas_sema(lock)
#endif /* HAS_TEST_AND_SET */
--- 480,498 ----
typedef struct
{
/* reference to semaphore used to implement this spinlock */
! IpcSemaphoreId semId;
! int sem;
} slock_t;
extern bool s_lock_free_sema(volatile slock_t *lock);
extern void s_unlock_sema(volatile slock_t *lock);
extern void s_init_lock_sema(volatile slock_t *lock);
! extern int tas_sema(volatile slock_t *lock);
! #define S_LOCK_FREE(lock) s_lock_free_sema(lock)
! #define S_UNLOCK(lock) s_unlock_sema(lock)
! #define S_INIT_LOCK(lock) s_init_lock_sema(lock)
! #define TAS(lock) tas_sema(lock)
#endif /* HAS_TEST_AND_SET */