changeset 4064:7176ebf08765

Semaphore: allow acquiring/releasing multiple resources
author Alain Mazy
date Thu, 11 Jun 2020 16:42:27 +0200
parents 6c6239aec462
children 408ac60c3cf8 e8d30585b909
files Core/MultiThreading/Semaphore.cpp Core/MultiThreading/Semaphore.h
diffstat 2 files changed, 29 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/Core/MultiThreading/Semaphore.cpp	Wed Jun 10 18:49:21 2020 +0200
+++ b/Core/MultiThreading/Semaphore.cpp	Thu Jun 11 16:42:27 2020 +0200
@@ -20,7 +20,7 @@
  * you do not wish to do so, delete this exception statement from your
  * version. If you delete this exception statement from all source files
  * in the program, then also delete it here.
- * 
+ *
  * 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
@@ -48,36 +48,36 @@
     }
   }
 
-  void Semaphore::Release()
+  void Semaphore::Release(unsigned int resourceCount)
   {
     boost::mutex::scoped_lock lock(mutex_);
 
-    availableResources_++;
-    condition_.notify_one(); 
+    availableResources_ += resourceCount;
+    condition_.notify_one();
   }
 
-  void Semaphore::Acquire()
+  void Semaphore::Acquire(unsigned int resourceCount)
   {
     boost::mutex::scoped_lock lock(mutex_);
 
-    while (availableResources_ == 0)
+    while (availableResources_ < resourceCount)
     {
       condition_.wait(lock);
     }
 
-    availableResources_--;
+    availableResources_ -= resourceCount;
   }
 
-  bool Semaphore::TryAcquire()
+  bool Semaphore::TryAcquire(unsigned int resourceCount)
   {
     boost::mutex::scoped_lock lock(mutex_);
 
-    if (availableResources_ == 0)
+    if (availableResources_ < resourceCount)
     {
       return false;
     }
 
-    availableResources_--;
+    availableResources_ -= resourceCount;
     return true;
   }
 }
--- a/Core/MultiThreading/Semaphore.h	Wed Jun 10 18:49:21 2020 +0200
+++ b/Core/MultiThreading/Semaphore.h	Thu Jun 11 16:42:27 2020 +0200
@@ -20,7 +20,7 @@
  * you do not wish to do so, delete this exception statement from your
  * version. If you delete this exception statement from all source files
  * in the program, then also delete it here.
- * 
+ *
  * 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
@@ -44,12 +44,12 @@
     unsigned int availableResources_;
     boost::mutex mutex_;
     boost::condition_variable condition_;
-    
-    void Release();
+
+    void Release(unsigned int resourceCount = 1);
 
-    void Acquire();
+    void Acquire(unsigned int resourceCount = 1);
 
-    bool TryAcquire();
+    bool TryAcquire(unsigned int resourceCount = 1);
   public:
     explicit Semaphore(unsigned int availableResources);
 
@@ -63,38 +63,42 @@
     {
     private:
       Semaphore&  that_;
+      unsigned int resourceCount_;
 
     public:
-      explicit Locker(Semaphore& that) :
-        that_(that)
+      explicit Locker(Semaphore& that, unsigned int resourceCount = 1) :
+        that_(that),
+        resourceCount_(resourceCount)
       {
-        that_.Acquire();
+        that_.Acquire(resourceCount_);
       }
 
       ~Locker()
       {
-        that_.Release();
+        that_.Release(resourceCount_);
       }
     };
 
     class TryLocker : public boost::noncopyable
     {
     private:
-      Semaphore&  that_;
-      bool        isAcquired_;
+      Semaphore&    that_;
+      unsigned int  resourceCount_;
+      bool          isAcquired_;
 
     public:
-      explicit TryLocker(Semaphore& that) :
-        that_(that)
+      explicit TryLocker(Semaphore& that, unsigned int resourceCount = 1) :
+        that_(that),
+        resourceCount_(resourceCount)
       {
-        isAcquired_ = that_.TryAcquire();
+        isAcquired_ = that_.TryAcquire(resourceCount_);
       }
 
       ~TryLocker()
       {
         if (isAcquired_)
         {
-          that_.Release();
+          that_.Release(resourceCount_);
         }
       }