Browse Source

Removed SpinLock class.

Lasse Öörni 14 years ago
parent
commit
80656971de

+ 4 - 12
Engine/Audio/Audio.cpp

@@ -216,15 +216,11 @@ public:
                 {
                     // Mix sound to locked positions
                     {
-                        SpinLock& lock = owner_->GetLock();
-                        lock.Acquire();
-                        
+                        MutexLock lock(owner_->GetMutex());
                         if (bytes1)
                             owner_->MixOutput(ptr1, bytes1 / sampleSize_);
                         if (bytes2)
                             owner_->MixOutput(ptr2, bytes2 / sampleSize_);
-                        
-                        lock.Release();
                     }
                     
                     // Unlock buffer and update write cursor
@@ -456,9 +452,8 @@ float Audio::GetMasterGain(SoundType type) const
 
 void Audio::AddSoundSource(SoundSource* channel)
 {
-    audioLock_.Acquire();
+    MutexLock lock(audioMutex_);
     soundSources_.Push(channel);
-    audioLock_.Release();
 }
 
 void Audio::RemoveSoundSource(SoundSource* channel)
@@ -466,9 +461,8 @@ void Audio::RemoveSoundSource(SoundSource* channel)
     PODVector<SoundSource*>::Iterator i = soundSources_.Find(channel);
     if (i != soundSources_.End())
     {
-        audioLock_.Acquire();
+        MutexLock lock(audioMutex_);
         soundSources_.Erase(i);
-        audioLock_.Release();
     }
 }
 
@@ -479,10 +473,8 @@ int AudioCallback(const void *inputBuffer, void *outputBuffer, unsigned long fra
     Audio* audio = static_cast<Audio*>(userData);
     
     {
-        SpinLock& lock = audio->GetLock();
-        lock.Acquire();
+        MutexLock lock(audio->GetMutex());
         audio->MixOutput(outputBuffer, framesPerBuffer);
-        lock.Release();
     }
     
     return 0;

+ 5 - 5
Engine/Audio/Audio.h

@@ -25,9 +25,9 @@
 
 #include "ArrayPtr.h"
 #include "AudioDefs.h"
+#include "Mutex.h"
 #include "Object.h"
 #include "Quaternion.h"
-#include "SpinLock.h"
 #include "Thread.h"
 
 class AudioImpl;
@@ -89,8 +89,8 @@ public:
     void AddSoundSource(SoundSource* soundSource);
     /// Remove a sound source. Called by SoundSource.
     void RemoveSoundSource(SoundSource* soundSource);
-    /// Return audio thread spinlock. Note: it is not re-entrant.
-    SpinLock& GetLock() { return audioLock_; }
+    /// Return audio thread mutex
+    Mutex& GetMutex() { return audioMutex_; }
     /// Return sound type specific gain multiplied by master gain.
     float GetSoundSourceMasterGain(SoundType type) const { return masterGain_[SOUND_MASTER] * masterGain_[type]; }
     
@@ -107,8 +107,8 @@ private:
     void* stream_;
     /// Clipping buffer for mixing.
     SharedArrayPtr<int> clipBuffer_;
-    /// Audio thread spinlock.
-    SpinLock audioLock_;
+    /// Audio thread mutex.
+    Mutex audioMutex_;
     /// Sample size.
     unsigned sampleSize_;
     /// Clip buffer size in samples.

+ 3 - 9
Engine/Audio/SoundSource.cpp

@@ -156,10 +156,8 @@ void SoundSource::Play(Sound* sound)
     // If sound source is currently playing, have to lock the audio mutex
     if (position_)
     {
-        SpinLock& lock = audio_->GetLock();
-        lock.Acquire();
+        MutexLock lock(audio_->GetMutex());
         PlayLockless(sound);
-        lock.Release();
     }
     else
         PlayLockless(sound);
@@ -194,10 +192,8 @@ void SoundSource::Stop()
     // If sound source is currently playing, have to lock the audio mutex
     if (position_)
     {
-        SpinLock& lock = audio_->GetLock();
-        lock.Acquire();
+        MutexLock lock(audio_->GetMutex());
         StopLockless();
-        lock.Release();
     }
     
     // Free the compressed sound decoder now if any
@@ -248,10 +244,8 @@ void SoundSource::SetPlayPosition(signed char* pos)
     if (!audio_ || !sound_)
         return;
     
-    SpinLock& lock = audio_->GetLock();
-    lock.Acquire();
+    MutexLock lock(audio_->GetMutex());
     SetPlayPositionLockless(pos);
-    lock.Release();
 }
 
 void SoundSource::PlayLockless(Sound* sound)

+ 0 - 77
Engine/Core/SpinLock.h

@@ -1,77 +0,0 @@
-//
-// Urho3D Engine
-// Copyright (c) 2008-2011 Lasse Öörni
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#pragma once
-
-/// Non-reentrant userspace mutual exclusion primitive.
-class SpinLock
-{
-public:
-    /// Construct.
-    SpinLock() :
-        locked_(0)
-    {
-    }
-    
-    /// Acquire the lock. Spin in a loop while waiting.
-    void Acquire()
-    {
-        for (;;)
-        {
-            if (TestAndSet(&locked_, 1) == 0)
-                break;
-        }
-    }
-    
-    /// Try to acquire the lock without waiting. Return true if successfully acquired.
-    bool TryAcquire()
-    {
-        return TestAndSet(&locked_, 1) == 0;
-    }
-    
-    /// Release the lock.
-    void Release()
-    {
-        locked_ = 0;
-    }
-    
-private:
-    /// Test-and-set a value atomically and return the previous value.
-    static unsigned TestAndSet(unsigned* dest, unsigned newValue)
-    {
-        #ifdef _MSC_VER
-        __asm
-        {
-            mov edx, dest
-            mov eax, newValue
-            lock xchg eax, dword ptr [edx]
-        }
-        #else
-        return __sync_lock_test_and_set(dest, newValue);
-        #endif
-    }
-    
-    /// Locked flag.
-    unsigned locked_;
-};
-

+ 12 - 11
Engine/Core/WorkQueue.cpp

@@ -100,7 +100,8 @@ WorkQueue::WorkQueue(Context* context) :
     shutDown_(false),
     numWaiting_(0)
 {
-    // Create worker threads and start them. Leave one core free for the main thread, and another for GPU & audio.
+    // Create worker threads and start them. For now use a maximum of 4 worker threads, and leave cores free for the main thread
+    // and the GPU driver + audio processing
     int numCores = GetNumCPUCores();
     if (numCores == 1)
         return;
@@ -135,10 +136,10 @@ void WorkQueue::AddWorkItem(const WorkItem& item)
 {
     if (threads_.Size())
     {
-        queueLock_.Acquire();
+        queueMutex_.Acquire();
         queue_.Push(item);
         bool isWaiting = numWaiting_ > 0;
-        queueLock_.Release();
+        queueMutex_.Release();
         if (isWaiting)
             impl_->Signal();
     }
@@ -153,17 +154,17 @@ void WorkQueue::Complete()
         // Wait for work to finish while also taking work items in the main thread
         for (;;)
         {
-            queueLock_.Acquire();
+            queueMutex_.Acquire();
             if (!queue_.Empty())
             {
                 WorkItem item = queue_.Front();
                 queue_.PopFront();
-                queueLock_.Release();
+                queueMutex_.Release();
                 item.workFunction_(&item, 0);
             }
             else
             {
-                queueLock_.Release();
+                queueMutex_.Release();
                 if (numWaiting_ == threads_.Size())
                     break;
             }
@@ -175,9 +176,9 @@ bool WorkQueue::IsCompleted()
 {
     if (threads_.Size())
     {
-        queueLock_.Acquire();
+        queueMutex_.Acquire();
         bool completed = queue_.Empty() && numWaiting_ == threads_.Size();
-        queueLock_.Release();
+        queueMutex_.Release();
         return completed;
     }
     else
@@ -193,7 +194,7 @@ void WorkQueue::ProcessItems(unsigned threadIndex)
         if (shutDown_)
             return;
         
-        queueLock_.Acquire();
+        queueMutex_.Acquire();
         if (wasWaiting)
         {
             --numWaiting_;
@@ -203,13 +204,13 @@ void WorkQueue::ProcessItems(unsigned threadIndex)
         {
             WorkItem item = queue_.Front();
             queue_.PopFront();
-            queueLock_.Release();
+            queueMutex_.Release();
             item.workFunction_(&item, threadIndex);
         }
         else
         {
             ++numWaiting_;
-            queueLock_.Release();
+            queueMutex_.Release();
             impl_->Wait();
             wasWaiting = true;
         }

+ 3 - 3
Engine/Core/WorkQueue.h

@@ -24,8 +24,8 @@
 #pragma once
 
 #include "List.h"
+#include "Mutex.h"
 #include "Object.h"
-#include "SpinLock.h"
 
 class WorkerThread;
 class WorkQueueImpl;
@@ -76,8 +76,8 @@ private:
     Vector<SharedPtr<WorkerThread> > threads_;
     /// Work item queue.
     List<WorkItem> queue_;
-    /// Queue lock.
-    SpinLock queueLock_;
+    /// Queue mutex.
+    Mutex queueMutex_;
     /// Number of waiting threads.
     volatile unsigned numWaiting_;
     /// Shutting down flag.

+ 1 - 2
Engine/Graphics/Octree.cpp

@@ -407,9 +407,8 @@ void Octree::QueueReinsertion(Drawable* drawable)
 {
     if (scene_ && scene_->IsThreadedUpdate())
     {
-        reinsertionLock_.Acquire();
+        MutexLock lock(octreeMutex_);
         drawableReinsertions_.Push(drawable);
-        reinsertionLock_.Release();
     }
     else
         drawableReinsertions_.Push(drawable);

+ 3 - 3
Engine/Graphics/Octree.h

@@ -25,7 +25,7 @@
 
 #include "Drawable.h"
 #include "List.h"
-#include "SpinLock.h"
+#include "Mutex.h"
 
 class Octree;
 class OctreeQuery;
@@ -207,8 +207,8 @@ private:
     PODVector<Drawable*> drawableUpdates_;
     /// Drawable objects that require reinsertion.
     PODVector<Drawable*> drawableReinsertions_;
-    /// Lock for octree reinsertions.
-    SpinLock reinsertionLock_;
+    /// Mutex for octree reinsertions.
+    Mutex octreeMutex_;
     /// Unculled drawables.
     Vector<WeakPtr<Drawable> > unculledDrawables_;
     /// Subdivision level.

+ 1 - 2
Engine/Scene/Scene.cpp

@@ -421,9 +421,8 @@ void Scene::EndThreadedUpdate()
 
 void Scene::DelayedMarkedDirty(Component* component)
 {
-    delayedDirtyLock_.Acquire();
+    MutexLock lock(sceneMutex_);
     delayedDirtyComponents_.Push(component);
-    delayedDirtyLock_.Release();
 }
 
 unsigned Scene::GetFreeNodeID(CreateMode mode)

+ 3 - 3
Engine/Scene/Scene.h

@@ -23,8 +23,8 @@
 
 #pragma once
 
+#include "Mutex.h"
 #include "Node.h"
-#include "SpinLock.h"
 #include "XMLElement.h"
 
 class File;
@@ -182,8 +182,8 @@ private:
     Map<ShortStringHash, String> varNames_;
     /// Delayed dirty notification queue for components.
     PODVector<Component*> delayedDirtyComponents_;
-    /// Lock for the delayed dirty notification queue.
-    SpinLock delayedDirtyLock_;
+    /// Mutex for the delayed dirty notification queue.
+    Mutex sceneMutex_;
     /// Next free non-local node ID.
     unsigned replicatedNodeID_;
     /// Next free local node ID.