Below is the list of changes that have just been committed into a local
5.1 repository of jonas. When jonas 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-11-08 20:44:01+01:00, jonas@stripped +7 -0
ndb - impl. rw-mutexes
(as part of parallel nr)
storage/ndb/include/kernel/signaldata/UtilLock.hpp@stripped, 2007-11-08 20:43:58+01:00, jonas@stripped +9 -4
Impl. shared lock (aka rw-mutexes)
storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp@stripped, 2007-11-08 20:43:58+01:00, jonas@stripped +159 -19
Impl. shared lock (aka rw-mutexes)
storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp@stripped, 2007-11-08 20:43:59+01:00, jonas@stripped +7 -0
Impl. shared lock (aka rw-mutexes)
storage/ndb/src/kernel/vm/Mutex.cpp@stripped, 2007-11-08 20:43:59+01:00, jonas@stripped +19 -23
Impl. shared lock (aka rw-mutexes)
storage/ndb/src/kernel/vm/Mutex.hpp@stripped, 2007-11-08 20:43:59+01:00, jonas@stripped +12 -7
Impl. shared lock (aka rw-mutexes)
storage/ndb/src/kernel/vm/SimulatedBlock.cpp@stripped, 2007-11-08 20:43:59+01:00, jonas@stripped +2 -1
Add extra virtual function for mutex dimensioning
storage/ndb/src/kernel/vm/SimulatedBlock.hpp@stripped, 2007-11-08 20:43:59+01:00, jonas@stripped +2 -2
Impl. shared lock (aka rw-mutexes)
diff -Nrup a/storage/ndb/include/kernel/signaldata/UtilLock.hpp b/storage/ndb/include/kernel/signaldata/UtilLock.hpp
--- a/storage/ndb/include/kernel/signaldata/UtilLock.hpp 2006-12-23 20:20:07 +01:00
+++ b/storage/ndb/include/kernel/signaldata/UtilLock.hpp 2007-11-08 20:43:58 +01:00
@@ -36,8 +36,11 @@ public:
STATIC_CONST( SignalLength = 4 );
enum RequestInfo {
- TryLock = 1
+ TryLock = 1,
+ SharedLock = 2,
+ Notify = 4
};
+
public:
Uint32 senderData;
Uint32 senderRef;
@@ -91,10 +94,11 @@ public:
NoSuchLock = 1,
OutOfLockRecords = 2,
DistributedLockNotSupported = 3,
- LockAlreadyHeld = 4
-
+ LockAlreadyHeld = 4,
+ InLockQueue = 5 // lock + notify
};
public:
+
Uint32 senderData;
Uint32 senderRef;
Uint32 lockId;
@@ -168,7 +172,8 @@ public:
enum ErrorCode {
OK = 0,
NoSuchLock = 1,
- NotLockOwner = 2
+ NotLockOwner = 2,
+ NotInLockQueue = 3
};
public:
Uint32 senderData;
diff -Nrup a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp b/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp
--- a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp 2007-10-25 08:46:20 +02:00
+++ b/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp 2007-11-08 20:43:58 +01:00
@@ -622,7 +622,7 @@ DbUtil::execDUMP_STATE_ORD(Signal* signa
ptr.p->m_mutexId = signal->theData[1];
Callback c = { safe_cast(&DbUtil::mutex_locked), ptr.i };
ptr.p->m_callback = c;
- c_mutexMgr.lock(signal, ptr);
+ c_mutexMgr.lock(signal, ptr, true);
ndbout_c("c_mutexMgr.lock ptrI=%d mutexId=%d", ptr.i, ptr.p->m_mutexId);
}
@@ -647,6 +647,48 @@ DbUtil::execDUMP_STATE_ORD(Signal* signa
ndbout_c("c_mutexMgr.destroy ptrI=%d mutexId=%d key=%d",
ptr.i, ptr.p->m_mutexId, ptr.p->m_mutexKey);
}
+
+ if (tCase == 244)
+ {
+ jam();
+ DLHashTable<LockQueue>::Iterator iter;
+ Uint32 bucket = signal->theData[1];
+ if (signal->getLength() == 1)
+ {
+ bucket = 0;
+ infoEvent("Starting dumping of DbUtil::Locks");
+ }
+ c_lockQueues.next(bucket, iter);
+
+ for (Uint32 i = 0; i<32 || iter.bucket == bucket; i++)
+ {
+ if (iter.curr.isNull())
+ {
+ infoEvent("Dumping of DbUtil::Locks - done");
+ return;
+ }
+
+ infoEvent("LockQueue %u", iter.curr.p->m_lockId);
+ LocalDLFifoList<LockQueueElement> queue(c_lockElementPool,
+ iter.curr.p->m_queue);
+ Ptr<LockQueueElement> ptr;
+ for (queue.first(ptr); !ptr.isNull(); queue.next(ptr))
+ {
+ infoEvent("- sender: 0x%x data: %u %s %s",
+ ptr.p->m_senderRef,
+ ptr.p->m_senderData,
+ (ptr.p->m_bits & LockQueueElement::LQE_EXCLUSIVE) ? "X":"S",
+ (ptr.p->m_bits & LockQueueElement::LQE_GRANTED) ?
+ "granted" : "");
+ }
+
+ c_lockQueues.next(iter);
+ }
+ signal->theData[0] = 244;
+ signal->theData[1] = iter.bucket;
+ sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 2, JBB);
+ return;
+ }
}
void
@@ -2337,6 +2379,9 @@ DbUtil::execUTIL_LOCK_REQ(Signal * signa
jamEntry();
UtilLockReq * req = (UtilLockReq*)signal->getDataPtr();
const Uint32 lockId = req->lockId;
+ const bool exclusive = ! (req->requestInfo & UtilLockReq::SharedLock);
+ const bool trylock = req->requestInfo & UtilLockReq::TryLock;
+ const bool notify = req->requestInfo & UtilLockReq::Notify;
LockQueuePtr lockQPtr;
if(!c_lockQueues.find(lockQPtr, lockId)){
@@ -2355,28 +2400,72 @@ DbUtil::execUTIL_LOCK_REQ(Signal * signa
LocalDLFifoList<LockQueueElement> queue(c_lockElementPool,
lockQPtr.p->m_queue);
- if(req->requestInfo & UtilLockReq::TryLock && !queue.isEmpty()){
+
+ bool grant = true;
+ LockQueueElementPtr lockEPtr;
+ for (queue.last(lockEPtr); ! lockEPtr.isNull(); queue.prev(lockEPtr))
+ {
+ jam();
+ if (lockEPtr.p->m_bits & LockQueueElement::LQE_EXCLUSIVE)
+ {
+ jam();
+ grant = false;
+ break;
+ }
+ else if (exclusive)
+ {
+ jam();
+ grant = false;
+ break;
+ }
+ }
+
+ if(trylock && grant == false)
+ {
jam();
sendLOCK_REF(signal, req, UtilLockRef::LockAlreadyHeld);
return;
}
- LockQueueElementPtr lockEPtr;
if(!c_lockElementPool.seize(lockEPtr)){
jam();
sendLOCK_REF(signal, req, UtilLockRef::OutOfLockRecords);
return;
}
+ lockEPtr.p->m_bits = 0;
lockEPtr.p->m_senderRef = req->senderRef;
lockEPtr.p->m_senderData = req->senderData;
- if(queue.isEmpty()){
+ if (exclusive)
+ {
+ lockEPtr.p->m_bits |= LockQueueElement::LQE_EXCLUSIVE;
+ }
+
+ if(grant)
+ {
jam();
+ lockEPtr.p->m_bits |= LockQueueElement::LQE_GRANTED;
+
+ if (queue.isEmpty())
+ {
+ jam();
+ lockQPtr.p->m_lockKey++;
+ }
+ else
+ {
+ infoEvent("Granting shared lock...");
+ }
+
sendLOCK_CONF(signal, lockQPtr.p, lockEPtr.p);
}
+ else if (notify)
+ {
+ jam();
+ sendLOCK_REF(signal, req, UtilLockRef::InLockQueue);
+ }
- queue.add(lockEPtr);
+ queue.addLast(lockEPtr);
}
void
@@ -2385,7 +2474,10 @@ DbUtil::execUTIL_UNLOCK_REQ(Signal* sign
UtilUnlockReq * req = (UtilUnlockReq*)signal->getDataPtr();
const Uint32 lockId = req->lockId;
+ const Uint32 senderRef = req->senderRef;
+ const Uint32 senderData = req->senderData;
+
LockQueuePtr lockQPtr;
if(!c_lockQueues.find(lockQPtr, lockId)){
jam();
@@ -2396,26 +2488,75 @@ DbUtil::execUTIL_UNLOCK_REQ(Signal* sign
LocalDLFifoList<LockQueueElement> queue(c_lockElementPool,
lockQPtr.p->m_queue);
LockQueueElementPtr lockEPtr;
- if(!queue.first(lockEPtr)){
- jam();
- sendUNLOCK_REF(signal, req, UtilUnlockRef::NotLockOwner);
- return;
- }
- if(lockQPtr.p->m_lockKey != req->lockKey){
+ bool found = false;
+ for (queue.first(lockEPtr); !lockEPtr.isNull(); queue.next(lockEPtr))
+ {
jam();
- sendUNLOCK_REF(signal, req, UtilUnlockRef::NotLockOwner);
- return;
+ if (lockEPtr.p->m_senderData == senderData &&
+ lockEPtr.p->m_senderRef == senderRef)
+ {
+ jam();
+ found = true;
+ sendUNLOCK_CONF(signal, lockQPtr.p, lockEPtr.p);
+ break;
+ }
}
-
- sendUNLOCK_CONF(signal, lockQPtr.p, lockEPtr.p);
+
queue.release(lockEPtr);
- if(queue.first(lockEPtr)){
+ if (!found)
+ {
jam();
- sendLOCK_CONF(signal, lockQPtr.p, lockEPtr.p);
+ sendUNLOCK_REF(signal, req, UtilUnlockRef::NotInLockQueue);
return;
}
+
+ if (queue.first(lockEPtr))
+ {
+ if (lockEPtr.p->m_bits & LockQueueElement::LQE_EXCLUSIVE)
+ {
+ jam();
+ if (! (lockEPtr.p->m_bits & LockQueueElement::LQE_GRANTED))
+ {
+ jam();
+ lockEPtr.p->m_bits |= LockQueueElement::LQE_GRANTED;
+ sendLOCK_CONF(signal, lockQPtr.p, lockEPtr.p);
+ }
+ return;
+ }
+
+ bool first = true;
+ for (; !lockEPtr.isNull(); queue.next(lockEPtr))
+ {
+ jam();
+ if (lockEPtr.p->m_bits & LockQueueElement::LQE_EXCLUSIVE)
+ {
+ jam();
+ return;
+ }
+ if (! (lockEPtr.p->m_bits & LockQueueElement::LQE_GRANTED))
+ {
+ jam();
+ lockEPtr.p->m_bits |= LockQueueElement::LQE_GRANTED;
+ sendLOCK_CONF(signal, lockQPtr.p, lockEPtr.p);
+
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ infoEvent("Granting shared lock...");
+ }
+ }
+ }
+ }
+ else
+ {
+ jam();
+ lockQPtr.p->m_lockKey++;
+ }
}
void
@@ -2441,7 +2582,7 @@ DbUtil::sendLOCK_CONF(Signal* signal,
const Uint32 senderData = lockEP->m_senderData;
const Uint32 senderRef = lockEP->m_senderRef;
const Uint32 lockId = lockQP->m_lockId;
- const Uint32 lockKey = ++lockQP->m_lockKey;
+ const Uint32 lockKey = lockQP->m_lockKey;
UtilLockConf * conf = (UtilLockConf*)signal->getDataPtrSend();
conf->senderData = senderData;
@@ -2476,7 +2617,6 @@ DbUtil::sendUNLOCK_CONF(Signal* signal,
const Uint32 senderData = lockEP->m_senderData;
const Uint32 senderRef = lockEP->m_senderRef;
const Uint32 lockId = lockQP->m_lockId;
- ++lockQP->m_lockKey;
UtilUnlockConf * conf = (UtilUnlockConf*)signal->getDataPtrSend();
conf->senderData = senderData;
diff -Nrup a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp b/storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp
--- a/storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp 2006-12-23 20:20:17 +01:00
+++ b/storage/ndb/src/kernel/blocks/dbutil/DbUtil.hpp 2007-11-08 20:43:59 +01:00
@@ -424,8 +424,15 @@ public:
* Lock manager
*/
struct LockQueueElement {
+ enum Bits
+ {
+ LQE_EXCLUSIVE = 1,
+ LQE_GRANTED = 2
+ };
+
Uint32 m_senderData;
Uint32 m_senderRef;
+ Uint32 m_bits;
union {
Uint32 nextPool;
Uint32 nextList;
diff -Nrup a/storage/ndb/src/kernel/vm/Mutex.cpp b/storage/ndb/src/kernel/vm/Mutex.cpp
--- a/storage/ndb/src/kernel/vm/Mutex.cpp 2006-12-23 20:20:19 +01:00
+++ b/storage/ndb/src/kernel/vm/Mutex.cpp 2007-11-08 20:43:59 +01:00
@@ -150,32 +150,16 @@ SimulatedBlock::MutexManager::execUTIL_D
void
-SimulatedBlock::MutexManager::lock(Signal* signal, ActiveMutexPtr& ptr){
+SimulatedBlock::MutexManager::lock(Signal* signal,
+ ActiveMutexPtr& ptr,
+ Uint32 flags){
UtilLockReq * req = (UtilLockReq*)signal->getDataPtrSend();
req->senderData = ptr.i;
req->senderRef = m_block.reference();
req->lockId = ptr.p->m_mutexId;
- req->requestInfo = 0;
-
- m_block.sendSignal(DBUTIL_REF,
- GSN_UTIL_LOCK_REQ,
- signal,
- UtilLockReq::SignalLength,
- JBB);
-
- ptr.p->m_gsn = GSN_UTIL_LOCK_REQ;
-}
+ req->requestInfo = flags;
-void
-SimulatedBlock::MutexManager::trylock(Signal* signal, ActiveMutexPtr& ptr){
-
- UtilLockReq * req = (UtilLockReq*)signal->getDataPtrSend();
- req->senderData = ptr.i;
- req->senderRef = m_block.reference();
- req->lockId = ptr.p->m_mutexId;
- req->requestInfo = UtilLockReq::TryLock;
-
m_block.sendSignal(DBUTIL_REF,
GSN_UTIL_LOCK_REQ,
signal,
@@ -193,8 +177,20 @@ SimulatedBlock::MutexManager::execUTIL_L
ndbrequire(ptr.p->m_gsn == GSN_UTIL_LOCK_REQ);
ndbrequire(ptr.p->m_mutexId == ref->lockId);
- ptr.p->m_gsn = 0;
+ bool notify = ref->errorCode == UtilLockRef::InLockQueue;
+ CallbackFunction fun = ptr.p->m_callback.m_callbackFunction;
+
+ if (!notify)
+ {
+ ptr.p->m_gsn = 0;
+ }
m_block.execute(signal, ptr.p->m_callback, ref->errorCode);
+
+ if (notify)
+ {
+ // execute clears function so that same callback shouldnt be called twice
+ ptr.p->m_callback.m_callbackFunction = fun;
+ }
}
void
@@ -204,9 +200,9 @@ SimulatedBlock::MutexManager::execUTIL_L
m_activeMutexes.getPtr(ptr, conf->senderData);
ndbrequire(ptr.p->m_gsn == GSN_UTIL_LOCK_REQ);
ndbrequire(ptr.p->m_mutexId == conf->lockId);
-
+
ptr.p->m_mutexKey = conf->lockKey;
-
+
ptr.p->m_gsn = 0;
m_block.execute(signal, ptr.p->m_callback, 0);
}
diff -Nrup a/storage/ndb/src/kernel/vm/Mutex.hpp b/storage/ndb/src/kernel/vm/Mutex.hpp
--- a/storage/ndb/src/kernel/vm/Mutex.hpp 2006-12-23 20:20:19 +01:00
+++ b/storage/ndb/src/kernel/vm/Mutex.hpp 2007-11-08 20:43:59 +01:00
@@ -18,6 +18,7 @@
#include "Callback.hpp"
#include "SimulatedBlock.hpp"
+#include <signaldata/UtilLock.hpp>
class Mutex;
@@ -69,11 +70,11 @@ public:
void release();
bool isNull() const ;
- bool lock(SimulatedBlock::Callback & callback);
- bool trylock(SimulatedBlock::Callback & callback);
+ bool lock(SimulatedBlock::Callback & callback, bool exclusive = true, bool notify = false);
+ bool trylock(SimulatedBlock::Callback & callback, bool exclusive = true);
void unlock(SimulatedBlock::Callback & callback);
void unlock(); // Ignore callback
-
+
bool create(SimulatedBlock::Callback & callback);
bool destroy(SimulatedBlock::Callback & callback);
@@ -181,12 +182,14 @@ Mutex::isNull() const {
inline
bool
-Mutex::lock(SimulatedBlock::Callback & callback){
+Mutex::lock(SimulatedBlock::Callback & callback, bool exclusive, bool notify){
if(m_ptr.isNull()){
if(m_mgr.seize(m_ptr)){
m_ptr.p->m_mutexId = m_mutexId;
m_ptr.p->m_callback = callback;
- m_mgr.lock(m_signal, m_ptr);
+ m_mgr.lock(m_signal, m_ptr,
+ ((exclusive == false) ? UtilLockReq::SharedLock : 0) |
+ ((notify == true) ? UtilLockReq::Notify : 0));
return true;
}
return false;
@@ -198,12 +201,14 @@ Mutex::lock(SimulatedBlock::Callback & c
inline
bool
-Mutex::trylock(SimulatedBlock::Callback & callback){
+Mutex::trylock(SimulatedBlock::Callback & callback, bool exclusive){
if(m_ptr.isNull()){
if(m_mgr.seize(m_ptr)){
m_ptr.p->m_mutexId = m_mutexId;
m_ptr.p->m_callback = callback;
- m_mgr.lock(m_signal, m_ptr);
+ m_mgr.lock(m_signal, m_ptr,
+ UtilLockReq::TryLock |
+ ((exclusive == false) ? UtilLockReq::SharedLock : 0));
return true;
}
return false;
diff -Nrup a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp 2007-06-14 16:10:10 +02:00
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp 2007-11-08 20:43:59 +01:00
@@ -96,7 +96,8 @@ SimulatedBlock::SimulatedBlock(BlockNumb
count = 5;
BaseString::snprintf(buf, 255, "%s.ActiveMutexes", getBlockName(blockNumber));
if(!p->get(buf, &count))
- p->get("ActiveMutexes", &count);
+ if (!this->getParam("ActiveMutexes", &count))
+ p->get("ActiveMutexes", &count);
c_mutexMgr.setSize(count);
c_counterMgr.setSize(5);
diff -Nrup a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp 2007-07-11 14:38:00 +02:00
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp 2007-11-08 20:43:59 +01:00
@@ -497,8 +497,7 @@ public:
void create(Signal*, ActiveMutexPtr&);
void destroy(Signal*, ActiveMutexPtr&);
- void lock(Signal*, ActiveMutexPtr&);
- void trylock(Signal*, ActiveMutexPtr&);
+ void lock(Signal*, ActiveMutexPtr&, Uint32 flags);
void unlock(Signal*, ActiveMutexPtr&);
private:
@@ -523,6 +522,7 @@ public:
MutexManager c_mutexMgr;
void ignoreMutexUnlockCallback(Signal* signal, Uint32 ptrI, Uint32 retVal);
+ virtual bool getParam(const char * param, Uint32 * retVal) { return false;}
SafeCounterManager c_counterMgr;
private:
| Thread |
|---|
| • bk commit into 5.1 tree (jonas:1.2676) | jonas | 8 Nov |