List:Commits« Previous MessageNext Message »
From:tim Date:January 18 2007 12:18am
Subject:bk commit into 5.1 tree (tsmith:1.2403)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of tsmith. When tsmith does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-01-17 17:18:10-07:00, tsmith@stripped +14 -0
  Merge siva.hindu.god:/home/tsmith/m/bk/mrg-jan17/50
  into  siva.hindu.god:/home/tsmith/m/bk/mrg-jan17/51
  MERGE: 1.1810.2368.66

  configure.in@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Auto merged
    MERGE: 1.245.1.175

  storage/innobase/buf/buf0buf.c@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -2
    Auto merged
    MERGE: 1.45.15.2

  storage/innobase/buf/buf0buf.c@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/buf/buf0buf.c -> storage/innobase/buf/buf0buf.c

  storage/innobase/buf/buf0flu.c@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +3 -2
    Auto merged
    MERGE: 1.28.4.2

  storage/innobase/buf/buf0flu.c@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/buf/buf0flu.c -> storage/innobase/buf/buf0flu.c

  storage/innobase/buf/buf0lru.c@stripped, 2007-01-17 17:18:03-07:00, tsmith@stripped +0 -0
    Auto merged
    MERGE: 1.24.4.2

  storage/innobase/buf/buf0lru.c@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/buf/buf0lru.c -> storage/innobase/buf/buf0lru.c

  storage/innobase/include/buf0buf.h@stripped, 2007-01-17 17:18:03-07:00, tsmith@stripped +0 -0
    Auto merged
    MERGE: 1.28.5.2

  storage/innobase/include/buf0buf.h@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/include/buf0buf.h -> storage/innobase/include/buf0buf.h

  storage/innobase/include/buf0buf.ic@stripped, 2007-01-17 17:18:03-07:00, tsmith@stripped +0 -4
    Auto merged
    MERGE: 1.17.8.2

  storage/innobase/include/buf0buf.ic@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/include/buf0buf.ic -> storage/innobase/include/buf0buf.ic

  storage/innobase/include/sync0arr.h@stripped, 2007-01-17 17:18:03-07:00, tsmith@stripped +0 -0
    Auto merged
    MERGE: 1.7.3.2

  storage/innobase/include/sync0arr.h@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/include/sync0arr.h -> storage/innobase/include/sync0arr.h

  storage/innobase/include/sync0rw.h@stripped, 2007-01-17 17:18:03-07:00, tsmith@stripped +0 -0
    Auto merged
    MERGE: 1.11.3.2

  storage/innobase/include/sync0rw.h@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/include/sync0rw.h -> storage/innobase/include/sync0rw.h

  storage/innobase/include/sync0rw.ic@stripped, 2007-01-17 17:18:03-07:00, tsmith@stripped +0 -0
    Auto merged
    MERGE: 1.9.5.2

  storage/innobase/include/sync0rw.ic@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/include/sync0rw.ic -> storage/innobase/include/sync0rw.ic

  storage/innobase/include/sync0sync.h@stripped, 2007-01-17 17:18:03-07:00, tsmith@stripped +0 -0
    Auto merged
    MERGE: 1.22.4.2

  storage/innobase/include/sync0sync.h@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/include/sync0sync.h -> storage/innobase/include/sync0sync.h

  storage/innobase/os/os0sync.c@stripped, 2007-01-17 17:18:03-07:00, tsmith@stripped +0 -0
    Auto merged
    MERGE: 1.24.6.2

  storage/innobase/os/os0sync.c@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/os/os0sync.c -> storage/innobase/os/os0sync.c

  storage/innobase/sync/sync0arr.c@stripped, 2007-01-17 17:18:03-07:00, tsmith@stripped +0 -0
    Auto merged
    MERGE: 1.20.3.2

  storage/innobase/sync/sync0arr.c@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/sync/sync0arr.c -> storage/innobase/sync/sync0arr.c

  storage/innobase/sync/sync0rw.c@stripped, 2007-01-17 17:18:03-07:00, tsmith@stripped +0 -0
    Auto merged
    MERGE: 1.19.3.2

  storage/innobase/sync/sync0rw.c@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/sync/sync0rw.c -> storage/innobase/sync/sync0rw.c

  storage/innobase/sync/sync0sync.c@stripped, 2007-01-17 17:18:03-07:00, tsmith@stripped +0 -0
    Auto merged
    MERGE: 1.34.5.2

  storage/innobase/sync/sync0sync.c@stripped, 2007-01-17 17:18:02-07:00, tsmith@stripped +0 -0
    Merge rename: innobase/sync/sync0sync.c -> storage/innobase/sync/sync0sync.c

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	tsmith
# Host:	siva.hindu.god
# Root:	/home/tsmith/m/bk/mrg-jan17/51/RESYNC

--- 1.45.15.1/innobase/buf/buf0buf.c	2007-01-17 16:44:04 -07:00
+++ 1.68/storage/innobase/buf/buf0buf.c	2007-01-17 17:18:02 -07:00
@@ -1,14 +1,14 @@
 /*   Innobase relational database engine; Copyright (C) 2001 Innobase Oy
-     
+
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License 2
      as published by the Free Software Foundation in June 1991.
-     
+
      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.
-     
+
      You should have received a copy of the GNU General Public License 2
      along with this program (in file COPYING); if not, write to the Free
      Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
@@ -42,7 +42,7 @@
 		IMPLEMENTATION OF THE BUFFER POOL
 		=================================
 
-Performance improvement: 
+Performance improvement:
 ------------------------
 Thread scheduling in NT may be so slow that the OS wait mechanism should
 not be used even in waiting for disk reads to complete.
@@ -160,8 +160,8 @@
 releases the X-lock on the frame and resets the io_fix field
 when the io operation completes.
 
-A thread may request the above operation using the buf_page_get-
-function. It may then continue to request a lock on the frame.
+A thread may request the above operation using the function
+buf_page_get(). It may then continue to request a lock on the frame.
 The lock is granted when the io-handler releases the x-lock.
 
 		Read-ahead
@@ -242,33 +242,33 @@
 ulint
 buf_calc_page_new_checksum(
 /*=======================*/
-		       /* out: checksum */
-	byte*    page) /* in: buffer page */
+			/* out: checksum */
+	byte*	 page)	/* in: buffer page */
 {
-  	ulint checksum;
+	ulint checksum;
 
-        /* Since the field FIL_PAGE_FILE_FLUSH_LSN, and in versions <= 4.1.x
-        ..._ARCH_LOG_NO, are written outside the buffer pool to the first
-        pages of data files, we have to skip them in the page checksum
-        calculation.
+	/* Since the field FIL_PAGE_FILE_FLUSH_LSN, and in versions <= 4.1.x
+	..._ARCH_LOG_NO, are written outside the buffer pool to the first
+	pages of data files, we have to skip them in the page checksum
+	calculation.
 	We must also skip the field FIL_PAGE_SPACE_OR_CHKSUM where the
 	checksum is stored, and also the last 8 bytes of page because
 	there we store the old formula checksum. */
-  	
-  	checksum = ut_fold_binary(page + FIL_PAGE_OFFSET,
-				 FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET)
-  		   + ut_fold_binary(page + FIL_PAGE_DATA, 
-				           UNIV_PAGE_SIZE - FIL_PAGE_DATA
-				           - FIL_PAGE_END_LSN_OLD_CHKSUM);
-  	checksum = checksum & 0xFFFFFFFFUL;
 
-  	return(checksum);
+	checksum = ut_fold_binary(page + FIL_PAGE_OFFSET,
+				  FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET)
+		+ ut_fold_binary(page + FIL_PAGE_DATA,
+				 UNIV_PAGE_SIZE - FIL_PAGE_DATA
+				 - FIL_PAGE_END_LSN_OLD_CHKSUM);
+	checksum = checksum & 0xFFFFFFFFUL;
+
+	return(checksum);
 }
 
 /************************************************************************
 In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
 looked at the first few bytes of the page. This calculates that old
-checksum. 
+checksum.
 NOTE: we must first store the new formula checksum to
 FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum
 because this takes that field as an input! */
@@ -276,16 +276,16 @@
 ulint
 buf_calc_page_old_checksum(
 /*=======================*/
-		       /* out: checksum */
-	byte*    page) /* in: buffer page */
+			/* out: checksum */
+	byte*	 page)	/* in: buffer page */
 {
-  	ulint checksum;
-  	
-  	checksum = ut_fold_binary(page, FIL_PAGE_FILE_FLUSH_LSN);
+	ulint checksum;
+
+	checksum = ut_fold_binary(page, FIL_PAGE_FILE_FLUSH_LSN);
 
-  	checksum = checksum & 0xFFFFFFFFUL;
+	checksum = checksum & 0xFFFFFFFFUL;
 
-  	return(checksum);
+	return(checksum);
 }
 
 /************************************************************************
@@ -305,7 +305,7 @@
 	dulint	current_lsn;
 #endif
 	if (mach_read_from_4(read_buf + FIL_PAGE_LSN + 4)
-	     != mach_read_from_4(read_buf + UNIV_PAGE_SIZE
+	    != mach_read_from_4(read_buf + UNIV_PAGE_SIZE
 				- FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
 
 		/* Stored log sequence numbers at the start and the end
@@ -318,63 +318,75 @@
 	if (recv_lsn_checks_on && log_peek_lsn(&current_lsn)) {
 		if (ut_dulint_cmp(current_lsn,
 				  mach_read_from_8(read_buf + FIL_PAGE_LSN))
-				 < 0) {
+		    < 0) {
 			ut_print_timestamp(stderr);
 
 			fprintf(stderr,
-"  InnoDB: Error: page %lu log sequence number %lu %lu\n"
-"InnoDB: is in the future! Current system log sequence number %lu %lu.\n"
-"InnoDB: Your database may be corrupt or you may have copied the InnoDB\n"
-"InnoDB: tablespace but not the InnoDB log files. See\n"
-"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html\n"
-"InnoDB: for more information.\n",
-		        (ulong) mach_read_from_4(read_buf + FIL_PAGE_OFFSET),
-			(ulong) ut_dulint_get_high(
-				mach_read_from_8(read_buf + FIL_PAGE_LSN)),
-			(ulong) ut_dulint_get_low(
-				mach_read_from_8(read_buf + FIL_PAGE_LSN)),
-			(ulong) ut_dulint_get_high(current_lsn),
-			(ulong) ut_dulint_get_low(current_lsn));
+				"  InnoDB: Error: page %lu log sequence number"
+				" %lu %lu\n"
+				"InnoDB: is in the future! Current system "
+				"log sequence number %lu %lu.\n"
+				"InnoDB: Your database may be corrupt or "
+				"you may have copied the InnoDB\n"
+				"InnoDB: tablespace but not the InnoDB "
+				"log files. See\n"
+				"InnoDB: http://dev.mysql.com/doc/refman/"
+				"5.1/en/forcing-recovery.html\n"
+				"InnoDB: for more information.\n",
+				(ulong) mach_read_from_4(read_buf
+							 + FIL_PAGE_OFFSET),
+				(ulong) ut_dulint_get_high
+				(mach_read_from_8(read_buf + FIL_PAGE_LSN)),
+				(ulong) ut_dulint_get_low
+				(mach_read_from_8(read_buf + FIL_PAGE_LSN)),
+				(ulong) ut_dulint_get_high(current_lsn),
+				(ulong) ut_dulint_get_low(current_lsn));
 		}
 	}
 #endif
-  
-  /* If we use checksums validation, make additional check before returning
-  TRUE to ensure that the checksum is not equal to BUF_NO_CHECKSUM_MAGIC which
-  might be stored by InnoDB with checksums disabled.
-     Otherwise, skip checksum calculation and return FALSE */
-  
-  if (srv_use_checksums) {
-    old_checksum = buf_calc_page_old_checksum(read_buf); 
-
-    old_checksum_field = mach_read_from_4(read_buf + UNIV_PAGE_SIZE
-					- FIL_PAGE_END_LSN_OLD_CHKSUM);
-
-    /* There are 2 valid formulas for old_checksum_field:
-	  1. Very old versions of InnoDB only stored 8 byte lsn to the start
-	  and the end of the page.
-	  2. Newer InnoDB versions store the old formula checksum there. */
-	
-    if (old_checksum_field != mach_read_from_4(read_buf + FIL_PAGE_LSN)
-        && old_checksum_field != old_checksum
-        && old_checksum_field != BUF_NO_CHECKSUM_MAGIC) {
-
-      return(TRUE);
-    }
-
-    checksum = buf_calc_page_new_checksum(read_buf);
-    checksum_field = mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM);
-
-    /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
-	  (always equal to 0), to FIL_PAGE_SPACE_SPACE_OR_CHKSUM */
-
-    if (checksum_field != 0 && checksum_field != checksum
-        && checksum_field != BUF_NO_CHECKSUM_MAGIC) {
-
-      return(TRUE);
-    }
-  }
-  
+
+	/* If we use checksums validation, make additional check before
+	returning TRUE to ensure that the checksum is not equal to
+	BUF_NO_CHECKSUM_MAGIC which might be stored by InnoDB with checksums
+	disabled. Otherwise, skip checksum calculation and return FALSE */
+
+	if (srv_use_checksums) {
+		old_checksum = buf_calc_page_old_checksum(read_buf);
+
+		old_checksum_field = mach_read_from_4(
+			read_buf + UNIV_PAGE_SIZE
+			- FIL_PAGE_END_LSN_OLD_CHKSUM);
+
+		/* There are 2 valid formulas for old_checksum_field:
+
+		1. Very old versions of InnoDB only stored 8 byte lsn to the
+		start and the end of the page.
+
+		2. Newer InnoDB versions store the old formula checksum
+		there. */
+
+		if (old_checksum_field != mach_read_from_4(read_buf
+							   + FIL_PAGE_LSN)
+		    && old_checksum_field != old_checksum
+		    && old_checksum_field != BUF_NO_CHECKSUM_MAGIC) {
+
+			return(TRUE);
+		}
+
+		checksum = buf_calc_page_new_checksum(read_buf);
+		checksum_field = mach_read_from_4(read_buf
+						  + FIL_PAGE_SPACE_OR_CHKSUM);
+
+		/* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
+		(always equal to 0), to FIL_PAGE_SPACE_SPACE_OR_CHKSUM */
+
+		if (checksum_field != 0 && checksum_field != checksum
+		    && checksum_field != BUF_NO_CHECKSUM_MAGIC) {
+
+			return(TRUE);
+		}
+	}
+
 	return(FALSE);
 }
 
@@ -396,65 +408,104 @@
 	ut_print_buf(stderr, read_buf, UNIV_PAGE_SIZE);
 	fputs("InnoDB: End of page dump\n", stderr);
 
-	checksum = srv_use_checksums ?
-    buf_calc_page_new_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
-	old_checksum = srv_use_checksums ?
-    buf_calc_page_old_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
+	checksum = srv_use_checksums
+		? buf_calc_page_new_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
+	old_checksum = srv_use_checksums
+		? buf_calc_page_old_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
 
 	ut_print_timestamp(stderr);
-	fprintf(stderr, 
-"  InnoDB: Page checksum %lu, prior-to-4.0.14-form checksum %lu\n"
-"InnoDB: stored checksum %lu, prior-to-4.0.14-form stored checksum %lu\n",
-			(ulong) checksum, (ulong) old_checksum,
-			(ulong) mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM),
-			(ulong) mach_read_from_4(read_buf + UNIV_PAGE_SIZE
-					- FIL_PAGE_END_LSN_OLD_CHKSUM));
 	fprintf(stderr,
-"InnoDB: Page lsn %lu %lu, low 4 bytes of lsn at page end %lu\n"
-"InnoDB: Page number (if stored to page already) %lu,\n"
-"InnoDB: space id (if created with >= MySQL-4.1.1 and stored already) %lu\n",
+		"  InnoDB: Page checksum %lu, prior-to-4.0.14-form"
+		" checksum %lu\n"
+		"InnoDB: stored checksum %lu, prior-to-4.0.14-form"
+		" stored checksum %lu\n"
+		"InnoDB: Page lsn %lu %lu, low 4 bytes of lsn"
+		" at page end %lu\n"
+		"InnoDB: Page number (if stored to page already) %lu,\n"
+		"InnoDB: space id (if created with >= MySQL-4.1.1"
+		" and stored already) %lu\n",
+		(ulong) checksum, (ulong) old_checksum,
+		(ulong) mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM),
+		(ulong) mach_read_from_4(read_buf + UNIV_PAGE_SIZE
+					 - FIL_PAGE_END_LSN_OLD_CHKSUM),
 		(ulong) mach_read_from_4(read_buf + FIL_PAGE_LSN),
 		(ulong) mach_read_from_4(read_buf + FIL_PAGE_LSN + 4),
 		(ulong) mach_read_from_4(read_buf + UNIV_PAGE_SIZE
-					- FIL_PAGE_END_LSN_OLD_CHKSUM + 4),
+					 - FIL_PAGE_END_LSN_OLD_CHKSUM + 4),
 		(ulong) mach_read_from_4(read_buf + FIL_PAGE_OFFSET),
-		(ulong) mach_read_from_4(read_buf + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID));
+		(ulong) mach_read_from_4(read_buf
+					 + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID));
 
 	if (mach_read_from_2(read_buf + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE)
 	    == TRX_UNDO_INSERT) {
-	    	fprintf(stderr,
+		fprintf(stderr,
 			"InnoDB: Page may be an insert undo log page\n");
 	} else if (mach_read_from_2(read_buf + TRX_UNDO_PAGE_HDR
-						+ TRX_UNDO_PAGE_TYPE)
-	    	== TRX_UNDO_UPDATE) {
-	    	fprintf(stderr,
+				    + TRX_UNDO_PAGE_TYPE)
+		   == TRX_UNDO_UPDATE) {
+		fprintf(stderr,
 			"InnoDB: Page may be an update undo log page\n");
 	}
 
-	if (fil_page_get_type(read_buf) == FIL_PAGE_INDEX) {
-	    	fprintf(stderr,
-"InnoDB: Page may be an index page where index id is %lu %lu\n",
-			(ulong) ut_dulint_get_high(btr_page_get_index_id(read_buf)),
-			(ulong) ut_dulint_get_low(btr_page_get_index_id(read_buf)));
+	switch (fil_page_get_type(read_buf)) {
+	case FIL_PAGE_INDEX:
+		fprintf(stderr,
+			"InnoDB: Page may be an index page where"
+			" index id is %lu %lu\n",
+			(ulong) ut_dulint_get_high
+			(btr_page_get_index_id(read_buf)),
+			(ulong) ut_dulint_get_low
+			(btr_page_get_index_id(read_buf)));
 
 		/* If the code is in ibbackup, dict_sys may be uninitialized,
 		i.e., NULL */
 
 		if (dict_sys != NULL) {
 
-		        index = dict_index_find_on_id_low(
-					btr_page_get_index_id(read_buf));
-		        if (index) {
+			index = dict_index_find_on_id_low(
+				btr_page_get_index_id(read_buf));
+			if (index) {
 				fputs("InnoDB: (", stderr);
 				dict_index_name_print(stderr, NULL, index);
 				fputs(")\n", stderr);
 			}
 		}
-	} else if (fil_page_get_type(read_buf) == FIL_PAGE_INODE) {
+		break;
+	case FIL_PAGE_INODE:
 		fputs("InnoDB: Page may be an 'inode' page\n", stderr);
-	} else if (fil_page_get_type(read_buf) == FIL_PAGE_IBUF_FREE_LIST) {
+		break;
+	case FIL_PAGE_IBUF_FREE_LIST:
 		fputs("InnoDB: Page may be an insert buffer free list page\n",
-			stderr);
+		      stderr);
+		break;
+	case FIL_PAGE_TYPE_ALLOCATED:
+		fputs("InnoDB: Page may be a freshly allocated page\n",
+		      stderr);
+		break;
+	case FIL_PAGE_IBUF_BITMAP:
+		fputs("InnoDB: Page may be an insert buffer bitmap page\n",
+		      stderr);
+		break;
+	case FIL_PAGE_TYPE_SYS:
+		fputs("InnoDB: Page may be a system page\n",
+		      stderr);
+		break;
+	case FIL_PAGE_TYPE_TRX_SYS:
+		fputs("InnoDB: Page may be a transaction system page\n",
+		      stderr);
+		break;
+	case FIL_PAGE_TYPE_FSP_HDR:
+		fputs("InnoDB: Page may be a file space header page\n",
+		      stderr);
+		break;
+	case FIL_PAGE_TYPE_XDES:
+		fputs("InnoDB: Page may be an extent descriptor page\n",
+		      stderr);
+		break;
+	case FIL_PAGE_TYPE_BLOB:
+		fputs("InnoDB: Page may be a BLOB page\n",
+		      stderr);
+		break;
 	}
 }
 
@@ -471,7 +522,7 @@
 	block->magic_n = 0;
 
 	block->state = BUF_BLOCK_NOT_USED;
-	
+
 	block->frame = frame;
 
 	block->awe_info = NULL;
@@ -480,7 +531,7 @@
 	block->io_fix = 0;
 
 	block->modify_clock = ut_dulint_zero;
-	
+
 	block->file_page_was_freed = FALSE;
 
 	block->check_index_page_at_flush = FALSE;
@@ -491,15 +542,13 @@
 
 	block->n_pointers = 0;
 
-	mutex_create(&block->mutex);
-	mutex_set_level(&block->mutex, SYNC_BUF_BLOCK);
+	mutex_create(&block->mutex, SYNC_BUF_BLOCK);
 
-	rw_lock_create(&(block->lock));
+	rw_lock_create(&block->lock, SYNC_LEVEL_VARYING);
 	ut_ad(rw_lock_validate(&(block->lock)));
 
 #ifdef UNIV_SYNC_DEBUG
-	rw_lock_create(&(block->debug_latch));
-	rw_lock_set_level(&(block->debug_latch), SYNC_NO_ORDER_CHECK);
+	rw_lock_create(&block->debug_latch, SYNC_NO_ORDER_CHECK);
 #endif /* UNIV_SYNC_DEBUG */
 }
 
@@ -525,15 +574,18 @@
 	byte*		frame;
 	ulint		i;
 	buf_block_t*	block;
-	
+
 	ut_a(max_size == curr_size);
 	ut_a(srv_use_awe || n_frames == max_size);
-	
+
 	if (n_frames > curr_size) {
-	        fprintf(stderr,
-"InnoDB: AWE: Error: you must specify in my.cnf .._awe_mem_mb larger\n"
-"InnoDB: than .._buffer_pool_size. Now the former is %lu pages,\n"
-"InnoDB: the latter %lu pages.\n", (ulong) curr_size, (ulong) n_frames);
+		fprintf(stderr,
+			"InnoDB: AWE: Error: you must specify in my.cnf"
+			" .._awe_mem_mb larger\n"
+			"InnoDB: than .._buffer_pool_size. Now the former"
+			" is %lu pages,\n"
+			"InnoDB: the latter %lu pages.\n",
+			(ulong) curr_size, (ulong) n_frames);
 
 		return(NULL);
 	}
@@ -541,9 +593,8 @@
 	buf_pool = mem_alloc(sizeof(buf_pool_t));
 
 	/* 1. Initialize general fields
-	   ---------------------------- */
-	mutex_create(&(buf_pool->mutex));
-	mutex_set_level(&(buf_pool->mutex), SYNC_BUF_POOL);
+	---------------------------- */
+	mutex_create(&buf_pool->mutex, SYNC_BUF_POOL);
 
 	mutex_enter(&(buf_pool->mutex));
 
@@ -553,31 +604,34 @@
 		buffer pool frames */
 
 		buf_pool->frame_mem = os_awe_allocate_virtual_mem_window(
-					UNIV_PAGE_SIZE * (n_frames + 1));
-					
+			UNIV_PAGE_SIZE * (n_frames + 1));
+
 		/* Allocate the physical memory for AWE and the AWE info array
 		for buf_pool */
 
 		if ((curr_size % ((1024 * 1024) / UNIV_PAGE_SIZE)) != 0) {
 
-		        fprintf(stderr,
-"InnoDB: AWE: Error: physical memory must be allocated in full megabytes.\n"
-"InnoDB: Trying to allocate %lu database pages.\n", 
-			  (ulong) curr_size);
+			fprintf(stderr,
+				"InnoDB: AWE: Error: physical memory must be"
+				" allocated in full megabytes.\n"
+				"InnoDB: Trying to allocate %lu"
+				" database pages.\n",
+				(ulong) curr_size);
 
-		        return(NULL);
+			return(NULL);
 		}
 
 		if (!os_awe_allocate_physical_mem(&(buf_pool->awe_info),
-			curr_size / ((1024 * 1024) / UNIV_PAGE_SIZE))) {
+						  curr_size
+						  / ((1024 * 1024)
+						     / UNIV_PAGE_SIZE))) {
 
 			return(NULL);
 		}
 		/*----------------------------------------*/
 	} else {
 		buf_pool->frame_mem = os_mem_alloc_large(
-					UNIV_PAGE_SIZE * (n_frames + 1),
-					TRUE, FALSE);
+			UNIV_PAGE_SIZE * (n_frames + 1), TRUE, FALSE);
 	}
 
 	if (buf_pool->frame_mem == NULL) {
@@ -610,14 +664,15 @@
 		the window */
 
 		os_awe_map_physical_mem_to_window(buf_pool->frame_zero,
-				n_frames *
-				(UNIV_PAGE_SIZE / OS_AWE_X86_PAGE_SIZE),
-					buf_pool->awe_info);
+						  n_frames
+						  * (UNIV_PAGE_SIZE
+						     / OS_AWE_X86_PAGE_SIZE),
+						  buf_pool->awe_info);
 		/*----------------------------------------*/
 	}
 
 	buf_pool->blocks_of_frames = ut_malloc(sizeof(void*) * n_frames);
-	
+
 	if (buf_pool->blocks_of_frames == NULL) {
 
 		return(NULL);
@@ -638,7 +693,7 @@
 		} else {
 			frame = NULL;
 		}
-		
+
 		buf_block_init(block, frame);
 
 		if (srv_use_awe) {
@@ -659,16 +714,16 @@
 	buf_pool->n_pages_written = 0;
 	buf_pool->n_pages_created = 0;
 	buf_pool->n_pages_awe_remapped = 0;
-	
+
 	buf_pool->n_page_gets = 0;
 	buf_pool->n_page_gets_old = 0;
 	buf_pool->n_pages_read_old = 0;
 	buf_pool->n_pages_written_old = 0;
 	buf_pool->n_pages_created_old = 0;
 	buf_pool->n_pages_awe_remapped_old = 0;
-	
+
 	/* 2. Initialize flushing fields
-	   ---------------------------- */
+	---------------------------- */
 	UT_LIST_INIT(buf_pool->flush_list);
 
 	for (i = BUF_FLUSH_LRU; i <= BUF_FLUSH_LIST; i++) {
@@ -681,9 +736,9 @@
 
 	buf_pool->ulint_clock = 1;
 	buf_pool->freed_page_clock = 0;
-	
+
 	/* 3. Initialize LRU fields
-	   ---------------------------- */
+	---------------------------- */
 	UT_LIST_INIT(buf_pool->LRU);
 
 	buf_pool->LRU_old = NULL;
@@ -707,9 +762,10 @@
 			if (srv_use_awe) {
 				/* Add to the list of blocks mapped to
 				frames */
-				
+
 				UT_LIST_ADD_LAST(awe_LRU_free_mapped,
-					buf_pool->awe_LRU_free_mapped, block);
+						 buf_pool->awe_LRU_free_mapped,
+						 block);
 			}
 		}
 
@@ -720,15 +776,15 @@
 	mutex_exit(&(buf_pool->mutex));
 
 	if (srv_use_adaptive_hash_indexes) {
-	  	btr_search_sys_create(
-			  curr_size * UNIV_PAGE_SIZE / sizeof(void*) / 64);
+		btr_search_sys_create(curr_size * UNIV_PAGE_SIZE
+				      / sizeof(void*) / 64);
 	} else {
-	        /* Create only a small dummy system */
-	        btr_search_sys_create(1000);
+		/* Create only a small dummy system */
+		btr_search_sys_create(1000);
 	}
 
 	return(buf_pool);
-}	
+}
 
 /************************************************************************
 Maps the page of block to a frame, if not mapped yet. Unmaps some page
@@ -761,7 +817,7 @@
 
 	bck = UT_LIST_GET_LAST(buf_pool->awe_LRU_free_mapped);
 
-	while (bck) {	
+	while (bck) {
 		ibool skip;
 
 		mutex_enter(&bck->mutex);
@@ -785,24 +841,25 @@
 			block->frame = bck->frame;
 
 			*(buf_pool->blocks_of_frames
-				+ (((ulint)(block->frame
-						- buf_pool->frame_zero))
-						>> UNIV_PAGE_SIZE_SHIFT))
+			  + (((ulint)(block->frame
+				      - buf_pool->frame_zero))
+			     >> UNIV_PAGE_SIZE_SHIFT))
 				= block;
-			
+
 			bck->frame = NULL;
 			UT_LIST_REMOVE(awe_LRU_free_mapped,
-					buf_pool->awe_LRU_free_mapped,
-					bck);
+				       buf_pool->awe_LRU_free_mapped,
+				       bck);
 
 			if (add_to_mapped_list) {
-				UT_LIST_ADD_FIRST(awe_LRU_free_mapped,
+				UT_LIST_ADD_FIRST(
+					awe_LRU_free_mapped,
 					buf_pool->awe_LRU_free_mapped,
 					block);
 			}
 
 			buf_pool->n_pages_awe_remapped++;
-			
+
 			mutex_exit(&bck->mutex);
 
 			return;
@@ -810,8 +867,8 @@
 	}
 
 	fprintf(stderr,
-"InnoDB: AWE: Fatal error: cannot find a page to unmap\n"
-"InnoDB: awe_LRU_free_mapped list length %lu\n",
+		"InnoDB: AWE: Fatal error: cannot find a page to unmap\n"
+		"InnoDB: awe_LRU_free_mapped list length %lu\n",
 		(ulong) UT_LIST_GET_LEN(buf_pool->awe_LRU_free_mapped));
 
 	ut_a(0);
@@ -850,7 +907,7 @@
 	/* Note that we read freed_page_clock's without holding any mutex:
 	this is allowed since the result is used only in heuristics */
 
-	if (buf_pool->freed_page_clock >= block->freed_page_clock 
+	if (buf_pool->freed_page_clock >= block->freed_page_clock
 				+ 1 + (buf_pool->curr_size / 4)) {
 
 		mutex_enter(&buf_pool->mutex);
@@ -869,11 +926,11 @@
 
 void
 buf_page_make_young(
-/*=================*/
+/*================*/
 	buf_frame_t*	frame)	/* in: buffer frame of a file page */
 {
 	buf_block_t*	block;
-	
+
 	mutex_enter(&(buf_pool->mutex));
 
 	block = buf_block_align(frame);
@@ -927,7 +984,7 @@
 {
 	buf_block_free(buf_block_align(frame));
 }
-	
+
 /************************************************************************
 Returns the buffer control block if the page can be found in the buffer
 pool. NOTE that it is possible that the page is not yet read
@@ -972,7 +1029,7 @@
 	if (block) {
 		block->check_index_page_at_flush = FALSE;
 	}
-	
+
 	mutex_exit(&(buf_pool->mutex));
 }
 
@@ -1108,7 +1165,7 @@
 	ulint		fix_type;
 	ibool		success;
 	ibool		must_read;
-	
+
 	ut_ad(mtr);
 	ut_ad((rw_latch == RW_S_LATCH)
 	      || (rw_latch == RW_X_LATCH)
@@ -1123,12 +1180,12 @@
 loop:
 	block = NULL;
 	mutex_enter_fast(&(buf_pool->mutex));
-	
+
 	if (guess) {
 		block = buf_block_align(guess);
 
 		if ((offset != block->offset) || (space != block->space)
-				|| (block->state != BUF_BLOCK_FILE_PAGE)) {
+		    || (block->state != BUF_BLOCK_FILE_PAGE)) {
 
 			block = NULL;
 		}
@@ -1165,7 +1222,7 @@
 	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 
 	must_read = FALSE;
-	
+
 	if (block->io_fix == BUF_IO_READ) {
 
 		must_read = TRUE;
@@ -1177,7 +1234,7 @@
 
 			return(NULL);
 		}
-	}		
+	}
 
 	/* If AWE is enabled and the page is not mapped to a frame, then
 	map it */
@@ -1188,10 +1245,10 @@
 		/* We set second parameter TRUE because the block is in the
 		LRU list and we must put it to awe_LRU_free_mapped list once
 		mapped to a frame */
-		
+
 		buf_awe_map_page_to_frame(block, TRUE);
 	}
-	
+
 #ifdef UNIV_SYNC_DEBUG
 	buf_block_buf_fix_inc_debug(block, file, line);
 #else
@@ -1211,7 +1268,7 @@
 
 #ifdef UNIV_DEBUG_FILE_ACCESSES
 	ut_a(block->file_page_was_freed == FALSE);
-#endif	
+#endif
 
 #ifdef UNIV_DEBUG
 	buf_dbg_counter++;
@@ -1226,12 +1283,12 @@
 	if (mode == BUF_GET_NOWAIT) {
 		if (rw_latch == RW_S_LATCH) {
 			success = rw_lock_s_lock_func_nowait(&(block->lock),
-								file, line);
+							     file, line);
 			fix_type = MTR_MEMO_PAGE_S_FIX;
 		} else {
 			ut_ad(rw_latch == RW_X_LATCH);
 			success = rw_lock_x_lock_func_nowait(&(block->lock),
-					file, line);
+							     file, line);
 			fix_type = MTR_MEMO_PAGE_X_FIX;
 		}
 
@@ -1243,29 +1300,29 @@
 			mutex_exit(&block->mutex);
 #ifdef UNIV_SYNC_DEBUG
 			rw_lock_s_unlock(&(block->debug_latch));
-#endif			
+#endif
 
 			return(NULL);
 		}
 	} else if (rw_latch == RW_NO_LATCH) {
 
 		if (must_read) {
-		        /* Let us wait until the read operation
+			/* Let us wait until the read operation
 			completes */
 
-		        for (;;) {
+			for (;;) {
 				mutex_enter(&block->mutex);
 
-		                if (block->io_fix == BUF_IO_READ) {
+				if (block->io_fix == BUF_IO_READ) {
 
 					mutex_exit(&block->mutex);
-				  
+
 					os_thread_sleep(WAIT_FOR_READ);
 				} else {
-				  
+
 					mutex_exit(&block->mutex);
 
-				       break;
+					break;
 				}
 			}
 		}
@@ -1294,7 +1351,7 @@
 #ifdef UNIV_IBUF_DEBUG
 	ut_a(ibuf_count_get(block->space, block->offset) == 0);
 #endif
-	return(block->frame);		
+	return(block->frame);
 }
 
 /************************************************************************
@@ -1352,17 +1409,17 @@
 
 	if (rw_latch == RW_S_LATCH) {
 		success = rw_lock_s_lock_func_nowait(&(block->lock),
-								file, line);
+						     file, line);
 		fix_type = MTR_MEMO_PAGE_S_FIX;
 	} else {
 		success = rw_lock_x_lock_func_nowait(&(block->lock),
-								file, line);
+						     file, line);
 		fix_type = MTR_MEMO_PAGE_X_FIX;
 	}
 
 	if (UNIV_UNLIKELY(!success)) {
 		mutex_enter(&block->mutex);
-		
+
 		block->buf_fix_count--;
 
 		mutex_exit(&block->mutex);
@@ -1384,7 +1441,7 @@
 		}
 
 		mutex_enter(&block->mutex);
-		
+
 		block->buf_fix_count--;
 
 		mutex_exit(&block->mutex);
@@ -1415,7 +1472,7 @@
 		read-ahead */
 
 		buf_read_ahead_linear(buf_frame_get_space_id(guess),
-					buf_frame_get_page_no(guess));
+				      buf_frame_get_page_no(guess));
 	}
 
 #ifdef UNIV_IBUF_DEBUG
@@ -1448,14 +1505,14 @@
 
 	ut_ad(mtr);
 	ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
-	
+
 	block = buf_block_align(guess);
 
 	mutex_enter(&block->mutex);
 
 	if (block->state == BUF_BLOCK_REMOVE_HASH) {
-	        /* Another thread is just freeing the block from the LRU list
-	        of the buffer pool: do not try to access this page; this
+		/* Another thread is just freeing the block from the LRU list
+		of the buffer pool: do not try to access this page; this
 		attempt to access the page can only come through the hash
 		index because when the buffer block state is ..._REMOVE_HASH,
 		we have already removed it from the page address hash table
@@ -1483,24 +1540,24 @@
 
 	if (rw_latch == RW_S_LATCH) {
 		success = rw_lock_s_lock_func_nowait(&(block->lock),
-								file, line);
+						     file, line);
 		fix_type = MTR_MEMO_PAGE_S_FIX;
 	} else {
 		success = rw_lock_x_lock_func_nowait(&(block->lock),
-								file, line);
+						     file, line);
 		fix_type = MTR_MEMO_PAGE_X_FIX;
 	}
-	
+
 	if (!success) {
 		mutex_enter(&block->mutex);
-		
+
 		block->buf_fix_count--;
 
 		mutex_exit(&block->mutex);
 
 #ifdef UNIV_SYNC_DEBUG
 		rw_lock_s_unlock(&(block->debug_latch));
-#endif		
+#endif
 
 		return(FALSE);
 	}
@@ -1522,7 +1579,7 @@
 
 #ifdef UNIV_IBUF_DEBUG
 	ut_a((mode == BUF_KEEP_OLD)
-		|| (ibuf_count_get(block->space, block->offset) == 0));
+	     || (ibuf_count_get(block->space, block->offset) == 0));
 #endif
 	buf_pool->n_page_gets++;
 
@@ -1543,9 +1600,9 @@
 	/* Set the state of the block */
 	block->magic_n		= BUF_BLOCK_MAGIC_N;
 
-	block->state 		= BUF_BLOCK_FILE_PAGE;
-	block->space 		= space;
-	block->offset 		= offset;
+	block->state		= BUF_BLOCK_FILE_PAGE;
+	block->space		= space;
+	block->offset		= offset;
 
 	block->lock_hash_val	= 0;
 
@@ -1553,16 +1610,16 @@
 
 	block->newest_modification = ut_dulint_zero;
 	block->oldest_modification = ut_dulint_zero;
-	
+
 	block->accessed		= FALSE;
-	block->buf_fix_count 	= 0;
+	block->buf_fix_count	= 0;
 	block->io_fix		= 0;
 
 	block->n_hash_helps	= 0;
 	block->is_hashed	= FALSE;
-	block->n_fields         = 1;
-	block->n_bytes          = 0;
-	block->side             = BTR_SEARCH_LEFT_SIDE;
+	block->n_fields		= 1;
+	block->n_bytes		= 0;
+	block->left_side	= TRUE;
 
 	block->file_page_was_freed = FALSE;
 }
@@ -1587,48 +1644,49 @@
 	/* Set the state of the block */
 	block->magic_n		= BUF_BLOCK_MAGIC_N;
 
-	block->state 		= BUF_BLOCK_FILE_PAGE;
-	block->space 		= space;
-	block->offset 		= offset;
+	block->state		= BUF_BLOCK_FILE_PAGE;
+	block->space		= space;
+	block->offset		= offset;
 
 	block->check_index_page_at_flush = FALSE;
 	block->index		= NULL;
-	
+
 	block->lock_hash_val	= lock_rec_hash(space, offset);
 
 	/* Insert into the hash table of file pages */
 
-        if (buf_page_hash_get(space, offset)) {
-                fprintf(stderr,
-"InnoDB: Error: page %lu %lu already found from the hash table\n",
+	if (buf_page_hash_get(space, offset)) {
+		fprintf(stderr,
+			"InnoDB: Error: page %lu %lu already found"
+			" in the hash table\n",
 			(ulong) space,
 			(ulong) offset);
 #ifdef UNIV_DEBUG
-                buf_print();
-                buf_LRU_print();
-                buf_validate();
-                buf_LRU_validate();
+		buf_print();
+		buf_LRU_print();
+		buf_validate();
+		buf_LRU_validate();
 #endif /* UNIV_DEBUG */
-                ut_a(0);
-        }
+		ut_a(0);
+	}
 
 	HASH_INSERT(buf_block_t, hash, buf_pool->page_hash,
-				buf_page_address_fold(space, offset), block);
+		    buf_page_address_fold(space, offset), block);
 
 	block->freed_page_clock = 0;
 
 	block->newest_modification = ut_dulint_zero;
 	block->oldest_modification = ut_dulint_zero;
-	
+
 	block->accessed		= FALSE;
-	block->buf_fix_count 	= 0;
+	block->buf_fix_count	= 0;
 	block->io_fix		= 0;
 
 	block->n_hash_helps	= 0;
 	block->is_hashed	= FALSE;
-	block->n_fields         = 1;
-	block->n_bytes          = 0;
-	block->side             = BTR_SEARCH_LEFT_SIDE;
+	block->n_fields		= 1;
+	block->n_bytes		= 0;
+	block->left_side	= TRUE;
 
 	block->file_page_was_freed = FALSE;
 }
@@ -1643,7 +1701,7 @@
 on the buffer frame. The io-handler must take care that the flag is cleared
 and the lock released later. This is one of the functions which perform the
 state transition NOT_USED => FILE_PAGE to a block (the other is
-buf_page_create). */ 
+buf_page_create). */
 
 buf_block_t*
 buf_page_init_for_read(
@@ -1669,9 +1727,9 @@
 
 		ut_ad(!ibuf_bitmap_page(offset));
 		ut_ad(ibuf_inside());
-	
+
 		mtr_start(&mtr);
-	
+
 		if (!ibuf_page_low(space, offset, &mtr)) {
 
 			mtr_commit(&mtr);
@@ -1681,7 +1739,7 @@
 	} else {
 		ut_ad(mode == BUF_READ_ANY_PAGE);
 	}
-	
+
 	block = buf_block_alloc();
 
 	ut_a(block);
@@ -1689,16 +1747,17 @@
 	mutex_enter(&(buf_pool->mutex));
 	mutex_enter(&block->mutex);
 
-	if (fil_tablespace_deleted_or_being_deleted_in_mem(space,
-							tablespace_version)) {
+	if (fil_tablespace_deleted_or_being_deleted_in_mem(
+		    space, tablespace_version)) {
 		*err = DB_TABLESPACE_DELETED;
 	}
 
 	if (*err == DB_TABLESPACE_DELETED
 	    || NULL != buf_page_hash_get(space, offset)) {
 
-		/* The page belongs to a space which has been deleted or is
-		being deleted, or the page is already in buf_pool, return */
+		/* The page belongs to a space which has been
+		deleted or is being deleted, or the page is
+		already in buf_pool, return */
 
 		mutex_exit(&block->mutex);
 		mutex_exit(&(buf_pool->mutex));
@@ -1714,28 +1773,28 @@
 	}
 
 	ut_ad(block);
-	
+
 	buf_page_init(space, offset, block);
 
 	/* The block must be put to the LRU list, to the old blocks */
 
-	buf_LRU_add_block(block, TRUE); 	/* TRUE == to old blocks */
-	
+	buf_LRU_add_block(block, TRUE);		/* TRUE == to old blocks */
+
 	block->io_fix = BUF_IO_READ;
 
 	buf_pool->n_pend_reads++;
-	
+
 	/* We set a pass-type x-lock on the frame because then the same
 	thread which called for the read operation (and is running now at
 	this point of code) can wait for the read to complete by waiting
 	for the x-lock on the frame; if the x-lock were recursive, the
 	same thread would illegally get the x-lock before the page read
 	is completed. The x-lock is cleared by the io-handler thread. */
-	
+
 	rw_lock_x_lock_gen(&(block->lock), BUF_IO_READ);
-	
+
 	mutex_exit(&block->mutex);
- 	mutex_exit(&(buf_pool->mutex));
+	mutex_exit(&(buf_pool->mutex));
 
 	if (mode == BUF_READ_IBUF_PAGES_ONLY) {
 
@@ -1743,7 +1802,7 @@
 	}
 
 	return(block);
-}	
+}
 
 /************************************************************************
 Initializes a page to the buffer buf_pool. The page is usually not read
@@ -1763,11 +1822,11 @@
 	buf_frame_t*	frame;
 	buf_block_t*	block;
 	buf_block_t*	free_block	= NULL;
-	
+
 	ut_ad(mtr);
 
 	free_block = buf_LRU_get_free_block();
-	
+
 	mutex_enter(&(buf_pool->mutex));
 
 	block = buf_page_hash_get(space, offset);
@@ -1798,14 +1857,14 @@
 #endif /* UNIV_DEBUG */
 
 	block = free_block;
-	
+
 	mutex_enter(&block->mutex);
 
 	buf_page_init(space, offset, block);
 
 	/* The block must be put to the LRU list */
 	buf_LRU_add_block(block, FALSE);
-		
+
 #ifdef UNIV_SYNC_DEBUG
 	buf_block_buf_fix_inc_debug(block, __FILE__, __LINE__);
 #else
@@ -1818,7 +1877,7 @@
 	mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
 
 	block->accessed = TRUE;
-	
+
 	mutex_exit(&block->mutex);
 
 	/* Delete possible entries for the page from the insert buffer:
@@ -1831,6 +1890,10 @@
 
 	frame = block->frame;
 
+	memset(frame + FIL_PAGE_PREV, 0xff, 4);
+	memset(frame + FIL_PAGE_NEXT, 0xff, 4);
+	mach_write_to_2(frame + FIL_PAGE_TYPE, FIL_PAGE_TYPE_ALLOCATED);
+
 	/* Reset to zero the file flush lsn field in the page; if the first
 	page of an ibdata file is 'created' in this function into the buffer
 	pool then we lose the original contents of the file flush lsn stamp.
@@ -1862,8 +1925,7 @@
 	buf_block_t*	block)	/* in: pointer to the block in question */
 {
 	ulint		io_type;
-	ulint		read_page_no;
-	
+
 	ut_ad(block);
 
 	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
@@ -1878,70 +1940,103 @@
 
 	if (io_type == BUF_IO_READ) {
 		/* If this page is not uninitialized and not in the
-		doublewrite buffer, then the page number should be the
-		same as in block */
+		doublewrite buffer, then the page number and space id
+		should be the same as in block. */
+		ulint	read_page_no = mach_read_from_4(
+			block->frame + FIL_PAGE_OFFSET);
+		ulint	read_space_id = mach_read_from_4(
+			block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
 
-		read_page_no = mach_read_from_4((block->frame)
-						+ FIL_PAGE_OFFSET);
-		if (read_page_no != 0
-			&& !trx_doublewrite_page_inside(read_page_no)
-	    		&& read_page_no != block->offset) {
+		if (!block->space
+		    && trx_doublewrite_page_inside(block->offset)) {
 
+			ut_print_timestamp(stderr);
+			fprintf(stderr,
+				"  InnoDB: Error: reading page %lu\n"
+				"InnoDB: which is in the"
+				" doublewrite buffer!\n",
+				(ulong) block->offset);
+		} else if (!read_space_id && !read_page_no) {
+			/* This is likely an uninitialized page. */
+		} else if ((block->space && block->space != read_space_id)
+			   || block->offset != read_page_no) {
+			/* We did not compare space_id to read_space_id
+			if block->space == 0, because the field on the
+			page may contain garbage in MySQL < 4.1.1,
+			which only supported block->space == 0. */
+
+			ut_print_timestamp(stderr);
 			fprintf(stderr,
-"InnoDB: Error: page n:o stored in the page read in is %lu, should be %lu!\n",
-				(ulong) read_page_no, (ulong) block->offset);
+				"  InnoDB: Error: space id and page n:o"
+				" stored in the page\n"
+				"InnoDB: read in are %lu:%lu,"
+				" should be %lu:%lu!\n",
+				(ulong) read_space_id, (ulong) read_page_no,
+				(ulong) block->space, (ulong) block->offset);
 		}
 		/* From version 3.23.38 up we store the page checksum
-		   to the 4 first bytes of the page end lsn field */
+		to the 4 first bytes of the page end lsn field */
 
 		if (buf_page_is_corrupted(block->frame)) {
-		  	fprintf(stderr,
-		"InnoDB: Database page corruption on disk or a failed\n"
-		"InnoDB: file read of page %lu.\n", (ulong) block->offset);
-			  
-			fputs(
-		"InnoDB: You may have to recover from a backup.\n", stderr);
+			fprintf(stderr,
+				"InnoDB: Database page corruption on disk"
+				" or a failed\n"
+				"InnoDB: file read of page %lu.\n",
+				(ulong) block->offset);
+
+			fputs("InnoDB: You may have to recover"
+			      " from a backup.\n", stderr);
 
 			buf_page_print(block->frame);
 
-		  	fprintf(stderr,
-		"InnoDB: Database page corruption on disk or a failed\n"
-		"InnoDB: file read of page %lu.\n", (ulong) block->offset);
-			fputs(
-		"InnoDB: You may have to recover from a backup.\n", stderr);
-			fputs(
-		"InnoDB: It is also possible that your operating\n"
-		"InnoDB: system has corrupted its own file cache\n"
-		"InnoDB: and rebooting your computer removes the\n"
-		"InnoDB: error.\n"
-		"InnoDB: If the corrupt page is an index page\n"
-		"InnoDB: you can also try to fix the corruption\n"
-		"InnoDB: by dumping, dropping, and reimporting\n"
-		"InnoDB: the corrupt table. You can use CHECK\n"
-		"InnoDB: TABLE to scan your table for corruption.\n"
-		"InnoDB: See also "
-"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html\n"
-		"InnoDB: about forcing recovery.\n", stderr);
-			  
+			fprintf(stderr,
+				"InnoDB: Database page corruption on disk"
+				" or a failed\n"
+				"InnoDB: file read of page %lu.\n",
+				(ulong) block->offset);
+			fputs("InnoDB: You may have to recover"
+			      " from a backup.\n", stderr);
+			fputs("InnoDB: It is also possible that"
+			      " your operating\n"
+			      "InnoDB: system has corrupted its"
+			      " own file cache\n"
+			      "InnoDB: and rebooting your computer"
+			      " removes the\n"
+			      "InnoDB: error.\n"
+			      "InnoDB: If the corrupt page is an index page\n"
+			      "InnoDB: you can also try to"
+			      " fix the corruption\n"
+			      "InnoDB: by dumping, dropping,"
+			      " and reimporting\n"
+			      "InnoDB: the corrupt table."
+			      " You can use CHECK\n"
+			      "InnoDB: TABLE to scan your"
+			      " table for corruption.\n"
+			      "InnoDB: See also"
+			      " http://dev.mysql.com/doc/refman/5.1/en/"
+			      "forcing-recovery.html\n"
+			      "InnoDB: about forcing recovery.\n", stderr);
+
 			if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) {
-				fputs(
-	"InnoDB: Ending processing because of a corrupt database page.\n",
-					stderr);
-		  		exit(1);
-		  	}
+				fputs("InnoDB: Ending processing because of"
+				      " a corrupt database page.\n",
+				      stderr);
+				exit(1);
+			}
 		}
 
 		if (recv_recovery_is_on()) {
 			recv_recover_page(FALSE, TRUE, block->frame,
-						block->space, block->offset);
+					  block->space, block->offset);
 		}
 
 		if (!recv_no_ibuf_operations) {
-			ibuf_merge_or_delete_for_page(block->frame,
-					block->space, block->offset, TRUE);
+			ibuf_merge_or_delete_for_page(
+				block->frame, block->space, block->offset,
+				TRUE);
 		}
 	}
-	
+
 	mutex_enter(&(buf_pool->mutex));
 	mutex_enter(&block->mutex);
 
@@ -1954,12 +2049,12 @@
 	id. */
 
 	block->io_fix = 0;
-	
+
 	if (io_type == BUF_IO_READ) {
 		/* NOTE that the call to ibuf may have moved the ownership of
 		the x-latch to this OS thread: do not let this confuse you in
-		debugging! */		
-	
+		debugging! */
+
 		ut_ad(buf_pool->n_pend_reads > 0);
 		buf_pool->n_pend_reads--;
 		buf_pool->n_pages_read++;
@@ -1989,7 +2084,7 @@
 		}
 #endif /* UNIV_DEBUG */
 	}
-	
+
 	mutex_exit(&block->mutex);
 	mutex_exit(&(buf_pool->mutex));
 
@@ -2013,13 +2108,13 @@
 	ibool	freed;
 
 	ut_ad(buf_all_freed());
-	
+
 	freed = TRUE;
 
 	while (freed) {
 		freed = buf_LRU_search_and_free_block(100);
 	}
-	
+
 	mutex_enter(&(buf_pool->mutex));
 
 	ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
@@ -2044,7 +2139,7 @@
 	ulint		n_flush		= 0;
 	ulint		n_free		= 0;
 	ulint		n_page		= 0;
-	
+
 	ut_ad(buf_pool);
 
 	mutex_enter(&(buf_pool->mutex));
@@ -2058,25 +2153,26 @@
 		if (block->state == BUF_BLOCK_FILE_PAGE) {
 
 			ut_a(buf_page_hash_get(block->space,
-						block->offset) == block);
+					       block->offset) == block);
 			n_page++;
 
 #ifdef UNIV_IBUF_DEBUG
 			ut_a((block->io_fix == BUF_IO_READ)
 			     || ibuf_count_get(block->space, block->offset)
-								== 0);
+			     == 0);
 #endif
 			if (block->io_fix == BUF_IO_WRITE) {
 
 				if (block->flush_type == BUF_FLUSH_LRU) {
 					n_lru_flush++;
-					ut_a(rw_lock_is_locked(&(block->lock),
-							RW_LOCK_SHARED));
-				} else if (block->flush_type ==
-						BUF_FLUSH_LIST) {
+					ut_a(rw_lock_is_locked(
+						     &block->lock,
+						     RW_LOCK_SHARED));
+				} else if (block->flush_type
+					   == BUF_FLUSH_LIST) {
 					n_list_flush++;
-				} else if (block->flush_type ==
-						BUF_FLUSH_SINGLE_PAGE) {
+				} else if (block->flush_type
+					   == BUF_FLUSH_SINGLE_PAGE) {
 					n_single_flush++;
 				} else {
 					ut_error;
@@ -2085,32 +2181,34 @@
 			} else if (block->io_fix == BUF_IO_READ) {
 
 				ut_a(rw_lock_is_locked(&(block->lock),
-							RW_LOCK_EX));
+						       RW_LOCK_EX));
 			}
-			
+
 			n_lru++;
 
 			if (ut_dulint_cmp(block->oldest_modification,
-						ut_dulint_zero) > 0) {
-					n_flush++;
-			}	
-		
+					  ut_dulint_zero) > 0) {
+				n_flush++;
+			}
+
 		} else if (block->state == BUF_BLOCK_NOT_USED) {
 			n_free++;
 		}
 
 		mutex_exit(&block->mutex);
- 	}
+	}
 
 	if (n_lru + n_free > buf_pool->curr_size) {
-		fprintf(stderr, "n LRU %lu, n free %lu\n", (ulong) n_lru, (ulong) n_free);
+		fprintf(stderr, "n LRU %lu, n free %lu\n",
+			(ulong) n_lru, (ulong) n_free);
 		ut_error;
 	}
 
 	ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == n_lru);
 	if (UT_LIST_GET_LEN(buf_pool->free) != n_free) {
 		fprintf(stderr, "Free list len %lu, free blocks %lu\n",
-			(ulong) UT_LIST_GET_LEN(buf_pool->free), (ulong) n_free);
+			(ulong) UT_LIST_GET_LEN(buf_pool->free),
+			(ulong) n_free);
 		ut_error;
 	}
 	ut_a(UT_LIST_GET_LEN(buf_pool->flush_list) == n_flush);
@@ -2118,14 +2216,14 @@
 	ut_a(buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE] == n_single_flush);
 	ut_a(buf_pool->n_flush[BUF_FLUSH_LIST] == n_list_flush);
 	ut_a(buf_pool->n_flush[BUF_FLUSH_LRU] == n_lru_flush);
-	
+
 	mutex_exit(&(buf_pool->mutex));
 
 	ut_a(buf_LRU_validate());
 	ut_a(buf_flush_validate());
 
 	return(TRUE);
-}	
+}
 
 /*************************************************************************
 Prints info of the buffer buf_pool data structure. */
@@ -2141,9 +2239,9 @@
 	ulint		j;
 	dulint		id;
 	ulint		n_found;
-	buf_frame_t* 	frame;
+	buf_frame_t*	frame;
 	dict_index_t*	index;
-	
+
 	ut_ad(buf_pool);
 
 	size = buf_pool->curr_size;
@@ -2152,7 +2250,7 @@
 	counts = mem_alloc(sizeof(ulint) * size);
 
 	mutex_enter(&(buf_pool->mutex));
-	
+
 	fprintf(stderr,
 		"buf_pool size %lu\n"
 		"database pages %lu\n"
@@ -2173,7 +2271,7 @@
 		(ulong) buf_pool->n_pages_written);
 
 	/* Count the number of blocks belonging to each index in the buffer */
-	
+
 	n_found = 0;
 
 	for (i = 0; i < size; i++) {
@@ -2211,8 +2309,8 @@
 
 		fprintf(stderr,
 			"Block count for index %lu in buffer is about %lu",
-		       (ulong) ut_dulint_get_low(index_ids[i]),
-		       (ulong) counts[i]);
+			(ulong) ut_dulint_get_low(index_ids[i]),
+			(ulong) counts[i]);
 
 		if (index) {
 			putc(' ', stderr);
@@ -2221,12 +2319,12 @@
 
 		putc('\n', stderr);
 	}
-	
+
 	mem_free(index_ids);
 	mem_free(counts);
 
 	ut_a(buf_validate());
-}	
+}
 #endif /* UNIV_DEBUG */
 
 /*************************************************************************
@@ -2235,13 +2333,13 @@
 ulint
 buf_get_latched_pages_number(void)
 {
-        buf_block_t* block;
-        ulint i;
-        ulint fixed_pages_number = 0;
+	buf_block_t*	block;
+	ulint		i;
+	ulint		fixed_pages_number = 0;
 
-        mutex_enter(&(buf_pool->mutex));
+	mutex_enter(&(buf_pool->mutex));
 
-        for (i = 0; i < buf_pool->curr_size; i++) {
+	for (i = 0; i < buf_pool->curr_size; i++) {
 
 		block = buf_pool_get_nth_block(buf_pool, i);
 
@@ -2254,10 +2352,11 @@
 
 			mutex_exit(&block->mutex);
 		}
-        }
+	}
+
+	mutex_exit(&(buf_pool->mutex));
 
-        mutex_exit(&(buf_pool->mutex));
-        return fixed_pages_number;
+	return(fixed_pages_number);
 }
 
 /*************************************************************************
@@ -2268,9 +2367,9 @@
 /*=======================*/
 {
 	return(buf_pool->n_pend_reads
-		+ buf_pool->n_flush[BUF_FLUSH_LRU]
-		+ buf_pool->n_flush[BUF_FLUSH_LIST]
-		+ buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);
+	       + buf_pool->n_flush[BUF_FLUSH_LRU]
+	       + buf_pool->n_flush[BUF_FLUSH_LIST]
+	       + buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);
 }
 
 /*************************************************************************
@@ -2286,10 +2385,10 @@
 	mutex_enter(&(buf_pool->mutex));
 
 	ratio = (100 * UT_LIST_GET_LEN(buf_pool->flush_list))
-		     / (1 + UT_LIST_GET_LEN(buf_pool->LRU)
-		        + UT_LIST_GET_LEN(buf_pool->free));
+		/ (1 + UT_LIST_GET_LEN(buf_pool->LRU)
+		   + UT_LIST_GET_LEN(buf_pool->free));
 
-		       /* 1 + is there to avoid division by zero */   
+	/* 1 + is there to avoid division by zero */
 
 	mutex_exit(&(buf_pool->mutex));
 
@@ -2307,20 +2406,22 @@
 	time_t	current_time;
 	double	time_elapsed;
 	ulint	size;
-	
+
 	ut_ad(buf_pool);
 	size = buf_pool->curr_size;
 
 	mutex_enter(&(buf_pool->mutex));
-	
+
 	if (srv_use_awe) {
 		fprintf(stderr,
-		"AWE: Buffer pool memory frames                        %lu\n",
-				(ulong) buf_pool->n_frames);
-		
+			"AWE: Buffer pool memory frames %lu\n",
+			(ulong) buf_pool->n_frames);
+
 		fprintf(stderr,
-		"AWE: Database pages and free buffers mapped in frames %lu\n",
-				(ulong) UT_LIST_GET_LEN(buf_pool->awe_LRU_free_mapped));
+			"AWE: Database pages and free buffers"
+			" mapped in frames %lu\n",
+			(ulong)
+			UT_LIST_GET_LEN(buf_pool->awe_LRU_free_mapped));
 	}
 	fprintf(file,
 		"Buffer pool size   %lu\n"
@@ -2335,14 +2436,14 @@
 		(ulong) UT_LIST_GET_LEN(buf_pool->flush_list),
 		(ulong) buf_pool->n_pend_reads,
 		(ulong) buf_pool->n_flush[BUF_FLUSH_LRU]
-			+ buf_pool->init_flush[BUF_FLUSH_LRU],
+		+ buf_pool->init_flush[BUF_FLUSH_LRU],
 		(ulong) buf_pool->n_flush[BUF_FLUSH_LIST]
-			+ buf_pool->init_flush[BUF_FLUSH_LIST],
+		+ buf_pool->init_flush[BUF_FLUSH_LIST],
 		(ulong) buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);
 
 	current_time = time(NULL);
 	time_elapsed = 0.001 + difftime(current_time,
-						buf_pool->last_printout_time);
+					buf_pool->last_printout_time);
 	buf_pool->last_printout_time = current_time;
 
 	fprintf(file,
@@ -2360,20 +2461,21 @@
 
 	if (srv_use_awe) {
 		fprintf(file, "AWE: %.2f page remaps/s\n",
-		(buf_pool->n_pages_awe_remapped
-				- buf_pool->n_pages_awe_remapped_old)
+			(buf_pool->n_pages_awe_remapped
+			 - buf_pool->n_pages_awe_remapped_old)
 			/ time_elapsed);
 	}
-		
+
 	if (buf_pool->n_page_gets > buf_pool->n_page_gets_old) {
 		fprintf(file, "Buffer pool hit rate %lu / 1000\n",
-       (ulong) (1000
-		- ((1000 *
-		    (buf_pool->n_pages_read - buf_pool->n_pages_read_old))
-		/ (buf_pool->n_page_gets - buf_pool->n_page_gets_old))));
+			(ulong)
+			(1000 - ((1000 * (buf_pool->n_pages_read
+					  - buf_pool->n_pages_read_old))
+				 / (buf_pool->n_page_gets
+				    - buf_pool->n_page_gets_old))));
 	} else {
 		fputs("No buffer pool page gets since the last printout\n",
-			file);
+		      file);
 	}
 
 	buf_pool->n_page_gets_old = buf_pool->n_page_gets;
@@ -2392,12 +2494,12 @@
 buf_refresh_io_stats(void)
 /*======================*/
 {
-        buf_pool->last_printout_time = time(NULL);
+	buf_pool->last_printout_time = time(NULL);
 	buf_pool->n_page_gets_old = buf_pool->n_page_gets;
 	buf_pool->n_pages_read_old = buf_pool->n_pages_read;
 	buf_pool->n_pages_created_old = buf_pool->n_pages_created;
 	buf_pool->n_pages_written_old = buf_pool->n_pages_written;
-	buf_pool->n_pages_awe_remapped_old = buf_pool->n_pages_awe_remapped; 
+	buf_pool->n_pages_awe_remapped_old = buf_pool->n_pages_awe_remapped;
 }
 
 /*************************************************************************
@@ -2409,7 +2511,7 @@
 {
 	buf_block_t*	block;
 	ulint		i;
-	
+
 	ut_ad(buf_pool);
 
 	mutex_enter(&(buf_pool->mutex));
@@ -2428,17 +2530,17 @@
 					"Page %lu %lu still fixed or dirty\n",
 					(ulong) block->space,
 					(ulong) block->offset);
-			    	ut_error;
+				ut_error;
 			}
 		}
 
 		mutex_exit(&block->mutex);
- 	}
+	}
 
 	mutex_exit(&(buf_pool->mutex));
 
 	return(TRUE);
-}	
+}
 
 /*************************************************************************
 Checks that there currently are no pending i/o-operations for the buffer
@@ -2454,8 +2556,8 @@
 	mutex_enter(&(buf_pool->mutex));
 
 	if (buf_pool->n_pend_reads + buf_pool->n_flush[BUF_FLUSH_LRU]
-				+ buf_pool->n_flush[BUF_FLUSH_LIST]
-				+ buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]) {
+	    + buf_pool->n_flush[BUF_FLUSH_LIST]
+	    + buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]) {
 		ret = FALSE;
 	} else {
 		ret = TRUE;

--- 1.28.4.1/innobase/buf/buf0flu.c	2007-01-17 16:44:04 -07:00
+++ 1.39/storage/innobase/buf/buf0flu.c	2007-01-17 17:18:02 -07:00
@@ -26,11 +26,11 @@
 #include "trx0sys.h"
 #include "srv0srv.h"
 
-/* When flushed, dirty blocks are searched in neigborhoods of this size, and
+/* When flushed, dirty blocks are searched in neighborhoods of this size, and
 flushed along with the original page. */
 
 #define BUF_FLUSH_AREA		ut_min(BUF_READ_AHEAD_AREA,\
-					       buf_pool->curr_size / 16)
+		buf_pool->curr_size / 16)
 
 /**********************************************************************
 Validates the flush list. */
@@ -55,10 +55,9 @@
 	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 
 	ut_ad((UT_LIST_GET_FIRST(buf_pool->flush_list) == NULL)
-	      || (ut_dulint_cmp(
-			(UT_LIST_GET_FIRST(buf_pool->flush_list))
-						->oldest_modification,
-			block->oldest_modification) <= 0));
+	      || (ut_dulint_cmp((UT_LIST_GET_FIRST(buf_pool->flush_list))
+				->oldest_modification,
+				block->oldest_modification) <= 0));
 
 	UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, block);
 
@@ -77,7 +76,7 @@
 {
 	buf_block_t*	prev_b;
 	buf_block_t*	b;
-	
+
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&(buf_pool->mutex)));
 #endif /* UNIV_SYNC_DEBUG */
@@ -86,7 +85,7 @@
 	b = UT_LIST_GET_FIRST(buf_pool->flush_list);
 
 	while (b && (ut_dulint_cmp(b->oldest_modification,
-					block->oldest_modification) > 0)) {
+				   block->oldest_modification) > 0)) {
 		prev_b = b;
 		b = UT_LIST_GET_NEXT(flush_list, b);
 	}
@@ -95,7 +94,7 @@
 		UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, block);
 	} else {
 		UT_LIST_INSERT_AFTER(flush_list, buf_pool->flush_list, prev_b,
-								block);
+				     block);
 	}
 
 	ut_ad(buf_flush_validate_low());
@@ -119,9 +118,10 @@
 	if (block->state != BUF_BLOCK_FILE_PAGE) {
 		ut_print_timestamp(stderr);
 		fprintf(stderr,
-"  InnoDB: Error: buffer block state %lu in the LRU list!\n",
+			"  InnoDB: Error: buffer block state %lu"
+			" in the LRU list!\n",
 			(ulong)block->state);
-		ut_print_buf(stderr, (byte*)block, sizeof(buf_block_t));
+		ut_print_buf(stderr, block, sizeof(buf_block_t));
 
 		return(FALSE);
 	}
@@ -132,7 +132,7 @@
 
 		return(FALSE);
 	}
-	
+
 	return(TRUE);
 }
 
@@ -154,13 +154,13 @@
 	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 
 	if ((ut_dulint_cmp(block->oldest_modification, ut_dulint_zero) > 0)
-	    					&& (block->io_fix == 0)) {
-	    	if (flush_type != BUF_FLUSH_LRU) {
+	    && (block->io_fix == 0)) {
+		if (flush_type != BUF_FLUSH_LRU) {
 
 			return(TRUE);
 
 		} else if (block->buf_fix_count == 0) {
- 
+
 			/* If we are flushing the LRU list, to avoid deadlocks
 			we require the block not to be bufferfixed, and hence
 			not latched. */
@@ -168,7 +168,7 @@
 			return(TRUE);
 		}
 	}
-	
+
 	return(FALSE);
 }
 
@@ -204,7 +204,7 @@
 	}
 
 	/* fprintf(stderr, "n pending flush %lu\n",
-		buf_pool->n_flush[block->flush_type]); */
+	buf_pool->n_flush[block->flush_type]); */
 
 	if ((buf_pool->n_flush[block->flush_type] == 0)
 	    && (buf_pool->init_flush[block->flush_type] == FALSE)) {
@@ -237,7 +237,7 @@
 
 		return;
 	}
-	
+
 	mutex_enter(&(trx_doublewrite->mutex));
 
 	/* Write first to doublewrite buffer blocks. We use synchronous
@@ -254,87 +254,100 @@
 	for (i = 0; i < trx_doublewrite->first_free; i++) {
 
 		block = trx_doublewrite->buf_block_arr[i];
-	        ut_a(block->state == BUF_BLOCK_FILE_PAGE);
+		ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 
 		if (mach_read_from_4(block->frame + FIL_PAGE_LSN + 4)
-                            != mach_read_from_4(block->frame + UNIV_PAGE_SIZE
-                                        - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
-                            ut_print_timestamp(stderr);
-                            fprintf(stderr,
-"  InnoDB: ERROR: The page to be written seems corrupt!\n"
-"InnoDB: The lsn fields do not match! Noticed in the buffer pool\n"
-"InnoDB: before posting to the doublewrite buffer.\n");
-                }
+		    != mach_read_from_4(block->frame + UNIV_PAGE_SIZE
+					- FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
+			ut_print_timestamp(stderr);
+			fprintf(stderr,
+				"  InnoDB: ERROR: The page to be written"
+				" seems corrupt!\n"
+				"InnoDB: The lsn fields do not match!"
+				" Noticed in the buffer pool\n"
+				"InnoDB: before posting to the"
+				" doublewrite buffer.\n");
+		}
 
 		if (block->check_index_page_at_flush
-				&& !page_simple_validate(block->frame)) {
+		    && !page_simple_validate(block->frame)) {
 
 			buf_page_print(block->frame);
 
 			ut_print_timestamp(stderr);
 			fprintf(stderr,
-	"  InnoDB: Apparent corruption of an index page n:o %lu in space %lu\n"
-	"InnoDB: to be written to data file. We intentionally crash server\n"
-	"InnoDB: to prevent corrupt data from ending up in data\n"
-	"InnoDB: files.\n",
-			(ulong) block->offset, (ulong) block->space);
+				"  InnoDB: Apparent corruption of an"
+				" index page n:o %lu in space %lu\n"
+				"InnoDB: to be written to data file."
+				" We intentionally crash server\n"
+				"InnoDB: to prevent corrupt data"
+				" from ending up in data\n"
+				"InnoDB: files.\n",
+				(ulong) block->offset, (ulong) block->space);
 
 			ut_error;
 		}
 	}
 
-        /* increment the doublewrite flushed pages counter */
-        srv_dblwr_pages_written+= trx_doublewrite->first_free;
-        srv_dblwr_writes++;
-        
+	/* increment the doublewrite flushed pages counter */
+	srv_dblwr_pages_written+= trx_doublewrite->first_free;
+	srv_dblwr_writes++;
+
 	if (trx_doublewrite->first_free > TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
 		len = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE;
 	} else {
 		len = trx_doublewrite->first_free * UNIV_PAGE_SIZE;
 	}
-	
+
 	fil_io(OS_FILE_WRITE,
-		TRUE, TRX_SYS_SPACE,
-		trx_doublewrite->block1, 0, len,
-		 	(void*)trx_doublewrite->write_buf, NULL);
-	
+	       TRUE, TRX_SYS_SPACE,
+	       trx_doublewrite->block1, 0, len,
+	       (void*)trx_doublewrite->write_buf, NULL);
+
 	write_buf = trx_doublewrite->write_buf;
 
-        for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len; len2 += UNIV_PAGE_SIZE) {
-        	if (mach_read_from_4(write_buf + len2 + FIL_PAGE_LSN + 4)
-                    != mach_read_from_4(write_buf + len2 + UNIV_PAGE_SIZE
-                                        - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
+	for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len; len2 += UNIV_PAGE_SIZE) {
+		if (mach_read_from_4(write_buf + len2 + FIL_PAGE_LSN + 4)
+		    != mach_read_from_4(write_buf + len2 + UNIV_PAGE_SIZE
+					- FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
 			ut_print_timestamp(stderr);
 			fprintf(stderr,
-"  InnoDB: ERROR: The page to be written seems corrupt!\n"
-"InnoDB: The lsn fields do not match! Noticed in the doublewrite block1.\n");
+				"  InnoDB: ERROR: The page to be written"
+				" seems corrupt!\n"
+				"InnoDB: The lsn fields do not match!"
+				" Noticed in the doublewrite block1.\n");
 		}
 	}
 
 	if (trx_doublewrite->first_free > TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
 		len = (trx_doublewrite->first_free
-			- TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) * UNIV_PAGE_SIZE;
-	
+		       - TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) * UNIV_PAGE_SIZE;
+
 		fil_io(OS_FILE_WRITE,
-			TRUE, TRX_SYS_SPACE,
-			trx_doublewrite->block2, 0, len,
-		 	(void*)(trx_doublewrite->write_buf
-		 	+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE),
-			NULL);
+		       TRUE, TRX_SYS_SPACE,
+		       trx_doublewrite->block2, 0, len,
+		       (void*)(trx_doublewrite->write_buf
+			       + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE
+			       * UNIV_PAGE_SIZE),
+		       NULL);
 
 		write_buf = trx_doublewrite->write_buf
-			   + TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE;
+			+ TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE;
 		for (len2 = 0; len2 + UNIV_PAGE_SIZE <= len;
-						len2 += UNIV_PAGE_SIZE) {
-        		if (mach_read_from_4(write_buf + len2
-							+ FIL_PAGE_LSN + 4)
-                    	    != mach_read_from_4(write_buf + len2
-					+ UNIV_PAGE_SIZE
-                                        - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
+		     len2 += UNIV_PAGE_SIZE) {
+			if (mach_read_from_4(write_buf + len2
+					     + FIL_PAGE_LSN + 4)
+			    != mach_read_from_4(write_buf + len2
+						+ UNIV_PAGE_SIZE
+						- FIL_PAGE_END_LSN_OLD_CHKSUM
+						+ 4)) {
 				ut_print_timestamp(stderr);
 				fprintf(stderr,
-"  InnoDB: ERROR: The page to be written seems corrupt!\n"
-"InnoDB: The lsn fields do not match! Noticed in the doublewrite block2.\n");
+					"  InnoDB: ERROR: The page to be"
+					" written seems corrupt!\n"
+					"InnoDB: The lsn fields do not match!"
+					" Noticed in"
+					" the doublewrite block2.\n");
 			}
 		}
 	}
@@ -351,32 +364,37 @@
 		block = trx_doublewrite->buf_block_arr[i];
 
 		if (mach_read_from_4(block->frame + FIL_PAGE_LSN + 4)
-                            != mach_read_from_4(block->frame + UNIV_PAGE_SIZE
-                                        - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
-                            ut_print_timestamp(stderr);
-                            fprintf(stderr,
-"  InnoDB: ERROR: The page to be written seems corrupt!\n"
-"InnoDB: The lsn fields do not match! Noticed in the buffer pool\n"
-"InnoDB: after posting and flushing the doublewrite buffer.\n"
-"InnoDB: Page buf fix count %lu, io fix %lu, state %lu\n",
-			(ulong)block->buf_fix_count, (ulong)block->io_fix,
-			(ulong)block->state);
-                }
+		    != mach_read_from_4(block->frame + UNIV_PAGE_SIZE
+					- FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
+			ut_print_timestamp(stderr);
+			fprintf(stderr,
+				"  InnoDB: ERROR: The page to be written"
+				" seems corrupt!\n"
+				"InnoDB: The lsn fields do not match!"
+				" Noticed in the buffer pool\n"
+				"InnoDB: after posting and flushing"
+				" the doublewrite buffer.\n"
+				"InnoDB: Page buf fix count %lu,"
+				" io fix %lu, state %lu\n",
+				(ulong)block->buf_fix_count,
+				(ulong)block->io_fix,
+				(ulong)block->state);
+		}
 		ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 
 		fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER,
-			FALSE, block->space, block->offset, 0, UNIV_PAGE_SIZE,
-		 			(void*)block->frame, (void*)block);
+		       FALSE, block->space, block->offset, 0, UNIV_PAGE_SIZE,
+		       (void*)block->frame, (void*)block);
 	}
-	
+
 	/* Wake possible simulated aio thread to actually post the
 	writes to the operating system */
 
 	os_aio_simulated_wake_handler_threads();
 
 	/* Wait that all async writes to tablespaces have been posted to
-	the OS */	
-	
+	the OS */
+
 	os_aio_wait_until_no_pending_writes();
 
 	/* Now we flush the data to disk (for example, with fsync) */
@@ -387,7 +405,7 @@
 
 	trx_doublewrite->first_free = 0;
 
-	mutex_exit(&(trx_doublewrite->mutex));	
+	mutex_exit(&(trx_doublewrite->mutex));
 }
 
 /************************************************************************
@@ -406,7 +424,7 @@
 	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 
 	if (trx_doublewrite->first_free
-				>= 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
+	    >= 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
 		mutex_exit(&(trx_doublewrite->mutex));
 
 		buf_flush_buffered_writes();
@@ -415,15 +433,15 @@
 	}
 
 	ut_memcpy(trx_doublewrite->write_buf
-				+ UNIV_PAGE_SIZE * trx_doublewrite->first_free,
-			block->frame, UNIV_PAGE_SIZE);
+		  + UNIV_PAGE_SIZE * trx_doublewrite->first_free,
+		  block->frame, UNIV_PAGE_SIZE);
 
 	trx_doublewrite->buf_block_arr[trx_doublewrite->first_free] = block;
 
 	trx_doublewrite->first_free++;
 
 	if (trx_doublewrite->first_free
-				>= 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
+	    >= 2 * TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) {
 		mutex_exit(&(trx_doublewrite->mutex));
 
 		buf_flush_buffered_writes();
@@ -444,22 +462,23 @@
 	dulint	newest_lsn,	/* in: newest modification lsn to the page */
 	ulint	space,		/* in: space id */
 	ulint	page_no)	/* in: page number */
-{	
+{
 	/* Write the newest modification lsn to the page header and trailer */
 	mach_write_to_8(page + FIL_PAGE_LSN, newest_lsn);
 
 	mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
-								newest_lsn);
+			newest_lsn);
 	/* Write the page number and the space id */
 
 	mach_write_to_4(page + FIL_PAGE_OFFSET, page_no);
-        mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space);
+	mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space);
 
 	/* Store the new formula checksum */
 
 	mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
-					srv_use_checksums ?
-                  buf_calc_page_new_checksum(page) : BUF_NO_CHECKSUM_MAGIC);
+			srv_use_checksums
+			? buf_calc_page_new_checksum(page)
+			: BUF_NO_CHECKSUM_MAGIC);
 
 	/* We overwrite the first 4 bytes of the end lsn field to store
 	the old formula checksum. Since it depends also on the field
@@ -467,8 +486,9 @@
 	new formula checksum. */
 
 	mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
-					srv_use_checksums ?
-                  buf_calc_page_old_checksum(page) : BUF_NO_CHECKSUM_MAGIC);
+			srv_use_checksums
+			? buf_calc_page_old_checksum(page)
+			: BUF_NO_CHECKSUM_MAGIC);
 }
 
 /************************************************************************
@@ -494,21 +514,21 @@
 #ifdef UNIV_LOG_DEBUG
 	if (!univ_log_debug_warned) {
 		univ_log_debug_warned = TRUE;
-		fputs(
-	"Warning: cannot force log to disk if UNIV_LOG_DEBUG is defined!\n"
-	"Crash recovery will not work!\n",
-			stderr);
+		fputs("Warning: cannot force log to disk if"
+		      " UNIV_LOG_DEBUG is defined!\n"
+		      "Crash recovery will not work!\n",
+		      stderr);
 	}
 #else
 	/* Force the log to the disk before writing the modified block */
 	log_write_up_to(block->newest_modification, LOG_WAIT_ALL_GROUPS, TRUE);
-#endif	
+#endif
 	buf_flush_init_for_writing(block->frame, block->newest_modification,
-						block->space, block->offset);
+				   block->space, block->offset);
 	if (!srv_use_doublewrite_buf || !trx_doublewrite) {
 		fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER,
-			FALSE, block->space, block->offset, 0, UNIV_PAGE_SIZE,
-		 			(void*)block->frame, (void*)block);
+		       FALSE, block->space, block->offset, 0, UNIV_PAGE_SIZE,
+		       (void*)block->frame, (void*)block);
 	} else {
 		buf_flush_post_to_doublewrite_buf(block);
 	}
@@ -531,9 +551,9 @@
 {
 	buf_block_t*	block;
 	ibool		locked;
-	
+
 	ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST
-				|| flush_type == BUF_FLUSH_SINGLE_PAGE);
+	      || flush_type == BUF_FLUSH_SINGLE_PAGE);
 
 	mutex_enter(&(buf_pool->mutex));
 
@@ -550,7 +570,7 @@
 
 	if (flush_type == BUF_FLUSH_LIST
 	    && buf_flush_ready_for_flush(block, flush_type)) {
-	
+
 		block->io_fix = BUF_IO_WRITE;
 
 		/* If AWE is enabled and the page is not mapped to a frame,
@@ -562,7 +582,7 @@
 			/* We set second parameter TRUE because the block is
 			in the LRU list and we must put it to
 			awe_LRU_free_mapped list once mapped to a frame */
-		
+
 			buf_awe_map_page_to_frame(block, TRUE);
 		}
 
@@ -576,7 +596,7 @@
 		(buf_pool->n_flush[flush_type])++;
 
 		locked = FALSE;
-		
+
 		/* If the simulated aio thread is not running, we must
 		not wait for any latch, as we may end up in a deadlock:
 		if buf_fix_count == 0, then we know we need not wait */
@@ -605,7 +625,7 @@
 #endif /* UNIV_DEBUG */
 
 		buf_flush_write_block_low(block);
-		
+
 		return(1);
 
 	} else if (flush_type == BUF_FLUSH_LRU
@@ -630,7 +650,7 @@
 			/* We set second parameter TRUE because the block is
 			in the LRU list and we must put it to
 			awe_LRU_free_mapped list once mapped to a frame */
-		
+
 			buf_awe_map_page_to_frame(block, TRUE);
 		}
 
@@ -648,7 +668,7 @@
 		/* Note that the s-latch is acquired before releasing the
 		buf_pool mutex: this ensures that the latch is acquired
 		immediately. */
-		
+
 		mutex_exit(&block->mutex);
 		mutex_exit(&(buf_pool->mutex));
 
@@ -658,7 +678,7 @@
 
 	} else if (flush_type == BUF_FLUSH_SINGLE_PAGE
 		   && buf_flush_ready_for_flush(block, flush_type)) {
-	
+
 		block->io_fix = BUF_IO_WRITE;
 
 		/* If AWE is enabled and the page is not mapped to a frame,
@@ -670,7 +690,7 @@
 			/* We set second parameter TRUE because the block is
 			in the LRU list and we must put it to
 			awe_LRU_free_mapped list once mapped to a frame */
-		
+
 			buf_awe_map_page_to_frame(block, TRUE);
 		}
 
@@ -691,14 +711,15 @@
 #ifdef UNIV_DEBUG
 		if (buf_debug_prints) {
 			fprintf(stderr,
-			"Flushing single page space %lu, page no %lu \n",
-						(ulong) block->space,
-			                        (ulong) block->offset);
+				"Flushing single page space %lu,"
+				" page no %lu \n",
+				(ulong) block->space,
+				(ulong) block->offset);
 		}
 #endif /* UNIV_DEBUG */
 
 		buf_flush_write_block_low(block);
-		
+
 		return(1);
 	}
 
@@ -732,13 +753,13 @@
 	if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) {
 		/* If there is little space, it is better not to flush any
 		block except from the end of the LRU list */
-	
+
 		low = offset;
 		high = offset + 1;
 	}
 
 	/* fprintf(stderr, "Flush area: low %lu high %lu\n", low, high); */
-	
+
 	if (high > fil_space_get_size(space)) {
 		high = fil_space_get_size(space);
 	}
@@ -757,10 +778,10 @@
 		} else if (flush_type == BUF_FLUSH_LRU && i != offset
 			   && !block->old) {
 
-		        /* We avoid flushing 'non-old' blocks in an LRU flush,
-		        because the flushed blocks are soon freed */
+			/* We avoid flushing 'non-old' blocks in an LRU flush,
+			because the flushed blocks are soon freed */
 
-		        continue;
+			continue;
 		} else {
 
 			mutex_enter(&block->mutex);
@@ -794,7 +815,7 @@
 			}
 		}
 	}
-				
+
 	mutex_exit(&(buf_pool->mutex));
 
 	return(count);
@@ -825,64 +846,66 @@
 				exceed min_n), otherwise ignored */
 {
 	buf_block_t*	block;
-	ulint		page_count 	= 0;
+	ulint		page_count	= 0;
 	ulint		old_page_count;
 	ulint		space;
 	ulint		offset;
 	ibool		found;
-	
+
 	ut_ad((flush_type == BUF_FLUSH_LRU)
-					|| (flush_type == BUF_FLUSH_LIST)); 
+	      || (flush_type == BUF_FLUSH_LIST));
+#ifdef UNIV_SYNC_DEBUG
 	ut_ad((flush_type != BUF_FLUSH_LIST)
-					|| sync_thread_levels_empty_gen(TRUE));
+	      || sync_thread_levels_empty_gen(TRUE));
+#endif /* UNIV_SYNC_DEBUG */
 	mutex_enter(&(buf_pool->mutex));
 
 	if ((buf_pool->n_flush[flush_type] > 0)
 	    || (buf_pool->init_flush[flush_type] == TRUE)) {
 
 		/* There is already a flush batch of the same type running */
-		
+
 		mutex_exit(&(buf_pool->mutex));
 
 		return(ULINT_UNDEFINED);
 	}
 
 	(buf_pool->init_flush)[flush_type] = TRUE;
-	
+
 	for (;;) {
 		/* If we have flushed enough, leave the loop */
 		if (page_count >= min_n) {
 
 			break;
 		}
-	
+
 		/* Start from the end of the list looking for a suitable
 		block to be flushed. */
-		
-	    	if (flush_type == BUF_FLUSH_LRU) {
+
+		if (flush_type == BUF_FLUSH_LRU) {
 			block = UT_LIST_GET_LAST(buf_pool->LRU);
-	    	} else {
+		} else {
 			ut_ad(flush_type == BUF_FLUSH_LIST);
 
 			block = UT_LIST_GET_LAST(buf_pool->flush_list);
 			if (!block
 			    || (ut_dulint_cmp(block->oldest_modification,
-			    				lsn_limit) >= 0)) {
+					      lsn_limit) >= 0)) {
 				/* We have flushed enough */
 
 				break;
 			}
-	    	}
-	    	
-	    	found = FALSE;
-	
+		}
+
+		found = FALSE;
+
 		/* Note that after finding a single flushable page, we try to
 		flush also all its neighbors, and after that start from the
 		END of the LRU list or flush list again: the list may change
 		during the flushing and we cannot safely preserve within this
 		function a pointer to a block in the list! */
 
-	    	while ((block != NULL) && !found) {
+		while ((block != NULL) && !found) {
 			ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 
 			mutex_enter(&block->mutex);
@@ -892,16 +915,15 @@
 				found = TRUE;
 				space = block->space;
 				offset = block->offset;
-	    
+
 				mutex_exit(&block->mutex);
 				mutex_exit(&(buf_pool->mutex));
 
 				old_page_count = page_count;
-				
+
 				/* Try to flush also all the neighbors */
-				page_count +=
-					buf_flush_try_neighbors(space, offset,
-								flush_type);
+				page_count += buf_flush_try_neighbors(
+					space, offset, flush_type);
 				/* fprintf(stderr,
 				"Flush type %lu, page no %lu, neighb %lu\n",
 				flush_type, offset,
@@ -921,13 +943,13 @@
 
 				block = UT_LIST_GET_PREV(flush_list, block);
 			}
-	    	}
+		}
 
-	    	/* If we could not find anything to flush, leave the loop */
+		/* If we could not find anything to flush, leave the loop */
 
-	    	if (!found) {
-	    		break;
-	    	}
+		if (!found) {
+			break;
+		}
 	}
 
 	(buf_pool->init_flush)[flush_type] = FALSE;
@@ -947,16 +969,16 @@
 #ifdef UNIV_DEBUG
 	if (buf_debug_prints && page_count > 0) {
 		ut_a(flush_type == BUF_FLUSH_LRU
-			|| flush_type == BUF_FLUSH_LIST);
+		     || flush_type == BUF_FLUSH_LIST);
 		fprintf(stderr, flush_type == BUF_FLUSH_LRU
 			? "Flushed %lu pages in LRU flush\n"
 			: "Flushed %lu pages in flush list flush\n",
 			(ulong) page_count);
 	}
 #endif /* UNIV_DEBUG */
-	
-        if (page_count != ULINT_UNDEFINED)
-          srv_buf_pool_flushed+= page_count;
+
+	if (page_count != ULINT_UNDEFINED)
+		srv_buf_pool_flushed+= page_count;
 
 	return(page_count);
 }
@@ -970,9 +992,9 @@
 	ulint	type)	/* in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */
 {
 	ut_ad((type == BUF_FLUSH_LRU) || (type == BUF_FLUSH_LIST));
-	
+
 	os_event_wait(buf_pool->no_flush[type]);
-}	
+}
 
 /**********************************************************************
 Gives a recommendation of how many blocks should be flushed to establish
@@ -988,7 +1010,7 @@
 	buf_block_t*	block;
 	ulint		n_replaceable;
 	ulint		distance	= 0;
-	
+
 	mutex_enter(&(buf_pool->mutex));
 
 	n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
@@ -997,7 +1019,7 @@
 
 	while ((block != NULL)
 	       && (n_replaceable < BUF_FLUSH_FREE_BLOCK_MARGIN
-	       				+ BUF_FLUSH_EXTRA_MARGIN)
+		   + BUF_FLUSH_EXTRA_MARGIN)
 	       && (distance < BUF_LRU_FREE_SEARCH_LEN)) {
 
 		mutex_enter(&block->mutex);
@@ -1009,19 +1031,19 @@
 		mutex_exit(&block->mutex);
 
 		distance++;
-			
+
 		block = UT_LIST_GET_PREV(LRU, block);
 	}
-	
+
 	mutex_exit(&(buf_pool->mutex));
 
 	if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN) {
 
 		return(0);
 	}
-	
+
 	return(BUF_FLUSH_FREE_BLOCK_MARGIN + BUF_FLUSH_EXTRA_MARGIN
-							- n_replaceable);
+	       - n_replaceable);
 }
 
 /*************************************************************************
@@ -1029,7 +1051,7 @@
 of replaceable pages there or in the free list. VERY IMPORTANT: this function
 is called also by threads which have locks on pages. To avoid deadlocks, we
 flush only pages such that the s-lock required for flushing can be acquired
-immediately, without waiting. */ 
+immediately, without waiting. */
 
 void
 buf_flush_free_margin(void)
@@ -1039,15 +1061,15 @@
 	ulint	n_flushed;
 
 	n_to_flush = buf_flush_LRU_recommendation();
-	
+
 	if (n_to_flush > 0) {
 		n_flushed = buf_flush_batch(BUF_FLUSH_LRU, n_to_flush,
-							ut_dulint_zero);
+					    ut_dulint_zero);
 		if (n_flushed == ULINT_UNDEFINED) {
 			/* There was an LRU type flush batch already running;
 			let us wait for it to end */
-		   
-		        buf_flush_wait_batch_end(BUF_FLUSH_LRU);
+
+			buf_flush_wait_batch_end(BUF_FLUSH_LRU);
 		}
 	}
 }
@@ -1062,7 +1084,7 @@
 {
 	buf_block_t*	block;
 	dulint		om;
-	
+
 	UT_LIST_VALIDATE(flush_list, buf_block_t, buf_pool->flush_list);
 
 	block = UT_LIST_GET_FIRST(buf_pool->flush_list);
@@ -1071,12 +1093,12 @@
 		om = block->oldest_modification;
 		ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 		ut_a(ut_dulint_cmp(om, ut_dulint_zero) > 0);
-		
+
 		block = UT_LIST_GET_NEXT(flush_list, block);
 
 		if (block) {
 			ut_a(ut_dulint_cmp(om, block->oldest_modification)
-									>= 0);
+			     >= 0);
 		}
 	}
 
@@ -1092,11 +1114,11 @@
 		/* out: TRUE if ok */
 {
 	ibool	ret;
-	
+
 	mutex_enter(&(buf_pool->mutex));
 
 	ret = buf_flush_validate_low();
-	
+
 	mutex_exit(&(buf_pool->mutex));
 
 	return(ret);

--- 1.24.4.1/innobase/buf/buf0lru.c	2007-01-17 16:44:04 -07:00
+++ 1.34/storage/innobase/buf/buf0lru.c	2007-01-17 17:18:03 -07:00
@@ -80,16 +80,18 @@
 
 scan_again:
 	mutex_enter(&(buf_pool->mutex));
-	
+
 	all_freed = TRUE;
-	
+
 	block = UT_LIST_GET_LAST(buf_pool->LRU);
 
 	while (block != NULL) {
+		buf_block_t*	prev_block;
 
 		mutex_enter(&block->mutex);
+		prev_block = UT_LIST_GET_PREV(LRU, block);
 
-	        ut_a(block->state == BUF_BLOCK_FILE_PAGE);
+		ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 
 		if (block->space == id
 		    && (block->buf_fix_count > 0 || block->io_fix != 0)) {
@@ -97,7 +99,7 @@
 			/* We cannot remove this page during this scan yet;
 			maybe the system is currently reading it in, or
 			flushing the modifications to the file */
-			
+
 			all_freed = FALSE;
 
 			goto next_page;
@@ -106,15 +108,15 @@
 		if (block->space == id) {
 #ifdef UNIV_DEBUG
 			if (buf_debug_prints) {
-				printf(
-				"Dropping space %lu page %lu\n",
+				fprintf(stderr,
+					"Dropping space %lu page %lu\n",
 					(ulong) block->space,
-				        (ulong) block->offset);
+					(ulong) block->offset);
 			}
 #endif
 			if (block->is_hashed) {
 				page_no = block->offset;
-			
+
 				mutex_exit(&block->mutex);
 
 				mutex_exit(&(buf_pool->mutex));
@@ -123,19 +125,19 @@
 				an S-latch on the page */
 
 				btr_search_drop_page_hash_when_freed(id,
-								page_no);
+								     page_no);
 				goto scan_again;
 			}
 
 			if (0 != ut_dulint_cmp(block->oldest_modification,
-							ut_dulint_zero)) {
+					       ut_dulint_zero)) {
 
 				/* Remove from the flush list of modified
 				blocks */
 				block->oldest_modification = ut_dulint_zero;
 
-				UT_LIST_REMOVE(flush_list, 
-						buf_pool->flush_list, block);
+				UT_LIST_REMOVE(flush_list,
+					       buf_pool->flush_list, block);
 			}
 
 			/* Remove from the LRU list */
@@ -144,15 +146,15 @@
 		}
 next_page:
 		mutex_exit(&block->mutex);
-		block = UT_LIST_GET_PREV(LRU, block);
+		block = prev_block;
 	}
 
 	mutex_exit(&(buf_pool->mutex));
-	
+
 	if (!all_freed) {
 		os_thread_sleep(20000);
 
-	        goto scan_again;
+		goto scan_again;
 	}
 }
 
@@ -199,7 +201,7 @@
 buf_LRU_search_and_free_block(
 /*==========================*/
 				/* out: TRUE if freed */
-	ulint	n_iterations)   /* in: how many times this has been called
+	ulint	n_iterations)	/* in: how many times this has been called
 				repeatedly without result: a high value means
 				that we should search farther; if value is
 				k < 10, then we only search k/10 * [number
@@ -211,12 +213,12 @@
 	ibool		freed;
 
 	mutex_enter(&(buf_pool->mutex));
-	
+
 	freed = FALSE;
 	block = UT_LIST_GET_LAST(buf_pool->LRU);
 
 	while (block != NULL) {
-	        ut_a(block->in_LRU_list);
+		ut_a(block->in_LRU_list);
 
 		mutex_enter(&block->mutex);
 
@@ -225,9 +227,10 @@
 #ifdef UNIV_DEBUG
 			if (buf_debug_prints) {
 				fprintf(stderr,
-				"Putting space %lu page %lu to free list\n",
+					"Putting space %lu page %lu"
+					" to free list\n",
 					(ulong) block->space,
-				        (ulong) block->offset);
+					(ulong) block->offset);
 			}
 #endif /* UNIV_DEBUG */
 
@@ -239,7 +242,7 @@
 			/* Remove possible adaptive hash index built on the
 			page; in the case of AWE the block may not have a
 			frame at all */
-			
+
 			if (block->frame) {
 				btr_search_drop_page_hash_index(block->frame);
 			}
@@ -263,25 +266,25 @@
 
 		if (!freed && n_iterations <= 10
 		    && distance > 100 + (n_iterations * buf_pool->curr_size)
-					/ 10) {
+		    / 10) {
 			buf_pool->LRU_flush_ended = 0;
 
 			mutex_exit(&(buf_pool->mutex));
-			
+
 			return(FALSE);
 		}
 	}
 	if (buf_pool->LRU_flush_ended > 0) {
 		buf_pool->LRU_flush_ended--;
 	}
- 	if (!freed) {
+	if (!freed) {
 		buf_pool->LRU_flush_ended = 0;
 	}
 	mutex_exit(&(buf_pool->mutex));
-	
+
 	return(freed);
 }
-	
+
 /**********************************************************************
 Tries to remove LRU flushed blocks from the end of the LRU list and put them
 to the free list. This is beneficial for the efficiency of the insert buffer
@@ -302,12 +305,12 @@
 		mutex_exit(&(buf_pool->mutex));
 
 		buf_LRU_search_and_free_block(1);
-		
+
 		mutex_enter(&(buf_pool->mutex));
 	}
 
 	mutex_exit(&(buf_pool->mutex));
-}	
+}
 
 /**********************************************************************
 Returns TRUE if less than 25 % of the buffer pool is available. This can be
@@ -325,8 +328,8 @@
 	mutex_enter(&(buf_pool->mutex));
 
 	if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
-	   + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 4) {
-		
+	    + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 4) {
+
 		ret = TRUE;
 	}
 
@@ -350,29 +353,34 @@
 	buf_block_t*	block		= NULL;
 	ibool		freed;
 	ulint		n_iterations	= 1;
-	ibool		mon_value_was   = FALSE;
+	ibool		mon_value_was	= FALSE;
 	ibool		started_monitor	= FALSE;
 loop:
 	mutex_enter(&(buf_pool->mutex));
 
 	if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
-	   + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 20) {
-	   	ut_print_timestamp(stderr);
+	    + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 20) {
+		ut_print_timestamp(stderr);
 
-	   	fprintf(stderr,
-"  InnoDB: ERROR: over 95 percent of the buffer pool is occupied by\n"
-"InnoDB: lock heaps or the adaptive hash index! Check that your\n"
-"InnoDB: transactions do not set too many row locks.\n"
-"InnoDB: Your buffer pool size is %lu MB. Maybe you should make\n"
-"InnoDB: the buffer pool bigger?\n"
-"InnoDB: We intentionally generate a seg fault to print a stack trace\n"
-"InnoDB: on Linux!\n",
-		(ulong)(buf_pool->curr_size / (1024 * 1024 / UNIV_PAGE_SIZE)));
+		fprintf(stderr,
+			"  InnoDB: ERROR: over 95 percent of the buffer pool"
+			" is occupied by\n"
+			"InnoDB: lock heaps or the adaptive hash index!"
+			" Check that your\n"
+			"InnoDB: transactions do not set too many row locks.\n"
+			"InnoDB: Your buffer pool size is %lu MB."
+			" Maybe you should make\n"
+			"InnoDB: the buffer pool bigger?\n"
+			"InnoDB: We intentionally generate a seg fault"
+			" to print a stack trace\n"
+			"InnoDB: on Linux!\n",
+			(ulong) (buf_pool->curr_size
+				 / (1024 * 1024 / UNIV_PAGE_SIZE)));
 
 		ut_error;
-	   
+
 	} else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
-	   + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 3) {
+		   + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 3) {
 
 		if (!buf_lru_switched_on_innodb_mon) {
 
@@ -380,16 +388,22 @@
 			heaps or the adaptive hash index. This may be a memory
 			leak! */
 
-	   		ut_print_timestamp(stderr);
-	   		fprintf(stderr,
-"  InnoDB: WARNING: over 67 percent of the buffer pool is occupied by\n"
-"InnoDB: lock heaps or the adaptive hash index! Check that your\n"
-"InnoDB: transactions do not set too many row locks.\n"
-"InnoDB: Your buffer pool size is %lu MB. Maybe you should make\n"
-"InnoDB: the buffer pool bigger?\n"
-"InnoDB: Starting the InnoDB Monitor to print diagnostics, including\n"
-"InnoDB: lock heap and hash index sizes.\n",
-			(ulong) (buf_pool->curr_size / (1024 * 1024 / UNIV_PAGE_SIZE)));
+			ut_print_timestamp(stderr);
+			fprintf(stderr,
+				"  InnoDB: WARNING: over 67 percent of"
+				" the buffer pool is occupied by\n"
+				"InnoDB: lock heaps or the adaptive"
+				" hash index! Check that your\n"
+				"InnoDB: transactions do not set too many"
+				" row locks.\n"
+				"InnoDB: Your buffer pool size is %lu MB."
+				" Maybe you should make\n"
+				"InnoDB: the buffer pool bigger?\n"
+				"InnoDB: Starting the InnoDB Monitor to print"
+				" diagnostics, including\n"
+				"InnoDB: lock heap and hash index sizes.\n",
+				(ulong) (buf_pool->curr_size
+					 / (1024 * 1024 / UNIV_PAGE_SIZE)));
 
 			buf_lru_switched_on_innodb_mon = TRUE;
 			srv_print_innodb_monitor = TRUE;
@@ -405,23 +419,24 @@
 		buf_lru_switched_on_innodb_mon = FALSE;
 		srv_print_innodb_monitor = FALSE;
 	}
-	
+
 	/* If there is a block in the free list, take it */
 	if (UT_LIST_GET_LEN(buf_pool->free) > 0) {
-		
+
 		block = UT_LIST_GET_FIRST(buf_pool->free);
 		ut_a(block->in_free_list);
 		UT_LIST_REMOVE(free, buf_pool->free, block);
 		block->in_free_list = FALSE;
 		ut_a(block->state != BUF_BLOCK_FILE_PAGE);
-	        ut_a(!block->in_LRU_list);
+		ut_a(!block->in_LRU_list);
 
 		if (srv_use_awe) {
 			if (block->frame) {
 				/* Remove from the list of mapped pages */
-		
+
 				UT_LIST_REMOVE(awe_LRU_free_mapped,
-					buf_pool->awe_LRU_free_mapped, block);
+					       buf_pool->awe_LRU_free_mapped,
+					       block);
 			} else {
 				/* We map the page to a frame; second param
 				FALSE below because we do not want it to be
@@ -430,7 +445,7 @@
 				buf_awe_map_page_to_frame(block, FALSE);
 			}
 		}
-		
+
 		mutex_enter(&block->mutex);
 
 		block->state = BUF_BLOCK_READY_FOR_USE;
@@ -441,11 +456,11 @@
 
 		if (started_monitor) {
 			srv_print_innodb_monitor = mon_value_was;
-		}	
+		}
 
 		return(block);
 	}
-	
+
 	/* If no block was in the free list, search from the end of the LRU
 	list and try to free a block there */
 
@@ -460,23 +475,30 @@
 	if (n_iterations > 30) {
 		ut_print_timestamp(stderr);
 		fprintf(stderr,
-		"InnoDB: Warning: difficult to find free blocks from\n"
-		"InnoDB: the buffer pool (%lu search iterations)! Consider\n"
-		"InnoDB: increasing the buffer pool size.\n"
-		"InnoDB: It is also possible that in your Unix version\n"
-		"InnoDB: fsync is very slow, or completely frozen inside\n"
-		"InnoDB: the OS kernel. Then upgrading to a newer version\n"
-		"InnoDB: of your operating system may help. Look at the\n"
-		"InnoDB: number of fsyncs in diagnostic info below.\n"
-		"InnoDB: Pending flushes (fsync) log: %lu; buffer pool: %lu\n"
-		"InnoDB: %lu OS file reads, %lu OS file writes, %lu OS fsyncs\n"
-		"InnoDB: Starting InnoDB Monitor to print further\n"
-		"InnoDB: diagnostics to the standard output.\n",
+			"InnoDB: Warning: difficult to find free blocks from\n"
+			"InnoDB: the buffer pool (%lu search iterations)!"
+			" Consider\n"
+			"InnoDB: increasing the buffer pool size.\n"
+			"InnoDB: It is also possible that"
+			" in your Unix version\n"
+			"InnoDB: fsync is very slow, or"
+			" completely frozen inside\n"
+			"InnoDB: the OS kernel. Then upgrading to"
+			" a newer version\n"
+			"InnoDB: of your operating system may help."
+			" Look at the\n"
+			"InnoDB: number of fsyncs in diagnostic info below.\n"
+			"InnoDB: Pending flushes (fsync) log: %lu;"
+			" buffer pool: %lu\n"
+			"InnoDB: %lu OS file reads, %lu OS file writes,"
+			" %lu OS fsyncs\n"
+			"InnoDB: Starting InnoDB Monitor to print further\n"
+			"InnoDB: diagnostics to the standard output.\n",
 			(ulong) n_iterations,
 			(ulong) fil_n_pending_log_flushes,
 			(ulong) fil_n_pending_tablespace_flushes,
 			(ulong) os_n_file_reads, (ulong) os_n_file_writes,
-                        (ulong) os_n_fsyncs);
+			(ulong) os_n_fsyncs);
 
 		mon_value_was = srv_print_innodb_monitor;
 		started_monitor = TRUE;
@@ -487,7 +509,7 @@
 	/* No free block was found: try to flush the LRU list */
 
 	buf_flush_free_margin();
-        ++srv_buf_pool_wait_free;
+	++srv_buf_pool_wait_free;
 
 	os_aio_simulated_wake_handler_threads();
 
@@ -512,8 +534,8 @@
 
 	n_iterations++;
 
-	goto loop;	
-}	
+	goto loop;
+}
 
 /***********************************************************************
 Moves the LRU_old pointer so that the length of the old blocks list
@@ -539,23 +561,23 @@
 		ut_a(buf_pool->LRU_old->in_LRU_list);
 
 		/* Update the LRU_old pointer if necessary */
-	
+
 		if (old_len < new_len - BUF_LRU_OLD_TOLERANCE) {
-		
-			buf_pool->LRU_old = UT_LIST_GET_PREV(LRU,
-							buf_pool->LRU_old);
+
+			buf_pool->LRU_old = UT_LIST_GET_PREV(
+				LRU, buf_pool->LRU_old);
 			(buf_pool->LRU_old)->old = TRUE;
 			buf_pool->LRU_old_len++;
 
 		} else if (old_len > new_len + BUF_LRU_OLD_TOLERANCE) {
 
 			(buf_pool->LRU_old)->old = FALSE;
-			buf_pool->LRU_old = UT_LIST_GET_NEXT(LRU,
-							buf_pool->LRU_old);
+			buf_pool->LRU_old = UT_LIST_GET_NEXT(
+				LRU, buf_pool->LRU_old);
 			buf_pool->LRU_old_len--;
 		} else {
 			ut_a(buf_pool->LRU_old); /* Check that we did not
-						fall out of the LRU list */
+						 fall out of the LRU list */
 			return;
 		}
 	}
@@ -581,16 +603,16 @@
 
 	while (block != NULL) {
 		ut_a(block->state == BUF_BLOCK_FILE_PAGE);
-	        ut_a(block->in_LRU_list);
+		ut_a(block->in_LRU_list);
 		block->old = TRUE;
 		block = UT_LIST_GET_NEXT(LRU, block);
 	}
 
 	buf_pool->LRU_old = UT_LIST_GET_FIRST(buf_pool->LRU);
 	buf_pool->LRU_old_len = UT_LIST_GET_LEN(buf_pool->LRU);
-	
+
 	buf_LRU_old_adjust_len();
-}	    	
+}
 
 /**********************************************************************
 Removes a block from the LRU list. */
@@ -605,7 +627,7 @@
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&(buf_pool->mutex)));
 #endif /* UNIV_SYNC_DEBUG */
-		
+
 	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 	ut_a(block->in_LRU_list);
 
@@ -631,10 +653,10 @@
 
 	if (srv_use_awe && block->frame) {
 		/* Remove from the list of mapped pages */
-		
+
 		UT_LIST_REMOVE(awe_LRU_free_mapped,
-					buf_pool->awe_LRU_free_mapped, block);
-	}	
+			       buf_pool->awe_LRU_free_mapped, block);
+	}
 
 	/* If the LRU list is so short that LRU_old not defined, return */
 	if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) {
@@ -644,7 +666,7 @@
 		return;
 	}
 
-	ut_ad(buf_pool->LRU_old);	
+	ut_ad(buf_pool->LRU_old);
 
 	/* Update the LRU_old_len field if necessary */
 	if (block->old) {
@@ -654,7 +676,7 @@
 
 	/* Adjust the length of the old block list if necessary */
 	buf_LRU_old_adjust_len();
-}	    	
+}
 
 /**********************************************************************
 Adds a block to the LRU list end. */
@@ -665,7 +687,7 @@
 	buf_block_t*	block)	/* in: control block */
 {
 	buf_block_t*	last_block;
-	
+
 	ut_ad(buf_pool);
 	ut_ad(block);
 #ifdef UNIV_SYNC_DEBUG
@@ -682,7 +704,7 @@
 		block->LRU_position = last_block->LRU_position;
 	} else {
 		block->LRU_position = buf_pool_clock_tic();
-	}			
+	}
 
 	ut_a(!block->in_LRU_list);
 	UT_LIST_ADD_LAST(LRU, buf_pool->LRU, block);
@@ -690,11 +712,11 @@
 
 	if (srv_use_awe && block->frame) {
 		/* Add to the list of mapped pages */
-		
+
 		UT_LIST_ADD_LAST(awe_LRU_free_mapped,
-					buf_pool->awe_LRU_free_mapped, block);
+				 buf_pool->awe_LRU_free_mapped, block);
 	}
-	
+
 	if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
 
 		buf_pool->LRU_old_len++;
@@ -715,7 +737,7 @@
 
 		buf_LRU_old_init();
 	}
-}	    	
+}
 
 /**********************************************************************
 Adds a block to the LRU list. */
@@ -730,7 +752,7 @@
 				the start, regardless of this parameter */
 {
 	ulint	cl;
-	
+
 	ut_ad(buf_pool);
 	ut_ad(block);
 #ifdef UNIV_SYNC_DEBUG
@@ -747,20 +769,20 @@
 		/* Add to the list of mapped pages; for simplicity we always
 		add to the start, even if the user would have set 'old'
 		TRUE */
-		
+
 		UT_LIST_ADD_FIRST(awe_LRU_free_mapped,
-					buf_pool->awe_LRU_free_mapped, block);
+				  buf_pool->awe_LRU_free_mapped, block);
 	}
 
 	if (!old || (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN)) {
 
 		UT_LIST_ADD_FIRST(LRU, buf_pool->LRU, block);
 
-		block->LRU_position = cl;		
+		block->LRU_position = cl;
 		block->freed_page_clock = buf_pool->freed_page_clock;
 	} else {
 		UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, buf_pool->LRU_old,
-								block);
+				     block);
 		buf_pool->LRU_old_len++;
 
 		/* We copy the LRU position field of the previous block
@@ -785,8 +807,8 @@
 		defined: init it */
 
 		buf_LRU_old_init();
-	}	
-}	    	
+	}
+}
 
 /**********************************************************************
 Adds a block to the LRU list. */
@@ -841,27 +863,27 @@
 	ut_ad(mutex_own(&block->mutex));
 #endif /* UNIV_SYNC_DEBUG */
 	ut_ad(block);
-	
+
 	ut_a((block->state == BUF_BLOCK_MEMORY)
-	      || (block->state == BUF_BLOCK_READY_FOR_USE));
+	     || (block->state == BUF_BLOCK_READY_FOR_USE));
 
 	ut_a(block->n_pointers == 0);
 	ut_a(!block->in_free_list);
 
 	block->state = BUF_BLOCK_NOT_USED;
 
-#ifdef UNIV_DEBUG	
+#ifdef UNIV_DEBUG
 	/* Wipe contents of page to reveal possible stale pointers to it */
 	memset(block->frame, '\0', UNIV_PAGE_SIZE);
-#endif	
+#endif
 	UT_LIST_ADD_FIRST(free, buf_pool->free, block);
 	block->in_free_list = TRUE;
 
 	if (srv_use_awe && block->frame) {
 		/* Add to the list of mapped pages */
-		
+
 		UT_LIST_ADD_FIRST(awe_LRU_free_mapped,
-					buf_pool->awe_LRU_free_mapped, block);
+				  buf_pool->awe_LRU_free_mapped, block);
 	}
 }
 
@@ -881,7 +903,7 @@
 	ut_ad(mutex_own(&block->mutex));
 #endif /* UNIV_SYNC_DEBUG */
 	ut_ad(block);
-	
+
 	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 	ut_a(block->io_fix == 0);
 	ut_a(block->buf_fix_count == 0);
@@ -892,35 +914,40 @@
 	buf_pool->freed_page_clock += 1;
 
 	/* Note that if AWE is enabled the block may not have a frame at all */
-	
- 	buf_block_modify_clock_inc(block);
-		
-        if (block != buf_page_hash_get(block->space, block->offset)) {
-                fprintf(stderr,
-"InnoDB: Error: page %lu %lu not found from the hash table\n",
+
+	buf_block_modify_clock_inc(block);
+
+	if (block != buf_page_hash_get(block->space, block->offset)) {
+		fprintf(stderr,
+			"InnoDB: Error: page %lu %lu not found"
+			" in the hash table\n",
 			(ulong) block->space,
 			(ulong) block->offset);
-                if (buf_page_hash_get(block->space, block->offset)) {
-                        fprintf(stderr,
-"InnoDB: From hash table we find block %p of %lu %lu which is not %p\n",
-		buf_page_hash_get(block->space, block->offset),
-                (ulong) buf_page_hash_get(block->space, block->offset)->space,
-                (ulong) buf_page_hash_get(block->space, block->offset)->offset,
-		block);
-                }
+		if (buf_page_hash_get(block->space, block->offset)) {
+			fprintf(stderr,
+				"InnoDB: In hash table we find block"
+				" %p of %lu %lu which is not %p\n",
+				(void*) buf_page_hash_get
+				(block->space, block->offset),
+				(ulong) buf_page_hash_get
+				(block->space, block->offset)->space,
+				(ulong) buf_page_hash_get
+				(block->space, block->offset)->offset,
+				(void*) block);
+		}
 
 #ifdef UNIV_DEBUG
-                buf_print();
-                buf_LRU_print();
-                buf_validate();
-                buf_LRU_validate();
+		buf_print();
+		buf_LRU_print();
+		buf_validate();
+		buf_LRU_validate();
 #endif
-                ut_a(0);
-        }	
+		ut_a(0);
+	}
 
 	HASH_DELETE(buf_block_t, hash, buf_pool->page_hash,
-			buf_page_address_fold(block->space, block->offset),
-			block);
+		    buf_page_address_fold(block->space, block->offset),
+		    block);
 
 	block->state = BUF_BLOCK_REMOVE_HASH;
 }
@@ -957,7 +984,7 @@
 	ulint		old_len;
 	ulint		new_len;
 	ulint		LRU_pos;
-	
+
 	ut_ad(buf_pool);
 	mutex_enter(&(buf_pool->mutex));
 
@@ -969,7 +996,7 @@
 		ut_a(old_len >= new_len - BUF_LRU_OLD_TOLERANCE);
 		ut_a(old_len <= new_len + BUF_LRU_OLD_TOLERANCE);
 	}
-		
+
 	UT_LIST_VALIDATE(LRU, buf_block_t, buf_pool->LRU);
 
 	block = UT_LIST_GET_FIRST(buf_pool->LRU);
@@ -1002,7 +1029,7 @@
 
 	if (buf_pool->LRU_old) {
 		ut_a(buf_pool->LRU_old_len == old_len);
-	} 
+	}
 
 	UT_LIST_VALIDATE(free, buf_block_t, buf_pool->free);
 
@@ -1028,11 +1055,12 @@
 	buf_block_t*	block;
 	buf_frame_t*	frame;
 	ulint		len;
-	
+
 	ut_ad(buf_pool);
 	mutex_enter(&(buf_pool->mutex));
 
-	fprintf(stderr, "Pool ulint clock %lu\n", (ulong) buf_pool->ulint_clock);
+	fprintf(stderr, "Pool ulint clock %lu\n",
+		(ulong) buf_pool->ulint_clock);
 
 	block = UT_LIST_GET_FIRST(buf_pool->LRU);
 
@@ -1056,7 +1084,7 @@
 		}
 
 		if (ut_dulint_cmp(block->oldest_modification,
-				ut_dulint_zero) > 0) {
+				  ut_dulint_zero) > 0) {
 			fputs("modif. ", stderr);
 		}
 
@@ -1065,7 +1093,8 @@
 		fprintf(stderr, "LRU pos %lu type %lu index id %lu ",
 			(ulong) block->LRU_position,
 			(ulong) fil_page_get_type(frame),
-			(ulong) ut_dulint_get_low(btr_page_get_index_id(frame)));
+			(ulong) ut_dulint_get_low
+			(btr_page_get_index_id(frame)));
 
 		block = UT_LIST_GET_NEXT(LRU, block);
 		if (++len == 10) {

--- 1.28.5.1/innobase/include/buf0buf.h	2007-01-17 16:44:04 -07:00
+++ 1.39/storage/innobase/include/buf0buf.h	2007-01-17 17:18:03 -07:00
@@ -1,14 +1,14 @@
 /*   Innobase relational database engine; Copyright (C) 2001 Innobase Oy
-     
+
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License 2
      as published by the Free Software Foundation in June 1991.
-     
+
      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.
-     
+
      You should have received a copy of the GNU General Public License 2
      along with this program (in file COPYING); if not, write to the Free
      Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
@@ -55,14 +55,14 @@
 /* Magic value to use instead of checksums when they are disabled */
 #define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
 
-extern buf_pool_t* 	buf_pool; 	/* The buffer pool of the database */
+extern buf_pool_t*	buf_pool;	/* The buffer pool of the database */
 #ifdef UNIV_DEBUG
 extern ibool		buf_debug_prints;/* If this is set TRUE, the program
 					prints info whenever read or flush
 					occurs */
 #endif /* UNIV_DEBUG */
 extern ulint srv_buf_pool_write_requests; /* variable to count write request
-                                          issued */
+					  issued */
 
 /************************************************************************
 Creates the buffer pool. */
@@ -134,7 +134,7 @@
 NOTE! The following macros should be used instead of buf_page_get_gen,
 to improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed
 in LA! */
-#define buf_page_get(SP, OF, LA, MTR)    buf_page_get_gen(\
+#define buf_page_get(SP, OF, LA, MTR)	 buf_page_get_gen(\
 				SP, OF, LA, NULL,\
 				BUF_GET, __FILE__, __LINE__, MTR)
 /******************************************************************
@@ -143,21 +143,21 @@
 the contents of the page! We have separated this case, because it is
 error-prone programming not to set a latch, and it should be used
 with care. */
-#define buf_page_get_with_no_latch(SP, OF, MTR)    buf_page_get_gen(\
+#define buf_page_get_with_no_latch(SP, OF, MTR)	   buf_page_get_gen(\
 				SP, OF, RW_NO_LATCH, NULL,\
 				BUF_GET_NO_LATCH, __FILE__, __LINE__, MTR)
 /******************************************************************
 NOTE! The following macros should be used instead of buf_page_get_gen, to
 improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed as LA! */
-#define buf_page_get_nowait(SP, OF, LA, MTR)    buf_page_get_gen(\
+#define buf_page_get_nowait(SP, OF, LA, MTR)	buf_page_get_gen(\
 				SP, OF, LA, NULL,\
 				BUF_GET_NOWAIT, __FILE__, __LINE__, MTR)
 /******************************************************************
 NOTE! The following macros should be used instead of
 buf_page_optimistic_get_func, to improve debugging. Only values RW_S_LATCH and
 RW_X_LATCH are allowed as LA! */
-#define buf_page_optimistic_get(LA, BL, G, MC, MTR) buf_page_optimistic_get_func(\
-				LA, BL, G, MC, __FILE__, __LINE__, MTR)
+#define buf_page_optimistic_get(LA, BL, G, MC, MTR)			     \
+	buf_page_optimistic_get_func(LA, BL, G, MC, __FILE__, __LINE__, MTR)
 /************************************************************************
 This is the general function used to get optimistic access to a database
 page. */
@@ -266,7 +266,7 @@
 
 void
 buf_page_make_young(
-/*=================*/
+/*================*/
 	buf_frame_t*	frame);	/* in: buffer frame of a file page */
 /************************************************************************
 Returns TRUE if the page can be found in the buffer pool hash table. NOTE
@@ -380,7 +380,7 @@
 				/* out: new value */
 	buf_block_t*	block);	/* in: block */
 /************************************************************************
-Returns the value of the modify clock. The caller must have an s-lock 
+Returns the value of the modify clock. The caller must have an s-lock
 or x-lock on the block. */
 UNIV_INLINE
 dulint
@@ -396,12 +396,12 @@
 ulint
 buf_calc_page_new_checksum(
 /*=======================*/
-		       /* out: checksum */
-	byte*   page); /* in: buffer page */
+			/* out: checksum */
+	byte*	page);	/* in: buffer page */
 /************************************************************************
 In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
 looked at the first few bytes of the page. This calculates that old
-checksum. 
+checksum.
 NOTE: we must first store the new formula checksum to
 FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum
 because this takes that field as an input! */
@@ -409,8 +409,8 @@
 ulint
 buf_calc_page_old_checksum(
 /*=======================*/
-		       /* out: checksum */
-	byte*    page); /* in: buffer page */
+			/* out: checksum */
+	byte*	 page);	/* in: buffer page */
 /************************************************************************
 Checks if a page is corrupt. */
 
@@ -648,7 +648,7 @@
 on the buffer frame. The io-handler must take care that the flag is cleared
 and the lock released later. This is one of the functions which perform the
 state transition NOT_USED => FILE_PAGE to a block (the other is
-buf_page_create). */ 
+buf_page_create). */
 
 buf_block_t*
 buf_page_init_for_read(
@@ -704,7 +704,7 @@
 /*=======================*/
 
 
-			
+
 /* The buffer control block structure */
 
 struct buf_block_struct{
@@ -832,19 +832,18 @@
 
 	/* 5. Hash search fields: NOTE that the first 4 fields are NOT
 	protected by any semaphore! */
-	
+
 	ulint		n_hash_helps;	/* counter which controls building
 					of a new hash index for the page */
 	ulint		n_fields;	/* recommended prefix length for hash
 					search: number of full fields */
 	ulint		n_bytes;	/* recommended prefix: number of bytes
 					in an incomplete field */
-	ulint		side;		/* BTR_SEARCH_LEFT_SIDE or
-					BTR_SEARCH_RIGHT_SIDE, depending on
+	ibool		left_side;	/* TRUE or FALSE, depending on
 					whether the leftmost record of several
 					records with the same prefix should be
 					indexed in the hash index */
-					
+
 	/* These 6 fields may only be modified when we have
 	an x-latch on btr_search_latch AND
 	a) we are holding an s-latch or x-latch on block->lock or
@@ -865,9 +864,7 @@
 	ulint		curr_n_fields;	/* prefix length for hash indexing:
 					number of full fields */
 	ulint		curr_n_bytes;	/* number of bytes in hash indexing */
-	ulint		curr_side;	/* BTR_SEARCH_LEFT_SIDE or
-					BTR_SEARCH_RIGHT_SIDE in hash
-					indexing */
+	ibool		curr_left_side;	/* TRUE or FALSE in hash indexing */
 	dict_index_t*	index;		/* Index for which the adaptive
 					hash index has been created. */
 	/* 6. Debug fields */
@@ -877,9 +874,9 @@
 					an s-latch here; so we can use the
 					debug utilities in sync0rw */
 #endif
-        ibool           file_page_was_freed;
-                                        /* this is set to TRUE when fsp
-                                        frees a page in buffer pool */
+	ibool		file_page_was_freed;
+					/* this is set to TRUE when fsp
+					frees a page in buffer pool */
 };
 
 #define BUF_BLOCK_MAGIC_N	41526563
@@ -993,7 +990,7 @@
 					physical memory is mapped to a frame */
 	UT_LIST_BASE_NODE_T(buf_block_t) LRU;
 					/* base node of the LRU list */
-	buf_block_t*	LRU_old; 	/* pointer to the about 3/8 oldest
+	buf_block_t*	LRU_old;	/* pointer to the about 3/8 oldest
 					blocks in the LRU list; NULL if LRU
 					length less than BUF_LRU_OLD_MIN_LEN */
 	ulint		LRU_old_len;	/* length of the LRU list from
@@ -1035,8 +1032,8 @@
 FILE_PAGE:	space and offset are defined, is in page hash table
 		if io_fix == BUF_IO_WRITE,
 			pool: no_flush[block->flush_type] is in reset state,
-			pool: n_flush[block->flush_type] > 0			
-		
+			pool: n_flush[block->flush_type] > 0
+
 		(1) if buf_fix_count == 0, then
 			is in LRU list, not in free list
 			is in flush list,
@@ -1045,23 +1042,23 @@
 				if and only if io_fix == BUF_IO_READ
 			is s-locked,
 				if and only if io_fix == BUF_IO_WRITE
-						
+
 		(2) if buf_fix_count > 0, then
 			is not in LRU list, not in free list
 			is in flush list,
 				if and only if oldest_modification > 0
-			if io_fix == BUF_IO_READ,		
+			if io_fix == BUF_IO_READ,
 				is x-locked
 			if io_fix == BUF_IO_WRITE,
 				is s-locked
-			
+
 State transitions:
 
 NOT_USED => READY_FOR_USE
 READY_FOR_USE => MEMORY
 READY_FOR_USE => FILE_PAGE
 MEMORY => NOT_USED
-FILE_PAGE => NOT_USED	NOTE: This transition is allowed if and only if 
+FILE_PAGE => NOT_USED	NOTE: This transition is allowed if and only if
 				(1) buf_fix_count == 0,
 				(2) oldest_modification == 0, and
 				(3) io_fix == 0.

--- 1.17.8.1/innobase/include/buf0buf.ic	2007-01-17 16:44:04 -07:00
+++ 1.30/storage/innobase/include/buf0buf.ic	2007-01-17 17:18:03 -07:00
@@ -28,7 +28,7 @@
 	buf_block_t*	block)	/* in: block to make younger */
 {
 	return(buf_pool->freed_page_clock >= block->freed_page_clock
-				+ 1 + (buf_pool->curr_size / 1024));
+	       + 1 + (buf_pool->curr_size / 1024));
 }
 
 /*************************************************************************
@@ -41,7 +41,7 @@
 			/* out: size in bytes */
 {
 	return((buf_pool->n_frames) * UNIV_PAGE_SIZE);
-}	
+}
 
 /*************************************************************************
 Gets the maximum size of buffer buf_pool in bytes. In the case of AWE, the
@@ -53,7 +53,7 @@
 			/* out: size in bytes */
 {
 	return((buf_pool->n_frames) * UNIV_PAGE_SIZE);
-}	
+}
 
 /***********************************************************************
 Accessor function for block array. */
@@ -69,7 +69,7 @@
 	ut_ad(i < buf_pool->max_size);
 
 	return(i + buf_pool->blocks);
-}	
+}
 
 /***********************************************************************
 Checks if a pointer points to the block array of the buffer pool (blocks, not
@@ -82,13 +82,14 @@
 	void*	ptr)	/* in: pointer to memory */
 {
 	if ((buf_pool->blocks <= (buf_block_t*)ptr)
-	    && ((buf_block_t*)ptr < buf_pool->blocks + buf_pool->max_size)) {
+	    && ((buf_block_t*)ptr < buf_pool->blocks
+		+ buf_pool->max_size)) {
 
 		return(TRUE);
 	}
 
 	return(FALSE);
-}	
+}
 
 /************************************************************************
 Gets the smallest oldest_modification lsn for any page in the pool. Returns
@@ -102,7 +103,7 @@
 {
 	buf_block_t*	block;
 	dulint		lsn;
-	
+
 	mutex_enter(&(buf_pool->mutex));
 
 	block = UT_LIST_GET_LAST(buf_pool->flush_list);
@@ -130,7 +131,7 @@
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&(buf_pool->mutex)));
 #endif /* UNIV_SYNC_DEBUG */
-	
+
 	buf_pool->ulint_clock++;
 
 	return(buf_pool->ulint_clock);
@@ -148,12 +149,12 @@
 	ut_ad(block);
 	ut_ad(block >= buf_pool->blocks);
 	ut_ad(block < buf_pool->blocks + buf_pool->max_size);
-	ut_ad(block->state != BUF_BLOCK_NOT_USED); 
-	ut_ad((block->state != BUF_BLOCK_FILE_PAGE) 
+	ut_ad(block->state != BUF_BLOCK_NOT_USED);
+	ut_ad((block->state != BUF_BLOCK_FILE_PAGE)
 	      || (block->buf_fix_count > 0));
-	
+
 	return(block->frame);
-}	
+}
 
 /*************************************************************************
 Gets the space id of a block. */
@@ -169,9 +170,9 @@
 	ut_ad(block < buf_pool->blocks + buf_pool->max_size);
 	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 	ut_ad(block->buf_fix_count > 0);
-	
+
 	return(block->space);
-}	
+}
 
 /*************************************************************************
 Gets the page number of a block. */
@@ -187,9 +188,9 @@
 	ut_ad(block < buf_pool->blocks + buf_pool->max_size);
 	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 	ut_ad(block->buf_fix_count > 0);
-	
+
 	return(block->offset);
-}	
+}
 
 /***********************************************************************
 Gets the block to whose frame the pointer is pointing to. */
@@ -210,23 +211,26 @@
 	if (UNIV_UNLIKELY((ulint)ptr < (ulint)frame_zero)
 	    || UNIV_UNLIKELY((ulint)ptr > (ulint)(buf_pool->high_end))) {
 
-		ut_print_timestamp(stderr);	
+		ut_print_timestamp(stderr);
 		fprintf(stderr,
-"InnoDB: Error: trying to access a stray pointer %p\n"
-"InnoDB: buf pool start is at %p, end at %p\n"
-"InnoDB: Probable reason is database corruption or memory\n"
-"InnoDB: corruption. If this happens in an InnoDB database recovery, see\n"
-"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html\n"
-"InnoDB: how to force recovery.\n",
- 			ptr, frame_zero,
+			"InnoDB: Error: trying to access a stray pointer %p\n"
+			"InnoDB: buf pool start is at %p, end at %p\n"
+			"InnoDB: Probable reason is database corruption"
+			" or memory\n"
+			"InnoDB: corruption. If this happens in an"
+			" InnoDB database recovery, see\n"
+			"InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
+			"forcing-recovery.html\n"
+			"InnoDB: how to force recovery.\n",
+			ptr, frame_zero,
 			buf_pool->high_end);
 		ut_error;
 	}
-	
+
 	block = *(buf_pool->blocks_of_frames + (((ulint)(ptr - frame_zero))
 						>> UNIV_PAGE_SIZE_SHIFT));
 	return(block);
-}	
+}
 
 /***********************************************************************
 Gets the frame the pointer is pointing to. */
@@ -246,15 +250,18 @@
 	if (UNIV_UNLIKELY((ulint)frame < (ulint)(buf_pool->frame_zero))
 	    || UNIV_UNLIKELY((ulint)frame >= (ulint)(buf_pool->high_end))) {
 
-		ut_print_timestamp(stderr);	
+		ut_print_timestamp(stderr);
 		fprintf(stderr,
-"InnoDB: Error: trying to access a stray pointer %p\n"
-"InnoDB: buf pool start is at %p, end at %p\n"
-"InnoDB: Probable reason is database corruption or memory\n"
-"InnoDB: corruption. If this happens in an InnoDB database recovery, see\n"
-"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html\n"
-"InnoDB: how to force recovery.\n",
- 			ptr, buf_pool->frame_zero,
+			"InnoDB: Error: trying to access a stray pointer %p\n"
+			"InnoDB: buf pool start is at %p, end at %p\n"
+			"InnoDB: Probable reason is database corruption"
+			" or memory\n"
+			"InnoDB: corruption. If this happens in an"
+			" InnoDB database recovery, see\n"
+			"InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
+			"forcing-recovery.html\n"
+			"InnoDB: how to force recovery.\n",
+			ptr, buf_pool->frame_zero,
 			buf_pool->high_end);
 		ut_error;
 	}
@@ -371,7 +378,7 @@
 	ulint	offset)	/* in: offset of the page within space */
 {
 	return((space << 20) + space + offset);
-}	
+}
 
 /************************************************************************
 This function is used to get info if there is an io operation
@@ -411,7 +418,7 @@
 {
 	buf_block_t*	block;
 	dulint		lsn;
-	
+
 	ut_ad(frame);
 
 	block = buf_block_align(frame);
@@ -478,7 +485,7 @@
 }
 
 /************************************************************************
-Returns the value of the modify clock. The caller must have an s-lock 
+Returns the value of the modify clock. The caller must have an s-lock
 or x-lock on the block. */
 UNIV_INLINE
 dulint
@@ -506,7 +513,7 @@
 	const char*	file __attribute__ ((unused)),	/* in: file name */
 	ulint		line __attribute__ ((unused)))	/* in: line */
 {
-#ifdef UNIV_SYNC_DEBUG	
+#ifdef UNIV_SYNC_DEBUG
 	ibool	ret;
 
 	ret = rw_lock_s_lock_func_nowait(&(block->debug_latch), file, line);
@@ -543,7 +550,7 @@
 {
 	buf_block_t*	block;
 	ulint		fold;
-	
+
 	ut_ad(buf_pool);
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(mutex_own(&(buf_pool->mutex)));
@@ -554,9 +561,9 @@
 	fold = buf_page_address_fold(space, offset);
 
 	HASH_SEARCH(hash, buf_pool->page_hash, fold, block,
-			(block->space == space) && (block->offset == offset));
+		    (block->space == space) && (block->offset == offset));
 	ut_a(block == NULL || block->state == BUF_BLOCK_FILE_PAGE);
-	
+
 	return(block);
 }
 
@@ -583,9 +590,9 @@
 	buf_frame_t*	frame;
 
 	frame = buf_page_get_gen(space, offset, rw_latch, guess,
-				BUF_GET_IF_IN_POOL,
-				__FILE__, __LINE__,
-				mtr);
+				 BUF_GET_IF_IN_POOL,
+				 __FILE__, __LINE__,
+				 mtr);
 	if (frame != NULL) {
 
 		return(frame);
@@ -593,16 +600,16 @@
 
 	/* The page was not in the buffer buf_pool: release the latches
 	down to the savepoint */
-		
+
 	mtr_rollback_to_savepoint(mtr, savepoint);
-		
+
 	buf_page_get(space, offset, RW_S_LATCH, mtr);
-		
+
 	/* When we get here, the page is in buffer, but we release
 	the latches again down to the savepoint, before returning */
 
 	mtr_rollback_to_savepoint(mtr, savepoint);
-		
+
 	return(NULL);
 }
 
@@ -618,8 +625,6 @@
 					RW_NO_LATCH */
 	mtr_t*		mtr)		/* in: mtr */
 {
-	ulint	buf_fix_count;
-	
 	ut_ad(block);
 
 	ut_a(block->state == BUF_BLOCK_FILE_PAGE);
@@ -636,8 +641,7 @@
 #ifdef UNIV_SYNC_DEBUG
 	rw_lock_s_unlock(&(block->debug_latch));
 #endif
-	buf_fix_count = block->buf_fix_count;
-	block->buf_fix_count = buf_fix_count - 1;
+	block->buf_fix_count--;
 
 	mutex_exit(&block->mutex);
 
@@ -659,9 +663,9 @@
 buf_page_dbg_add_level(
 /*===================*/
 	buf_frame_t*	frame __attribute__((unused)), /* in: buffer page
-                                where we have acquired latch */
+				where we have acquired latch */
 	ulint		level __attribute__((unused))) /* in: latching order
-                                level */
+				level */
 {
 	sync_thread_add_level(&(buf_block_align(frame)->lock), level);
 }

--- 1.7.3.1/innobase/include/sync0arr.h	2007-01-17 16:44:04 -07:00
+++ 1.11/storage/innobase/include/sync0arr.h	2007-01-17 17:18:03 -07:00
@@ -14,7 +14,7 @@
 #include "ut0mem.h"
 #include "os0thread.h"
 
-typedef struct sync_cell_struct        	sync_cell_t;
+typedef struct sync_cell_struct		sync_cell_t;
 typedef struct sync_array_struct	sync_array_t;
 
 #define SYNC_ARRAY_OS_MUTEX	1
@@ -48,12 +48,12 @@
 void
 sync_array_reserve_cell(
 /*====================*/
-        sync_array_t*	arr,	/* in: wait array */
-        void*   	object, /* in: pointer to the object to wait for */
-        ulint		type,	/* in: lock request type */
+	sync_array_t*	arr,	/* in: wait array */
+	void*		object, /* in: pointer to the object to wait for */
+	ulint		type,	/* in: lock request type */
 	const char*	file,	/* in: file where requested */
-        ulint		line,	/* in: line where requested */
-        ulint*   	index); /* out: index of the reserved cell */
+	ulint		line,	/* in: line where requested */
+	ulint*		index); /* out: index of the reserved cell */
 /**********************************************************************
 This function should be called when a thread starts to wait on
 a wait array cell. In the debug version this function checks
@@ -63,24 +63,29 @@
 void
 sync_array_wait_event(
 /*==================*/
-        sync_array_t*	arr,	/* in: wait array */
-        ulint   	index);  /* in: index of the reserved cell */
+	sync_array_t*	arr,	/* in: wait array */
+	ulint		index);	 /* in: index of the reserved cell */
 /**********************************************************************
-Frees the cell. NOTE! sync_array_wait_event frees the cell
-automatically! */
+Frees the cell safely by reserving the sync array mutex and decrementing
+n_reserved if necessary. Should only be called from mutex_spin_wait. */
 
 void
-sync_array_free_cell(
-/*=================*/
+sync_array_free_cell_protected(
+/*===========================*/
 	sync_array_t*	arr,	/* in: wait array */
-        ulint    	index);  /* in: index of the cell in array */
+	ulint		index);	/* in: index of the cell in array */
 /**************************************************************************
-Note that one of the wait objects was signalled. */
+Looks for the cells in the wait array which refer
+to the wait object specified,
+and sets their corresponding events to the signaled state. In this
+way releases the threads waiting for the object to contend for the object.
+It is possible that no such cell is found, in which case does nothing. */
 
 void
-sync_array_object_signalled(
-/*========================*/
-	sync_array_t*	arr);	/* in: wait array */
+sync_array_signal_object(
+/*=====================*/
+	sync_array_t*	arr,	/* in: wait array */
+	void*		object);/* in: wait object */
 /**************************************************************************
 If the wakeup algorithm does not work perfectly at semaphore relases,
 this function will do the waking (see the comment in mutex_exit). This

--- 1.11.3.1/innobase/include/sync0rw.h	2007-01-17 16:44:04 -07:00
+++ 1.21/storage/innobase/include/sync0rw.h	2007-01-17 17:18:03 -07:00
@@ -31,7 +31,7 @@
 
 typedef UT_LIST_BASE_NODE_T(rw_lock_t)	rw_lock_list_t;
 
-extern rw_lock_list_t 	rw_lock_list;
+extern rw_lock_list_t	rw_lock_list;
 extern mutex_t		rw_lock_list_mutex;
 
 #ifdef UNIV_SYNC_DEBUG
@@ -62,12 +62,18 @@
 to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
 is necessary only if the memory block containing it is freed. */
 #ifdef UNIV_DEBUG
-# define rw_lock_create(L) rw_lock_create_func((L), #L, __FILE__, __LINE__)
+# ifdef UNIV_SYNC_DEBUG
+#  define rw_lock_create(L, level) 					\
+	rw_lock_create_func((L), (level), #L, __FILE__, __LINE__)
+# else /* UNIV_SYNC_DEBUG */
+#  define rw_lock_create(L, level) 					\
+	rw_lock_create_func((L), #L, __FILE__, __LINE__)
+# endif /* UNIV_SYNC_DEBUG */
 #else /* UNIV_DEBUG */
-# define rw_lock_create(L) rw_lock_create_func((L), __FILE__, __LINE__)
+# define rw_lock_create(L, level) 					\
+	rw_lock_create_func((L), __FILE__, __LINE__)
 #endif /* UNIV_DEBUG */
 
-/*=====================*/
 /**********************************************************************
 Creates, or rather, initializes an rw-lock object in a specified memory
 location (which must be appropriately aligned). The rw-lock is initialized
@@ -79,10 +85,13 @@
 /*================*/
 	rw_lock_t*	lock,		/* in: pointer to memory */
 #ifdef UNIV_DEBUG
+# ifdef UNIV_SYNC_DEBUG
+	ulint		level,		/* in: level */
+# endif /* UNIV_SYNC_DEBUG */
 	const char*	cmutex_name, 	/* in: mutex name */
 #endif /* UNIV_DEBUG */
 	const char*	cfile_name,	/* in: file name where created */
-	ulint		cline);		/* in: file line where created */
+	ulint 		cline);		/* in: file line where created */
 /**********************************************************************
 Calling this function is obligatory only if the memory buffer containing
 the rw-lock is freed. Removes an rw-lock object from the global list. The
@@ -104,20 +113,20 @@
 NOTE! The following macros should be used in rw s-locking, not the
 corresponding function. */
 
-#define rw_lock_s_lock(M)    rw_lock_s_lock_func(\
-					  (M), 0, __FILE__, __LINE__)
+#define rw_lock_s_lock(M)	rw_lock_s_lock_func(\
+		(M), 0, __FILE__, __LINE__)
 /******************************************************************
 NOTE! The following macros should be used in rw s-locking, not the
 corresponding function. */
 
-#define rw_lock_s_lock_gen(M, P)    rw_lock_s_lock_func(\
-					  (M), (P), __FILE__, __LINE__)
+#define rw_lock_s_lock_gen(M, P)	rw_lock_s_lock_func(\
+		(M), (P), __FILE__, __LINE__)
 /******************************************************************
 NOTE! The following macros should be used in rw s-locking, not the
 corresponding function. */
 
-#define rw_lock_s_lock_nowait(M)    rw_lock_s_lock_func_nowait(\
-					     (M), __FILE__, __LINE__)
+#define rw_lock_s_lock_nowait(M)	rw_lock_s_lock_func_nowait(\
+		(M), __FILE__, __LINE__)
 /**********************************************************************
 NOTE! Use the corresponding macro, not directly this function, except if
 you supply the file name and line number. Lock an rw-lock in shared mode
@@ -129,7 +138,7 @@
 void
 rw_lock_s_lock_func(
 /*================*/
-        rw_lock_t*   	lock,  	/* in: pointer to rw-lock */
+	rw_lock_t*	lock,	/* in: pointer to rw-lock */
 	ulint		pass,	/* in: pass value; != 0, if the lock will
 				be passed to another thread to unlock */
 	const char*	file_name,/* in: file name where lock requested */
@@ -143,7 +152,7 @@
 rw_lock_s_lock_func_nowait(
 /*=======================*/
 				/* out: TRUE if success */
-        rw_lock_t*   	lock,  	/* in: pointer to rw-lock */
+	rw_lock_t*	lock,	/* in: pointer to rw-lock */
 	const char*	file_name,/* in: file name where lock requested */
 	ulint		line);	/* in: line where requested */
 /**********************************************************************
@@ -155,7 +164,7 @@
 rw_lock_x_lock_func_nowait(
 /*=======================*/
 				/* out: TRUE if success */
-        rw_lock_t*   	lock,  	/* in: pointer to rw-lock */
+	rw_lock_t*	lock,	/* in: pointer to rw-lock */
 	const char*	file_name,/* in: file name where lock requested */
 	ulint		line);	/* in: line where requested */
 /**********************************************************************
@@ -174,36 +183,36 @@
 Releases a shared mode lock. */
 
 #ifdef UNIV_SYNC_DEBUG
-#define rw_lock_s_unlock(L)    rw_lock_s_unlock_func(L, 0)
+#define rw_lock_s_unlock(L)	rw_lock_s_unlock_func(L, 0)
 #else
-#define rw_lock_s_unlock(L)    rw_lock_s_unlock_func(L)
+#define rw_lock_s_unlock(L)	rw_lock_s_unlock_func(L)
 #endif
 /***********************************************************************
 Releases a shared mode lock. */
 
 #ifdef UNIV_SYNC_DEBUG
-#define rw_lock_s_unlock_gen(L, P)    rw_lock_s_unlock_func(L, P)
+#define rw_lock_s_unlock_gen(L, P)	rw_lock_s_unlock_func(L, P)
 #else
-#define rw_lock_s_unlock_gen(L, P)    rw_lock_s_unlock_func(L)
+#define rw_lock_s_unlock_gen(L, P)	rw_lock_s_unlock_func(L)
 #endif
 /******************************************************************
 NOTE! The following macro should be used in rw x-locking, not the
 corresponding function. */
 
-#define rw_lock_x_lock(M)    rw_lock_x_lock_func(\
-					  (M), 0, __FILE__, __LINE__)
+#define rw_lock_x_lock(M)	rw_lock_x_lock_func(\
+		(M), 0, __FILE__, __LINE__)
 /******************************************************************
 NOTE! The following macro should be used in rw x-locking, not the
 corresponding function. */
 
-#define rw_lock_x_lock_gen(M, P)    rw_lock_x_lock_func(\
-					  (M), (P), __FILE__, __LINE__)
+#define rw_lock_x_lock_gen(M, P)	rw_lock_x_lock_func(\
+		(M), (P), __FILE__, __LINE__)
 /******************************************************************
 NOTE! The following macros should be used in rw x-locking, not the
 corresponding function. */
 
-#define rw_lock_x_lock_nowait(M)    rw_lock_x_lock_func_nowait(\
-					     (M), __FILE__, __LINE__)
+#define rw_lock_x_lock_nowait(M)	rw_lock_x_lock_func_nowait(\
+		(M), __FILE__, __LINE__)
 /**********************************************************************
 NOTE! Use the corresponding macro, not directly this function! Lock an
 rw-lock in exclusive mode for the current thread. If the rw-lock is locked
@@ -217,7 +226,7 @@
 void
 rw_lock_x_lock_func(
 /*================*/
-        rw_lock_t*   	lock,  	/* in: pointer to rw-lock */
+	rw_lock_t*	lock,	/* in: pointer to rw-lock */
 	ulint		pass,	/* in: pass value; != 0, if the lock will
 				be passed to another thread to unlock */
 	const char*	file_name,/* in: file name where lock requested */
@@ -238,17 +247,17 @@
 Releases an exclusive mode lock. */
 
 #ifdef UNIV_SYNC_DEBUG
-#define rw_lock_x_unlock(L)    rw_lock_x_unlock_func(L, 0)
+#define rw_lock_x_unlock(L)	rw_lock_x_unlock_func(L, 0)
 #else
-#define rw_lock_x_unlock(L)    rw_lock_x_unlock_func(L)
+#define rw_lock_x_unlock(L)	rw_lock_x_unlock_func(L)
 #endif
 /***********************************************************************
 Releases an exclusive mode lock. */
 
 #ifdef UNIV_SYNC_DEBUG
-#define rw_lock_x_unlock_gen(L, P)    rw_lock_x_unlock_func(L, P)
+#define rw_lock_x_unlock_gen(L, P)	rw_lock_x_unlock_func(L, P)
 #else
-#define rw_lock_x_unlock_gen(L, P)    rw_lock_x_unlock_func(L)
+#define rw_lock_x_unlock_gen(L, P)	rw_lock_x_unlock_func(L)
 #endif
 /**********************************************************************
 Low-level function which locks an rw-lock in s-mode when we know that it
@@ -305,14 +314,6 @@
 /*====================*/
 	rw_lock_t*	lock);	/* in: rw-lock */
 /**********************************************************************
-Sets the rw-lock latching level field. */
-
-void
-rw_lock_set_level(
-/*==============*/
-	rw_lock_t*	lock,	/* in: rw-lock */
-	ulint		level);	/* in: level */
-/**********************************************************************
 Returns the value of writer_count for the lock. Does not reserve the lock
 mutex, so the caller must be sure it is not changed during the call. */
 UNIV_INLINE
@@ -371,8 +372,9 @@
 Prints debug info of currently locked rw-locks. */
 
 void
-rw_lock_list_print_info(void);
-/*=========================*/
+rw_lock_list_print_info(
+/*====================*/
+	FILE*	file);		/* in: file where to print */
 /*******************************************************************
 Returns the number of currently locked rw-locks.
 Works only in the debug version. */
@@ -417,10 +419,9 @@
 field. Then no new readers are allowed in. */
 
 struct rw_lock_struct {
-	os_event_t	event;	/* Used by sync0arr.c for thread queueing */
 	ulint	reader_count;	/* Number of readers who have locked this
 				lock in the shared mode */
-	ulint	writer; 	/* This field is set to RW_LOCK_EX if there
+	ulint	writer;		/* This field is set to RW_LOCK_EX if there
 				is a writer owning the lock (in exclusive
 				mode), RW_LOCK_WAIT_EX if a writer is
 				queueing for the lock, and
@@ -431,7 +432,7 @@
 				recursively locked the lock in the exclusive
 				mode */
 	mutex_t	mutex;		/* The mutex protecting rw_lock_struct */
-	ulint	pass; 		/* Default value 0. This is set to some
+	ulint	pass;		/* Default value 0. This is set to some
 				value != 0 given by the caller of an x-lock
 				operation, if the x-lock is to be passed to
 				another thread to unlock (which happens in
@@ -440,13 +441,6 @@
 				waiters (readers or writers) in the global
 				wait array, waiting for this rw_lock.
 				Otherwise, == 0. */
-	ibool	writer_is_wait_ex;
-				/* This is TRUE if the writer field is
-				RW_LOCK_WAIT_EX; this field is located far
-				from the memory update hotspot fields which
-				are at the start of this struct, thus we can
-				peek this field without causing much memory
-				bus traffic */
 	UT_LIST_NODE_T(rw_lock_t) list;
 				/* All allocated rw locks are put into a
 				list */
@@ -454,15 +448,21 @@
 	UT_LIST_BASE_NODE_T(rw_lock_debug_t) debug_list;
 				/* In the debug version: pointer to the debug
 				info list of the lock */
+	ulint	level;		/* Level in the global latching order. */
 #endif /* UNIV_SYNC_DEBUG */
-	ulint	level;		/* Level in the global latching
-				order; default SYNC_LEVEL_NONE */
 	const char*	cfile_name;/* File name where lock created */
-	ulint	cline;		/* Line where created */
 	const char*	last_s_file_name;/* File name where last s-locked */
 	const char*	last_x_file_name;/* File name where last x-locked */
-	ulint	last_s_line;	/* Line number where last time s-locked */
-	ulint	last_x_line;	/* Line number where last time x-locked */
+	ibool		writer_is_wait_ex;
+				/* This is TRUE if the writer field is
+				RW_LOCK_WAIT_EX; this field is located far
+				from the memory update hotspot fields which
+				are at the start of this struct, thus we can
+				peek this field without causing much memory
+				bus traffic */
+	unsigned	cline:14;	/* Line where created */
+	unsigned	last_s_line:14;	/* Line number where last time s-locked */
+	unsigned	last_x_line:14;	/* Line number where last time x-locked */
 	ulint	magic_n;
 };
 

--- 1.9.5.1/innobase/include/sync0rw.ic	2007-01-17 16:44:04 -07:00
+++ 1.17/storage/innobase/include/sync0rw.ic	2007-01-17 17:18:03 -07:00
@@ -15,7 +15,7 @@
 void
 rw_lock_s_lock_spin(
 /*================*/
-        rw_lock_t*   	lock,  	/* in: pointer to rw-lock */
+	rw_lock_t*	lock,	/* in: pointer to rw-lock */
 	ulint		pass,	/* in: pass value; != 0, if the lock will
 				be passed to another thread to unlock */
 	const char*	file_name,/* in: file name where lock requested */
@@ -126,9 +126,9 @@
 rw_lock_s_lock_low(
 /*===============*/
 				/* out: TRUE if success */
-        rw_lock_t*   	lock,  	/* in: pointer to rw-lock */
+	rw_lock_t*	lock,	/* in: pointer to rw-lock */
 	ulint		pass __attribute__((unused)),
-                                /* in: pass value; != 0, if the lock will be
+				/* in: pass value; != 0, if the lock will be
 				passed to another thread to unlock */
 	const char*	file_name, /* in: file name where lock requested */
 	ulint		line)	/* in: line where requested */
@@ -144,7 +144,7 @@
 
 #ifdef UNIV_SYNC_DEBUG
 		rw_lock_add_debug_info(lock, pass, RW_LOCK_SHARED, file_name,
-									line);
+				       line);
 #endif
 		lock->last_s_file_name = file_name;
 		lock->last_s_line = line;
@@ -169,7 +169,7 @@
 {
 	ut_ad(lock->writer == RW_LOCK_NOT_LOCKED);
 	ut_ad(rw_lock_get_reader_count(lock) == 0);
-	
+
 	/* Set the shared lock by incrementing the reader count */
 	lock->reader_count++;
 
@@ -193,7 +193,7 @@
 	const char*	file_name,	/* in: file name where requested */
 	ulint		line)		/* in: line where lock requested */
 {
-        ut_ad(rw_lock_validate(lock));
+	ut_ad(rw_lock_validate(lock));
 	ut_ad(rw_lock_get_reader_count(lock) == 0);
 	ut_ad(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED);
 
@@ -201,7 +201,7 @@
 	lock->writer_thread = os_thread_get_curr_id();
 	lock->writer_count++;
 	lock->pass = 0;
-			
+
 	lock->last_x_file_name = file_name;
 	lock->last_x_line = line;
 
@@ -220,7 +220,7 @@
 void
 rw_lock_s_lock_func(
 /*================*/
-        rw_lock_t*   	lock,  	/* in: pointer to rw-lock */
+	rw_lock_t*	lock,	/* in: pointer to rw-lock */
 	ulint		pass,	/* in: pass value; != 0, if the lock will
 				be passed to another thread to unlock */
 	const char*	file_name,/* in: file name where lock requested */
@@ -236,7 +236,7 @@
 	safe recursive s-locking, we should keep in a list the thread ids of
 	the threads which have s-locked a latch. This would use some CPU
 	time. */
-	
+
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(!rw_lock_own(lock, RW_LOCK_SHARED)); /* see NOTE above */
 #endif /* UNIV_SYNC_DEBUG */
@@ -266,7 +266,7 @@
 rw_lock_s_lock_func_nowait(
 /*=======================*/
 				/* out: TRUE if success */
-        rw_lock_t*   	lock,  	/* in: pointer to rw-lock */
+	rw_lock_t*	lock,	/* in: pointer to rw-lock */
 	const char*	file_name,/* in: file name where lock requested */
 	ulint		line)	/* in: line where requested */
 {
@@ -280,12 +280,12 @@
 
 #ifdef UNIV_SYNC_DEBUG
 		rw_lock_add_debug_info(lock, 0, RW_LOCK_SHARED, file_name,
-									line);
+				       line);
 #endif
 
 		lock->last_s_file_name = file_name;
 		lock->last_s_line = line;
-		
+
 		success = TRUE;
 	}
 
@@ -303,7 +303,7 @@
 rw_lock_x_lock_func_nowait(
 /*=======================*/
 				/* out: TRUE if success */
-        rw_lock_t*   	lock,  	/* in: pointer to rw-lock */
+	rw_lock_t*	lock,	/* in: pointer to rw-lock */
 	const char*	file_name,/* in: file name where lock requested */
 	ulint		line)	/* in: line where requested */
 {
@@ -317,9 +317,9 @@
 		rw_lock_set_writer(lock, RW_LOCK_EX);
 		lock->writer_thread = curr_thread;
 		lock->pass = 0;
-	relock:
+relock:
 		lock->writer_count++;
-			
+
 #ifdef UNIV_SYNC_DEBUG
 		rw_lock_add_debug_info(lock, 0, RW_LOCK_EX, file_name, line);
 #endif
@@ -329,14 +329,14 @@
 
 		success = TRUE;
 	} else if (rw_lock_get_writer(lock) == RW_LOCK_EX
-			&& lock->pass == 0
-			&& os_thread_eq(lock->writer_thread, curr_thread)) {
+		   && lock->pass == 0
+		   && os_thread_eq(lock->writer_thread, curr_thread)) {
 		goto relock;
 	}
 
 	mutex_exit(rw_lock_get_mutex(lock));
 
-        ut_ad(rw_lock_validate(lock));
+	ut_ad(rw_lock_validate(lock));
 
 	return(success);
 }
@@ -355,9 +355,9 @@
 	)
 {
 	mutex_t*	mutex	= &(lock->mutex);
-	ibool		sg 	= FALSE;
+	ibool		sg	= FALSE;
 
-        /* Acquire the mutex protecting the rw-lock fields */
+	/* Acquire the mutex protecting the rw-lock fields */
 	mutex_enter(mutex);
 
 	/* Reset the shared lock by decrementing the reader count */
@@ -368,25 +368,24 @@
 #ifdef UNIV_SYNC_DEBUG
 	rw_lock_remove_debug_info(lock, pass, RW_LOCK_SHARED);
 #endif
-	
+
 	/* If there may be waiters and this was the last s-lock,
 	signal the object */
 
 	if (UNIV_UNLIKELY(lock->waiters)
-			&& lock->reader_count == 0) {
-	       	sg = TRUE;
+	    && lock->reader_count == 0) {
+		sg = TRUE;
 
 		rw_lock_set_waiters(lock, 0);
 	}
-	
+
 	mutex_exit(mutex);
 
 	if (UNIV_UNLIKELY(sg)) {
-		os_event_set(lock->event);
-		sync_array_object_signalled(sync_primary_wait_array);
+		sync_array_signal_object(sync_primary_wait_array, lock);
 	}
 
-        ut_ad(rw_lock_validate(lock));
+	ut_ad(rw_lock_validate(lock));
 
 #ifdef UNIV_SYNC_PERF_STAT
 	rw_s_exit_count++;
@@ -413,7 +412,7 @@
 #endif
 
 	ut_ad(!lock->waiters);
-        ut_ad(rw_lock_validate(lock));
+	ut_ad(rw_lock_validate(lock));
 #ifdef UNIV_SYNC_PERF_STAT
 	rw_s_exit_count++;
 #endif
@@ -432,9 +431,9 @@
 #endif
 	)
 {
-	ibool	sg 	= FALSE;
+	ibool	sg	= FALSE;
 
-        /* Acquire the mutex protecting the rw-lock fields */
+	/* Acquire the mutex protecting the rw-lock fields */
 	mutex_enter(&(lock->mutex));
 
 	/* Reset the exclusive lock if this thread no longer has an x-mode
@@ -451,23 +450,22 @@
 #ifdef UNIV_SYNC_DEBUG
 	rw_lock_remove_debug_info(lock, pass, RW_LOCK_EX);
 #endif
-	
+
 	/* If there may be waiters, signal the lock */
 	if (UNIV_UNLIKELY(lock->waiters)
-			&& lock->writer_count == 0) {
+	    && lock->writer_count == 0) {
 
-	       	sg = TRUE;
+		sg = TRUE;
 		rw_lock_set_waiters(lock, 0);
 	}
-	
+
 	mutex_exit(&(lock->mutex));
 
 	if (UNIV_UNLIKELY(sg)) {
-		os_event_set(lock->event);
-		sync_array_object_signalled(sync_primary_wait_array);
+		sync_array_signal_object(sync_primary_wait_array, lock);
 	}
 
-        ut_ad(rw_lock_validate(lock));
+	ut_ad(rw_lock_validate(lock));
 
 #ifdef UNIV_SYNC_PERF_STAT
 	rw_x_exit_count++;
@@ -499,7 +497,7 @@
 #endif
 
 	ut_ad(!lock->waiters);
-        ut_ad(rw_lock_validate(lock));
+	ut_ad(rw_lock_validate(lock));
 
 #ifdef UNIV_SYNC_PERF_STAT
 	rw_x_exit_count++;

--- 1.22.4.1/innobase/include/sync0sync.h	2007-01-17 16:44:04 -07:00
+++ 1.32/storage/innobase/include/sync0sync.h	2007-01-17 17:18:03 -07:00
@@ -18,7 +18,7 @@
 #include "sync0arr.h"
 
 #ifndef UNIV_HOTBACKUP
-extern my_bool  timed_mutexes;
+extern my_bool	timed_mutexes;
 #endif /* UNIV_HOTBACKUP */
 
 /**********************************************************************
@@ -40,11 +40,18 @@
 necessary only if the memory block containing it is freed. */
 
 #ifdef UNIV_DEBUG
-# define mutex_create(M) mutex_create_func((M), #M, __FILE__, __LINE__)
+# ifdef UNIV_SYNC_DEBUG
+#  define mutex_create(M, level)					\
+	mutex_create_func((M), #M, (level), __FILE__, __LINE__)
+# else
+#  define mutex_create(M, level)					\
+	mutex_create_func((M), #M, __FILE__, __LINE__)
+# endif
 #else
-# define mutex_create(M) mutex_create_func((M), __FILE__, __LINE__)
+# define mutex_create(M, level)					\
+	mutex_create_func((M), __FILE__, __LINE__)
 #endif
-/*===================*/
+
 /**********************************************************************
 Creates, or rather, initializes a mutex object in a specified memory
 location (which must be appropriately aligned). The mutex is initialized
@@ -57,6 +64,9 @@
 	mutex_t*	mutex,		/* in: pointer to memory */
 #ifdef UNIV_DEBUG
 	const char*	cmutex_name,	/* in: mutex name */
+# ifdef UNIV_SYNC_DEBUG
+	ulint		level,		/* in: level */
+# endif /* UNIV_SYNC_DEBUG */
 #endif /* UNIV_DEBUG */
 	const char*	cfile_name,	/* in: file name where created */
 	ulint		cline);		/* in: file line where created */
@@ -74,7 +84,7 @@
 NOTE! The following macro should be used in mutex locking, not the
 corresponding function. */
 
-#define mutex_enter(M)    mutex_enter_func((M), __FILE__, __LINE__)
+#define mutex_enter(M)	  mutex_enter_func((M), __FILE__, __LINE__)
 /**********************************************************************
 A noninlined function that reserves a mutex. In ha_innodb.cc we have disabled
 inlining of InnoDB functions, and no inlined functions should be called from
@@ -90,8 +100,8 @@
 
 /* NOTE! currently same as mutex_enter! */
 
-#define mutex_enter_fast(M)    	mutex_enter_func((M), __FILE__, __LINE__)
-#define mutex_enter_fast_func  	mutex_enter_func;
+#define mutex_enter_fast(M)	mutex_enter_func((M), __FILE__, __LINE__)
+#define mutex_enter_fast_func	mutex_enter_func;
 /**********************************************************************
 NOTE! Use the corresponding macro in the header file, not this function
 directly. Locks a mutex for the current thread. If the mutex is reserved
@@ -102,7 +112,7 @@
 mutex_enter_func(
 /*=============*/
 	mutex_t*	mutex,		/* in: pointer to mutex */
-	const char*	file_name, 	/* in: file name where locked */
+	const char*	file_name,	/* in: file name where locked */
 	ulint		line);		/* in: line where locked */
 /************************************************************************
 Tries to lock the mutex for the current thread. If the lock is not acquired
@@ -153,6 +163,7 @@
 sync_print(
 /*=======*/
 	FILE*	file);		/* in: file where to print */
+#ifdef UNIV_DEBUG
 /**********************************************************************
 Checks that the mutex has been initialized. */
 
@@ -160,14 +171,8 @@
 mutex_validate(
 /*===========*/
 	mutex_t*	mutex);
-/**********************************************************************
-Sets the mutex latching level field. */
-
-void
-mutex_set_level(
-/*============*/
-	mutex_t*	mutex,	/* in: mutex */
-	ulint		level);	/* in: level */
+#endif /* UNIV_DEBUG */
+#ifdef UNIV_SYNC_DEBUG
 /**********************************************************************
 Adds a latch and its level in the thread level array. Allocates the memory
 for the array if called first time for this OS thread. Makes the checks
@@ -177,8 +182,8 @@
 sync_thread_add_level(
 /*==================*/
 	void*	latch,	/* in: pointer to a mutex or an rw-lock */
-	ulint	level);	/* in: level in the latching order; if SYNC_LEVEL_NONE,
-			nothing is done */			
+	ulint	level);	/* in: level in the latching order; if
+			SYNC_LEVEL_VARYING, nothing is done */
 /**********************************************************************
 Removes a latch from the thread level array if it is found there. */
 
@@ -209,7 +214,6 @@
 					allowed to be owned by the thread,
 					also purge_is_running mutex is
 					allowed */
-#ifdef UNIV_SYNC_DEBUG
 /**********************************************************************
 Checks that the current thread owns the mutex. Works only
 in the debug version. */
@@ -236,12 +240,6 @@
 ulint
 mutex_n_reserved(void);
 /*==================*/
-/**********************************************************************
-Prints debug info of currently reserved mutexes. */
-
-void
-mutex_list_print_info(void);
-/*========================*/
 #endif /* UNIV_SYNC_DEBUG */
 /**********************************************************************
 NOT to be used outside this module except in debugging! Gets the value
@@ -259,7 +257,7 @@
 ulint
 mutex_get_waiters(
 /*==============*/
-				/* out: value to set */		
+				/* out: value to set */
 	mutex_t*	mutex);	/* in: mutex */
 #endif /* UNIV_SYNC_DEBUG */
 
@@ -275,7 +273,7 @@
 
 Synchronization object			Notes
 ----------------------			-----
-		
+
 Dictionary mutex			If we have a pointer to a dictionary
 |					object, e.g., a table, it can be
 |					accessed without reserving the
@@ -287,7 +285,7 @@
 V
 Dictionary header
 |
-V					
+V
 Secondary index tree latch		The tree latch protects also all
 |					the B-tree non-leaf pages. These
 V					can be read with the page only
@@ -299,7 +297,7 @@
 |					it is allowed to latch non-leaf pages
 |					even after it has acquired the fsp
 |					latch.
-V					
+V
 Secondary index leaf			The latch on the secondary index leaf
 |					can be kept while accessing the
 |					clustered index, to save CPU time.
@@ -307,7 +305,7 @@
 Clustered index tree latch		To increase concurrency, the tree
 |					latch is usually released when the
 |					leaf page latch has been acquired.
-V					
+V
 Clustered index non-leaf
 |
 V
@@ -325,7 +323,7 @@
 |					trx undo mutex reserved, it is allowed
 |					to latch the undo log pages in any
 |					order, and also after it has acquired
-|					the fsp latch. 
+|					the fsp latch.
 V
 Rollback segment mutex			The rollback segment mutex must be
 |					reserved, if, e.g., a new page must
@@ -389,7 +387,12 @@
 #define SYNC_USER_TRX_LOCK	9999
 #define SYNC_NO_ORDER_CHECK	3000	/* this can be used to suppress
 					latching order checking */
-#define	SYNC_LEVEL_NONE		2000	/* default: level not defined */
+#define	SYNC_LEVEL_VARYING	2000	/* Level is varying. Only used with
+					buffer pool page locks, which do not
+					have a fixed level, but instead have
+					their level set after the page is
+					locked; see e.g.
+					ibuf_bitmap_get_map_page(). */
 #define	SYNC_DICT_OPERATION	1001	/* table create, drop, etc. reserve
 					this in X-mode, implicit or backround
 					operations purge, rollback, foreign
@@ -418,7 +421,7 @@
 #define SYNC_EXTERN_STORAGE	500
 #define	SYNC_FSP		400
 #define	SYNC_FSP_PAGE		395
-/*------------------------------------- Insert buffer headers */ 
+/*------------------------------------- Insert buffer headers */
 /*------------------------------------- ibuf_mutex */
 /*------------------------------------- Insert buffer tree */
 #define	SYNC_IBUF_BITMAP_MUTEX	351
@@ -432,6 +435,7 @@
 #define SYNC_TRX_SYS_HEADER	290
 #define SYNC_LOG		170
 #define SYNC_RECV		168
+#define SYNC_WORK_QUEUE		161
 #define	SYNC_SEARCH_SYS		160	/* NOTE that if we have a memory
 					heap that can be extended to the
 					buffer pool, its logical level is
@@ -447,7 +451,7 @@
 #define	SYNC_MEM_POOL		130
 
 /* Codes used to designate lock operations */
-#define RW_LOCK_NOT_LOCKED 	350
+#define RW_LOCK_NOT_LOCKED	350
 #define RW_LOCK_EX		351
 #define RW_LOCK_EXCLUSIVE	351
 #define RW_LOCK_SHARED		352
@@ -459,7 +463,6 @@
 implementation of a mutual exclusion semaphore. */
 
 struct mutex_struct {
-	os_event_t	event;	/* Used by sync0arr.c for the wait queue */
 	ulint	lock_word;	/* This ulint is the target of the atomic
 				test-and-set instruction in Win32 */
 #if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER)
@@ -478,12 +481,14 @@
 	ulint	line;		/* Line where the mutex was locked */
 	os_thread_id_t thread_id; /* Debug version: The thread id of the
 				thread which locked the mutex. */
+	ulint	level;		/* Level in the global latching order */
 #endif /* UNIV_SYNC_DEBUG */
-	ulint	level;		/* Level in the global latching
-				order; default SYNC_LEVEL_NONE */
 	const char*	cfile_name;/* File name where mutex created */
-	ulint	cline;		/* Line where created */
-	ulint	magic_n;
+	ulint		cline;	/* Line where created */
+#ifdef UNIV_DEBUG
+	ulint		magic_n;
+# define MUTEX_MAGIC_N	(ulint)979585
+#endif /* UNIV_DEBUG */
 #ifndef UNIV_HOTBACKUP
 	ulong		count_os_wait; /* count of os_wait */
 # ifdef UNIV_DEBUG
@@ -499,8 +504,6 @@
 #endif /* !UNIV_HOTBACKUP */
 };
 
-#define MUTEX_MAGIC_N	(ulint)979585
-
 /* The global array of wait cells for implementation of the databases own
 mutexes and read-write locks. Appears here for debugging purposes only! */
 
@@ -512,20 +515,16 @@
 
 #define	SYNC_SPIN_ROUNDS	srv_n_spin_wait_rounds
 
-#define SYNC_INFINITE_TIME	((ulint)(-1))
-
-/* Means that a timeout elapsed when waiting */
-
-#define SYNC_TIME_EXCEEDED	(ulint)1
-
 /* The number of system calls made in this module. Intended for performance
 monitoring. */
 
-extern 	ulint	mutex_system_call_count;
+extern	ulint	mutex_system_call_count;
 extern	ulint	mutex_exit_count;
 
+#ifdef UNIV_SYNC_DEBUG
 /* Latching order checks start when this is set TRUE */
 extern ibool	sync_order_checks_on;
+#endif /* UNIV_SYNC_DEBUG */
 
 /* This variable is set to TRUE when sync_init is called */
 extern ibool	sync_initialized;

--- 1.24.6.1/innobase/os/os0sync.c	2007-01-17 16:44:05 -07:00
+++ 1.33/storage/innobase/os/os0sync.c	2007-01-17 17:18:03 -07:00
@@ -20,8 +20,7 @@
 #include "srv0start.h"
 
 /* Type definition for an operating system mutex struct */
-struct os_mutex_struct{ 
-	os_event_t	event;	/* Used by sync0arr.c for queing threads */
+struct os_mutex_struct{
 	void*		handle;	/* OS handle to mutex */
 	ulint		count;	/* we use this counter to check
 				that the same thread does not
@@ -36,7 +35,6 @@
 /* Mutex protecting counts and the lists of OS mutexes and events */
 os_mutex_t	os_sync_mutex;
 ibool		os_sync_mutex_inited	= FALSE;
-ibool		os_sync_free_called	= FALSE;
 
 /* This is incremented by 1 in os_thread_create and decremented by 1 in
 os_thread_exit */
@@ -52,10 +50,6 @@
 ulint	os_mutex_count		= 0;
 ulint	os_fast_mutex_count	= 0;
 
-/* Because a mutex is embedded inside an event and there is an
-event embedded inside a mutex, on free, this generates a recursive call.
-This version of the free event function doesn't acquire the global lock */
-static void os_event_free_internal(os_event_t	event);
 
 /*************************************************************
 Initializes global event and OS 'slow' mutex lists. */
@@ -82,31 +76,29 @@
 	os_event_t	event;
 	os_mutex_t	mutex;
 
-	os_sync_free_called = TRUE;
 	event = UT_LIST_GET_FIRST(os_event_list);
 
 	while (event) {
 
-	      os_event_free(event);
+		os_event_free(event);
 
-	      event = UT_LIST_GET_FIRST(os_event_list);
+		event = UT_LIST_GET_FIRST(os_event_list);
 	}
 
 	mutex = UT_LIST_GET_FIRST(os_mutex_list);
 
 	while (mutex) {
-	      if (mutex == os_sync_mutex) {
-		      /* Set the flag to FALSE so that we do not try to
-		      reserve os_sync_mutex any more in remaining freeing
-		      operations in shutdown */
-		      os_sync_mutex_inited = FALSE;
-	      }
+		if (mutex == os_sync_mutex) {
+			/* Set the flag to FALSE so that we do not try to
+			reserve os_sync_mutex any more in remaining freeing
+			operations in shutdown */
+			os_sync_mutex_inited = FALSE;
+		}
 
-	      os_mutex_free(mutex);
+		os_mutex_free(mutex);
 
-	      mutex = UT_LIST_GET_FIRST(os_mutex_list);
+		mutex = UT_LIST_GET_FIRST(os_mutex_list);
 	}
-	os_sync_free_called = FALSE;
 }
 
 /*************************************************************
@@ -122,18 +114,19 @@
 				the event is created without a name */
 {
 #ifdef __WIN__
-        os_event_t event;
+	os_event_t event;
 
 	event = ut_malloc(sizeof(struct os_event_struct));
 
-	event->handle = CreateEvent(NULL,/* No security attributes */
-			TRUE,		/* Manual reset */
-			FALSE,		/* Initial state nonsignaled */
-			(LPCTSTR) name);
+	event->handle = CreateEvent(NULL, /* No security attributes */
+				    TRUE, /* Manual reset */
+				    FALSE, /* Initial state nonsignaled */
+				    (LPCTSTR) name);
 	if (!event->handle) {
-	        fprintf(stderr,
-"InnoDB: Could not create a Windows event semaphore; Windows error %lu\n",
-		  (ulong) GetLastError());
+		fprintf(stderr,
+			"InnoDB: Could not create a Windows event semaphore;"
+			" Windows error %lu\n",
+			(ulong) GetLastError());
 	}
 #else /* Unix */
 	os_event_t	event;
@@ -146,7 +139,7 @@
 
 #if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
 	ut_a(0 == pthread_cond_init(&(event->cond_var),
-					pthread_condattr_default));
+				    pthread_condattr_default));
 #else
 	ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
 #endif
@@ -154,21 +147,14 @@
 	event->signal_count = 0;
 #endif /* __WIN__ */
 
-	/* The os_sync_mutex can be NULL because during startup an event
-	can be created [ because it's embedded in the mutex/rwlock ] before
-	this module has been initialized */
-	if (os_sync_mutex != NULL) {
-		os_mutex_enter(os_sync_mutex);
-	}
-
 	/* Put to the list of events */
+	os_mutex_enter(os_sync_mutex);
+
 	UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
 
 	os_event_count++;
 
-	if (os_sync_mutex != NULL) {
-		os_mutex_exit(os_sync_mutex);
-	}
+	os_mutex_exit(os_sync_mutex);
 
 	return(event);
 }
@@ -185,22 +171,23 @@
 	const char*	name)	/* in: the name of the event, if NULL
 				the event is created without a name */
 {
-        os_event_t event;
+	os_event_t event;
 
 	event = ut_malloc(sizeof(struct os_event_struct));
 
-	event->handle = CreateEvent(NULL,/* No security attributes */
-			FALSE,		/* Auto-reset */
-			FALSE,		/* Initial state nonsignaled */
-			(LPCTSTR) name);
+	event->handle = CreateEvent(NULL, /* No security attributes */
+				    FALSE, /* Auto-reset */
+				    FALSE, /* Initial state nonsignaled */
+				    (LPCTSTR) name);
 
 	if (!event->handle) {
-	        fprintf(stderr,
-"InnoDB: Could not create a Windows auto event semaphore; Windows error %lu\n",
-		  (ulong) GetLastError());
+		fprintf(stderr,
+			"InnoDB: Could not create a Windows auto"
+			" event semaphore; Windows error %lu\n",
+			(ulong) GetLastError());
 	}
 
-        /* Put to the list of events */
+	/* Put to the list of events */
 	os_mutex_enter(os_sync_mutex);
 
 	UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
@@ -222,7 +209,7 @@
 /*=========*/
 	os_event_t	event)	/* in: event to set */
 {
-#ifdef __WIN__	
+#ifdef __WIN__
 	ut_a(event);
 	ut_a(SetEvent(event->handle));
 #else
@@ -239,7 +226,7 @@
 	}
 
 	os_fast_mutex_unlock(&(event->os_mutex));
-#endif		
+#endif
 }
 
 /**************************************************************
@@ -271,42 +258,13 @@
 }
 
 /**************************************************************
-Frees an event object, without acquiring the global lock. */
-static
-void
-os_event_free_internal(
-/*===================*/
-	os_event_t	event)	/* in: event to free */
-{
-#ifdef __WIN__
-	ut_a(event);
-
-	ut_a(CloseHandle(event->handle));
-#else
-	ut_a(event);
-
-	/* This is to avoid freeing the mutex twice */
-	os_fast_mutex_free(&(event->os_mutex));
-
-	ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
-#endif
-	/* Remove from the list of events */
-
-	UT_LIST_REMOVE(os_event_list, os_event_list, event);
-
-	os_event_count--;
-
-	ut_free(event);
-}
-
-/**************************************************************
 Frees an event object. */
 
 void
 os_event_free(
 /*==========*/
 	os_event_t	event)	/* in: event to free */
-	
+
 {
 #ifdef __WIN__
 	ut_a(event);
@@ -318,7 +276,7 @@
 	os_fast_mutex_free(&(event->os_mutex));
 	ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
 #endif
-        /* Remove from the list of events */
+	/* Remove from the list of events */
 
 	os_mutex_enter(os_sync_mutex);
 
@@ -353,7 +311,7 @@
 	ut_a(err == WAIT_OBJECT_0);
 
 	if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
-	        os_thread_exit(NULL);
+		os_thread_exit(NULL);
 	}
 #else
 	ib_longlong	old_signal_count;
@@ -364,7 +322,7 @@
 
 	for (;;) {
 		if (event->is_set == TRUE
-			|| event->signal_count != old_signal_count) {
+		    || event->signal_count != old_signal_count) {
 
 			os_fast_mutex_unlock(&(event->os_mutex));
 
@@ -409,7 +367,7 @@
 	} else {
 		err = WaitForSingleObject(event->handle, INFINITE);
 	}
-	
+
 	if (err == WAIT_OBJECT_0) {
 
 		return(0);
@@ -422,7 +380,7 @@
 	}
 #else
 	UT_NOT_USED(time);
-	
+
 	/* In Posix this is just an ordinary, infinite wait */
 
 	os_event_wait(event);
@@ -453,14 +411,14 @@
 	ut_a(n > 0);
 
 	index = WaitForMultipleObjects((DWORD) n, native_event_array,
-					FALSE,	   /* Wait for any 1 event */
-					INFINITE); /* Infinite wait time
-						   limit */
+				       FALSE,	   /* Wait for any 1 event */
+				       INFINITE); /* Infinite wait time
+						  limit */
 	ut_a(index >= WAIT_OBJECT_0);	/* NOTE: Pointless comparision */
 	ut_a(index < WAIT_OBJECT_0 + n);
 
 	if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
-	        os_thread_exit(NULL);
+		os_thread_exit(NULL);
 	}
 
 	return(index - WAIT_OBJECT_0);
@@ -483,28 +441,27 @@
 	os_mutex_t	mutex_str;
 
 	mutex = CreateMutex(NULL,	/* No security attributes */
-			FALSE,		/* Initial state: no owner */
-			(LPCTSTR) name);
+			    FALSE,		/* Initial state: no owner */
+			    (LPCTSTR) name);
 	ut_a(mutex);
 #else
 	os_fast_mutex_t*	mutex;
 	os_mutex_t		mutex_str;
 
 	UT_NOT_USED(name);
-	
+
 	mutex = ut_malloc(sizeof(os_fast_mutex_t));
 
 	os_fast_mutex_init(mutex);
-#endif	
+#endif
 	mutex_str = ut_malloc(sizeof(os_mutex_str_t));
 
 	mutex_str->handle = mutex;
 	mutex_str->count = 0;
-	mutex_str->event = os_event_create(NULL);
 
 	if (os_sync_mutex_inited) {
 		/* When creating os_sync_mutex itself we cannot reserve it */
-	        os_mutex_enter(os_sync_mutex);
+		os_mutex_enter(os_sync_mutex);
 	}
 
 	UT_LIST_ADD_FIRST(os_mutex_list, os_mutex_list, mutex_str);
@@ -564,7 +521,7 @@
 	ut_a(ReleaseMutex(mutex->handle));
 #else
 	os_fast_mutex_unlock(mutex->handle);
-#endif	
+#endif
 }
 
 /**************************************************************
@@ -577,16 +534,12 @@
 {
 	ut_a(mutex);
 
-	if (!os_sync_free_called) {
-		os_event_free_internal(mutex->event);
-	}
-
 	if (os_sync_mutex_inited) {
 		os_mutex_enter(os_sync_mutex);
 	}
 
 	UT_LIST_REMOVE(os_mutex_list, os_mutex_list, mutex);
-	
+
 	os_mutex_count--;
 
 	if (os_sync_mutex_inited) {
@@ -614,7 +567,7 @@
 {
 #ifdef __WIN__
 	ut_a(fast_mutex);
-	
+
 	InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex);
 #else
 #if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
@@ -633,7 +586,7 @@
 	os_fast_mutex_count++;
 
 	if (os_sync_mutex_inited) {
-	        os_mutex_exit(os_sync_mutex);
+		os_mutex_exit(os_sync_mutex);
 	}
 }
 
@@ -681,18 +634,18 @@
 	DeleteCriticalSection((LPCRITICAL_SECTION) fast_mutex);
 #else
 	int	ret;
-	
+
 	ret = pthread_mutex_destroy(fast_mutex);
 
 	if (ret != 0) {
 		ut_print_timestamp(stderr);
 		fprintf(stderr,
-"  InnoDB: error: return value %lu when calling\n"
-"InnoDB: pthread_mutex_destroy().\n", (ulint)ret);
+			"  InnoDB: error: return value %lu when calling\n"
+			"InnoDB: pthread_mutex_destroy().\n", (ulint)ret);
 		fprintf(stderr,
-"InnoDB: Byte contents of the pthread mutex at %p:\n", fast_mutex);
-		ut_print_buf(stderr, (const byte*)fast_mutex,
-						sizeof(os_fast_mutex_t));
+			"InnoDB: Byte contents of the pthread mutex at %p:\n",
+			(void*) fast_mutex);
+		ut_print_buf(stderr, fast_mutex, sizeof(os_fast_mutex_t));
 		fprintf(stderr, "\n");
 	}
 #endif

--- 1.20.3.1/innobase/sync/sync0arr.c	2007-01-17 16:44:05 -07:00
+++ 1.28/storage/innobase/sync/sync0arr.c	2007-01-17 17:18:03 -07:00
@@ -46,13 +46,22 @@
 until a resource is released. The suspending is implemented
 using an operating system event semaphore. */
 struct sync_cell_struct {
-        void*           wait_object;    /* pointer to the object the
-                                        thread is waiting for; if NULL
-                                        the cell is free for use */
+	/* State of the cell. SC_WAKING_UP means
+	sync_array_struct->n_reserved has been decremented, but the thread
+	in this cell has not waken up yet. When it does, it will set the
+	state to SC_FREE. Note that this is done without the protection of
+	any mutex. */
+	enum { SC_FREE, SC_RESERVED, SC_WAKING_UP } state;
+
+	void*		wait_object;	/* pointer to the object the
+					thread is waiting for; this is not
+					reseted to NULL when a cell is
+					freed. */
+
 	mutex_t*	old_wait_mutex;	/* the latest wait mutex in cell */
 	rw_lock_t*	old_wait_rw_lock;/* the latest wait rw-lock in cell */
-        ulint		request_type;	/* lock type requested on the
-        				object */
+	ulint		request_type;	/* lock type requested on the
+					object */
 	const char*	file;		/* in debug version file where
 					requested */
 	ulint		line;		/* in debug version line where
@@ -62,15 +71,13 @@
 	ibool		waiting;	/* TRUE if the thread has already
 					called sync_array_event_wait
 					on this cell */
+	ibool		event_set;	/* TRUE if the event is set */
+	os_event_t	event;		/* operating system event
+					semaphore handle */
 	time_t		reservation_time;/* time when the thread reserved
 					the wait cell */
 };
 
-/* NOTE: It is allowed for a thread to wait
-for an event allocated for the array without owning the
-protecting mutex (depending on the case: OS or database mutex), but
-all changes (set or reset) to the state of the event must be made
-while owning the mutex. */
 struct sync_array_struct {
 	ulint		n_reserved;	/* number of currently reserved
 					cells in the wait array */
@@ -103,8 +110,8 @@
 sync_array_detect_deadlock(
 /*=======================*/
 				/* out: TRUE if deadlock detected */
-        sync_array_t*	arr,	/* in: wait array; NOTE! the caller must
-        			own the mutex to array */
+	sync_array_t*	arr,	/* in: wait array; NOTE! the caller must
+				own the mutex to array */
 	sync_cell_t*	start,	/* in: cell where recursive search started */
 	sync_cell_t*	cell,	/* in: cell to search */
 	ulint		depth);	/* in: recursion depth */
@@ -187,7 +194,7 @@
 	sync_cell_t*	cell_array;
 	sync_cell_t*	cell;
 	ulint		i;
-	
+
 	ut_a(n_cells > 0);
 
 	/* Allocate memory for the data structures */
@@ -202,20 +209,23 @@
 	arr->sg_count = 0;
 	arr->res_count = 0;
 
-        /* Then create the mutex to protect the wait array complex */
+	/* Then create the mutex to protect the wait array complex */
 	if (protection == SYNC_ARRAY_OS_MUTEX) {
 		arr->os_mutex = os_mutex_create(NULL);
 	} else if (protection == SYNC_ARRAY_MUTEX) {
-		mutex_create(&(arr->mutex));
-		mutex_set_level(&(arr->mutex), SYNC_NO_ORDER_CHECK);
+		mutex_create(&arr->mutex, SYNC_NO_ORDER_CHECK);
 	} else {
 		ut_error;
 	}
 
-        for (i = 0; i < n_cells; i++) {
-		cell = sync_array_get_nth_cell(arr, i);        	
-                cell->wait_object = NULL;
-		cell->waiting = FALSE;
+	for (i = 0; i < n_cells; i++) {
+		cell = sync_array_get_nth_cell(arr, i);
+		cell->state = SC_FREE;
+		cell->wait_object = NULL;
+
+		/* Create an operating system event semaphore with no name */
+		cell->event = os_event_create(NULL);
+		cell->event_set = FALSE; /* it is created in reset state */
 	}
 
 	return(arr);
@@ -229,15 +239,22 @@
 /*============*/
 	sync_array_t*	arr)	/* in, own: sync wait array */
 {
+	ulint		i;
+	sync_cell_t*	cell;
 	ulint		protection;
 
-        ut_a(arr->n_reserved == 0);
-        
+	ut_a(arr->n_reserved == 0);
+
 	sync_array_validate(arr);
-        
+
+	for (i = 0; i < arr->n_cells; i++) {
+		cell = sync_array_get_nth_cell(arr, i);
+		os_event_free(cell->event);
+	}
+
 	protection = arr->protection;
 
-        /* Release the mutex protecting the wait array complex */
+	/* Release the mutex protecting the wait array complex */
 
 	if (protection == SYNC_ARRAY_OS_MUTEX) {
 		os_mutex_free(arr->os_mutex);
@@ -248,7 +265,7 @@
 	}
 
 	ut_free(arr->array);
-	ut_free(arr);	
+	ut_free(arr);
 }
 
 /************************************************************************
@@ -260,40 +277,24 @@
 /*================*/
 	sync_array_t*	arr)	/* in: sync wait array */
 {
-        ulint           i;
-        sync_cell_t*   	cell;
-        ulint           count           = 0;
-        
-        sync_array_enter(arr);
-
-        for (i = 0; i < arr->n_cells; i++) {
-		cell = sync_array_get_nth_cell(arr, i);        	
-
-                if (cell->wait_object != NULL) {
-                        count++;
-                }
-        }
+	ulint		i;
+	sync_cell_t*	cell;
+	ulint		count		= 0;
 
-        ut_a(count == arr->n_reserved);
+	sync_array_enter(arr);
 
-        sync_array_exit(arr);
-}
+	for (i = 0; i < arr->n_cells; i++) {
+		cell = sync_array_get_nth_cell(arr, i);
 
-/***********************************************************************
-Puts the cell event in reset state. */
-static
-void
-sync_cell_event_reset(
-/*==================*/
-	ulint		type,	/* in: lock type mutex/rw_lock */
-	void*		object) /* in: the rw_lock/mutex object */
-{
-	if (type == SYNC_MUTEX) {
-		os_event_reset(((mutex_t *) object)->event);
-	} else {
-		os_event_reset(((rw_lock_t *) object)->event);
+		if (cell->state == SC_RESERVED) {
+			count++;
+		}
 	}
-}		
+
+	ut_a(count == arr->n_reserved);
+
+	sync_array_exit(arr);
+}
 
 /**********************************************************************
 Reserves a wait array cell for waiting for an object.
@@ -302,30 +303,42 @@
 void
 sync_array_reserve_cell(
 /*====================*/
-        sync_array_t*	arr,	/* in: wait array */
-        void*   	object, /* in: pointer to the object to wait for */
-        ulint		type,	/* in: lock request type */
+	sync_array_t*	arr,	/* in: wait array */
+	void*		object, /* in: pointer to the object to wait for */
+	ulint		type,	/* in: lock request type */
 	const char*	file,	/* in: file where requested */
-        ulint		line,	/* in: line where requested */
-        ulint*   	index)  /* out: index of the reserved cell */
+	ulint		line,	/* in: line where requested */
+	ulint*		index)	/* out: index of the reserved cell */
 {
-        sync_cell_t*   	cell;
-        ulint           i;
-        
-        ut_a(object);
-        ut_a(index);
+	sync_cell_t*	cell;
+	ulint		i;
 
-        sync_array_enter(arr);
+	ut_a(object);
+	ut_a(index);
 
-        arr->res_count++;
+	sync_array_enter(arr);
+
+	arr->res_count++;
 
 	/* Reserve a new cell. */
-        for (i = 0; i < arr->n_cells; i++) {
-		cell = sync_array_get_nth_cell(arr, i);        	
+	for (i = 0; i < arr->n_cells; i++) {
+		cell = sync_array_get_nth_cell(arr, i);
 
-                if (cell->wait_object == NULL) {
+		if (cell->state == SC_FREE) {
+
+			/* We do not check cell->event_set because it is
+			set outside the protection of the sync array mutex
+			and we had a bug regarding it, and since resetting
+			an event when it is not needed does no harm it is
+			safer always to do it. */
+
+			cell->event_set = FALSE;
+			os_event_reset(cell->event);
+
+			cell->state = SC_RESERVED;
+			cell->reservation_time = time(NULL);
+			cell->thread = os_thread_get_curr_id();
 
-			cell->waiting = FALSE;
 			cell->wait_object = object;
 
 			if (type == SYNC_MUTEX) {
@@ -333,32 +346,88 @@
 			} else {
 				cell->old_wait_rw_lock = object;
 			}
-				
+
 			cell->request_type = type;
-			
+			cell->waiting = FALSE;
+
 			cell->file = file;
 			cell->line = line;
-			
+
 			arr->n_reserved++;
 
 			*index = i;
 
 			sync_array_exit(arr);
 
-			/* Make sure the event is reset */
-			sync_cell_event_reset(type, object);
+			return;
+		}
+	}
 
-			cell->reservation_time = time(NULL);
+	ut_error; /* No free cell found */
 
-			cell->thread = os_thread_get_curr_id();
-                        
-                        return;
-                }
-        }
+	return;
+}
 
-        ut_error; /* No free cell found */
+/**********************************************************************
+Frees the cell. Note that we don't have any mutex reserved when calling
+this. */
+static
+void
+sync_array_free_cell(
+/*=================*/
+	sync_array_t*	arr,	/* in: wait array */
+	ulint		index)	/* in: index of the cell in array */
+{
+	sync_cell_t*	cell;
 
-	return;
+	cell = sync_array_get_nth_cell(arr, index);
+
+	ut_a(cell->state == SC_WAKING_UP);
+	ut_a(cell->wait_object != NULL);
+
+	cell->state = SC_FREE;
+}
+
+/**********************************************************************
+Frees the cell safely by reserving the sync array mutex and decrementing
+n_reserved if necessary. Should only be called from mutex_spin_wait. */
+
+void
+sync_array_free_cell_protected(
+/*===========================*/
+	sync_array_t*	arr,	/* in: wait array */
+	ulint		index)	/* in: index of the cell in array */
+{
+	sync_cell_t*	cell;
+
+	sync_array_enter(arr);
+
+	cell = sync_array_get_nth_cell(arr, index);
+
+	ut_a(cell->state != SC_FREE);
+	ut_a(cell->wait_object != NULL);
+
+	/* We only need to decrement n_reserved if it has not already been
+	done by sync_array_signal_object. */
+	if (cell->state == SC_RESERVED) {
+		ut_a(arr->n_reserved > 0);
+		arr->n_reserved--;
+	} else if (cell->state == SC_WAKING_UP) {
+		/* This is tricky; if we don't wait for the event to be
+		signaled, signal_object can set the state of a cell to
+		SC_WAKING_UP, mutex_spin_wait can call this and set the
+		state to SC_FREE, and then signal_object gets around to
+		calling os_set_event for the cell but since it's already
+		been freed things break horribly. */
+
+		sync_array_exit(arr);
+		os_event_wait(cell->event);
+		sync_array_enter(arr);
+	}
+
+	cell->state = SC_FREE;
+
+	sync_array_exit(arr);
 }
 
 /**********************************************************************
@@ -370,56 +439,51 @@
 void
 sync_array_wait_event(
 /*==================*/
-        sync_array_t*	arr,	/* in: wait array */
-        ulint   	index)  /* in: index of the reserved cell */
+	sync_array_t*	arr,	/* in: wait array */
+	ulint		index)	/* in: index of the reserved cell */
 {
-        sync_cell_t*   	cell;
-        os_event_t 	event;
-        
-        ut_a(arr);
+	sync_cell_t*	cell;
+	os_event_t	event;
 
-        sync_array_enter(arr);
+	ut_a(arr);
 
-	cell = sync_array_get_nth_cell(arr, index);        	
+	cell = sync_array_get_nth_cell(arr, index);
 
+	ut_a((cell->state == SC_RESERVED) || (cell->state == SC_WAKING_UP));
 	ut_a(cell->wait_object);
 	ut_a(!cell->waiting);
 	ut_ad(os_thread_get_curr_id() == cell->thread);
 
-	if (cell->request_type == SYNC_MUTEX) {
-		event = ((mutex_t*) cell->wait_object)->event;
-	} else {
-		event = ((rw_lock_t*) cell->wait_object)->event;
-	}
-
-       	cell->waiting = TRUE;
+	event = cell->event;
+	cell->waiting = TRUE;
 
 #ifdef UNIV_SYNC_DEBUG
-       	
+
 	/* We use simple enter to the mutex below, because if
 	we cannot acquire it at once, mutex_enter would call
 	recursively sync_array routines, leading to trouble.
 	rw_lock_debug_mutex freezes the debug lists. */
 
+	sync_array_enter(arr);
 	rw_lock_debug_mutex_enter();
 
 	if (TRUE == sync_array_detect_deadlock(arr, cell, cell, 0)) {
 
 		fputs("########################################\n", stderr);
 		ut_error;
-	}		
+	}
 
 	rw_lock_debug_mutex_exit();
+	sync_array_exit(arr);
 #endif
-        sync_array_exit(arr);
+	os_event_wait(event);
 
-        os_event_wait(event);
-
-        sync_array_free_cell(arr, index);
+	sync_array_free_cell(arr, index);
 }
 
 /**********************************************************************
-Reports info of a wait array cell. */
+Reports info of a wait array cell. Note: sync_array_print_long_waits()
+calls this without mutex protection. */
 static
 void
 sync_array_cell_print(
@@ -434,12 +498,22 @@
 	type = cell->request_type;
 
 	fprintf(file,
-"--Thread %lu has waited at %s line %lu for %.2f seconds the semaphore:\n",
-			(ulong) os_thread_pf(cell->thread), cell->file,
-		       (ulong) cell->line,
-		       difftime(time(NULL), cell->reservation_time));
+		"--Thread %lu has waited at %s line %lu"
+		" for %.2f seconds the semaphore:\n",
+		(ulong) os_thread_pf(cell->thread), cell->file,
+		(ulong) cell->line,
+		difftime(time(NULL), cell->reservation_time));
+	fprintf(file, "Wait array cell state %lu\n", (ulong)cell->state);
+
+	/* If the memory area pointed to by old_wait_mutex /
+	old_wait_rw_lock has been freed, this can crash. */
+
+	if (cell->state != SC_RESERVED) {
+		/* If cell has this state, then even if we are holding the sync
+		array mutex, the wait object may get freed meanwhile. Do not
+		print the wait object then. */
 
-	if (type == SYNC_MUTEX) {
+	} else if (type == SYNC_MUTEX) {
 		/* We use old_wait_mutex in case the cell has already
 		been freed meanwhile */
 		mutex = cell->old_wait_mutex;
@@ -450,7 +524,7 @@
 			"Last time reserved in file %s line %lu, "
 #endif /* UNIV_SYNC_DEBUG */
 			"waiters flag %lu\n",
-			mutex, mutex->cfile_name, (ulong) mutex->cline,
+			(void*) mutex, mutex->cfile_name, (ulong) mutex->cline,
 			(ulong) mutex->lock_word,
 #ifdef UNIV_SYNC_DEBUG
 			mutex->file_name, (ulong) mutex->line,
@@ -465,17 +539,18 @@
 
 		fprintf(file,
 			" RW-latch at %p created in file %s line %lu\n",
-			rwlock, rwlock->cfile_name,
+			(void*) rwlock, rwlock->cfile_name,
 			(ulong) rwlock->cline);
 		if (rwlock->writer != RW_LOCK_NOT_LOCKED) {
 			fprintf(file,
-			"a writer (thread id %lu) has reserved it in mode %s",
+				"a writer (thread id %lu) has"
+				" reserved it in mode %s",
 				(ulong) os_thread_pf(rwlock->writer_thread),
 				rwlock->writer == RW_LOCK_EX
 				? " exclusive\n"
 				: " wait exclusive\n");
 		}
-		
+
 		fprintf(file,
 			"number of readers %lu, waiters flag %lu\n"
 			"Last time read locked in file %s line %lu\n"
@@ -490,8 +565,8 @@
 		ut_error;
 	}
 
-        if (!cell->waiting) {
-		fputs("wait has ended\n", file);
+	if (cell->event_set) {
+		fputs("wait is ending\n", file);
 	}
 }
 
@@ -504,22 +579,22 @@
 /*===================*/
 				/* out: pointer to cell or NULL
 				if not found */
-        sync_array_t*	arr,	/* in: wait array */
+	sync_array_t*	arr,	/* in: wait array */
 	os_thread_id_t	thread)	/* in: thread id */
 {
-        ulint           i;
-        sync_cell_t*   	cell;
+	ulint		i;
+	sync_cell_t*	cell;
 
-        for (i = 0; i < arr->n_cells; i++) {
+	for (i = 0; i < arr->n_cells; i++) {
 
-		cell = sync_array_get_nth_cell(arr, i);        	
+		cell = sync_array_get_nth_cell(arr, i);
 
-                if (cell->wait_object != NULL
+		if ((cell->state == SC_RESERVED)
 		    && os_thread_eq(cell->thread, thread)) {
 
-		    	return(cell);	/* Found */
-                }
-        }
+			return(cell);	/* Found */
+		}
+	}
 
 	return(NULL);	/* Not found */
 }
@@ -531,8 +606,8 @@
 sync_array_deadlock_step(
 /*=====================*/
 				/* out: TRUE if deadlock detected */
-        sync_array_t*	arr,	/* in: wait array; NOTE! the caller must
-        			own the mutex to array */
+	sync_array_t*	arr,	/* in: wait array; NOTE! the caller must
+				own the mutex to array */
 	sync_cell_t*	start,	/* in: cell where recursive search
 				started */
 	os_thread_id_t	thread,	/* in: thread to look at */
@@ -551,7 +626,7 @@
 
 		return(FALSE);
 	}
-			    	
+
 	new = sync_array_find_thread(arr, thread);
 
 	if (new == start) {
@@ -561,7 +636,7 @@
 
 		/* Deadlock */
 		fputs("########################################\n"
-			"DEADLOCK of threads detected!\n", stderr);
+		      "DEADLOCK of threads detected!\n", stderr);
 
 		return(TRUE);
 
@@ -583,8 +658,8 @@
 sync_array_detect_deadlock(
 /*=======================*/
 				/* out: TRUE if deadlock detected */
-        sync_array_t*	arr,	/* in: wait array; NOTE! the caller must
-        			own the mutex to array */
+	sync_array_t*	arr,	/* in: wait array; NOTE! the caller must
+				own the mutex to array */
 	sync_cell_t*	start,	/* in: cell where recursive search started */
 	sync_cell_t*	cell,	/* in: cell to search */
 	ulint		depth)	/* in: recursion depth */
@@ -594,19 +669,19 @@
 	os_thread_id_t	thread;
 	ibool		ret;
 	rw_lock_debug_t*debug;
-	
-        ut_a(arr && start && cell);
+
+	ut_a(arr && start && cell);
 	ut_ad(cell->wait_object);
 	ut_ad(os_thread_get_curr_id() == start->thread);
 	ut_ad(depth < 100);
-	
+
 	depth++;
-	
-	if (!cell->waiting) {
+
+	if (cell->event_set || !cell->waiting) {
 
 		return(FALSE); /* No deadlock here */
 	}
-	
+
 	if (cell->request_type == SYNC_MUTEX) {
 
 		mutex = cell->wait_object;
@@ -624,11 +699,13 @@
 			a thread with ID_UNDEFINED value. */
 
 			ret = sync_array_deadlock_step(arr, start, thread, 0,
-								depth);
+						       depth);
 			if (ret) {
 				fprintf(stderr,
-			"Mutex %p owned by thread %lu file %s line %lu\n",
-					mutex, (ulong) os_thread_pf(mutex->thread_id),
+					"Mutex %p owned by thread %lu"
+					" file %s line %lu\n",
+					(void*) mutex,
+					(ulong) os_thread_pf(mutex->thread_id),
 					mutex->file_name, (ulong) mutex->line);
 				sync_array_cell_print(stderr, cell);
 
@@ -640,76 +717,79 @@
 
 	} else if (cell->request_type == RW_LOCK_EX) {
 
-	    lock = cell->wait_object;
-
-	    debug = UT_LIST_GET_FIRST(lock->debug_list);
+		lock = cell->wait_object;
 
-	    while (debug != NULL) {
+		debug = UT_LIST_GET_FIRST(lock->debug_list);
 
-		thread = debug->thread_id;
+		while (debug != NULL) {
 
-		if (((debug->lock_type == RW_LOCK_EX)
-	             && !os_thread_eq(thread, cell->thread))
-	            || ((debug->lock_type == RW_LOCK_WAIT_EX)
-			&& !os_thread_eq(thread, cell->thread))
-	            || (debug->lock_type == RW_LOCK_SHARED)) {
+			thread = debug->thread_id;
 
-			/* The (wait) x-lock request can block infinitely
-			only if someone (can be also cell thread) is holding
-			s-lock, or someone (cannot be cell thread) (wait)
-			x-lock, and he is blocked by start thread */
-
-			ret = sync_array_deadlock_step(arr, start, thread,
-							debug->pass,
-							depth);
-			if (ret) {
-			print:
-				fprintf(stderr, "rw-lock %p ", lock);
-				sync_array_cell_print(stderr, cell);
-				rw_lock_debug_print(debug);
-				return(TRUE);
+			if (((debug->lock_type == RW_LOCK_EX)
+			     && !os_thread_eq(thread, cell->thread))
+			    || ((debug->lock_type == RW_LOCK_WAIT_EX)
+				&& !os_thread_eq(thread, cell->thread))
+			    || (debug->lock_type == RW_LOCK_SHARED)) {
+
+				/* The (wait) x-lock request can block
+				infinitely only if someone (can be also cell
+				thread) is holding s-lock, or someone
+				(cannot be cell thread) (wait) x-lock, and
+				he is blocked by start thread */
+
+				ret = sync_array_deadlock_step(
+					arr, start, thread, debug->pass,
+					depth);
+				if (ret) {
+print:
+					fprintf(stderr, "rw-lock %p ",
+						(void*) lock);
+					sync_array_cell_print(stderr, cell);
+					rw_lock_debug_print(debug);
+					return(TRUE);
+				}
 			}
-		}
 
-		debug = UT_LIST_GET_NEXT(list, debug);
-	    }
+			debug = UT_LIST_GET_NEXT(list, debug);
+		}
 
-	    return(FALSE);
+		return(FALSE);
 
 	} else if (cell->request_type == RW_LOCK_SHARED) {
 
-	    lock = cell->wait_object;
-	    debug = UT_LIST_GET_FIRST(lock->debug_list);
-
-	    while (debug != NULL) {
-
-		thread = debug->thread_id;
+		lock = cell->wait_object;
+		debug = UT_LIST_GET_FIRST(lock->debug_list);
 
-		if ((debug->lock_type == RW_LOCK_EX)
-	            || (debug->lock_type == RW_LOCK_WAIT_EX)) {
+		while (debug != NULL) {
 
-			/* The s-lock request can block infinitely only if
-			someone (can also be cell thread) is holding (wait)
-			x-lock, and he is blocked by start thread */
+			thread = debug->thread_id;
 
-			ret = sync_array_deadlock_step(arr, start, thread,
-							debug->pass,
-							depth);
-			if (ret) {
-				goto print;
+			if ((debug->lock_type == RW_LOCK_EX)
+			    || (debug->lock_type == RW_LOCK_WAIT_EX)) {
+
+				/* The s-lock request can block infinitely
+				only if someone (can also be cell thread) is
+				holding (wait) x-lock, and he is blocked by
+				start thread */
+
+				ret = sync_array_deadlock_step(
+					arr, start, thread, debug->pass,
+					depth);
+				if (ret) {
+					goto print;
+				}
 			}
-		}
 
-		debug = UT_LIST_GET_NEXT(list, debug);
-	    }
+			debug = UT_LIST_GET_NEXT(list, debug);
+		}
 
-	    return(FALSE);
+		return(FALSE);
 
 	} else {
 		ut_error;
 	}
 
-	return(TRUE); 	/* Execution never reaches this line: for compiler
+	return(TRUE);	/* Execution never reaches this line: for compiler
 			fooling only */
 }
 #endif /* UNIV_SYNC_DEBUG */
@@ -724,7 +804,7 @@
 {
 	mutex_t*	mutex;
 	rw_lock_t*	lock;
-	
+
 	if (cell->request_type == SYNC_MUTEX) {
 
 		mutex = cell->wait_object;
@@ -736,15 +816,15 @@
 
 	} else if (cell->request_type == RW_LOCK_EX) {
 
-	    	lock = cell->wait_object;
+		lock = cell->wait_object;
 
-	    	if (rw_lock_get_reader_count(lock) == 0
+		if (rw_lock_get_reader_count(lock) == 0
 		    && rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
 
 			return(TRUE);
 		}
 
-	    	if (rw_lock_get_reader_count(lock) == 0
+		if (rw_lock_get_reader_count(lock) == 0
 		    && rw_lock_get_writer(lock) == RW_LOCK_WAIT_EX
 		    && os_thread_eq(lock->writer_thread, cell->thread)) {
 
@@ -752,10 +832,10 @@
 		}
 
 	} else if (cell->request_type == RW_LOCK_SHARED) {
-	    	lock = cell->wait_object;
+		lock = cell->wait_object;
 
 		if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
-		
+
 			return(TRUE);
 		}
 	}
@@ -763,95 +843,154 @@
 	return(FALSE);
 }
 
-/**********************************************************************
-Frees the cell. NOTE! sync_array_wait_event frees the cell
-automatically! */
+/**************************************************************************
+Looks for the cells in the wait array which refer to the wait object
+specified, and sets their corresponding events to the signaled state. In this
+way releases the threads waiting for the object to contend for the object.
+It is possible that no such cell is found, in which case does nothing. */
 
 void
-sync_array_free_cell(
-/*=================*/
+sync_array_signal_object(
+/*=====================*/
 	sync_array_t*	arr,	/* in: wait array */
-        ulint    	index)  /* in: index of the cell in array */
+	void*		object)	/* in: wait object */
 {
-        sync_cell_t*   	cell;
-        
-        sync_array_enter(arr);
+	sync_cell_t*	cell;
+	ulint		count;
+	ulint		i;
+	ulint		res_count;
 
-        cell = sync_array_get_nth_cell(arr, index);
+	/* We store the addresses of cells we need to signal and signal
+	them only after we have released the sync array's mutex (for
+	performance reasons). cell_count is the number of such cells, and
+	cell_ptr points to the first one. If there are less than
+	UT_ARR_SIZE(cells) of them, cell_ptr == &cells[0], otherwise
+	cell_ptr points to malloc'd memory that we must free. */
+
+	sync_cell_t*	cells[100];
+	sync_cell_t**	cell_ptr = &cells[0];
+	ulint		cell_count = 0;
+	ulint		cell_max_count = UT_ARR_SIZE(cells);
 
-        ut_a(cell->wait_object != NULL);
+	ut_a(100 == cell_max_count);
 
-	cell->waiting = FALSE;
-	cell->wait_object =  NULL;
+	sync_array_enter(arr);
 
-	ut_a(arr->n_reserved > 0);
-	arr->n_reserved--;
+	arr->sg_count++;
 
-        sync_array_exit(arr);
-}
+	i = 0;
+	count = 0;
 
-/**************************************************************************
-Increments the signalled count. */
+	/* We need to store this to a local variable because it is modified
+	inside the loop */
+	res_count = arr->n_reserved;
 
-void
-sync_array_object_signalled(
-/*========================*/
-	sync_array_t*	arr)	/* in: wait array */
-{
-        sync_array_enter(arr);
+	while (count < res_count) {
 
-	arr->sg_count++;
+		cell = sync_array_get_nth_cell(arr, i);
+
+		if (cell->state == SC_RESERVED) {
+
+			count++;
+			if (cell->wait_object == object) {
+				cell->state = SC_WAKING_UP;
+
+				ut_a(arr->n_reserved > 0);
+				arr->n_reserved--;
+
+				if (cell_count == cell_max_count) {
+					sync_cell_t** old_cell_ptr = cell_ptr;
+					size_t old_size, new_size;
+
+					old_size = cell_max_count
+						* sizeof(sync_cell_t*);
+					cell_max_count *= 2;
+					new_size = cell_max_count
+						* sizeof(sync_cell_t*);
+
+					cell_ptr = malloc(new_size);
+					ut_a(cell_ptr);
+					memcpy(cell_ptr, old_cell_ptr,
+					       old_size);
+
+					if (old_cell_ptr != &cells[0]) {
+						free(old_cell_ptr);
+					}
+				}
+
+				cell_ptr[cell_count] = cell;
+				cell_count++;
+			}
+		}
+
+		i++;
+	}
+
+	sync_array_exit(arr);
 
-        sync_array_exit(arr);
+	for (i = 0; i < cell_count; i++) {
+		cell = cell_ptr[i];
+
+		cell->event_set = TRUE;
+		os_event_set(cell->event);
+	}
+
+	if (cell_ptr != &cells[0]) {
+		free(cell_ptr);
+	}
 }
 
 /**************************************************************************
 If the wakeup algorithm does not work perfectly at semaphore relases,
 this function will do the waking (see the comment in mutex_exit). This
-function should be called about every 1 second in the server. */
+function should be called about every 1 second in the server.
+
+Note that there's a race condition between this thread and mutex_exit
+changing the lock_word and calling signal_object, so sometimes this finds
+threads to wake up even when nothing has gone wrong. */
 
 void
 sync_arr_wake_threads_if_sema_free(void)
 /*====================================*/
 {
-	sync_array_t*	arr 	= sync_primary_wait_array;
-        sync_cell_t*   	cell;
-        ulint           count;
-        ulint           i;
+	sync_array_t*	arr	= sync_primary_wait_array;
+	sync_cell_t*	cell;
+	ulint		count;
+	ulint		i;
+	ulint		res_count;
 
-        sync_array_enter(arr);
+	sync_array_enter(arr);
 
 	i = 0;
 	count = 0;
 
-        while (count < arr->n_reserved) {
+	/* We need to store this to a local variable because it is modified
+	inside the loop */
 
-        	cell = sync_array_get_nth_cell(arr, i);
+	res_count = arr->n_reserved;
 
-                if (cell->wait_object != NULL) {
+	while (count < res_count) {
 
-                        count++;
+		cell = sync_array_get_nth_cell(arr, i);
 
-                        if (sync_arr_cell_can_wake_up(cell)) {
+		if (cell->state == SC_RESERVED) {
 
-				if (cell->request_type == SYNC_MUTEX) {
-					mutex_t*	mutex;
+			count++;
 
-					mutex = cell->wait_object;
-					os_event_set(mutex->event);
-				} else {
-					rw_lock_t*	lock;
+			if (sync_arr_cell_can_wake_up(cell)) {
+				cell->state = SC_WAKING_UP;
+				cell->event_set = TRUE;
+				os_event_set(cell->event);
 
-					lock = cell->wait_object;
-					os_event_set(lock->event);
-				}
-                        }
-                }
+				ut_a(arr->n_reserved > 0);
+				arr->n_reserved--;
+			}
+		}
 
-                i++;
-        }
+		i++;
+	}
 
-        sync_array_exit(arr);
+	sync_array_exit(arr);
 }
 
 /**************************************************************************
@@ -863,36 +1002,37 @@
 			/* out: TRUE if fatal semaphore wait threshold
 			was exceeded */
 {
-        sync_cell_t*   	cell;
-        ibool		old_val;
+	sync_cell_t*	cell;
+	ibool		old_val;
 	ibool		noticed = FALSE;
-	ulint           i;
+	ulint		i;
 	ulint		fatal_timeout = srv_fatal_semaphore_wait_threshold;
 	ibool		fatal = FALSE;
 
-        for (i = 0; i < sync_primary_wait_array->n_cells; i++) {
+	for (i = 0; i < sync_primary_wait_array->n_cells; i++) {
 
-        	cell = sync_array_get_nth_cell(sync_primary_wait_array, i);
+		cell = sync_array_get_nth_cell(sync_primary_wait_array, i);
 
-		if (cell->wait_object != NULL && cell->waiting
+		if ((cell->state != SC_FREE)
 		    && difftime(time(NULL), cell->reservation_time) > 240) {
 			fputs("InnoDB: Warning: a long semaphore wait:\n",
-				stderr);
+			      stderr);
 			sync_array_cell_print(stderr, cell);
 			noticed = TRUE;
-                }
+		}
 
-		if (cell->wait_object != NULL && cell->waiting
+		if ((cell->state != SC_FREE)
 		    && difftime(time(NULL), cell->reservation_time)
 		    > fatal_timeout) {
 			fatal = TRUE;
-                }
-       	}
+		}
+	}
 
 	if (noticed) {
 		fprintf(stderr,
-"InnoDB: ###### Starts InnoDB Monitor for 30 secs to print diagnostic info:\n");
-        	old_val = srv_print_innodb_monitor;
+			"InnoDB: ###### Starts InnoDB Monitor"
+			" for 30 secs to print diagnostic info:\n");
+		old_val = srv_print_innodb_monitor;
 
 		/* If some crucial semaphore is reserved, then also the InnoDB
 		Monitor can hang, and we do not get diagnostics. Since in
@@ -901,17 +1041,19 @@
 		now the values of pending calls of these. */
 
 		fprintf(stderr,
-"InnoDB: Pending preads %lu, pwrites %lu\n", (ulong)os_file_n_pending_preads,
-				(ulong)os_file_n_pending_pwrites);
+			"InnoDB: Pending preads %lu, pwrites %lu\n",
+			(ulong)os_file_n_pending_preads,
+			(ulong)os_file_n_pending_pwrites);
 
-        	srv_print_innodb_monitor = TRUE;
+		srv_print_innodb_monitor = TRUE;
 		os_event_set(srv_lock_timeout_thread_event);
 
-        	os_thread_sleep(30000000);
+		os_thread_sleep(30000000);
 
-        	srv_print_innodb_monitor = old_val;
+		srv_print_innodb_monitor = old_val;
 		fprintf(stderr,
-"InnoDB: ###### Diagnostic info printed to the standard error stream\n");
+			"InnoDB: ###### Diagnostic info printed"
+			" to the standard error stream\n");
 	}
 
 	return(fatal);
@@ -927,27 +1069,22 @@
 	sync_array_t*	arr)	/* in: wait array; NOTE! caller must own the
 				mutex */
 {
-        sync_cell_t*   	cell;
-        ulint           count;
-	ulint           i;
+	sync_cell_t*	cell;
+	ulint		i;
 
 	fprintf(file,
-		"OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n",
-						(long) arr->res_count, (long) arr->sg_count);
-	i = 0;
-	count = 0;
+		"OS WAIT ARRAY INFO: reservation count %ld,"
+		" signal count %ld\n",
+		(long) arr->res_count,
+		(long) arr->sg_count);
+	for (i = 0; i < arr->n_cells; i++) {
 
-        while (count < arr->n_reserved) {
+		cell = sync_array_get_nth_cell(arr, i);
 
-        	cell = sync_array_get_nth_cell(arr, i);
-
-                if (cell->wait_object != NULL) {
-                        count++;
+		if (cell->state != SC_FREE) {
 			sync_array_cell_print(file, cell);
-                }
-
-                i++;
-       	}
+		}
+	}
 }
 
 /**************************************************************************
@@ -959,10 +1096,10 @@
 	FILE*		file,	/* in: file where to print */
 	sync_array_t*	arr)	/* in: wait array */
 {
-        sync_array_enter(arr);
+	sync_array_enter(arr);
 
 	sync_array_output_info(file, arr);
-        
-        sync_array_exit(arr);
+
+	sync_array_exit(arr);
 }
 

--- 1.19.3.1/innobase/sync/sync0rw.c	2007-01-17 16:44:05 -07:00
+++ 1.30/storage/innobase/sync/sync0rw.c	2007-01-17 17:18:03 -07:00
@@ -90,25 +90,27 @@
 /*================*/
 	rw_lock_t*	lock,		/* in: pointer to memory */
 #ifdef UNIV_DEBUG
+# ifdef UNIV_SYNC_DEBUG
+	ulint		level,		/* in: level */
+# endif /* UNIV_SYNC_DEBUG */
 	const char*	cmutex_name, 	/* in: mutex name */
 #endif /* UNIV_DEBUG */
 	const char*	cfile_name,	/* in: file name where created */
-	ulint		cline)		/* in: file line where created */
+	ulint 		cline)		/* in: file line where created */
 {
-	/* If this is the very first time a synchronization
-	object is created, then the following call initializes
-	the sync system. */
+	/* If this is the very first time a synchronization object is
+	created, then the following call initializes the sync system. */
 
-	mutex_create(rw_lock_get_mutex(lock));
-	mutex_set_level(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK);
+	mutex_create(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK);
 
 	lock->mutex.cfile_name = cfile_name;
 	lock->mutex.cline = cline;
+
 #if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
 	lock->mutex.cmutex_name = cmutex_name;
 	lock->mutex.mutex_type = 1;
 #endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
-  
+
 	rw_lock_set_waiters(lock, 0);
 	rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
 	lock->writer_count = 0;
@@ -119,10 +121,11 @@
 #ifdef UNIV_SYNC_DEBUG
 	UT_LIST_INIT(lock->debug_list);
 
-	lock->level = SYNC_LEVEL_NONE;
+	lock->level = level;
 #endif /* UNIV_SYNC_DEBUG */
+
 	lock->magic_n = RW_LOCK_MAGIC_N;
-	
+
 	lock->cfile_name = cfile_name;
 	lock->cline = cline;
 
@@ -130,13 +133,12 @@
 	lock->last_x_file_name = "not yet reserved";
 	lock->last_s_line = 0;
 	lock->last_x_line = 0;
-	lock->event = os_event_create(NULL);
 
 	mutex_enter(&rw_lock_list_mutex);
-	
+
 	if (UT_LIST_GET_LEN(rw_lock_list) > 0) {
 		ut_a(UT_LIST_GET_FIRST(rw_lock_list)->magic_n
-							== RW_LOCK_MAGIC_N);
+		     == RW_LOCK_MAGIC_N);
 	}
 
 	UT_LIST_ADD_FIRST(list, rw_lock_list, lock);
@@ -160,13 +162,12 @@
 	ut_a(rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED);
 	ut_a(rw_lock_get_waiters(lock) == 0);
 	ut_a(rw_lock_get_reader_count(lock) == 0);
-	
+
 	lock->magic_n = 0;
 
 	mutex_free(rw_lock_get_mutex(lock));
 
 	mutex_enter(&rw_lock_list_mutex);
-	os_event_free(lock->event);
 
 	if (UT_LIST_GET_PREV(list, lock)) {
 		ut_a(UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N);
@@ -202,7 +203,7 @@
 	ut_a((rw_lock_get_waiters(lock) == 0)
 	     || (rw_lock_get_waiters(lock) == 1));
 	ut_a((lock->writer != RW_LOCK_EX) || (lock->writer_count > 0));
-	     
+
 	mutex_exit(rw_lock_get_mutex(lock));
 
 	return(TRUE);
@@ -217,31 +218,31 @@
 void
 rw_lock_s_lock_spin(
 /*================*/
-        rw_lock_t*   	lock,  	/* in: pointer to rw-lock */
+	rw_lock_t*	lock,	/* in: pointer to rw-lock */
 	ulint		pass,	/* in: pass value; != 0, if the lock
 				will be passed to another thread to unlock */
 	const char*	file_name, /* in: file name where lock requested */
 	ulint		line)	/* in: line where requested */
 {
-        ulint    index;	/* index of the reserved wait cell */
-        ulint    i;   	/* spin round count */
-        
-        ut_ad(rw_lock_validate(lock));
+	ulint	 index;	/* index of the reserved wait cell */
+	ulint	 i;	/* spin round count */
+
+	ut_ad(rw_lock_validate(lock));
 
 lock_loop:
 	rw_s_spin_wait_count++;
 
 	/* Spin waiting for the writer field to become free */
-        i = 0;
+	i = 0;
 
-        while (rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED
-						&& i < SYNC_SPIN_ROUNDS) {
-        	if (srv_spin_wait_delay) {
-        		ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
-        	}
+	while (rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED
+	       && i < SYNC_SPIN_ROUNDS) {
+		if (srv_spin_wait_delay) {
+			ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
+		}
 
-        	i++;
-        }
+		i++;
+	}
 
 	if (i == SYNC_SPIN_ROUNDS) {
 		os_thread_yield();
@@ -249,14 +250,16 @@
 
 	if (srv_print_latch_waits) {
 		fprintf(stderr,
-	"Thread %lu spin wait rw-s-lock at %p cfile %s cline %lu rnds %lu\n",
-		(ulong) os_thread_pf(os_thread_get_curr_id()), lock,
-		lock->cfile_name, (ulong) lock->cline, (ulong) i);
+			"Thread %lu spin wait rw-s-lock at %p"
+			" cfile %s cline %lu rnds %lu\n",
+			(ulong) os_thread_pf(os_thread_get_curr_id()),
+			(void*) lock,
+			lock->cfile_name, (ulong) lock->cline, (ulong) i);
 	}
 
 	mutex_enter(rw_lock_get_mutex(lock));
 
-        /* We try once again to obtain the lock */
+	/* We try once again to obtain the lock */
 
 	if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
 		mutex_exit(rw_lock_get_mutex(lock));
@@ -268,10 +271,10 @@
 
 		rw_s_system_call_count++;
 
-        	sync_array_reserve_cell(sync_primary_wait_array,
-				lock, RW_LOCK_SHARED,
-				file_name, line,
-				&index);
+		sync_array_reserve_cell(sync_primary_wait_array,
+					lock, RW_LOCK_SHARED,
+					file_name, line,
+					&index);
 
 		rw_lock_set_waiters(lock, 1);
 
@@ -279,18 +282,20 @@
 
 		if (srv_print_latch_waits) {
 			fprintf(stderr,
-		"Thread %lu OS wait rw-s-lock at %p cfile %s cline %lu\n",
+				"Thread %lu OS wait rw-s-lock at %p"
+				" cfile %s cline %lu\n",
 				os_thread_pf(os_thread_get_curr_id()),
-		        lock, lock->cfile_name, (ulong) lock->cline);
+				(void*) lock, lock->cfile_name,
+				(ulong) lock->cline);
 		}
 
 		rw_s_system_call_count++;
 		rw_s_os_wait_count++;
 
-       	 	sync_array_wait_event(sync_primary_wait_array, index);
+		sync_array_wait_event(sync_primary_wait_array, index);
 
-        	goto lock_loop;
-	}        
+		goto lock_loop;
+	}
 }
 
 /**********************************************************************
@@ -328,7 +333,7 @@
 				/* out: RW_LOCK_NOT_LOCKED if did
 				not succeed, RW_LOCK_EX if success,
 				RW_LOCK_WAIT_EX, if got wait reservation */
-        rw_lock_t*   	lock,  	/* in: pointer to rw-lock */
+	rw_lock_t*	lock,	/* in: pointer to rw-lock */
 	ulint		pass,	/* in: pass value; != 0, if the lock will
 				be passed to another thread to unlock */
 	const char*	file_name,/* in: file name where lock requested */
@@ -340,19 +345,19 @@
 	if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) {
 
 		if (rw_lock_get_reader_count(lock) == 0) {
-			
+
 			rw_lock_set_writer(lock, RW_LOCK_EX);
 			lock->writer_thread = os_thread_get_curr_id();
 			lock->writer_count++;
 			lock->pass = pass;
-			
+
 #ifdef UNIV_SYNC_DEBUG
 			rw_lock_add_debug_info(lock, pass, RW_LOCK_EX,
-							file_name, line);
+					       file_name, line);
 #endif
 			lock->last_x_file_name = file_name;
 			lock->last_x_line = line;
-		
+
 			/* Locking succeeded, we may return */
 			return(RW_LOCK_EX);
 		} else {
@@ -364,7 +369,7 @@
 
 #ifdef UNIV_SYNC_DEBUG
 			rw_lock_add_debug_info(lock, pass, RW_LOCK_WAIT_EX,
-							file_name, line);
+					       file_name, line);
 #endif
 
 			return(RW_LOCK_WAIT_EX);
@@ -372,7 +377,7 @@
 
 	} else if ((rw_lock_get_writer(lock) == RW_LOCK_WAIT_EX)
 		   && os_thread_eq(lock->writer_thread,
-						os_thread_get_curr_id())) {
+				   os_thread_get_curr_id())) {
 
 		if (rw_lock_get_reader_count(lock) == 0) {
 
@@ -384,9 +389,9 @@
 #ifdef UNIV_SYNC_DEBUG
 			rw_lock_remove_debug_info(lock, pass, RW_LOCK_WAIT_EX);
 			rw_lock_add_debug_info(lock, pass, RW_LOCK_EX,
-							file_name, line);
+					       file_name, line);
 #endif
-		
+
 			lock->last_x_file_name = file_name;
 			lock->last_x_line = line;
 
@@ -398,7 +403,7 @@
 
 	} else if ((rw_lock_get_writer(lock) == RW_LOCK_EX)
 		   && os_thread_eq(lock->writer_thread,
-						os_thread_get_curr_id())
+				   os_thread_get_curr_id())
 		   && (lock->pass == 0)
 		   && (pass == 0)) {
 
@@ -406,9 +411,9 @@
 
 #ifdef UNIV_SYNC_DEBUG
 		rw_lock_add_debug_info(lock, pass, RW_LOCK_EX, file_name,
-									line);
+				       line);
 #endif
-		
+
 		lock->last_x_file_name = file_name;
 		lock->last_x_line = line;
 
@@ -433,79 +438,80 @@
 void
 rw_lock_x_lock_func(
 /*================*/
-        rw_lock_t*   	lock,  	/* in: pointer to rw-lock */
+	rw_lock_t*	lock,	/* in: pointer to rw-lock */
 	ulint		pass,	/* in: pass value; != 0, if the lock will
 				be passed to another thread to unlock */
 	const char*	file_name,/* in: file name where lock requested */
 	ulint		line)	/* in: line where requested */
 {
-        ulint	index;  /* index of the reserved wait cell */
-        ulint	state;	/* lock state acquired */
-        ulint	i;	/* spin round count */
-        
-        ut_ad(rw_lock_validate(lock));
+	ulint	index;	/* index of the reserved wait cell */
+	ulint	state;	/* lock state acquired */
+	ulint	i;	/* spin round count */
+
+	ut_ad(rw_lock_validate(lock));
 
 lock_loop:
-        /* Acquire the mutex protecting the rw-lock fields */
+	/* Acquire the mutex protecting the rw-lock fields */
 	mutex_enter_fast(&(lock->mutex));
 
 	state = rw_lock_x_lock_low(lock, pass, file_name, line);
-		
+
 	mutex_exit(&(lock->mutex));
-        
+
 	if (state == RW_LOCK_EX) {
 
 		return;	/* Locking succeeded */
 
 	} else if (state == RW_LOCK_NOT_LOCKED) {
 
- 		/* Spin waiting for the writer field to become free */
+		/* Spin waiting for the writer field to become free */
 		i = 0;
 
-        	while (rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED 
-               					&& i < SYNC_SPIN_ROUNDS) {
-        		if (srv_spin_wait_delay) {
+		while (rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED
+		       && i < SYNC_SPIN_ROUNDS) {
+			if (srv_spin_wait_delay) {
 				ut_delay(ut_rnd_interval(0,
-							srv_spin_wait_delay));
-        		}
-        		
-        		i++;
-        	}
+							 srv_spin_wait_delay));
+			}
+
+			i++;
+		}
 		if (i == SYNC_SPIN_ROUNDS) {
 			os_thread_yield();
 		}
-        } else if (state == RW_LOCK_WAIT_EX) {
+	} else if (state == RW_LOCK_WAIT_EX) {
 
- 		/* Spin waiting for the reader count field to become zero */
+		/* Spin waiting for the reader count field to become zero */
 		i = 0;
 
-        	while (rw_lock_get_reader_count(lock) != 0 
-               					&& i < SYNC_SPIN_ROUNDS) {
-        		if (srv_spin_wait_delay) {
+		while (rw_lock_get_reader_count(lock) != 0
+		       && i < SYNC_SPIN_ROUNDS) {
+			if (srv_spin_wait_delay) {
 				ut_delay(ut_rnd_interval(0,
-							srv_spin_wait_delay));
-        		}
+							 srv_spin_wait_delay));
+			}
 
 			i++;
-        	}
+		}
 		if (i == SYNC_SPIN_ROUNDS) {
 			os_thread_yield();
 		}
-        } else {
+	} else {
 		i = 0; /* Eliminate a compiler warning */
 		ut_error;
-	}	
+	}
 
 	if (srv_print_latch_waits) {
 		fprintf(stderr,
-	"Thread %lu spin wait rw-x-lock at %p cfile %s cline %lu rnds %lu\n",
-			os_thread_pf(os_thread_get_curr_id()), lock,
-		lock->cfile_name, (ulong) lock->cline, (ulong) i);
+			"Thread %lu spin wait rw-x-lock at %p"
+			" cfile %s cline %lu rnds %lu\n",
+			os_thread_pf(os_thread_get_curr_id()), (void*) lock,
+			lock->cfile_name, (ulong) lock->cline, (ulong) i);
 	}
 
 	rw_x_spin_wait_count++;
 
-        /* We try once again to obtain the lock. Acquire the mutex protecting
+	/* We try once again to obtain the lock. Acquire the mutex protecting
 	the rw-lock fields */
 
 	mutex_enter(rw_lock_get_mutex(lock));
@@ -520,7 +526,7 @@
 
 	rw_x_system_call_count++;
 
-        sync_array_reserve_cell(sync_primary_wait_array,
+	sync_array_reserve_cell(sync_primary_wait_array,
 				lock, RW_LOCK_EX,
 				file_name, line,
 				&index);
@@ -531,17 +537,18 @@
 
 	if (srv_print_latch_waits) {
 		fprintf(stderr,
-		"Thread %lu OS wait for rw-x-lock at %p cfile %s cline %lu\n",
-			os_thread_pf(os_thread_get_curr_id()), lock,
-		lock->cfile_name, (ulong) lock->cline);
+			"Thread %lu OS wait for rw-x-lock at %p"
+			" cfile %s cline %lu\n",
+			os_thread_pf(os_thread_get_curr_id()), (void*) lock,
+			lock->cfile_name, (ulong) lock->cline);
 	}
 
 	rw_x_system_call_count++;
 	rw_x_os_wait_count++;
 
-        sync_array_wait_event(sync_primary_wait_array, index);
+	sync_array_wait_event(sync_primary_wait_array, index);
 
-        goto lock_loop;
+	goto lock_loop;
 }
 
 #ifdef UNIV_SYNC_DEBUG
@@ -558,7 +565,7 @@
 {
 loop:
 	if (0 == mutex_enter_nowait(&rw_lock_debug_mutex,
-			__FILE__, __LINE__)) {
+				    __FILE__, __LINE__)) {
 		return;
 	}
 
@@ -567,13 +574,13 @@
 	rw_lock_debug_waiters = TRUE;
 
 	if (0 == mutex_enter_nowait(&rw_lock_debug_mutex,
-			__FILE__, __LINE__)) {
+				    __FILE__, __LINE__)) {
 		return;
 	}
 
 	os_event_wait(rw_lock_debug_event);
 
-	goto loop;	
+	goto loop;
 }
 
 /**********************************************************************
@@ -613,19 +620,19 @@
 	rw_lock_debug_mutex_enter();
 
 	info->file_name = file_name;
-	info->line 	= line;
+	info->line	= line;
 	info->lock_type = lock_type;
 	info->thread_id = os_thread_get_curr_id();
 	info->pass	= pass;
 
-	UT_LIST_ADD_FIRST(list, lock->debug_list, info);	
+	UT_LIST_ADD_FIRST(list, lock->debug_list, info);
 
 	rw_lock_debug_mutex_exit();
 
 	if ((pass == 0) && (lock_type != RW_LOCK_WAIT_EX)) {
 		sync_thread_add_level(lock, lock->level);
 	}
-}	
+}
 
 /**********************************************************************
 Removes a debug information struct for an rw-lock. */
@@ -653,16 +660,16 @@
 		if ((pass == info->pass)
 		    && ((pass != 0)
 			|| os_thread_eq(info->thread_id,
-						os_thread_get_curr_id()))
+					os_thread_get_curr_id()))
 		    && (info->lock_type == lock_type)) {
 
-		    	/* Found! */
-		    	UT_LIST_REMOVE(list, lock->debug_list, info);
+			/* Found! */
+			UT_LIST_REMOVE(list, lock->debug_list, info);
 			rw_lock_debug_mutex_exit();
 
-		    	rw_lock_debug_free(info);
+			rw_lock_debug_free(info);
 
-		    	return;
+			return;
 		}
 
 		info = UT_LIST_GET_NEXT(list, info);
@@ -672,18 +679,6 @@
 }
 #endif /* UNIV_SYNC_DEBUG */
 
-/**********************************************************************
-Sets the rw-lock latching level field. */
-
-void
-rw_lock_set_level(
-/*==============*/
-	rw_lock_t*	lock,	/* in: rw-lock */
-	ulint		level)	/* in: level */
-{
-	lock->level = level;
-}
-
 #ifdef UNIV_SYNC_DEBUG
 /**********************************************************************
 Checks if the thread has locked the rw-lock in the specified mode, with
@@ -713,9 +708,9 @@
 		    && (info->lock_type == lock_type)) {
 
 			mutex_exit(&(lock->mutex));
-		    	/* Found! */
+			/* Found! */
 
-		    	return(TRUE);
+			return(TRUE);
 		}
 
 		info = UT_LIST_GET_NEXT(list, info);
@@ -741,7 +736,7 @@
 
 	ut_ad(lock);
 	ut_ad(rw_lock_validate(lock));
-	
+
 	mutex_enter(&(lock->mutex));
 
 	if (lock_type == RW_LOCK_SHARED) {
@@ -766,18 +761,19 @@
 Prints debug info of currently locked rw-locks. */
 
 void
-rw_lock_list_print_info(void)
-/*=========================*/
+rw_lock_list_print_info(
+/*====================*/
+	FILE*	file)		/* in: file where to print */
 {
 	rw_lock_t*	lock;
 	ulint		count		= 0;
 	rw_lock_debug_t* info;
-	
+
 	mutex_enter(&rw_lock_list_mutex);
 
 	fputs("-------------\n"
-		"RW-LATCH INFO\n"
-		"-------------\n", stderr);
+	      "RW-LATCH INFO\n"
+	      "-------------\n", file);
 
 	lock = UT_LIST_GET_FIRST(rw_lock_list);
 
@@ -791,16 +787,16 @@
 		    || (rw_lock_get_reader_count(lock) != 0)
 		    || (rw_lock_get_waiters(lock) != 0)) {
 
-			fprintf(stderr, "RW-LOCK: %p ", lock);
+			fprintf(file, "RW-LOCK: %p ", (void*) lock);
 
 			if (rw_lock_get_waiters(lock)) {
-				fputs(" Waiters for the lock exist\n", stderr);
+				fputs(" Waiters for the lock exist\n", file);
 			} else {
-				putc('\n', stderr);
+				putc('\n', file);
 			}
-		    
+
 			info = UT_LIST_GET_FIRST(lock->debug_list);
-			while (info != NULL) {	
+			while (info != NULL) {
 				rw_lock_debug_print(info);
 				info = UT_LIST_GET_NEXT(list, info);
 			}
@@ -810,7 +806,7 @@
 		lock = UT_LIST_GET_NEXT(list, lock);
 	}
 
-	fprintf(stderr, "Total number of rw-locks %ld\n", count);
+	fprintf(file, "Total number of rw-locks %ld\n", count);
 	mutex_exit(&rw_lock_list_mutex);
 }
 
@@ -823,11 +819,11 @@
 	rw_lock_t*	lock)	/* in: rw-lock */
 {
 	rw_lock_debug_t* info;
-	
+
 	fprintf(stderr,
 		"-------------\n"
 		"RW-LATCH INFO\n"
-		"RW-LATCH: %p ", lock);
+		"RW-LATCH: %p ", (void*) lock);
 
 	if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED)
 	    || (rw_lock_get_reader_count(lock) != 0)
@@ -838,9 +834,9 @@
 		} else {
 			putc('\n', stderr);
 		}
-		    
+
 		info = UT_LIST_GET_FIRST(lock->debug_list);
-		while (info != NULL) {	
+		while (info != NULL) {
 			rw_lock_debug_print(info);
 			info = UT_LIST_GET_NEXT(list, info);
 		}
@@ -857,11 +853,11 @@
 {
 	ulint	rwt;
 
-	rwt 	  = info->lock_type;	
-			
+	rwt	  = info->lock_type;
+
 	fprintf(stderr, "Locked: thread %ld file %s line %ld  ",
 		(ulong) os_thread_pf(info->thread_id), info->file_name,
-	        (ulong) info->line);
+		(ulong) info->line);
 	if (rwt == RW_LOCK_SHARED) {
 		fputs("S-LOCK", stderr);
 	} else if (rwt == RW_LOCK_EX) {
@@ -887,7 +883,7 @@
 {
 	rw_lock_t*	lock;
 	ulint		count		= 0;
-	
+
 	mutex_enter(&rw_lock_list_mutex);
 
 	lock = UT_LIST_GET_FIRST(rw_lock_list);
@@ -896,7 +892,7 @@
 		mutex_enter(rw_lock_get_mutex(lock));
 
 		if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED)
-				|| (rw_lock_get_reader_count(lock) != 0)) {
+		    || (rw_lock_get_reader_count(lock) != 0)) {
 			count++;
 		}
 

--- 1.34.5.1/innobase/sync/sync0sync.c	2007-01-17 16:44:05 -07:00
+++ 1.47/storage/innobase/sync/sync0sync.c	2007-01-17 17:18:03 -07:00
@@ -27,7 +27,7 @@
 provide efficient spin locks, but we cannot count on that.
 
 Another reason for implementing a spin lock is that on multiprocessor systems
-it can be more efficient for a processor to run a loop waiting for the 
+it can be more efficient for a processor to run a loop waiting for the
 semaphore to be released than to switch to a different thread. A thread switch
 takes 25 us on both platforms mentioned above. See Gray and Reuter's book
 Transaction processing for background.
@@ -35,7 +35,7 @@
 How long should the spin loop last before suspending the thread? On a
 uniprocessor, spinning does not help at all, because if the thread owning the
 mutex is not executing, it cannot be released. Spinning actually wastes
-resources. 
+resources.
 
 On a multiprocessor, we do not know if the thread owning the mutex is
 executing or not. Thus it would make sense to spin as long as the operation
@@ -52,12 +52,12 @@
 make sure that thread swithches due to mutex collisions are not frequent,
 i.e., they do not happen every 100 us or so, because that wastes too much
 resources. If the thread switches are not frequent, the 20 us wasted in spin
-loop is not too much. 
+loop is not too much.
 
 Empirical studies on the effect of spin time should be done for different
 platforms.
 
-	
+
 	IMPLEMENTATION OF THE MUTEX
 	===========================
 
@@ -105,11 +105,9 @@
 or it reserves the mutex for itself. In any case, some thread (which may be
 also some earlier thread, not necessarily the one currently holding the mutex)
 will set the waiters field to 0 in mutex_exit, and then call
-sync_array_signal_object with the mutex as an argument. 
+sync_array_signal_object with the mutex as an argument.
 Q.E.D. */
 
-ulint	sync_dummy			= 0;
-
 /* The number of system calls made in this module. Intended for performance
 monitoring. */
 
@@ -133,6 +131,7 @@
 typedef struct sync_level_struct	sync_level_t;
 typedef struct sync_thread_struct	sync_thread_t;
 
+#ifdef UNIV_SYNC_DEBUG
 /* The latch levels currently owned by threads are stored in this data
 structure; the size of this array is OS_THREAD_MAX_N */
 
@@ -140,6 +139,7 @@
 
 /* Mutex protecting sync_thread_level_arrays */
 mutex_t	sync_thread_mutex;
+#endif /* UNIV_SYNC_DEBUG */
 
 /* Global list of database mutexes (not OS mutexes) created. */
 ut_list_base_node_t  mutex_list;
@@ -147,11 +147,10 @@
 /* Mutex protecting the mutex_list variable */
 mutex_t mutex_list_mutex;
 
+#ifdef UNIV_SYNC_DEBUG
 /* Latching order checks start when this is set TRUE */
 ibool	sync_order_checks_on	= FALSE;
-
-/* Dummy mutex used to implement mutex_fence */
-mutex_t	dummy_mutex_for_fence;
+#endif /* UNIV_SYNC_DEBUG */
 
 struct sync_thread_struct{
 	os_thread_id_t	id;	/* OS thread id */
@@ -204,55 +203,62 @@
 	mutex_t*	mutex,		/* in: pointer to memory */
 #ifdef UNIV_DEBUG
 	const char*	cmutex_name,	/* in: mutex name */
+# ifdef UNIV_SYNC_DEBUG
+	ulint		level,		/* in: level */
+# endif /* UNIV_SYNC_DEBUG */
 #endif /* UNIV_DEBUG */
 	const char*	cfile_name,	/* in: file name where created */
 	ulint		cline)		/* in: file line where created */
 {
 #if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
 	mutex_reset_lock_word(mutex);
-#else	
+#else
 	os_fast_mutex_init(&(mutex->os_fast_mutex));
 	mutex->lock_word = 0;
 #endif
-	mutex->event = os_event_create(NULL);
 	mutex_set_waiters(mutex, 0);
+#ifdef UNIV_DEBUG
 	mutex->magic_n = MUTEX_MAGIC_N;
+#endif /* UNIV_DEBUG */
 #ifdef UNIV_SYNC_DEBUG
 	mutex->line = 0;
 	mutex->file_name = "not yet reserved";
+	mutex->level = level;
 #endif /* UNIV_SYNC_DEBUG */
-	mutex->level = SYNC_LEVEL_NONE;
 	mutex->cfile_name = cfile_name;
 	mutex->cline = cline;
 #ifndef UNIV_HOTBACKUP
 	mutex->count_os_wait = 0;
 # ifdef UNIV_DEBUG
-  mutex->cmutex_name=     cmutex_name;
-  mutex->count_using=     0;
-  mutex->mutex_type=      0;
-  mutex->lspent_time=     0;
-  mutex->lmax_spent_time=     0;
-  mutex->count_spin_loop= 0;
-  mutex->count_spin_rounds=   0; 
-  mutex->count_os_yield=  0;
+	mutex->cmutex_name=	  cmutex_name;
+	mutex->count_using=	  0;
+	mutex->mutex_type=	  0;
+	mutex->lspent_time=	  0;
+	mutex->lmax_spent_time=     0;
+	mutex->count_spin_loop= 0;
+	mutex->count_spin_rounds=   0;
+	mutex->count_os_yield=  0;
 # endif /* UNIV_DEBUG */
 #endif /* !UNIV_HOTBACKUP */
-	
+
 	/* Check that lock_word is aligned; this is important on Intel */
 	ut_ad(((ulint)(&(mutex->lock_word))) % 4 == 0);
 
 	/* NOTE! The very first mutexes are not put to the mutex list */
 
-	if ((mutex == &mutex_list_mutex) || (mutex == &sync_thread_mutex)) {
+	if ((mutex == &mutex_list_mutex)
+#ifdef UNIV_SYNC_DEBUG
+	    || (mutex == &sync_thread_mutex)
+#endif /* UNIV_SYNC_DEBUG */
+	    ) {
 
-	    	return;
+		return;
 	}
-	
+
 	mutex_enter(&mutex_list_mutex);
 
-        if (UT_LIST_GET_LEN(mutex_list) > 0) {
-                ut_a(UT_LIST_GET_FIRST(mutex_list)->magic_n == MUTEX_MAGIC_N);
-        }
+	ut_ad(UT_LIST_GET_LEN(mutex_list) == 0
+	      || UT_LIST_GET_FIRST(mutex_list)->magic_n == MUTEX_MAGIC_N);
 
 	UT_LIST_ADD_FIRST(list, mutex_list, mutex);
 
@@ -269,40 +275,39 @@
 /*=======*/
 	mutex_t*	mutex)	/* in: mutex */
 {
-#ifdef UNIV_DEBUG
-	ut_a(mutex_validate(mutex));
-#endif /* UNIV_DEBUG */
+	ut_ad(mutex_validate(mutex));
 	ut_a(mutex_get_lock_word(mutex) == 0);
 	ut_a(mutex_get_waiters(mutex) == 0);
-	
-	if (mutex != &mutex_list_mutex && mutex != &sync_thread_mutex) {
 
-	        mutex_enter(&mutex_list_mutex);
+	if (mutex != &mutex_list_mutex
+#ifdef UNIV_SYNC_DEBUG
+	    && mutex != &sync_thread_mutex
+#endif /* UNIV_SYNC_DEBUG */
+	    ) {
 
-		if (UT_LIST_GET_PREV(list, mutex)) {
-			ut_a(UT_LIST_GET_PREV(list, mutex)->magic_n
-							== MUTEX_MAGIC_N);
-		}
-		if (UT_LIST_GET_NEXT(list, mutex)) {
-			ut_a(UT_LIST_GET_NEXT(list, mutex)->magic_n
-							== MUTEX_MAGIC_N);
-		}
-        
-	        UT_LIST_REMOVE(list, mutex_list, mutex);
+		mutex_enter(&mutex_list_mutex);
+
+		ut_ad(!UT_LIST_GET_PREV(list, mutex)
+		      || UT_LIST_GET_PREV(list, mutex)->magic_n
+		      == MUTEX_MAGIC_N);
+		ut_ad(!UT_LIST_GET_NEXT(list, mutex)
+		      || UT_LIST_GET_NEXT(list, mutex)->magic_n
+		      == MUTEX_MAGIC_N);
+
+		UT_LIST_REMOVE(list, mutex_list, mutex);
 
 		mutex_exit(&mutex_list_mutex);
 	}
 
-	os_event_free(mutex->event);
-
-#if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER) 
+#if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER)
 	os_fast_mutex_free(&(mutex->os_fast_mutex));
 #endif
 	/* If we free the mutex protecting the mutex list (freeing is
 	not necessary), we have to reset the magic number AFTER removing
 	it from the list. */
-	
+#ifdef UNIV_DEBUG
 	mutex->magic_n = 0;
+#endif /* UNIV_DEBUG */
 }
 
 /************************************************************************
@@ -334,6 +339,7 @@
 	return(1);
 }
 
+#ifdef UNIV_DEBUG
 /**********************************************************************
 Checks that the mutex has been initialized. */
 
@@ -347,6 +353,7 @@
 
 	return(TRUE);
 }
+#endif /* UNIV_DEBUG */
 
 /**********************************************************************
 Sets the waiters field in a mutex. */
@@ -355,10 +362,10 @@
 mutex_set_waiters(
 /*==============*/
 	mutex_t*	mutex,	/* in: mutex */
-	ulint		n)	/* in: value to set */		
+	ulint		n)	/* in: value to set */
 {
-volatile ulint*	ptr;		/* declared volatile to ensure that
-				the value is stored to memory */
+	volatile ulint*	ptr;		/* declared volatile to ensure that
+					the value is stored to memory */
 	ut_ad(mutex);
 
 	ptr = &(mutex->waiters);
@@ -375,190 +382,180 @@
 void
 mutex_spin_wait(
 /*============*/
-  mutex_t*  mutex,      /* in: pointer to mutex */
-  const char*    file_name,   /* in: file name where
-                             mutex requested */
-  ulint line) /* in: line where requested */
+	mutex_t*	mutex,		/* in: pointer to mutex */
+	const char*	file_name,	/* in: file name where mutex
+					requested */
+	ulint		line)		/* in: line where requested */
 {
-  ulint    index; /* index of the reserved wait cell */
-  ulint    i;     /* spin round count */
+	ulint	   index; /* index of the reserved wait cell */
+	ulint	   i;	  /* spin round count */
 #if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
-  ib_longlong lstart_time = 0, lfinish_time; /* for timing os_wait */
-  ulint ltime_diff;
-  ulint sec;
-  ulint ms;
-  uint timer_started = 0;
+	ib_longlong lstart_time = 0, lfinish_time; /* for timing os_wait */
+	ulint ltime_diff;
+	ulint sec;
+	ulint ms;
+	uint timer_started = 0;
 #endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
-  ut_ad(mutex);
+	ut_ad(mutex);
 
 mutex_loop:
 
-  i = 0;
+	i = 0;
 
-/* Spin waiting for the lock word to become zero. Note that we do not
-  have to assume that the read access to the lock word is atomic, as the
-  actual locking is always committed with atomic test-and-set. In
-  reality, however, all processors probably have an atomic read of a
-  memory word. */
+	/* Spin waiting for the lock word to become zero. Note that we do
+	not have to assume that the read access to the lock word is atomic,
+	as the actual locking is always committed with atomic test-and-set.
+	In reality, however, all processors probably have an atomic read of
+	a memory word. */
 
 spin_loop:
 #if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
-  mutex_spin_wait_count++;
-  mutex->count_spin_loop++;
+	mutex_spin_wait_count++;
+	mutex->count_spin_loop++;
 #endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
 
-  while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS)
-  {
-    if (srv_spin_wait_delay)
-    {
-      ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
-    }
+	while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) {
+		if (srv_spin_wait_delay) {
+			ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
+		}
 
-    i++;
-  }
+		i++;
+	}
 
-  if (i == SYNC_SPIN_ROUNDS)
-  {
+	if (i == SYNC_SPIN_ROUNDS) {
 #if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
-    mutex->count_os_yield++;
-    if (timed_mutexes == 1 && timer_started==0)
-    {
-      ut_usectime(&sec, &ms);
-      lstart_time= (ib_longlong)sec * 1000000 + ms;
-      timer_started = 1;
-    }
+		mutex->count_os_yield++;
+		if (timed_mutexes == 1 && timer_started==0) {
+			ut_usectime(&sec, &ms);
+			lstart_time= (ib_longlong)sec * 1000000 + ms;
+			timer_started = 1;
+		}
 #endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
-    os_thread_yield();
-  }
+		os_thread_yield();
+	}
 
 #ifdef UNIV_SRV_PRINT_LATCH_WAITS
-    fprintf(stderr,
-            "Thread %lu spin wait mutex at %p cfile %s cline %lu rnds %lu\n",
-            (ulong) os_thread_pf(os_thread_get_curr_id()), mutex,
-            mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
+	fprintf(stderr,
+		"Thread %lu spin wait mutex at %p"
+		" cfile %s cline %lu rnds %lu\n",
+		(ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
+		mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
 #endif
 
-  mutex_spin_round_count += i;
+	mutex_spin_round_count += i;
 
 #if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
-  mutex->count_spin_rounds += i;
+	mutex->count_spin_rounds += i;
 #endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
 
-  if (mutex_test_and_set(mutex) == 0)
-  {
-    /* Succeeded! */
+	if (mutex_test_and_set(mutex) == 0) {
+		/* Succeeded! */
 
 #ifdef UNIV_SYNC_DEBUG
-    mutex_set_debug_info(mutex, file_name, line);
+		mutex_set_debug_info(mutex, file_name, line);
 #endif
 
-    goto finish_timing;
-  }
+		goto finish_timing;
+	}
+
+	/* We may end up with a situation where lock_word is 0 but the OS
+	fast mutex is still reserved. On FreeBSD the OS does not seem to
+	schedule a thread which is constantly calling pthread_mutex_trylock
+	(in mutex_test_and_set implementation). Then we could end up
+	spinning here indefinitely. The following 'i++' stops this infinite
+	spin. */
+
+	i++;
+
+	if (i < SYNC_SPIN_ROUNDS) {
+		goto spin_loop;
+	}
+
+	sync_array_reserve_cell(sync_primary_wait_array, mutex,
+				SYNC_MUTEX, file_name, line, &index);
+
+	mutex_system_call_count++;
+
+	/* The memory order of the array reservation and the change in the
+	waiters field is important: when we suspend a thread, we first
+	reserve the cell and then set waiters field to 1. When threads are
+	released in mutex_exit, the waiters field is first set to zero and
+	then the event is set to the signaled state. */
+
+	mutex_set_waiters(mutex, 1);
 
-  /* We may end up with a situation where lock_word is
-  0 but the OS fast mutex is still reserved. On FreeBSD
-  the OS does not seem to schedule a thread which is constantly
-  calling pthread_mutex_trylock (in mutex_test_and_set
-  implementation). Then we could end up spinning here indefinitely.
-  The following 'i++' stops this infinite spin. */
-
-  i++;
-
-  if (i < SYNC_SPIN_ROUNDS)
-  {
-    goto spin_loop;
-  }
-
-  sync_array_reserve_cell(sync_primary_wait_array, mutex,
-                          SYNC_MUTEX, file_name, line, &index);
-
-  mutex_system_call_count++;
-
-  /* The memory order of the array reservation and the change in the
-  waiters field is important: when we suspend a thread, we first
-  reserve the cell and then set waiters field to 1. When threads are
-  released in mutex_exit, the waiters field is first set to zero and
-  then the event is set to the signaled state. */
-
-  mutex_set_waiters(mutex, 1);
-
-  /* Try to reserve still a few times */
-  for (i = 0; i < 4; i++)
-  {
-    if (mutex_test_and_set(mutex) == 0)
-    {
-      /* Succeeded! Free the reserved wait cell */
+	/* Try to reserve still a few times */
+	for (i = 0; i < 4; i++) {
+		if (mutex_test_and_set(mutex) == 0) {
+			/* Succeeded! Free the reserved wait cell */
 
-      sync_array_free_cell(sync_primary_wait_array, index);
+			sync_array_free_cell_protected(sync_primary_wait_array,
+						       index);
 
 #ifdef UNIV_SYNC_DEBUG
-      mutex_set_debug_info(mutex, file_name, line);
+			mutex_set_debug_info(mutex, file_name, line);
 #endif
 
 #ifdef UNIV_SRV_PRINT_LATCH_WAITS
-        fprintf(stderr, "Thread %lu spin wait succeeds at 2:"
-                " mutex at %p\n",
-                (ulong) os_thread_pf(os_thread_get_curr_id()),
-                mutex);
+			fprintf(stderr, "Thread %lu spin wait succeeds at 2:"
+				" mutex at %p\n",
+				(ulong) os_thread_pf(os_thread_get_curr_id()),
+				(void*) mutex);
 #endif
 
-      goto finish_timing;
+			goto finish_timing;
+
+			/* Note that in this case we leave the waiters field
+			set to 1. We cannot reset it to zero, as we do not
+			know if there are other waiters. */
+		}
+	}
 
-      /* Note that in this case we leave the waiters field
-      set to 1. We cannot reset it to zero, as we do not know
-      if there are other waiters. */
-    }
-  }
-
-  /* Now we know that there has been some thread holding the mutex
-  after the change in the wait array and the waiters field was made.
-Now there is no risk of infinite wait on the event. */
+	/* Now we know that there has been some thread holding the mutex
+	after the change in the wait array and the waiters field was made.
+	Now there is no risk of infinite wait on the event. */
 
 #ifdef UNIV_SRV_PRINT_LATCH_WAITS
-    fprintf(stderr,
-            "Thread %lu OS wait mutex at %p cfile %s cline %lu rnds %lu\n",
-            (ulong) os_thread_pf(os_thread_get_curr_id()), mutex,
-            mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
+	fprintf(stderr,
+		"Thread %lu OS wait mutex at %p cfile %s cline %lu rnds %lu\n",
+		(ulong) os_thread_pf(os_thread_get_curr_id()), (void*) mutex,
+		mutex->cfile_name, (ulong) mutex->cline, (ulong) i);
 #endif
 
-  mutex_system_call_count++;
-  mutex_os_wait_count++;
+	mutex_system_call_count++;
+	mutex_os_wait_count++;
 
 #ifndef UNIV_HOTBACKUP
-  mutex->count_os_wait++;
+	mutex->count_os_wait++;
 # ifdef UNIV_DEBUG
-  /*
-    !!!!! Sometimes os_wait can be called without  os_thread_yield
-  */
-
-  if (timed_mutexes == 1 && timer_started==0)
-  {
-    ut_usectime(&sec, &ms);
-    lstart_time= (ib_longlong)sec * 1000000 + ms;
-    timer_started = 1;
-  }
+	/* !!!!! Sometimes os_wait can be called without os_thread_yield */
+
+	if (timed_mutexes == 1 && timer_started==0) {
+		ut_usectime(&sec, &ms);
+		lstart_time= (ib_longlong)sec * 1000000 + ms;
+		timer_started = 1;
+	}
 # endif /* UNIV_DEBUG */
 #endif /* !UNIV_HOTBACKUP */
 
-  sync_array_wait_event(sync_primary_wait_array, index);
-  goto mutex_loop;  
+	sync_array_wait_event(sync_primary_wait_array, index);
+	goto mutex_loop;
 
 finish_timing:
 #if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
-  if (timed_mutexes == 1 && timer_started==1)
-  {
-    ut_usectime(&sec, &ms);
-    lfinish_time= (ib_longlong)sec * 1000000 + ms;
-
-    ltime_diff= (ulint) (lfinish_time - lstart_time);
-    mutex->lspent_time += ltime_diff;
-    if (mutex->lmax_spent_time < ltime_diff)
-    {
-      mutex->lmax_spent_time= ltime_diff;
-    }
-  }
+	if (timed_mutexes == 1 && timer_started==1) {
+		ut_usectime(&sec, &ms);
+		lfinish_time= (ib_longlong)sec * 1000000 + ms;
+
+		ltime_diff= (ulint) (lfinish_time - lstart_time);
+		mutex->lspent_time += ltime_diff;
+
+		if (mutex->lmax_spent_time < ltime_diff) {
+			mutex->lmax_spent_time= ltime_diff;
+		}
+	}
 #endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
-  return;
+	return;
 }
 
 /**********************************************************************
@@ -573,8 +570,8 @@
 
 	/* The memory order of resetting the waiters field and
 	signaling the object is important. See LEMMA 1 above. */
-	os_event_set(mutex->event);
-	sync_array_object_signalled(sync_primary_wait_array);
+
+	sync_array_signal_object(sync_primary_wait_array, mutex);
 }
 
 #ifdef UNIV_SYNC_DEBUG
@@ -594,9 +591,9 @@
 	sync_thread_add_level(mutex, mutex->level);
 
 	mutex->file_name = file_name;
-	mutex->line 	 = line;
+	mutex->line	 = line;
 	mutex->thread_id = os_thread_get_curr_id();
-}	
+}
 
 /**********************************************************************
 Gets the debug information for a reserved mutex. */
@@ -616,23 +613,8 @@
 	*line	   = mutex->line;
 	*thread_id = mutex->thread_id;
 }
-#endif /* UNIV_SYNC_DEBUG */
 
 /**********************************************************************
-Sets the mutex latching level field. */
-
-void
-mutex_set_level(
-/*============*/
-	mutex_t*	mutex,	/* in: mutex */
-	ulint		level)	/* in: level */
-{
-	mutex->level = level;
-}
-
-
-#ifdef UNIV_SYNC_DEBUG
-/**********************************************************************
 Checks that the current thread owns the mutex. Works only in the debug
 version. */
 
@@ -642,13 +624,13 @@
 				/* out: TRUE if owns */
 	mutex_t*	mutex)	/* in: mutex */
 {
-	ut_a(mutex_validate(mutex));
+	ut_ad(mutex_validate(mutex));
 
 	if (mutex_get_lock_word(mutex) != 1) {
 
 		return(FALSE);
 	}
-	
+
 	if (!os_thread_eq(mutex->thread_id, os_thread_get_curr_id())) {
 
 		return(FALSE);
@@ -659,10 +641,11 @@
 
 /**********************************************************************
 Prints debug info of currently reserved mutexes. */
-
+static
 void
-mutex_list_print_info(void)
-/*=======================*/
+mutex_list_print_info(
+/*==================*/
+	FILE*	file)		/* in: file where to print */
 {
 	mutex_t*	mutex;
 	const char*	file_name;
@@ -671,8 +654,8 @@
 	ulint		count		= 0;
 
 	fputs("----------\n"
-		"MUTEX INFO\n"
-		"----------\n", stderr);
+	      "MUTEX INFO\n"
+	      "----------\n", file);
 
 	mutex_enter(&mutex_list_mutex);
 
@@ -682,19 +665,20 @@
 		count++;
 
 		if (mutex_get_lock_word(mutex) != 0) {
-		    	mutex_get_debug_info(mutex, &file_name, &line,
-								&thread_id);
-			fprintf(stderr,
-			"Locked mutex: addr %p thread %ld file %s line %ld\n",
-				mutex, os_thread_pf(thread_id),
+			mutex_get_debug_info(mutex, &file_name, &line,
+					     &thread_id);
+			fprintf(file,
+				"Locked mutex: addr %p thread %ld"
+				" file %s line %ld\n",
+				(void*) mutex, os_thread_pf(thread_id),
 				file_name, line);
 		}
 
 		mutex = UT_LIST_GET_NEXT(list, mutex);
 	}
 
-	fprintf(stderr, "Total number of mutexes %ld\n", count);
-	
+	fprintf(file, "Total number of mutexes %ld\n", count);
+
 	mutex_exit(&mutex_list_mutex);
 }
 
@@ -739,7 +723,6 @@
 {
 	return(mutex_n_reserved() + rw_lock_n_locked() == 0);
 }
-#endif /* UNIV_SYNC_DEBUG */
 
 /**********************************************************************
 Gets the value in the nth slot in the thread level arrays. */
@@ -762,7 +745,7 @@
 sync_thread_level_arrays_find_slot(void)
 /*====================================*/
 			/* out: pointer to thread slot, NULL if not found */
-	
+
 {
 	sync_thread_t*	slot;
 	os_thread_id_t	id;
@@ -790,7 +773,7 @@
 sync_thread_level_arrays_find_free(void)
 /*====================================*/
 			/* out: pointer to thread slot */
-	
+
 {
 	sync_thread_t*	slot;
 	ulint		i;
@@ -852,8 +835,9 @@
 				mutex = slot->latch;
 
 				fprintf(stderr,
-	"InnoDB error: sync levels should be > %lu but a level is %lu\n",
-				(ulong) limit, (ulong) slot->level);
+					"InnoDB error: sync levels should be"
+					" > %lu but a level is %lu\n",
+					(ulong) limit, (ulong) slot->level);
 
 				if (mutex->magic_n == MUTEX_MAGIC_N) {
 					fprintf(stderr,
@@ -862,30 +846,30 @@
 						(ulong) mutex->cline);
 
 					if (mutex_get_lock_word(mutex) != 0) {
-#ifdef UNIV_SYNC_DEBUG
 						const char*	file_name;
 						ulint		line;
 						os_thread_id_t	thread_id;
 
-		    				mutex_get_debug_info(mutex,
-						&file_name, &line, &thread_id);
+						mutex_get_debug_info(
+							mutex, &file_name,
+							&line, &thread_id);
 
 						fprintf(stderr,
-		"InnoDB: Locked mutex: addr %p thread %ld file %s line %ld\n",
-		mutex, os_thread_pf(thread_id), file_name, (ulong) line);
-#else /* UNIV_SYNC_DEBUG */
-						fprintf(stderr,
-		"InnoDB: Locked mutex: addr %p\n", mutex);
-#endif /* UNIV_SYNC_DEBUG */
+							"InnoDB: Locked mutex:"
+							" addr %p thread %ld"
+							" file %s line %ld\n",
+							(void*) mutex,
+							os_thread_pf(
+								thread_id),
+							file_name,
+							(ulong) line);
 					} else {
 						fputs("Not locked\n", stderr);
-					}	
+					}
 				} else {
-#ifdef UNIV_SYNC_DEBUG
 					rw_lock_print(lock);
-#endif /* UNIV_SYNC_DEBUG */
 				}
-								
+
 				return(FALSE);
 			}
 		}
@@ -963,9 +947,10 @@
 
 		slot = sync_thread_levels_get_nth(arr, i);
 
-		if (slot->latch != NULL && (!dict_mutex_allowed ||
-				(slot->level != SYNC_DICT
-				&& slot->level != SYNC_DICT_OPERATION))) {
+		if (slot->latch != NULL
+		    && (!dict_mutex_allowed
+			|| (slot->level != SYNC_DICT
+			    && slot->level != SYNC_DICT_OPERATION))) {
 
 			mutex_exit(&sync_thread_mutex);
 			ut_error;
@@ -999,14 +984,14 @@
 sync_thread_add_level(
 /*==================*/
 	void*	latch,	/* in: pointer to a mutex or an rw-lock */
-	ulint	level)	/* in: level in the latching order; if SYNC_LEVEL_NONE,
-			nothing is done */
+	ulint	level)	/* in: level in the latching order; if
+			SYNC_LEVEL_VARYING, nothing is done */
 {
 	sync_level_t*	array;
 	sync_level_t*	slot;
 	sync_thread_t*	thread_slot;
 	ulint		i;
-	
+
 	if (!sync_order_checks_on) {
 
 		return;
@@ -1014,15 +999,13 @@
 
 	if ((latch == (void*)&sync_thread_mutex)
 	    || (latch == (void*)&mutex_list_mutex)
-#ifdef UNIV_SYNC_DEBUG
 	    || (latch == (void*)&rw_lock_debug_mutex)
-#endif /* UNIV_SYNC_DEBUG */
 	    || (latch == (void*)&rw_lock_list_mutex)) {
 
 		return;
 	}
 
-	if (level == SYNC_LEVEL_NONE) {
+	if (level == SYNC_LEVEL_VARYING) {
 
 		return;
 	}
@@ -1034,12 +1017,12 @@
 	if (thread_slot == NULL) {
 		/* We have to allocate the level array for a new thread */
 		array = ut_malloc(sizeof(sync_level_t) * SYNC_THREAD_N_LEVELS);
-	
+
 		thread_slot = sync_thread_level_arrays_find_free();
-	
- 		thread_slot->id = os_thread_get_curr_id();
+
+		thread_slot->id = os_thread_get_curr_id();
 		thread_slot->levels = array;
-		
+
 		for (i = 0; i < SYNC_THREAD_N_LEVELS; i++) {
 
 			slot = sync_thread_levels_get_nth(array, i);
@@ -1049,116 +1032,152 @@
 	}
 
 	array = thread_slot->levels;
-	
+
 	/* NOTE that there is a problem with _NODE and _LEAF levels: if the
 	B-tree height changes, then a leaf can change to an internal node
 	or the other way around. We do not know at present if this can cause
 	unnecessary assertion failures below. */
 
-	if (level == SYNC_NO_ORDER_CHECK) {
+	switch (level) {
+	case SYNC_NO_ORDER_CHECK:
+	case SYNC_EXTERN_STORAGE:
+	case SYNC_TREE_NODE_FROM_HASH:
 		/* Do no order checking */
-
-	} else if (level == SYNC_MEM_POOL) {
+		break;
+	case SYNC_MEM_POOL:
 		ut_a(sync_thread_levels_g(array, SYNC_MEM_POOL));
-	} else if (level == SYNC_MEM_HASH) {
+		break;
+	case SYNC_MEM_HASH:
 		ut_a(sync_thread_levels_g(array, SYNC_MEM_HASH));
-	} else if (level == SYNC_RECV) {
+		break;
+	case SYNC_RECV:
 		ut_a(sync_thread_levels_g(array, SYNC_RECV));
-	} else if (level == SYNC_LOG) {
+		break;
+	case SYNC_WORK_QUEUE:
+		ut_a(sync_thread_levels_g(array, SYNC_WORK_QUEUE));
+		break;
+	case SYNC_LOG:
 		ut_a(sync_thread_levels_g(array, SYNC_LOG));
-	} else if (level == SYNC_THR_LOCAL) {
+		break;
+	case SYNC_THR_LOCAL:
 		ut_a(sync_thread_levels_g(array, SYNC_THR_LOCAL));
-	} else if (level == SYNC_ANY_LATCH) {
+		break;
+	case SYNC_ANY_LATCH:
 		ut_a(sync_thread_levels_g(array, SYNC_ANY_LATCH));
-	} else if (level == SYNC_TRX_SYS_HEADER) {
+		break;
+	case SYNC_TRX_SYS_HEADER:
 		ut_a(sync_thread_levels_g(array, SYNC_TRX_SYS_HEADER));
-	} else if (level == SYNC_DOUBLEWRITE) {
+		break;
+	case SYNC_DOUBLEWRITE:
 		ut_a(sync_thread_levels_g(array, SYNC_DOUBLEWRITE));
-	} else if (level == SYNC_BUF_BLOCK) {
+		break;
+	case SYNC_BUF_BLOCK:
 		ut_a((sync_thread_levels_contain(array, SYNC_BUF_POOL)
-			&& sync_thread_levels_g(array, SYNC_BUF_BLOCK - 1))
+		      && sync_thread_levels_g(array, SYNC_BUF_BLOCK - 1))
 		     || sync_thread_levels_g(array, SYNC_BUF_BLOCK));
-	} else if (level == SYNC_BUF_POOL) {
+		break;
+	case SYNC_BUF_POOL:
 		ut_a(sync_thread_levels_g(array, SYNC_BUF_POOL));
-	} else if (level == SYNC_SEARCH_SYS) {
+		break;
+	case SYNC_SEARCH_SYS:
 		ut_a(sync_thread_levels_g(array, SYNC_SEARCH_SYS));
-	} else if (level == SYNC_TRX_LOCK_HEAP) {
+		break;
+	case SYNC_TRX_LOCK_HEAP:
 		ut_a(sync_thread_levels_g(array, SYNC_TRX_LOCK_HEAP));
-	} else if (level == SYNC_REC_LOCK) {
+		break;
+	case SYNC_REC_LOCK:
 		ut_a((sync_thread_levels_contain(array, SYNC_KERNEL)
-			&& sync_thread_levels_g(array, SYNC_REC_LOCK - 1))
+		      && sync_thread_levels_g(array, SYNC_REC_LOCK - 1))
 		     || sync_thread_levels_g(array, SYNC_REC_LOCK));
-	} else if (level == SYNC_KERNEL) {
+		break;
+	case SYNC_KERNEL:
 		ut_a(sync_thread_levels_g(array, SYNC_KERNEL));
-	} else if (level == SYNC_IBUF_BITMAP) {
+		break;
+	case SYNC_IBUF_BITMAP:
 		ut_a((sync_thread_levels_contain(array, SYNC_IBUF_BITMAP_MUTEX)
-		         && sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1))
+		      && sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1))
 		     || sync_thread_levels_g(array, SYNC_IBUF_BITMAP));
-	} else if (level == SYNC_IBUF_BITMAP_MUTEX) {
+		break;
+	case SYNC_IBUF_BITMAP_MUTEX:
 		ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP_MUTEX));
-	} else if (level == SYNC_FSP_PAGE) {
+		break;
+	case SYNC_FSP_PAGE:
 		ut_a(sync_thread_levels_contain(array, SYNC_FSP));
-	} else if (level == SYNC_FSP) {
+		break;
+	case SYNC_FSP:
 		ut_a(sync_thread_levels_contain(array, SYNC_FSP)
 		     || sync_thread_levels_g(array, SYNC_FSP));
-	} else if (level == SYNC_EXTERN_STORAGE) {
-		ut_a(TRUE);
-	} else if (level == SYNC_TRX_UNDO_PAGE) {
+		break;
+	case SYNC_TRX_UNDO_PAGE:
 		ut_a(sync_thread_levels_contain(array, SYNC_TRX_UNDO)
 		     || sync_thread_levels_contain(array, SYNC_RSEG)
 		     || sync_thread_levels_contain(array, SYNC_PURGE_SYS)
 		     || sync_thread_levels_g(array, SYNC_TRX_UNDO_PAGE));
-	} else if (level == SYNC_RSEG_HEADER) {
+		break;
+	case SYNC_RSEG_HEADER:
 		ut_a(sync_thread_levels_contain(array, SYNC_RSEG));
-	} else if (level == SYNC_RSEG_HEADER_NEW) {
+		break;
+	case SYNC_RSEG_HEADER_NEW:
 		ut_a(sync_thread_levels_contain(array, SYNC_KERNEL)
 		     && sync_thread_levels_contain(array, SYNC_FSP_PAGE));
-	} else if (level == SYNC_RSEG) {
+		break;
+	case SYNC_RSEG:
 		ut_a(sync_thread_levels_g(array, SYNC_RSEG));
-	} else if (level == SYNC_TRX_UNDO) {
+		break;
+	case SYNC_TRX_UNDO:
 		ut_a(sync_thread_levels_g(array, SYNC_TRX_UNDO));
-	} else if (level == SYNC_PURGE_LATCH) {
+		break;
+	case SYNC_PURGE_LATCH:
 		ut_a(sync_thread_levels_g(array, SYNC_PURGE_LATCH));
-	} else if (level == SYNC_PURGE_SYS) {
+		break;
+	case SYNC_PURGE_SYS:
 		ut_a(sync_thread_levels_g(array, SYNC_PURGE_SYS));
-	} else if (level == SYNC_TREE_NODE) {
+		break;
+	case SYNC_TREE_NODE:
 		ut_a(sync_thread_levels_contain(array, SYNC_INDEX_TREE)
-		     || sync_thread_levels_contain(array, SYNC_DICT_OPERATION)
 		     || sync_thread_levels_g(array, SYNC_TREE_NODE - 1));
-	} else if (level == SYNC_TREE_NODE_FROM_HASH) {
-		ut_a(1);
-	} else if (level == SYNC_TREE_NODE_NEW) {
+		break;
+	case SYNC_TREE_NODE_NEW:
 		ut_a(sync_thread_levels_contain(array, SYNC_FSP_PAGE)
 		     || sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
-	} else if (level == SYNC_INDEX_TREE) {
+		break;
+	case SYNC_INDEX_TREE:
 		ut_a((sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
 		      && sync_thread_levels_contain(array, SYNC_FSP)
 		      && sync_thread_levels_g(array, SYNC_FSP_PAGE - 1))
 		     || sync_thread_levels_g(array, SYNC_TREE_NODE - 1));
-	} else if (level == SYNC_IBUF_MUTEX) {
+		break;
+	case SYNC_IBUF_MUTEX:
 		ut_a(sync_thread_levels_g(array, SYNC_FSP_PAGE - 1));
-	} else if (level == SYNC_IBUF_PESS_INSERT_MUTEX) {
+		break;
+	case SYNC_IBUF_PESS_INSERT_MUTEX:
 		ut_a(sync_thread_levels_g(array, SYNC_FSP - 1)
 		     && !sync_thread_levels_contain(array, SYNC_IBUF_MUTEX));
-	} else if (level == SYNC_IBUF_HEADER) {
+		break;
+	case SYNC_IBUF_HEADER:
 		ut_a(sync_thread_levels_g(array, SYNC_FSP - 1)
 		     && !sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
-		     && !sync_thread_levels_contain(array,
-						SYNC_IBUF_PESS_INSERT_MUTEX));
-	} else if (level == SYNC_DICT_AUTOINC_MUTEX) {
+		     && !sync_thread_levels_contain(
+			     array, SYNC_IBUF_PESS_INSERT_MUTEX));
+		break;
+	case SYNC_DICT_AUTOINC_MUTEX:
 		ut_a(sync_thread_levels_g(array, SYNC_DICT_AUTOINC_MUTEX));
-	} else if (level == SYNC_DICT_OPERATION) {
+		break;
+	case SYNC_DICT_OPERATION:
 		ut_a(sync_thread_levels_g(array, SYNC_DICT_OPERATION));
-	} else if (level == SYNC_DICT_HEADER) {
+		break;
+	case SYNC_DICT_HEADER:
 		ut_a(sync_thread_levels_g(array, SYNC_DICT_HEADER));
-	} else if (level == SYNC_DICT) {
+		break;
+	case SYNC_DICT:
 #ifdef UNIV_DEBUG
 		ut_a(buf_debug_prints
 		     || sync_thread_levels_g(array, SYNC_DICT));
 #else /* UNIV_DEBUG */
 		ut_a(sync_thread_levels_g(array, SYNC_DICT));
 #endif /* UNIV_DEBUG */
-	} else {
+		break;
+	default:
 		ut_error;
 	}
 
@@ -1178,7 +1197,7 @@
 
 	mutex_exit(&sync_thread_mutex);
 }
-	
+
 /**********************************************************************
 Removes a latch from the thread level array if it is found there. */
 
@@ -1193,7 +1212,7 @@
 	sync_level_t*	slot;
 	sync_thread_t*	thread_slot;
 	ulint		i;
-	
+
 	if (!sync_order_checks_on) {
 
 		return(FALSE);
@@ -1201,9 +1220,7 @@
 
 	if ((latch == (void*)&sync_thread_mutex)
 	    || (latch == (void*)&mutex_list_mutex)
-#ifdef UNIV_SYNC_DEBUG
 	    || (latch == (void*)&rw_lock_debug_mutex)
-#endif /* UNIV_SYNC_DEBUG */
 	    || (latch == (void*)&rw_lock_list_mutex)) {
 
 		return(FALSE);
@@ -1222,7 +1239,7 @@
 	}
 
 	array = thread_slot->levels;
-	
+
 	for (i = 0; i < SYNC_THREAD_N_LEVELS; i++) {
 
 		slot = sync_thread_levels_get_nth(array, i);
@@ -1242,7 +1259,8 @@
 
 	return(FALSE);
 }
-	
+#endif /* UNIV_SYNC_DEBUG */
+
 /**********************************************************************
 Initializes the synchronization data structures. */
 
@@ -1250,9 +1268,11 @@
 sync_init(void)
 /*===========*/
 {
+#ifdef UNIV_SYNC_DEBUG
 	sync_thread_t*	thread_slot;
 	ulint		i;
-	
+#endif /* UNIV_SYNC_DEBUG */
+
 	ut_a(sync_initialized == FALSE);
 
 	sync_initialized = TRUE;
@@ -1261,37 +1281,34 @@
 	mutex */
 
 	sync_primary_wait_array = sync_array_create(OS_THREAD_MAX_N,
-						    SYNC_ARRAY_OS_MUTEX);	
-
+						    SYNC_ARRAY_OS_MUTEX);
+#ifdef UNIV_SYNC_DEBUG
 	/* Create the thread latch level array where the latch levels
 	are stored for each OS thread */
 
 	sync_thread_level_arrays = ut_malloc(OS_THREAD_MAX_N
-						* sizeof(sync_thread_t));
+					     * sizeof(sync_thread_t));
 	for (i = 0; i < OS_THREAD_MAX_N; i++) {
 
 		thread_slot = sync_thread_level_arrays_get_nth(i);
 		thread_slot->levels = NULL;
 	}
-
-        /* Init the mutex list and create the mutex to protect it. */
+#endif /* UNIV_SYNC_DEBUG */
+	/* Init the mutex list and create the mutex to protect it. */
 
 	UT_LIST_INIT(mutex_list);
-        mutex_create(&mutex_list_mutex);
-        mutex_set_level(&mutex_list_mutex, SYNC_NO_ORDER_CHECK);
+	mutex_create(&mutex_list_mutex, SYNC_NO_ORDER_CHECK);
+#ifdef UNIV_SYNC_DEBUG
+	mutex_create(&sync_thread_mutex, SYNC_NO_ORDER_CHECK);
+#endif /* UNIV_SYNC_DEBUG */
 
-        mutex_create(&sync_thread_mutex);
-        mutex_set_level(&sync_thread_mutex, SYNC_NO_ORDER_CHECK);
-        
 	/* Init the rw-lock list and create the mutex to protect it. */
 
 	UT_LIST_INIT(rw_lock_list);
-        mutex_create(&rw_lock_list_mutex);
-        mutex_set_level(&rw_lock_list_mutex, SYNC_NO_ORDER_CHECK);
+	mutex_create(&rw_lock_list_mutex, SYNC_NO_ORDER_CHECK);
 
 #ifdef UNIV_SYNC_DEBUG
-        mutex_create(&rw_lock_debug_mutex);
-        mutex_set_level(&rw_lock_debug_mutex, SYNC_NO_ORDER_CHECK);
+	mutex_create(&rw_lock_debug_mutex, SYNC_NO_ORDER_CHECK);
 
 	rw_lock_debug_event = os_event_create(NULL);
 	rw_lock_debug_waiters = FALSE;
@@ -1313,12 +1330,14 @@
 	mutex = UT_LIST_GET_FIRST(mutex_list);
 
 	while (mutex) {
-	        mutex_free(mutex);
+		mutex_free(mutex);
 		mutex = UT_LIST_GET_FIRST(mutex_list);
 	}
 
 	mutex_free(&mutex_list_mutex);
-	mutex_free(&sync_thread_mutex);	
+#ifdef UNIV_SYNC_DEBUG
+	mutex_free(&sync_thread_mutex);
+#endif /* UNIV_SYNC_DEBUG */
 }
 
 /***********************************************************************
@@ -1330,20 +1349,21 @@
 	FILE*	file)		/* in: file where to print */
 {
 #ifdef UNIV_SYNC_DEBUG
-	fprintf(stderr, "Mutex exits %lu, rws exits %lu, rwx exits %lu\n",
+	fprintf(file, "Mutex exits %lu, rws exits %lu, rwx exits %lu\n",
 		mutex_exit_count, rw_s_exit_count, rw_x_exit_count);
 #endif
 
 	fprintf(file,
-"Mutex spin waits %lu, rounds %lu, OS waits %lu\n"
-"RW-shared spins %lu, OS waits %lu; RW-excl spins %lu, OS waits %lu\n",
-			(ulong) mutex_spin_wait_count,
-		        (ulong) mutex_spin_round_count,
-			(ulong) mutex_os_wait_count,
-			(ulong) rw_s_spin_wait_count,
-		        (ulong) rw_s_os_wait_count,
-			(ulong) rw_x_spin_wait_count,
-		        (ulong) rw_x_os_wait_count);
+		"Mutex spin waits %lu, rounds %lu, OS waits %lu\n"
+		"RW-shared spins %lu, OS waits %lu;"
+		" RW-excl spins %lu, OS waits %lu\n",
+		(ulong) mutex_spin_wait_count,
+		(ulong) mutex_spin_round_count,
+		(ulong) mutex_os_wait_count,
+		(ulong) rw_s_spin_wait_count,
+		(ulong) rw_s_os_wait_count,
+		(ulong) rw_x_spin_wait_count,
+		(ulong) rw_x_os_wait_count);
 }
 
 /***********************************************************************
@@ -1355,9 +1375,9 @@
 	FILE*	file)		/* in: file where to print */
 {
 #ifdef UNIV_SYNC_DEBUG
-	mutex_list_print_info();
+	mutex_list_print_info(file);
 
-	rw_lock_list_print_info();
+	rw_lock_list_print_info(file);
 #endif /* UNIV_SYNC_DEBUG */
 
 	sync_array_print_info(file, sync_primary_wait_array);
Thread
bk commit into 5.1 tree (tsmith:1.2403)tim18 Jan