#include "config.h"
#ifndef lint
-static const char sccsid[] = "@(#)mutex.c 10.25 (Sleepycat) 9/23/97";
+static const char sccsid[] = "@(#)mutex.c 10.32 (Sleepycat) 1/16/98";
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES
#define TSL_UNSET(x) _lock_clear(x)
#endif
+#ifdef HAVE_ASSEM_SCO_CC
+#include "sco.cc"
+#endif
+
#ifdef HAVE_ASSEM_SPARC_GCC
#include "sparc.gcc"
#endif
#endif /* HAVE_SPINLOCKS */
-#ifdef MORE_THAN_ONE_PROCESSOR
-#define TSL_DEFAULT_SPINS 5 /* Default spins before block. */
-#else
-#define TSL_DEFAULT_SPINS 1 /* Default spins before block. */
-#endif
-
/*
* __db_mutex_init --
* Initialize a DB mutex structure.
*
- * PUBLIC: void __db_mutex_init __P((db_mutex_t *, off_t));
+ * PUBLIC: void __db_mutex_init __P((db_mutex_t *, u_int32_t));
*/
void
__db_mutex_init(mp, off)
db_mutex_t *mp;
- off_t off;
+ u_int32_t off;
{
#ifdef DEBUG
if ((ALIGNTYPE)mp & (MUTEX_ALIGNMENT - 1)) {
memset(mp, 0, sizeof(db_mutex_t));
#ifdef HAVE_SPINLOCKS
+ COMPQUIET(off, 0);
+
TSL_INIT(&mp->tsl_resource);
+ mp->spins = __os_spin();
#else
mp->off = off;
#endif
* __db_mutex_lock
* Lock on a mutex, logically blocking if necessary.
*
- * PUBLIC: int __db_mutex_lock __P((db_mutex_t *, int, int (*)(void)));
+ * PUBLIC: int __db_mutex_lock __P((db_mutex_t *, int));
*/
int
-__db_mutex_lock(mp, fd, yield)
+__db_mutex_lock(mp, fd)
db_mutex_t *mp;
int fd;
- int (*yield) __P((void));
{
u_long usecs;
#ifdef HAVE_SPINLOCKS
int nspins;
+ COMPQUIET(fd, 0);
+
for (usecs = MS(10);;) {
- /*
- * Try and acquire the uncontested resource lock for
- * TSL_DEFAULT_SPINS.
- */
- for (nspins = TSL_DEFAULT_SPINS; nspins > 0; --nspins)
+ /* Try and acquire the uncontested resource lock for N spins. */
+ for (nspins = mp->spins; nspins > 0; --nspins)
if (TSL_SET(&mp->tsl_resource)) {
#ifdef DEBUG
if (mp->pid != 0) {
}
mp->pid = getpid();
#endif
-#ifdef MUTEX_STATISTICS
if (usecs == MS(10))
++mp->mutex_set_nowait;
else
++mp->mutex_set_wait;
-#endif
return (0);
}
/* Yield the processor; wait 10ms initially, up to 1 second. */
- if (yield == NULL || yield() != 0) {
+ if (__db_yield == NULL || __db_yield() != 0) {
(void)__db_sleep(0, usecs);
if ((usecs <<= 1) > SECOND)
usecs = SECOND;
* up to 1 second.
*/
for (usecs = MS(10); mp->pid != 0;)
- if (yield == NULL || yield() != 0) {
+ if (__db_yield == NULL || __db_yield() != 0) {
(void)__db_sleep(0, usecs);
if ((usecs <<= 1) > SECOND)
usecs = SECOND;
/* Acquire an exclusive kernel lock. */
k_lock.l_type = F_WRLCK;
if (fcntl(fd, F_SETLKW, &k_lock))
- return (1);
+ return (errno);
/* If the resource tsl is still available, it's ours. */
if (mp->pid == 0) {
/* Release the kernel lock. */
k_lock.l_type = F_UNLCK;
if (fcntl(fd, F_SETLK, &k_lock))
- return (1);
+ return (errno);
/*
* If we got the resource tsl we're done.
if (locked)
break;
}
-
-#ifdef MUTEX_STATISTICS
- ++mp->mutex_set_wait;
-#endif
return (0);
#endif /* !HAVE_SPINLOCKS */
}
#endif
#ifdef HAVE_SPINLOCKS
+ COMPQUIET(fd, 0);
+
#ifdef DEBUG
mp->pid = 0;
#endif