#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(¤tCycle[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 Lewis | 17 Apr |