فهرست منبع

add ability to store notifies in Synchronizer before wate was calles

Kolja Strohm 1 ماه پیش
والد
کامیت
b91084b3b3
2فایلهای تغییر یافته به همراه51 افزوده شده و 10 حذف شده
  1. 47 7
      Critical.cpp
  2. 4 3
      Critical.h

+ 47 - 7
Critical.cpp

@@ -59,7 +59,8 @@ bool Critical::isLocked() const
 }
 
 Synchronizer::Synchronizer()
-    : numWaiting(0),
+    : storedNotifications(0),
+      numWaiting(0),
       skip(0)
 {}
 
@@ -83,6 +84,11 @@ bool Synchronizer::wait()
 {
     std::unique_lock<std::mutex> lk(mutex);
     if (skip) return false;
+    if (storedNotifications > 0)
+    {
+        storedNotifications--;
+        return !skip;
+    }
     numWaiting++;
     block.wait(lk);
     numWaiting--;
@@ -93,6 +99,11 @@ bool Synchronizer::wait(int milisec)
 {
     std::unique_lock<std::mutex> lk(mutex);
     if (skip) return false;
+    if (storedNotifications > 0)
+    {
+        storedNotifications--;
+        return !skip;
+    }
     numWaiting++;
     std::cv_status status
         = block.wait_for(lk, std::chrono::milliseconds(milisec));
@@ -100,19 +111,48 @@ bool Synchronizer::wait(int milisec)
     return !skip && status == std::cv_status::no_timeout;
 }
 
-void Synchronizer::notify()
+void Synchronizer::notify(bool storedNotifications)
 {
+    std::unique_lock<std::mutex> lk(mutex);
+    if (numWaiting == 0)
+    {
+        if (storedNotifications)
+        {
+            this->storedNotifications++;
+        }
+        return;
+    }
     block.notify_one();
 }
 
-void Synchronizer::notify(int amount)
+void Synchronizer::notify(int amount, bool storedNotifications)
 {
+    std::unique_lock<std::mutex> lk(mutex);
+    if (numWaiting < amount)
+    {
+        if (storedNotifications)
+        {
+            this->storedNotifications += numWaiting - amount;
+        }
+        amount = numWaiting;
+    }
     while (amount--)
+    {
         block.notify_one();
+    }
 }
 
-void Synchronizer::notifyAll()
+void Synchronizer::notifyAll(bool storedNotifications)
 {
+    std::unique_lock<std::mutex> lk(mutex);
+    if (numWaiting == 0)
+    {
+        if (storedNotifications)
+        {
+            this->storedNotifications++;
+        }
+        return;
+    }
     block.notify_all();
 }
 
@@ -335,7 +375,7 @@ void Framework::ReadWriteLock::unlockRead()
     }
     if (readerThreadCount == 0 && waitingWriters > 0)
     {
-        writerBlock.notify();
+        writerBlock.notify(true);
     }
     currentThreadLockCount--;
     cs.unlock();
@@ -354,11 +394,11 @@ void Framework::ReadWriteLock::unlockWrite()
     {
         if (waitingWriters > 0)
         {
-            writerBlock.notify();
+            writerBlock.notify(true);
         }
         else if (waitingReaders > 0)
         {
-            readerBlock.notify(waitingReaders);
+            readerBlock.notify(waitingReaders, true);
         }
     }
     currentThreadLockCount--;

+ 4 - 3
Critical.h

@@ -58,6 +58,7 @@ namespace Framework
     private:
         std::condition_variable block;
         std::mutex mutex;
+        int storedNotifications;
         int numWaiting;
         bool skip;
 
@@ -67,9 +68,9 @@ namespace Framework
 
         DLLEXPORT bool wait();
         DLLEXPORT bool wait(int milisec);
-        DLLEXPORT void notify();
-        DLLEXPORT void notify(int amount);
-        DLLEXPORT void notifyAll();
+        DLLEXPORT void notify(bool store = 0);
+        DLLEXPORT void notify(int amount, bool store = 0);
+        DLLEXPORT void notifyAll(bool store = 0);
 
         DLLEXPORT int getNumberOfWaitingThreads() const;
     };