RPM Community Forums

Mailing List Message of <rpm-cvs>

[CVS] RPM: db/ README db/build_vxworks/ db.h db_config.h db_config_sma...

From: Jeff Johnson <jbj@rpm5.org>
Date: Wed 10 Oct 2007 - 00:50:09 CEST
Message-Id: <20071009225009.C037834845D@rpm5.org>
  RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  ____________________________________________________________________________

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  jbj@rpm5.org
  Module: db                               Date:   10-Oct-2007 00:50:09
  Branch: HEAD                             Handle: 2007100923500504

  Modified files:
    db                      README
    db/build_vxworks        db.h db_config.h db_config_small.h
    db/build_windows        db.h db_config.h libdb.rc
    db/dbinc                mp.h
    db/dist                 RELEASE configure tags
    db/hash                 hash_page.c
    db/java/src/com/sleepycat/db/internal
                            DbConstants.java
    db/log                  log_put.c
    db/mp                   mp_alloc.c mp_bh.c mp_fget.c mp_fput.c mp_fset.c
                            mp_mvcc.c
    db/mutex                mut_tas.c
    db/php_db4              Makefile.frag
    db/txn                  txn.c txn_util.c

  Log:
    merge conflicts on HEAD after import of Berkeley-DB 4.6.21

  Summary:
    Revision    Changes     Path
    1.15        +2  -2      db/README
    1.15        +2  -2      db/build_vxworks/db.h
    1.15        +3  -3      db/build_vxworks/db_config.h
    1.11        +3  -3      db/build_vxworks/db_config_small.h
    1.4         +2  -2      db/build_windows/db.h
    1.4         +3  -3      db/build_windows/db_config.h
    1.4         +4  -4      db/build_windows/libdb.rc
    1.8         +20 -5      db/dbinc/mp.h
    1.13        +1  -1      db/dist/RELEASE
    1.19        +13 -13     db/dist/configure
    1.12        +5  -3      db/dist/tags
    1.11        +3  -2      db/hash/hash_page.c
    1.11        +1  -1      db/java/src/com/sleepycat/db/internal/DbConstants.java
    1.12        +6  -3      db/log/log_put.c
    1.9         +6  -4      db/mp/mp_alloc.c
    1.12        +6  -4      db/mp/mp_bh.c
    1.9         +113 -83    db/mp/mp_fget.c
    1.9         +6  -7      db/mp/mp_fput.c
    1.9         +11 -4      db/mp/mp_fset.c
    1.3         +42 -18     db/mp/mp_mvcc.c
    1.9         +3  -0      db/mutex/mut_tas.c
    1.2         +0  -1      db/php_db4/Makefile.frag
    1.11        +15 -5      db/txn/txn.c
    1.8         +3  -1      db/txn/txn_util.c
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: db/README
  ============================================================================
  $ cvs diff -u -r1.14 -r1.15 README
  --- db/README	15 Aug 2007 20:53:22 -0000	1.14
  +++ db/README	9 Oct 2007 22:50:05 -0000	1.15
  @@ -1,5 +1,5 @@
  -Berkeley DB 4.6.19: (August 10, 2007)
  +Berkeley DB 4.6.21: (September 27, 2007)
   
  -This is version 4.6.19 of Berkeley DB from Oracle.  To view release and
  +This is version 4.6.21 of Berkeley DB from Oracle.  To view release and
   installation documentation, load the distribution file docs/index.html
   into your web browser.
  @@ .
  patch -p0 <<'@@ .'
  Index: db/build_vxworks/db.h
  ============================================================================
  $ cvs diff -u -r1.14 -r1.15 db.h
  --- db/build_vxworks/db.h	15 Aug 2007 20:53:22 -0000	1.14
  +++ db/build_vxworks/db.h	9 Oct 2007 22:50:06 -0000	1.15
  @@ -44,8 +44,8 @@
    */
   #define	DB_VERSION_MAJOR	4
   #define	DB_VERSION_MINOR	6
  -#define	DB_VERSION_PATCH	19
  -#define	DB_VERSION_STRING	"Berkeley DB 4.6.19: (August 10, 2007)"
  +#define	DB_VERSION_PATCH	21
  +#define	DB_VERSION_STRING	"Berkeley DB 4.6.21: (September 27, 2007)"
   
   /*
    * !!!
  @@ .
  patch -p0 <<'@@ .'
  Index: db/build_vxworks/db_config.h
  ============================================================================
  $ cvs diff -u -r1.14 -r1.15 db_config.h
  --- db/build_vxworks/db_config.h	15 Aug 2007 20:53:22 -0000	1.14
  +++ db/build_vxworks/db_config.h	9 Oct 2007 22:50:06 -0000	1.15
  @@ -482,13 +482,13 @@
   #define PACKAGE_NAME "Berkeley DB"
   
   /* Define to the full name and version of this package. */
  -#define PACKAGE_STRING "Berkeley DB 4.6.19"
  +#define PACKAGE_STRING "Berkeley DB 4.6.21"
   
   /* Define to the one symbol short name of this package. */
  -#define PACKAGE_TARNAME "db-4.6.19"
  +#define PACKAGE_TARNAME "db-4.6.21"
   
   /* Define to the version of this package. */
  -#define PACKAGE_VERSION "4.6.19"
  +#define PACKAGE_VERSION "4.6.21"
   
   /* The size of a `char', as computed by sizeof. */
   /* #undef SIZEOF_CHAR */
  @@ .
  patch -p0 <<'@@ .'
  Index: db/build_vxworks/db_config_small.h
  ============================================================================
  $ cvs diff -u -r1.10 -r1.11 db_config_small.h
  --- db/build_vxworks/db_config_small.h	15 Aug 2007 20:53:22 -0000	1.10
  +++ db/build_vxworks/db_config_small.h	9 Oct 2007 22:50:06 -0000	1.11
  @@ -482,13 +482,13 @@
   #define PACKAGE_NAME "Berkeley DB"
   
   /* Define to the full name and version of this package. */
  -#define PACKAGE_STRING "Berkeley DB 4.6.19"
  +#define PACKAGE_STRING "Berkeley DB 4.6.21"
   
   /* Define to the one symbol short name of this package. */
  -#define PACKAGE_TARNAME "db-4.6.19"
  +#define PACKAGE_TARNAME "db-4.6.21"
   
   /* Define to the version of this package. */
  -#define PACKAGE_VERSION "4.6.19"
  +#define PACKAGE_VERSION "4.6.21"
   
   /* The size of a `char', as computed by sizeof. */
   /* #undef SIZEOF_CHAR */
  @@ .
  patch -p0 <<'@@ .'
  Index: db/build_windows/db.h
  ============================================================================
  $ cvs diff -u -r1.3 -r1.4 db.h
  --- db/build_windows/db.h	15 Aug 2007 20:53:23 -0000	1.3
  +++ db/build_windows/db.h	9 Oct 2007 22:50:06 -0000	1.4
  @@ -59,8 +59,8 @@
    */
   #define	DB_VERSION_MAJOR	4
   #define	DB_VERSION_MINOR	6
  -#define	DB_VERSION_PATCH	19
  -#define	DB_VERSION_STRING	"Berkeley DB 4.6.19: (August 10, 2007)"
  +#define	DB_VERSION_PATCH	21
  +#define	DB_VERSION_STRING	"Berkeley DB 4.6.21: (September 27, 2007)"
   
   /*
    * !!!
  @@ .
  patch -p0 <<'@@ .'
  Index: db/build_windows/db_config.h
  ============================================================================
  $ cvs diff -u -r1.3 -r1.4 db_config.h
  --- db/build_windows/db_config.h	15 Aug 2007 20:53:23 -0000	1.3
  +++ db/build_windows/db_config.h	9 Oct 2007 22:50:06 -0000	1.4
  @@ -490,13 +490,13 @@
   #define PACKAGE_NAME "Berkeley DB"
   
   /* Define to the full name and version of this package. */
  -#define PACKAGE_STRING "Berkeley DB 4.6.19"
  +#define PACKAGE_STRING "Berkeley DB 4.6.21"
   
   /* Define to the one symbol short name of this package. */
  -#define PACKAGE_TARNAME "db-4.6.19"
  +#define PACKAGE_TARNAME "db-4.6.21"
   
   /* Define to the version of this package. */
  -#define PACKAGE_VERSION "4.6.19"
  +#define PACKAGE_VERSION "4.6.21"
   
   /* The size of a `char', as computed by sizeof. */
   /* #undef SIZEOF_CHAR */
  @@ .
  patch -p0 <<'@@ .'
  Index: db/build_windows/libdb.rc
  ============================================================================
  $ cvs diff -u -r1.3 -r1.4 libdb.rc
  --- db/build_windows/libdb.rc	15 Aug 2007 20:53:23 -0000	1.3
  +++ db/build_windows/libdb.rc	9 Oct 2007 22:50:06 -0000	1.4
  @@ -1,6 +1,6 @@
   1 VERSIONINFO
  - FILEVERSION 4,0,6,19
  - PRODUCTVERSION 4,0,6,19
  + FILEVERSION 4,0,6,21
  + PRODUCTVERSION 4,0,6,21
    FILEFLAGSMASK 0x3fL
   #ifdef _DEBUG
    FILEFLAGS 0x1L
  @@ -18,12 +18,12 @@
           BEGIN
               VALUE "CompanyName", "Oracle\0"
               VALUE "FileDescription", "Berkeley DB 4.6 DLL\0"
  -            VALUE "FileVersion", "4.6.19\0"
  +            VALUE "FileVersion", "4.6.21\0"
               VALUE "InternalName", "libdb46.dll\0"
               VALUE "LegalCopyright", "Copyright © Oracle 1997,2007\0"
               VALUE "OriginalFilename", "libdb46.dll\0"
               VALUE "ProductName", "Oracle libdb\0"
  -            VALUE "ProductVersion", "4.6.19\0"
  +            VALUE "ProductVersion", "4.6.21\0"
           END
       END
       BLOCK "VarFileInfo"
  @@ .
  patch -p0 <<'@@ .'
  Index: db/dbinc/mp.h
  ============================================================================
  $ cvs diff -u -r1.7 -r1.8 mp.h
  --- db/dbinc/mp.h	29 Jul 2007 13:10:49 -0000	1.7
  +++ db/dbinc/mp.h	9 Oct 2007 22:50:06 -0000	1.8
  @@ -492,6 +492,7 @@
   #define	BH_FROZEN	0x020		/* Frozen buffer: allocate & re-read. */
   #define	BH_LOCKED	0x040		/* Page is locked (I/O in progress). */
   #define	BH_TRASH	0x080		/* Page is garbage. */
  +#define	BH_THAWED	0x100		/* Page was thawed. */
   	u_int16_t	flags;
   
   	u_int32_t	priority;	/* LRU priority. */
  @@ -553,11 +554,25 @@
   #define	VISIBLE_LSN(dbenv, bhp)						\
       (&BH_OWNER(dbenv, bhp)->visible_lsn)
   
  -#define	BH_OBSOLETE(bhp, old_lsn)	((SH_CHAIN_HASNEXT(bhp, vc) ?	\
  -	LOG_COMPARE(&(old_lsn), VISIBLE_LSN(dbenv,			\
  -	SH_CHAIN_NEXTP(bhp, vc, __bh))) :				\
  -	(bhp->td_off == INVALID_ROFF ? 1 :				\
  -	LOG_COMPARE(&(old_lsn), VISIBLE_LSN(dbenv, bhp)))) > 0)
  +/*
  + * Make a copy of the buffer's visible LSN, one field at a time.  We rely on the
  + * 32-bit operations being atomic.  The visible_lsn starts at MAX_LSN and is
  + * set during commit or abort to the current LSN.
  + *
  + * If we race with a commit / abort, we may see either the file or the offset
  + * still at UINT32_MAX, so vlsn is guaranteed to be in the future.  That's OK,
  + * since we had to take the log region lock to allocate the read LSN so we were
  + * never going to see this buffer anyway.
  + */
  +#define	BH_VISIBLE(dbenv, bhp, read_lsnp, vlsn)				\
  +    (bhp->td_off == INVALID_ROFF ||					\
  +    ((vlsn).file = VISIBLE_LSN(dbenv, bhp)->file,			\
  +    (vlsn).offset = VISIBLE_LSN(dbenv, bhp)->offset,			\
  +    LOG_COMPARE((read_lsnp), &(vlsn)) >= 0))
  +
  +#define	BH_OBSOLETE(bhp, old_lsn, vlsn)	(SH_CHAIN_HASNEXT(bhp, vc) ?	\
  +    BH_VISIBLE(dbenv, SH_CHAIN_NEXTP(bhp, vc, __bh), &(old_lsn), vlsn) :\
  +    BH_VISIBLE(dbenv, bhp, &(old_lsn), vlsn))
   
   #define	MVCC_SKIP_CURADJ(dbc, pgno)					\
       (dbc->txn != NULL && F_ISSET(dbc->txn, TXN_SNAPSHOT) &&		\
  @@ .
  patch -p0 <<'@@ .'
  Index: db/dist/RELEASE
  ============================================================================
  $ cvs diff -u -r1.12 -r1.13 RELEASE
  --- db/dist/RELEASE	15 Aug 2007 20:53:23 -0000	1.12
  +++ db/dist/RELEASE	9 Oct 2007 22:50:07 -0000	1.13
  @@ -2,7 +2,7 @@
   
   DB_VERSION_MAJOR=4
   DB_VERSION_MINOR=6
  -DB_VERSION_PATCH=19
  +DB_VERSION_PATCH=21
   DB_VERSION="$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH"
   
   DB_VERSION_UNIQUE_NAME=`printf "_%d%03d" $DB_VERSION_MAJOR $DB_VERSION_MINOR`
  @@ .
  patch -p0 <<'@@ .'
  Index: db/dist/configure
  ============================================================================
  $ cvs diff -u -r1.18 -r1.19 configure
  --- db/dist/configure	15 Aug 2007 20:53:23 -0000	1.18
  +++ db/dist/configure	9 Oct 2007 22:50:07 -0000	1.19
  @@ -1,6 +1,6 @@
   #! /bin/sh
   # Guess values for system-dependent variables and create Makefiles.
  -# Generated by GNU Autoconf 2.61 for Berkeley DB 4.6.19.
  +# Generated by GNU Autoconf 2.61 for Berkeley DB 4.6.21.
   #
   # Report bugs to <Oracle Technology Network Berkeley DB forum>.
   #
  @@ -727,9 +727,9 @@
   
   # Identity of this package.
   PACKAGE_NAME='Berkeley DB'
  -PACKAGE_TARNAME='db-4.6.19'
  -PACKAGE_VERSION='4.6.19'
  -PACKAGE_STRING='Berkeley DB 4.6.19'
  +PACKAGE_TARNAME='db-4.6.21'
  +PACKAGE_VERSION='4.6.21'
  +PACKAGE_STRING='Berkeley DB 4.6.21'
   PACKAGE_BUGREPORT='Oracle Technology Network Berkeley DB forum'
   
   ac_unique_file="../db/db.c"
  @@ -1459,7 +1459,7 @@
     # Omit some internal or obsolete options to make the list less imposing.
     # This message is too long to be a string in the A/UX 3.1 sh.
     cat <<_ACEOF
  -\`configure' configures Berkeley DB 4.6.19 to adapt to many kinds of systems.
  +\`configure' configures Berkeley DB 4.6.21 to adapt to many kinds of systems.
   
   Usage: $0 [OPTION]... [VAR=VALUE]...
   
  @@ -1507,7 +1507,7 @@
     --infodir=DIR          info documentation [DATAROOTDIR/info]
     --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
     --mandir=DIR           man documentation [DATAROOTDIR/man]
  -  --docdir=DIR           documentation root [DATAROOTDIR/doc/db-4.6.19]
  +  --docdir=DIR           documentation root [DATAROOTDIR/doc/db-4.6.21]
     --htmldir=DIR          html documentation [DOCDIR]
     --dvidir=DIR           dvi documentation [DOCDIR]
     --pdfdir=DIR           pdf documentation [DOCDIR]
  @@ -1529,7 +1529,7 @@
   
   if test -n "$ac_init_help"; then
     case $ac_init_help in
  -     short | recursive ) echo "Configuration of Berkeley DB 4.6.19:";;
  +     short | recursive ) echo "Configuration of Berkeley DB 4.6.21:";;
      esac
     cat <<\_ACEOF
   
  @@ -1664,7 +1664,7 @@
   test -n "$ac_init_help" && exit $ac_status
   if $ac_init_version; then
     cat <<\_ACEOF
  -Berkeley DB configure 4.6.19
  +Berkeley DB configure 4.6.21
   generated by GNU Autoconf 2.61
   
   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
  @@ -1678,7 +1678,7 @@
   This file contains any messages produced by compilers while
   running configure, to aid debugging if configure makes a mistake.
   
  -It was created by Berkeley DB $as_me 4.6.19, which was
  +It was created by Berkeley DB $as_me 4.6.21, which was
   generated by GNU Autoconf 2.61.  Invocation command line was
   
     $ $0 $@
  @@ -2247,9 +2247,9 @@
   
   DB_VERSION_MINOR="6"
   
  -DB_VERSION_PATCH="19"
  +DB_VERSION_PATCH="21"
   
  -DB_VERSION_STRING='"Berkeley DB 4.6.19: (August 10, 2007)"'
  +DB_VERSION_STRING='"Berkeley DB 4.6.21: (September 27, 2007)"'
   
   
   # Process all options before using them.
  @@ -35925,7 +35925,7 @@
   # report actual input values of CONFIG_FILES etc. instead of their
   # values after options handling.
   ac_log="
  -This file was extended by Berkeley DB $as_me 4.6.19, which was
  +This file was extended by Berkeley DB $as_me 4.6.21, which was
   generated by GNU Autoconf 2.61.  Invocation command line was
   
     CONFIG_FILES    = $CONFIG_FILES
  @@ -35974,7 +35974,7 @@
   _ACEOF
   cat >>$CONFIG_STATUS <<_ACEOF
   ac_cs_version="\\
  -Berkeley DB config.status 4.6.19
  +Berkeley DB config.status 4.6.21
   configured by $0, generated by GNU Autoconf 2.61,
     with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
   
  @@ .
  patch -p0 <<'@@ .'
  Index: db/dist/tags
  ============================================================================
  $ cvs diff -u -r1.11 -r1.12 tags
  --- db/dist/tags	15 Aug 2007 20:53:23 -0000	1.11
  +++ db/dist/tags	9 Oct 2007 22:50:07 -0000	1.12
  @@ -44,11 +44,13 @@
   BH_FROZEN_ALLOC	../dbinc/mp.h	18
   BH_FROZEN_PAGE	../dbinc/mp.h	17
   BH_LOCKED	../dbinc/mp.h	493
  -BH_OBSOLETE	../dbinc/mp.h	/^#define	BH_OBSOLETE(bhp, old_lsn)	((SH_CHAIN_HASNE/
  +BH_OBSOLETE	../dbinc/mp.h	/^#define	BH_OBSOLETE(bhp, old_lsn, vlsn)	(SH_CHAIN_/
   BH_OWNED_BY	../dbinc/mp.h	/^#define	BH_OWNED_BY(dbenv, bhp, txn)	((txn) != NUL/
   BH_OWNER	../dbinc/mp.h	/^#define	BH_OWNER(dbenv, bhp)						\\$/
   BH_PRIORITY	../dbinc/mp.h	/^#define	BH_PRIORITY(bhp)						\\$/
  +BH_THAWED	../dbinc/mp.h	495
   BH_TRASH	../dbinc/mp.h	494
  +BH_VISIBLE	../dbinc/mp.h	/^#define	BH_VISIBLE(dbenv, bhp, read_lsnp, vlsn)			/
   BINTERNAL_PSIZE	../dbinc/db_page.h	/^#define	BINTERNAL_PSIZE(len)						\\$/
   BINTERNAL_SIZE	../dbinc/db_page.h	/^#define	BINTERNAL_SIZE(len)						\\$/
   BITEM_PSIZE	../dbinc/db_page.h	/^#define	BITEM_PSIZE(bk)							\\$/
  @@ -1764,7 +1766,7 @@
   MP_OPEN_CALLED	../dbinc/db.in	872
   MP_READONLY	../dbinc/db.in	873
   MP_TEMP	../dbinc/mp.h	468
  -MP_TRUNC_RECOVER	../dbinc/mp.h	625
  +MP_TRUNC_RECOVER	../dbinc/mp.h	640
   MSG_SIZE	../dbinc/tcl_db.h	16
   MS_PER_NS	../dbinc/db_int.in	125
   MS_PER_SEC	../dbinc/db_int.in	126
  @@ -2450,7 +2452,7 @@
   US_PER_SEC	../dbinc/db_int.in	124
   VERIFY_FLAGS	../db/db_vrfy.c	57
   VISIBLE_LSN	../dbinc/mp.h	/^#define	VISIBLE_LSN(dbenv, bhp)						\\$/
  -VM_PAGESIZE	../dbinc/mp.h	567
  +VM_PAGESIZE	../dbinc/mp.h	582
   VRFY_CHILDINFO	../dbinc/db_int.in	703
   VRFY_DBINFO	../dbinc/db_int.in	704
   VRFY_DUPS_UNSORTED	../dbinc/db_verify.h	180
  @@ .
  patch -p0 <<'@@ .'
  Index: db/hash/hash_page.c
  ============================================================================
  $ cvs diff -u -r1.10 -r1.11 hash_page.c
  --- db/hash/hash_page.c	29 Jul 2007 13:13:03 -0000	1.10
  +++ db/hash/hash_page.c	9 Oct 2007 22:50:07 -0000	1.11
  @@ -1815,8 +1815,9 @@
   			 * cursors for the second etc pages within a bucket.
   			 */
   			if (PGNO(temp_pagep) != bucket_pgno) {
  -				if ((ret = __db_cursor(
  -				    dbp, dbc->txn, &tmp_dbc, 0)) != 0)
  +				if ((ret = __db_cursor_int(dbp, dbc->txn, 
  +				    dbp->type, PGNO_INVALID, 0, 
  +				    DB_LOCK_INVALIDID, &tmp_dbc)) != 0)
   					goto err;
   				hcp = (HASH_CURSOR*)tmp_dbc->internal;
   				hcp->pgno = PGNO(*pp);
  @@ .
  patch -p0 <<'@@ .'
  Index: db/java/src/com/sleepycat/db/internal/DbConstants.java
  ============================================================================
  $ cvs diff -u -r1.10 -r1.11 DbConstants.java
  --- db/java/src/com/sleepycat/db/internal/DbConstants.java	15 Aug 2007 20:56:27 -0000	1.10
  +++ db/java/src/com/sleepycat/db/internal/DbConstants.java	9 Oct 2007 22:50:08 -0000	1.11
  @@ -204,7 +204,7 @@
       int DB_VERIFY = 0x0000002;
       int DB_VERSION_MAJOR = 4;
       int DB_VERSION_MINOR = 6;
  -    int DB_VERSION_PATCH = 19;
  +    int DB_VERSION_PATCH = 21;
       int DB_WRITECURSOR = 30;
       int DB_XA_CREATE = 0x0000002;
       int DB_XIDDATASIZE = 128;
  @@ .
  patch -p0 <<'@@ .'
  Index: db/log/log_put.c
  ============================================================================
  $ cvs diff -u -r1.11 -r1.12 log_put.c
  --- db/log/log_put.c	29 Jul 2007 13:13:22 -0000	1.11
  +++ db/log/log_put.c	9 Oct 2007 22:50:08 -0000	1.12
  @@ -162,10 +162,13 @@
   
   	/*
   	 * Assign the return LSN before dropping the region lock.  Necessary
  -	 * in case the lsn is a begin_lsn from a TXN_DETAIL structure passed
  -	 * in by the logging routines.
  +	 * in case the lsn is a begin_lsn from a TXN_DETAIL structure passed in
  +	 * by the logging routines.  We use atomic 32-bit operations because
  +	 * during commit this will be a TXN_DETAIL visible_lsn field, and MVCC
  +	 * relies on reading the fields atomically.
   	 */
  -	*lsnp = lsn;
  +	lsnp->file = lsn.file;
  +	lsnp->offset = lsn.offset;
   
   	if (IS_REP_MASTER(dbenv)) {
   		/*
  @@ .
  patch -p0 <<'@@ .'
  Index: db/mp/mp_alloc.c
  ============================================================================
  $ cvs diff -u -r1.8 -r1.9 mp_alloc.c
  --- db/mp/mp_alloc.c	29 Jul 2007 13:13:23 -0000	1.8
  +++ db/mp/mp_alloc.c	9 Oct 2007 22:50:08 -0000	1.9
  @@ -33,6 +33,7 @@
   	BH *bhp, *oldest_bhp, *tbhp;
   	BH_FROZEN_PAGE *frozen_bhp;
   	DB_ENV *dbenv;
  +	DB_LSN vlsn;
   	DB_MPOOL_HASH *dbht, *hp, *hp_end, *hp_tmp;
   	MPOOL *c_mp;
   	MPOOLFILE *bh_mfp;
  @@ -313,12 +314,13 @@
   			if (F_ISSET(bhp, BH_FROZEN) &&
   			    !F_ISSET(oldest_bhp, BH_FROZEN))
   				bhp = oldest_bhp;
  -			else if (BH_OBSOLETE(oldest_bhp, hp->old_reader))
  +			else if (BH_OBSOLETE(oldest_bhp, hp->old_reader, vlsn))
   				bhp = oldest_bhp;
   			else if (!got_oldest &&
   			    __txn_oldest_reader(dbenv, &hp->old_reader) == 0) {
   				got_oldest = 1;
  -				if (BH_OBSOLETE(oldest_bhp, hp->old_reader))
  +				if (BH_OBSOLETE(
  +				    oldest_bhp, hp->old_reader, vlsn))
   					bhp = oldest_bhp;
   			}
   		}
  @@ -350,13 +352,13 @@
   		 */
   		if (ret == 0 && bh_mfp->multiversion) {
   			if (!got_oldest && !SH_CHAIN_HASPREV(bhp, vc) &&
  -			    !BH_OBSOLETE(bhp, hp->old_reader)) {
  +			    !BH_OBSOLETE(bhp, hp->old_reader, vlsn)) {
   				(void)__txn_oldest_reader(dbenv,
   				    &hp->old_reader);
   				got_oldest = 1;
   			}
   			if (SH_CHAIN_HASPREV(bhp, vc) ||
  -			    !BH_OBSOLETE(bhp, hp->old_reader)) {
  +			    !BH_OBSOLETE(bhp, hp->old_reader, vlsn)) {
   				/*
   				 * Before freezing, double-check that we have
   				 * an up-to-date old_reader LSN.
  @@ .
  patch -p0 <<'@@ .'
  Index: db/mp/mp_bh.c
  ============================================================================
  $ cvs diff -u -r1.11 -r1.12 mp_bh.c
  --- db/mp/mp_bh.c	29 Jul 2007 13:13:24 -0000	1.11
  +++ db/mp/mp_bh.c	9 Oct 2007 22:50:08 -0000	1.12
  @@ -529,6 +529,9 @@
   	u_int32_t flags;
   {
   	DB_ENV *dbenv;
  +#ifdef DIAGNOSTIC
  +	DB_LSN vlsn;
  +#endif
   	MPOOL *c_mp;
   	MPOOLFILE *mfp;
   	BH *next_bhp, *prev_bhp;
  @@ -548,15 +551,14 @@
   	pagesize = mfp->stat.st_pagesize;
   #endif
   
  -	DB_ASSERT(dbenv, bhp->ref == 0);
  +	DB_ASSERT(dbenv, bhp->ref == 0 && !F_ISSET(bhp, BH_FROZEN));
   	DB_ASSERT(dbenv, LF_ISSET(BH_FREE_UNLOCKED) ||
   	    SH_CHAIN_SINGLETON(bhp, vc) ||
   	    (SH_CHAIN_HASNEXT(bhp, vc) &&
  -	    F_ISSET(SH_CHAIN_NEXT(bhp, vc, __bh), BH_FROZEN) &&
  -	    bhp->td_off == INVALID_ROFF) ||
  +	    SH_CHAIN_NEXTP(bhp, vc, __bh)->td_off == bhp->td_off) ||
   	    (SH_CHAIN_HASPREV(bhp, vc) ?
   	    IS_MAX_LSN(*VISIBLE_LSN(dbenv, bhp)) :
  -	    BH_OBSOLETE(bhp, hp->old_reader)));
  +	    BH_OBSOLETE(bhp, hp->old_reader, vlsn)));
   
   	/*
   	 * Delete the buffer header from the hash bucket queue or the
  @@ .
  patch -p0 <<'@@ .'
  Index: db/mp/mp_fget.c
  ============================================================================
  $ cvs diff -u -r1.8 -r1.9 mp_fget.c
  --- db/mp/mp_fget.c	29 Jul 2007 13:13:24 -0000	1.8
  +++ db/mp/mp_fget.c	9 Oct 2007 22:50:08 -0000	1.9
  @@ -105,9 +105,9 @@
   	void *addrp;
   {
   	enum { FIRST_FOUND, FIRST_MISS, SECOND_FOUND, SECOND_MISS } state;
  -	BH *alloc_bhp, *bhp, *current_bhp, *frozen_bhp, *oldest_bhp;
  +	BH *alloc_bhp, *bhp, *frozen_bhp, *oldest_bhp;
   	DB_ENV *dbenv;
  -	DB_LSN *read_lsnp;
  +	DB_LSN *read_lsnp, vlsn;
   	DB_MPOOL *dbmp;
   	DB_MPOOL_HASH *hp;
   	MPOOL *c_mp;
  @@ -243,34 +243,21 @@
   		if (bhp->pgno != *pgnoaddr || bhp->mf_offset != mf_offset)
   			continue;
   
  -		if (mvcc) {
  -			/*
  -			 * Snapshot reads -- get the version of the page that
  -			 * was visible *at* the read_lsn.
  -			 */
  -			current_bhp = bhp;
  -			if (read_lsnp != NULL &&
  -			    !BH_OWNED_BY(dbenv, bhp, txn) && !edit) {
  -				while (bhp != NULL &&
  -				    bhp->td_off != INVALID_ROFF &&
  -				    log_compare(VISIBLE_LSN(dbenv, bhp),
  -				    read_lsnp) > 0)
  -					bhp = SH_CHAIN_PREV(bhp, vc, __bh);
  +		/* Snapshot reads -- get the version visible at read_lsn. */
  +		if (mvcc && !edit && read_lsnp != NULL) {
  +			while (bhp != NULL &&
  +			    !BH_OWNED_BY(dbenv, bhp, txn) &&
  +			    !BH_VISIBLE(dbenv, bhp, read_lsnp, vlsn))
  +				bhp = SH_CHAIN_PREV(bhp, vc, __bh);
   
  -				DB_ASSERT(dbenv, bhp != NULL);
  -			}
  +			DB_ASSERT(dbenv, bhp != NULL);
  +		}
   
  -			makecopy = dirty && !BH_OWNED_BY(dbenv, bhp, txn);
  -			if (makecopy && bhp != current_bhp) {
  -				ret = DB_LOCK_DEADLOCK;
  -				goto err;
  -			}
  +		makecopy = mvcc && dirty && !BH_OWNED_BY(dbenv, bhp, txn);
   
  -			if (F_ISSET(bhp, BH_FROZEN) &&
  -			    !F_ISSET(bhp, BH_FREED)) {
  -				DB_ASSERT(dbenv, frozen_bhp == NULL);
  -				frozen_bhp = bhp;
  -			}
  +		if (F_ISSET(bhp, BH_FROZEN) && !F_ISSET(bhp, BH_FREED)) {
  +			DB_ASSERT(dbenv, frozen_bhp == NULL);
  +			frozen_bhp = bhp;
   		}
   
   		/*
  @@ -306,6 +293,7 @@
   			if (!first && bhp->ref_sync != 0) {
   				--bhp->ref;
   				MUTEX_UNLOCK(dbenv, hp->mtx_hash);
  +				bhp = frozen_bhp = NULL;
   				b_incr = b_locked = 0;
   				__os_sleep(dbenv, 0, 1);
   				goto retry;
  @@ -335,11 +323,11 @@
   
   		/*
   		 * If the buffer was frozen before we waited for any I/O to
  -		 * complete and is still frozen, we need to unfreeze it.
  -		 * Otherwise, it was unfrozen while we waited, and we need to
  +		 * complete and is still frozen, we will need to thaw it.
  +		 * Otherwise, it was thawed while we waited, and we need to
   		 * search again.
   		 */
  -		if (frozen_bhp != NULL && !F_ISSET(frozen_bhp, BH_FROZEN)) {
  +		if (frozen_bhp != NULL && F_ISSET(frozen_bhp, BH_THAWED)) {
   thawed:			need_free = (--frozen_bhp->ref == 0);
   			b_incr = 0;
   			MUTEX_UNLOCK(dbenv, hp->mtx_hash);
  @@ -352,8 +340,24 @@
   				SH_TAILQ_INSERT_TAIL(&c_mp->free_frozen,
   				    frozen_bhp, hq);
   			MPOOL_REGION_UNLOCK(dbenv, infop);
  -			frozen_bhp = NULL;
  +			bhp = frozen_bhp = NULL;
  +			goto retry;
  +		}
  +
  +		/*
  +		 * If the buffer we wanted was frozen or thawed while we
  +		 * waited, we need to start again.
  +		 */
  +		if (SH_CHAIN_HASNEXT(bhp, vc) &&
  +		    SH_CHAIN_NEXTP(bhp, vc, __bh)->td_off == bhp->td_off) {
  +			--bhp->ref;
  +			b_incr = 0;
  +			MUTEX_UNLOCK(dbenv, hp->mtx_hash);
  +			bhp = frozen_bhp = NULL;
   			goto retry;
  +		} else if (dirty && SH_CHAIN_HASNEXT(bhp, vc)) {
  +			ret = DB_LOCK_DEADLOCK;
  +			goto err;
   		}
   
   #ifdef HAVE_STATISTICS
  @@ -423,7 +427,8 @@
   				 * Mark it with BH_FREED so we don't reuse the
   				 * data when the page is resurrected.
   				 */
  -				if (mvcc && (!SH_CHAIN_SINGLETON(bhp, vc) ||
  +				if (mvcc && (F_ISSET(bhp, BH_FROZEN) ||
  +				    !SH_CHAIN_SINGLETON(bhp, vc) ||
   				    bhp->td_off == INVALID_ROFF ||
   				    !IS_MAX_LSN(*VISIBLE_LSN(dbenv, bhp)))) {
   					F_SET(bhp, BH_FREED);
  @@ -461,33 +466,42 @@
   			 * that we've seen a buffer older than the oldest
   			 * snapshot read LSN.
   			 */
  -			if ((makecopy || frozen_bhp != NULL) && (oldest_bhp =
  +reuse:			if ((makecopy || frozen_bhp != NULL) && (oldest_bhp =
   			    SH_CHAIN_PREV(bhp, vc, __bh)) != NULL) {
   				while (SH_CHAIN_HASPREV(oldest_bhp, vc))
   					oldest_bhp = SH_CHAIN_PREVP(oldest_bhp,
   					    vc, __bh);
   
  -				if (oldest_bhp->ref == 0 &&
  -				    !F_ISSET(oldest_bhp, BH_FROZEN) &&
  -				    (BH_OBSOLETE(oldest_bhp, hp->old_reader) ||
  -				    ((ret = __txn_oldest_reader(dbenv,
  -				    &hp->old_reader)) == 0 &&
  -				    BH_OBSOLETE(oldest_bhp, hp->old_reader)))) {
  -					if ((ret = __memp_bhfree(dbmp,
  +				if (oldest_bhp->ref == 0 && !BH_OBSOLETE(
  +				    oldest_bhp, hp->old_reader, vlsn) &&
  +				    (ret = __txn_oldest_reader(dbenv,
  +				    &hp->old_reader)) != 0)
  +					goto err;
  +
  +				if (BH_OBSOLETE(
  +				    oldest_bhp, hp->old_reader, vlsn) &&
  +				    oldest_bhp->ref == 0) {
  +					if (F_ISSET(oldest_bhp, BH_FROZEN)) {
  +						++oldest_bhp->ref;
  +						if ((ret = __memp_bh_thaw(dbmp,
  +						    infop, hp, oldest_bhp,
  +						    NULL)) != 0)
  +							goto err;
  +						goto reuse;
  +					} else if ((ret = __memp_bhfree(dbmp,
   					    infop, hp, oldest_bhp,
   					    BH_FREE_REUSE)) != 0)
   						goto err;
   					alloc_bhp = oldest_bhp;
  -				} else if (ret != 0)
  -					goto err;
  +				}
   
   				DB_ASSERT(dbenv, alloc_bhp == NULL ||
   				    !F_ISSET(alloc_bhp, BH_FROZEN));
   			}
   		}
   
  +		/* We found the buffer or we're ready to copy -- we're done. */
   		if ((!makecopy && frozen_bhp == NULL) || alloc_bhp != NULL)
  -			/* We found the buffer -- we're done. */
   			break;
   
   		/* FALLTHROUGH */
  @@ -511,6 +525,7 @@
   		 * If neither DB_MPOOL_CREATE or DB_MPOOL_NEW is set, then
   		 * it's an error to try and get a page past the end of file.
   		 */
  +		DB_ASSERT(dbenv, !b_locked);
   		MUTEX_LOCK(dbenv, mfp->mutex);
   		switch (flags) {
   		case DB_MPOOL_NEW:
  @@ -640,6 +655,7 @@
   			b_locked = 1;
   			break;
   		}
  +		DB_ASSERT(dbenv, frozen_bhp == NULL);
   		goto retry;
   	case SECOND_FOUND:
   		/*
  @@ -786,7 +802,7 @@
   		 * If the empty buffer has been filled in the meantime, don't
   		 * overwrite it.
   		 */
  -		if (!F_ISSET(frozen_bhp, BH_FROZEN))
  +		if (F_ISSET(frozen_bhp, BH_THAWED))
   			goto thawed;
   		else {
   			if ((ret = __memp_bh_thaw(dbmp, infop, hp,
  @@ -804,35 +820,12 @@
   		 */
   		if (makecopy) {
   			MUTEX_UNLOCK(dbenv, hp->mtx_hash);
  +			b_locked = 0;
   			goto alloc;
   		}
   	}
   
   	/*
  -	 * If we're the only reference, update buffer and bucket priorities.
  -	 * We may be about to release the hash bucket lock, and everything
  -	 * should be correct, first.  (We've already done this if we created
  -	 * the buffer, so there is no need to do it again.)
  -	 */
  -	if (state != SECOND_MISS && bhp->ref == 1) {
  -		if (SH_CHAIN_SINGLETON(bhp, vc)) {
  -			bhp->priority = UINT32_MAX;
  -			if (bhp != SH_TAILQ_LAST(&hp->hash_bucket, hq, __bh)) {
  -				SH_TAILQ_REMOVE(&hp->hash_bucket,
  -				    bhp, hq, __bh);
  -				SH_TAILQ_INSERT_TAIL(&hp->hash_bucket, bhp, hq);
  -			}
  -			hp->hash_priority = BH_PRIORITY(
  -			    SH_TAILQ_FIRSTP(&hp->hash_bucket, __bh));
  -		} else {
  -			reorder = (BH_PRIORITY(bhp) == bhp->priority);
  -			bhp->priority = UINT32_MAX;
  -			if (reorder)
  -				__memp_bucket_reorder(dbenv, hp, bhp);
  -		}
  -	}
  -
  -	/*
   	 * BH_TRASH --
   	 * The buffer we found may need to be filled from the disk.
   	 *
  @@ -882,6 +875,9 @@
   		alloc_bhp->pgno = bhp->pgno;
   		alloc_bhp->mf_offset = bhp->mf_offset;
   		alloc_bhp->td_off = INVALID_ROFF;
  +		if (txn != NULL &&
  +		    (ret = __memp_bh_settxn(dbmp, mfp, alloc_bhp, td)) != 0)
  +			goto err;
   		if (extending) {
   			memset(alloc_bhp->buf, 0, mfp->stat.st_pagesize);
   			F_SET(alloc_bhp, BH_DIRTY_CREATE);
  @@ -892,8 +888,11 @@
   		SH_TAILQ_INSERT_BEFORE(&hp->hash_bucket,
   		    bhp, alloc_bhp, hq, __bh);
   		SH_TAILQ_REMOVE(&hp->hash_bucket, bhp, hq, __bh);
  -		if (--bhp->ref == 0)
  +		if (--bhp->ref == 0) {
  +			bhp->priority = c_mp->lru_count;
  +			__memp_bucket_reorder(dbenv, hp, bhp);
   			MVCC_MPROTECT(bhp->buf, mfp->stat.st_pagesize, 0);
  +		}
   		bhp = alloc_bhp;
   
   		if (alloc_bhp != oldest_bhp) {
  @@ -903,17 +902,39 @@
   		}
   
   		alloc_bhp = NULL;
  -	}
  +	} else if (mvcc && extending && txn != NULL &&
  +	    (ret = __memp_bh_settxn(dbmp, mfp, bhp, td)) != 0)
  +		goto err;
   
   	if ((dirty || edit || extending) && !F_ISSET(bhp, BH_DIRTY)) {
  +		DB_ASSERT(dbenv, !SH_CHAIN_HASNEXT(bhp, vc));
   		++hp->hash_page_dirty;
   		F_SET(bhp, BH_DIRTY);
   	}
   
  -	if (mvcc &&
  -	    ((makecopy && !extending) || (extending && txn != NULL)) &&
  -	    (ret = __memp_bh_settxn(dbmp, mfp, bhp, td)) != 0)
  -		goto err;
  +	/*
  +	 * If we're the only reference, update buffer and bucket priorities.
  +	 * We may be about to release the hash bucket lock, and everything
  +	 * should be correct, first.  (We've already done this if we created
  +	 * the buffer, so there is no need to do it again.)
  +	 */
  +	if (state != SECOND_MISS && bhp->ref == 1) {
  +		if (SH_CHAIN_SINGLETON(bhp, vc)) {
  +			bhp->priority = UINT32_MAX;
  +			if (bhp != SH_TAILQ_LAST(&hp->hash_bucket, hq, __bh)) {
  +				SH_TAILQ_REMOVE(&hp->hash_bucket,
  +				    bhp, hq, __bh);
  +				SH_TAILQ_INSERT_TAIL(&hp->hash_bucket, bhp, hq);
  +			}
  +			hp->hash_priority = BH_PRIORITY(
  +			    SH_TAILQ_FIRSTP(&hp->hash_bucket, __bh));
  +		} else {
  +			reorder = (BH_PRIORITY(bhp) == bhp->priority);
  +			bhp->priority = UINT32_MAX;
  +			if (reorder)
  +				__memp_bucket_reorder(dbenv, hp, bhp);
  +		}
  +	}
   
   	MVCC_MPROTECT(bhp->buf, mfp->stat.st_pagesize, PROT_READ |
   	    (dirty || edit || extending || F_ISSET(bhp, BH_DIRTY) ?
  @@ -921,10 +942,22 @@
   
   #ifdef DIAGNOSTIC
   	__memp_check_order(dbenv, hp);
  -#endif
   
  -	DB_ASSERT(dbenv, !(mfp->multiversion && F_ISSET(bhp, BH_DIRTY)) ||
  -	    !SH_CHAIN_HASNEXT(bhp, vc));
  +	{
  +	BH *next_bhp = SH_CHAIN_NEXT(bhp, vc, __bh);
  +
  +	DB_ASSERT(dbenv, !mfp->multiversion ||
  +	    !F_ISSET(bhp, BH_DIRTY) || next_bhp == NULL);
  +
  +	DB_ASSERT(dbenv, !mvcc || edit || read_lsnp == NULL ||
  +	    bhp->td_off == INVALID_ROFF || BH_OWNED_BY(dbenv, bhp, txn) ||
  +	    (BH_VISIBLE(dbenv, bhp, read_lsnp, vlsn) &&
  +	    (next_bhp == NULL || F_ISSET(next_bhp, BH_FROZEN) ||
  +	    (next_bhp->td_off != INVALID_ROFF &&
  +	    (BH_OWNER(dbenv, next_bhp)->status != TXN_COMMITTED ||
  +	    !BH_VISIBLE(dbenv, next_bhp, read_lsnp, vlsn))))));
  +	}
  +#endif
   
   	MUTEX_UNLOCK(dbenv, hp->mtx_hash);
   
  @@ -958,12 +991,9 @@
   			b_locked = 1;
   		}
   		if (frozen_bhp != NULL)
  -			--frozen_bhp;
  -		if (b_incr && --bhp->ref == 0) {
  -			(void)__memp_bhfree(dbmp,
  -			    infop, hp, bhp, BH_FREE_FREEMEM);
  -			b_locked = 0;
  -		}
  +			--frozen_bhp->ref;
  +		if (b_incr && bhp != frozen_bhp)
  +			--bhp->ref;
   	}
   	if (b_locked)
   		MUTEX_UNLOCK(dbenv, hp->mtx_hash);
  @@ .
  patch -p0 <<'@@ .'
  Index: db/mp/mp_fput.c
  ============================================================================
  $ cvs diff -u -r1.8 -r1.9 mp_fput.c
  --- db/mp/mp_fput.c	29 Jul 2007 13:13:24 -0000	1.8
  +++ db/mp/mp_fput.c	9 Oct 2007 22:50:08 -0000	1.9
  @@ -124,14 +124,13 @@
   	/* Note the activity so allocation won't decide to quit. */
   	++c_mp->put_counter;
   
  -	/*
  -	 * Mark the file dirty.  Check for a dirty bit on the buffer as well
  -	 * as the dirty flag because the buffer might have been marked dirty
  -	 * in the DB_MPOOLFILE->set method.
  -	 */
  -	if (F_ISSET(bhp, BH_DIRTY))
  +	/* Mark the file dirty. */
  +	if (F_ISSET(bhp, BH_DIRTY)) {
   		mfp->file_written = 1;
   
  +		DB_ASSERT(dbenv, !SH_CHAIN_HASNEXT(bhp, vc));
  +	}
  +
   	/*
   	 * If more than one reference to the page or a reference other than a
   	 * thread waiting to flush the buffer to disk, we're done.  Ignore the
  @@ -289,7 +288,7 @@
   		 */
   		if ((tbhp =
   		    SH_TAILQ_FIRST(&hp->hash_bucket, __bh)) != NULL)
  -			hp->hash_priority = tbhp->priority;
  +			hp->hash_priority = BH_PRIORITY(tbhp);
   		MUTEX_UNLOCK(dbenv, hp->mtx_hash);
   	}
   	c_mp->lru_reset = 0;
  @@ .
  patch -p0 <<'@@ .'
  Index: db/mp/mp_fset.c
  ============================================================================
  $ cvs diff -u -r1.8 -r1.9 mp_fset.c
  --- db/mp/mp_fset.c	29 Jul 2007 13:13:24 -0000	1.8
  +++ db/mp/mp_fset.c	9 Oct 2007 22:50:08 -0000	1.9
  @@ -36,12 +36,13 @@
   	MPOOLFILE *mfp;
   #endif
   	REGINFO *infop;
  -	int ret;
  +	int mvcc, ret;
   	db_pgno_t pgno;
   	void *pgaddr;
   
   	dbenv = dbmfp->dbenv;
   	pgaddr = *(void **)addrp;
  +	mvcc = dbmfp->mfp->multiversion;
   
   	/* Convert the page address to a buffer header. */
   	bhp = (BH *)((u_int8_t *)pgaddr - SSZA(BH, buf));
  @@ -62,9 +63,9 @@
   	    ancestor = ancestor->parent)
   		;
   
  -	if (dbmfp->mfp->multiversion &&
  -	    txn != NULL && !BH_OWNED_BY(dbenv, bhp, ancestor)) {
  -		if ((ret = __memp_fget(dbmfp,
  +	if (mvcc && txn != NULL &&
  +	    (!BH_OWNED_BY(dbenv, bhp, ancestor) || SH_CHAIN_HASNEXT(bhp, vc))) {
  +slow:		if ((ret = __memp_fget(dbmfp,
   		    &pgno, txn, flags, addrp)) != 0) {
   			if (ret != DB_LOCK_DEADLOCK)
   				__db_errx(dbenv,
  @@ -96,6 +97,12 @@
   	if (ret != 0)
   		return (ret);
   
  +	/* Need to recheck in case we raced with a freeze operation. */
  +	if (mvcc && txn != NULL && SH_CHAIN_HASNEXT(bhp, vc)) {
  +		MUTEX_UNLOCK(dbenv, hp->mtx_hash);
  +		goto slow;
  +	}
  +
   	/* Set/clear the page bits. */
   	if (!F_ISSET(bhp, BH_DIRTY)) {
   		++hp->hash_page_dirty;
  @@ .
  patch -p0 <<'@@ .'
  Index: db/mp/mp_mvcc.c
  ============================================================================
  $ cvs diff -u -r1.2 -r1.3 mp_mvcc.c
  --- db/mp/mp_mvcc.c	29 Jul 2007 13:13:24 -0000	1.2
  +++ db/mp/mp_mvcc.c	9 Oct 2007 22:50:08 -0000	1.3
  @@ -274,8 +274,8 @@
   
   	/*
   	 * For now, keep things simple and have one file per page size per
  -	 * cache.  Concurrency will be suboptimal, but debugging should be
  -	 * simpler.
  +	 * hash bucket.  This improves concurrency but can mean lots of files
  +	 * if there is lots of freezing.
   	 */
   	ncache = (u_int32_t)(infop - dbmp->reginfo);
   	nbucket = (u_int32_t)(hp - (DB_MPOOL_HASH *)R_ADDR(infop, c_mp->htab));
  @@ -354,12 +354,22 @@
   	frozen_bhp->priority = UINT32_MAX;
   	((BH_FROZEN_PAGE *)frozen_bhp)->spgno = newpgno;
   
  -	bhp->td_off = INVALID_ROFF;
  +	/*
  +	 * We're about to add the frozen buffer header to the version chain, so
  +	 * we have temporarily created another buffer for the owning
  +	 * transaction.
  +	 */
  +	if (frozen_bhp->td_off != INVALID_ROFF &&
  +	    (ret = __txn_add_buffer(dbenv, BH_OWNER(dbenv, frozen_bhp))) != 0) {
  +		(void)__db_panic(dbenv, ret);
  +		goto err;
  +	}
   
   	/*
   	 * Add the frozen buffer to the version chain and update the hash
  -	 * bucket if this is the head revision.  __memp_alloc will remove it by
  -	 * calling __memp_bhfree on the old version of the buffer.
  +	 * bucket if this is the head revision.  The original buffer will be
  +	 * freed by __memp_alloc calling __memp_bhfree (assuming no other
  +	 * thread has blocked waiting for it while we were freezing).
   	 */
   	SH_CHAIN_INSERT_AFTER(bhp, frozen_bhp, vc, __bh);
   	if (!SH_CHAIN_HASNEXT(frozen_bhp, vc)) {
  @@ -441,11 +451,15 @@
   	BH *next_bhp;
   	DB_ENV *dbenv;
   	DB_FH *fhp;
  +#ifdef DIAGNOSTIC
  +	DB_LSN vlsn;
  +#endif
   	MPOOL *c_mp;
   	MPOOLFILE *bh_mfp;
   	db_pgno_t *freelist, *ppgno, freepgno, maxpgno, spgno;
   	size_t nio;
   	u_int32_t listsize, magic, nbucket, ncache, ntrunc, nfree, pagesize;
  +	u_int32_t priority;
   #ifdef HAVE_FTRUNCATE
   	int i;
   #endif
  @@ -464,7 +478,7 @@
   	DB_ASSERT(dbenv, F_ISSET(frozen_bhp, BH_FROZEN));
   	DB_ASSERT(dbenv, !F_ISSET(frozen_bhp, BH_LOCKED));
   	DB_ASSERT(dbenv, alloc_bhp != NULL ||
  -	    BH_OBSOLETE(frozen_bhp, hp->old_reader));
  +	    BH_OBSOLETE(frozen_bhp, hp->old_reader, vlsn));
   
   	spgno = ((BH_FROZEN_PAGE *)frozen_bhp)->spgno;
   
  @@ -483,8 +497,8 @@
   
   	/*
   	 * For now, keep things simple and have one file per page size per
  -	 * cache.  Concurrency will be suboptimal, but debugging should be
  -	 * simpler.
  +	 * hash bucket.  This improves concurrency but can mean lots of files
  +	 * if there is lots of freezing.
   	 */
   	ncache = (u_int32_t)(infop - dbmp->reginfo);
   	nbucket = (u_int32_t)(hp - (DB_MPOOL_HASH *)R_ADDR(infop, c_mp->htab));
  @@ -534,7 +548,7 @@
   			goto err;
   		nfree = 0;
   		while (freepgno != 0) {
  -			if (nfree == listsize) {
  +			if (nfree == listsize - 1) {
   				listsize *= 2;
   				if ((ret = __os_realloc(dbenv,
   				    listsize * sizeof(db_pgno_t),
  @@ -608,16 +622,19 @@
   	 * another cache lookup to find out where the new page should live.
   	 */
   	if (alloc_bhp != NULL) {
  +		alloc_bhp->priority = c_mp->lru_count;
  +
   		SH_CHAIN_INSERT_AFTER(frozen_bhp, alloc_bhp, vc, __bh);
   		if (!SH_CHAIN_HASNEXT(alloc_bhp, vc)) {
   			SH_TAILQ_INSERT_BEFORE(&hp->hash_bucket,
   			    frozen_bhp, alloc_bhp, hq, __bh);
   			SH_TAILQ_REMOVE(&hp->hash_bucket, frozen_bhp, hq, __bh);
   		}
  -	}
  -
  -	reorder = (alloc_bhp == NULL) &&
  -	    BH_PRIORITY(frozen_bhp) == frozen_bhp->priority;
  +		priority = BH_PRIORITY(alloc_bhp);
  +		reorder = (priority == alloc_bhp->priority ||
  +		    priority == frozen_bhp->priority);
  +	} else
  +		reorder = BH_PRIORITY(frozen_bhp) == frozen_bhp->priority;
   	if ((next_bhp = SH_CHAIN_NEXT(frozen_bhp, vc, __bh)) == NULL) {
   		if ((next_bhp = SH_CHAIN_PREV(frozen_bhp, vc, __bh)) != NULL)
   			SH_TAILQ_INSERT_BEFORE(&hp->hash_bucket, frozen_bhp,
  @@ -641,17 +658,24 @@
   	if (--frozen_bhp->ref == 0) {
   		MUTEX_UNLOCK(dbenv, hp->mtx_hash);
   
  -		if (alloc_bhp == NULL && frozen_bhp->td_off != INVALID_ROFF)
  -			ret = __txn_remove_buffer(dbenv,
  -			    BH_OWNER(dbenv, frozen_bhp), MUTEX_INVALID);
  +		if (alloc_bhp == NULL && frozen_bhp->td_off != INVALID_ROFF &&
  +		    (ret = __txn_remove_buffer(dbenv,
  +		    BH_OWNER(dbenv, frozen_bhp), MUTEX_INVALID)) != 0) {
  +			(void)__db_panic(dbenv, ret);
  +			goto err;
  +		}
   
  +		/*
  +		 * We need to be careful in the error case, because our caller
  +		 * will attempt to free frozen_bhp.
  +		 */
   		MPOOL_REGION_LOCK(dbenv, infop);
   		SH_TAILQ_INSERT_TAIL(&c_mp->free_frozen, frozen_bhp, hq);
   		MPOOL_REGION_UNLOCK(dbenv, infop);
   		MUTEX_LOCK(dbenv, hp->mtx_hash);
   	} else {
  -		DB_ASSERT(dbenv, alloc_bhp != NULL);
  -		F_CLR(frozen_bhp, BH_FROZEN | BH_LOCKED);
  +		F_SET(frozen_bhp, BH_THAWED);
  +		F_CLR(frozen_bhp, BH_LOCKED);
   	}
   
   #ifdef HAVE_STATISTICS
  @@ .
  patch -p0 <<'@@ .'
  Index: db/mutex/mut_tas.c
  ============================================================================
  $ cvs diff -u -r1.8 -r1.9 mut_tas.c
  --- db/mutex/mut_tas.c	29 Jul 2007 13:13:26 -0000	1.8
  +++ db/mutex/mut_tas.c	9 Oct 2007 22:50:09 -0000	1.9
  @@ -177,6 +177,9 @@
   
   	/* Wait for the lock to become available. */
   #ifdef HAVE_MUTEX_HYBRID
  +	__os_yield(dbenv);
  +	if (!F_ISSET(mutexp, DB_MUTEX_LOCKED))
  +		goto loop;
   	if ((ret = __db_pthread_mutex_lock(dbenv, mutex)) != 0)
   		return (ret);
   #else
  @@ .
  patch -p0 <<'@@ .'
  Index: db/php_db4/Makefile.frag
  ============================================================================
  $ cvs diff -u -r1.1 -r1.2 Makefile.frag
  --- db/php_db4/Makefile.frag	11 Nov 2004 16:25:25 -0000	1.1
  +++ db/php_db4/Makefile.frag	9 Oct 2007 22:50:09 -0000	1.2
  @@ -1,4 +1,3 @@
  -phpincludedir=$(prefix)/include/php
   
   PHP_DB4_HEADER_FILES = php_db4.h
   
  @@ .
  patch -p0 <<'@@ .'
  Index: db/txn/txn.c
  ============================================================================
  $ cvs diff -u -r1.10 -r1.11 txn.c
  --- db/txn/txn.c	29 Jul 2007 13:14:22 -0000	1.10
  +++ db/txn/txn.c	9 Oct 2007 22:50:09 -0000	1.11
  @@ -1321,8 +1321,21 @@
   	if (td->nlog_dbs != 0 && (ret = __txn_dref_fname(dbenv, txn)) != 0)
   		return (__db_panic(dbenv, ret));
   
  -	TXN_SYSTEM_LOCK(dbenv);
  +	if (td->mvcc_ref != 0 && IS_MAX_LSN(td->visible_lsn)) {
  +		DB_ASSERT(dbenv, !is_commit);
   
  +		/*
  +		 * In the abort path, we need to make sure that the versions
  +		 * become visible to future transactions.  We need to set
  +		 * visible_lsn before setting td->status to ensure safe reads
  +		 * of visible_lsn in __memp_fget.
  +		 */
  +		if ((ret = __log_current_lsn(dbenv, &td->visible_lsn,
  +		    NULL, NULL)) != 0)
  +			return (__db_panic(dbenv, ret));
  +	}
  +
  +	TXN_SYSTEM_LOCK(dbenv);
   	td->status = is_commit ? TXN_COMMITTED : TXN_ABORTED;
   	SH_TAILQ_REMOVE(&region->active_txn, td, links, __txn_detail);
   	if (F_ISSET(td, TXN_DTL_RESTORED)) {
  @@ -1338,10 +1351,7 @@
   	if (txn->parent != NULL) {
   		ptd = txn->parent->td;
   		SH_TAILQ_REMOVE(&ptd->kids, td, klinks, __txn_detail);
  -	} else if ((mvcc_mtx = td->mvcc_mtx) != MUTEX_INVALID ||
  -	    td->mvcc_ref != 0) {
  -		if (IS_MAX_LSN(td->visible_lsn))
  -			td->visible_lsn = td->last_lsn;
  +	} else if ((mvcc_mtx = td->mvcc_mtx) != MUTEX_INVALID) {
   		MUTEX_LOCK(dbenv, mvcc_mtx);
   		if (td->mvcc_ref != 0) {
   			SH_TAILQ_INSERT_HEAD(&region->mvcc_txn,
  @@ .
  patch -p0 <<'@@ .'
  Index: db/txn/txn_util.c
  ============================================================================
  $ cvs diff -u -r1.7 -r1.8 txn_util.c
  --- db/txn/txn_util.c	29 Jul 2007 13:14:23 -0000	1.7
  +++ db/txn/txn_util.c	9 Oct 2007 22:50:09 -0000	1.8
  @@ -312,8 +312,10 @@
   				__os_free(dbenv, e->u.r.fileid);
   			__os_free(dbenv, e->u.r.name);
   			break;
  -		case TXN_CLOSE:
   		case TXN_TRADE:
  +			if (opcode == TXN_ABORT)
  +				e->u.t.dbp->cur_txn = NULL;
  +		case TXN_CLOSE:
   		case TXN_TRADED:
   		default:
   			break;
  @@ .
Received on Wed Oct 10 00:50:09 2007
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.