List:Commits« Previous MessageNext Message »
From:Kevin Lewis Date:May 1 2009 6:26pm
Subject:bzr commit into mysql-6.0-falcon-team branch (kevin.lewis:2703)
View as plain text  
#At file:///C:/Work/bzr/Merge/mysql-6.0-falcon-team/ based on revid:kevin.lewis@stripped

 2703 Kevin Lewis	2009-05-01
      Bug#38568 continued;  This is only a cleanup patch to the previous patch which uses COMPARE_EXCHANGE_POINTER on all calls that update RecordVersion::priorVersion.  Jim Starkey originally intended the priorRecord chain to be accessed in a completely non-blocking manner.  This use of CAS should be unneccessary, in theory.  It is used in order to try and catch any conflicting code path in which two separate threads may want to update a priorVersion pointer simultaneously, or nearly so on separate CPUs.  So these CAS assignments are enclosed in a new macro called  USE_CAS_FOR_PRIOR_VERSION  in this patch.  If there is no perceptible performance cost with this, the CAS code may become permanent and this patch can be undone.
      Basically, this patch  allows one to revert to the old direct assignments of priorVersion in order to test the performance.  That is done by commenting out 

=== modified file 'storage/falcon/RecordVersion.cpp'
--- a/storage/falcon/RecordVersion.cpp	2009-04-16 12:09:15 +0000
+++ b/storage/falcon/RecordVersion.cpp	2009-05-01 18:26:25 +0000
@@ -39,6 +39,19 @@
 static const char THIS_FILE[]=__FILE__;
+// USE_CAS_FOR_PRIOR_VERSION ma be temporary while we look for  
+// problems... or not if the performance hit is unoticeable.
+// In theory, Record::priorVersion can be updated without CAS 
+// because the code is organized so that only one thread can change 
+// this at a time, even though many threads can be traversing the 
+// prior record chain simultaneously on separate CPUs.  
+// The CycleManagermakes sure that any pointer read from a priorRecord 
+// remains valid while the local copy of that pointer exists.
+// These CAS exchanges protect and identify places where multiple 
+// threads change this pointer at the same time, if possible.
 // Construction/Destruction
@@ -125,8 +138,12 @@ RecordVersion::~RecordVersion()
 	state = recDeleting;
 	Record* prior = priorVersion;
 	if (!COMPARE_EXCHANGE_POINTER(&priorVersion, prior, NULL))
 		FATAL("~RecordVersion; Unexpected contents in priorVersion\n");
+	priorVersion = NULL;
 	// Avoid recursion here. May crash from too many levels
 	// if the same record is updated too often and quickly.
@@ -149,9 +166,13 @@ Record* RecordVersion::releaseNonRecursi
 	if (useCount == 1)
 		prior = priorVersion;
 		if (!COMPARE_EXCHANGE_POINTER(&priorVersion, prior, NULL))
 			FATAL("RecordVersion::releaseNonRecursive; Unexpected contents in priorVersion\n");
+		priorVersion = NULL;
@@ -328,8 +349,13 @@ Record* RecordVersion::clearPriorVersion
 	if (prior && prior->useCount == 1)
 		if (COMPARE_EXCHANGE_POINTER(&priorVersion, prior, NULL))
 			return prior;
+		priorVersion = NULL;
+		return prior;
 	return NULL;
@@ -340,8 +366,13 @@ void RecordVersion::setPriorVersion(Reco
 	if (newPriorVersion)
 	if (!COMPARE_EXCHANGE_POINTER(&priorVersion, oldPriorVersion, newPriorVersion))
 		FATAL("RecordVersion::setPriorVersion; Unexpected contents in priorVersion\n");
+	ASSERT(priorVersion == oldPriorVersion);
+	priorVersion = newPriorVersion;
 	if (oldPriorVersion)

Attachment: [text/bzr-bundle] bzr/
bzr commit into mysql-6.0-falcon-team branch (kevin.lewis:2703)Bug#38568Kevin Lewis1 May