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

 3129 Kevin Lewis	2009-04-17
      Adding an array of SyncObjects to each cycle instead of only one 
      so that the cache line collisions at high concurrency are reduced.
      create these syncObjects as needed using CAS in case multiple threads 
      make them at the same time.

    modified:
      storage/falcon/CycleLock.cpp
      storage/falcon/CycleManager.cpp
      storage/falcon/CycleManager.h
=== modified file 'storage/falcon/CycleLock.cpp'
--- a/storage/falcon/CycleLock.cpp	2009-03-20 19:33:52 +0000
+++ b/storage/falcon/CycleLock.cpp	2009-04-17 21:16:36 +0000
@@ -7,11 +7,11 @@
 CycleLock::CycleLock(Database *database)
 {
 	cycleManager = database->cycleManager;
-	syncObject = cycleManager->currentCycle;
+	syncObject = cycleManager->getSyncObject();
 	thread = Thread::getThread("CycleLock::CycleLock");
 
 	// If there already is a cycle manager, let him worry about all this
-		
+
 	if ( (chain = thread->cycleLock) )
 		locked = false;
 	else
@@ -61,7 +61,7 @@ void CycleLock::lockCycle(void)
 		chain->lockCycle();
 	else
 		{
-		syncObject = cycleManager->currentCycle;
+		syncObject = cycleManager->getSyncObject();
 		syncObject->lock(NULL, Shared);
 		locked = true;
 		}

=== modified file 'storage/falcon/CycleManager.cpp'
--- a/storage/falcon/CycleManager.cpp	2009-04-16 11:25:48 +0000
+++ b/storage/falcon/CycleManager.cpp	2009-04-17 21:16:36 +0000
@@ -1,3 +1,24 @@
+/* Copyright (C) 2009 MySQL AB, 2009 Sun Microsystems, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   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
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+// CycleManager: implementation of the CycleManager class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include <stdlib.h>
 #include "Engine.h"
 #include "CycleManager.h"
 #include "Sync.h"
@@ -24,13 +45,30 @@ CycleManager::CycleManager(Database *db)
 	valuePurgatory = NULL;
 	bufferPurgatory = NULL;
 
-	currentCycle = &cycle1;
-	cycle1.setName("CycleManager::cycle1");
-	cycle2.setName("CycleManager::cycle2");
+	cycle1 = new SyncObject* [syncArraySize];
+	cycle2 = new SyncObject* [syncArraySize];
+	currentCycle = cycle1;
+	for (int i = 0; i < syncArraySize; i++)
+		{
+		cycle1[i] = NULL;
+		cycle2[i] = NULL;
+		}
 }
 
 CycleManager::~CycleManager(void)
 {
+	for (int i = 0; i < syncArraySize; i++)
+		{
+		if (cycle1[i] != NULL)
+			delete cycle1[i];
+
+		if (cycle2[i] != NULL)
+			delete cycle2[i];
+		}
+
+	delete [] cycle1;
+	delete [] cycle2;
+
 }
 
 void CycleManager::start(void)
@@ -109,14 +147,21 @@ void CycleManager::cycleManager(void)
 		
 		// Swap cycle clocks to start next cycle
 		
-		SyncObject *priorCycle = currentCycle;
-		currentCycle = (currentCycle == &cycle1) ? &cycle2 : &cycle1;
+		SyncObject **priorCycle = currentCycle;
+		currentCycle = (currentCycle == cycle1) ? cycle2 : cycle1;
 	
-		// Wait for previous cycle to complete
+		// Wait for the previous cycle to complete by getting an exclusive 
+		// lock on each of the allocated syncObjects in that cycle.
 		
-		Sync sync(priorCycle, "CycleManager::cycleManager");
-		sync.lock(Exclusive);
-		sync.unlock();
+		for (int i = 0; i < syncArraySize; i++)
+			{
+			if (priorCycle[i] != NULL)
+				{
+				Sync sync(priorCycle[i], "CycleManager::cycleManager");
+				sync.lock(Exclusive);
+				sync.unlock();
+				}
+			}
 		
 		for (RecordVersion *recordVersion; (recordVersion = doomedRecordVersions);)
 			{
@@ -144,8 +189,26 @@ void CycleManager::cycleManager(void)
 			DELETE_RECORD (bufferList->zombie);
 			delete bufferList;
 			}
+		}
+}
 
+SyncObject *CycleManager::getSyncObject(void)
+{
+	int slot = rand() & syncArrayMask;
+	SyncObject* syncObject = currentCycle[slot];
+	if (syncObject == NULL)
+		{
+		syncObject = new SyncObject;
+		if (COMPARE_EXCHANGE_POINTER(&currentCycle[slot], NULL, syncObject))
+			syncObject->setName("CycleManager::cycle1");
+		else // another thread beat us to the slot.
+			{
+			delete syncObject;
+			syncObject = currentCycle[slot];
+			}
 		}
+
+	return syncObject;
 }
 
 void CycleManager::queueForDelete(Record* zombie)

=== modified file 'storage/falcon/CycleManager.h'
--- a/storage/falcon/CycleManager.h	2009-04-09 17:31:22 +0000
+++ b/storage/falcon/CycleManager.h	2009-04-17 21:16:36 +0000
@@ -9,6 +9,9 @@ class Record;
 class RecordVersion;
 class Value;
 
+static const int syncArraySize = 64;
+static const int syncArrayMask = 63;
+
 class CycleManager
 {
 	struct RecordList
@@ -36,15 +39,16 @@ public:
 	void		start(void);
 	void		shutdown(void);
 	void		cycleManager(void);
+	SyncObject *getSyncObject(void);
 	void		queueForDelete(Record* zombie);
 	void		queueForDelete(Value** zombie);
 	void		queueForDelete(char* zombie);
 
 	static void cycleManager(void *arg);
 	
-	SyncObject		cycle1;
-	SyncObject		cycle2;
-	SyncObject		*currentCycle;
+	SyncObject		**cycle1;
+	SyncObject		**cycle2;
+	SyncObject		**currentCycle;
 	RecordVersion	*recordVersionPurgatory;
 	RecordList		*recordPurgatory;
 	ValueList		*valuePurgatory;


Attachment: [text/bzr-bundle] bzr/kevin.lewis@sun.com-20090417211636-0sdp160fnbgvyhrq.bundle
Thread
bzr commit into mysql-6.0-falcon-team branch (kevin.lewis:3129)Kevin Lewis17 Apr