List:Commits« Previous MessageNext Message »
From:jonas Date:November 8 2007 7:44pm
Subject:bk commit into 5.1 tree (jonas:1.2676)
View as plain text  
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)jonas8 Nov