mudgangster

Tiny, scriptable MUD client
Log | Files | Refs | README

tracy_benaphore.h (1902B)


      1 // Copyright (c) 2015 Jeff Preshing
      2 //
      3 // This software is provided 'as-is', without any express or implied
      4 // warranty. In no event will the authors be held liable for any damages
      5 // arising from the use of this software.
      6 //
      7 // Permission is granted to anyone to use this software for any purpose,
      8 // including commercial applications, and to alter it and redistribute it
      9 // freely, subject to the following restrictions:
     10 //
     11 // 1. The origin of this software must not be misrepresented; you must not
     12 // claim that you wrote the original software. If you use this software
     13 // in a product, an acknowledgement in the product documentation would be
     14 // appreciated but is not required.
     15 // 2. Altered source versions must be plainly marked as such, and must not be
     16 // misrepresented as being the original software.
     17 // 3. This notice may not be removed or altered from any source distribution.
     18 
     19 #ifndef __TRACY_CPP11OM_BENAPHORE_H__
     20 #define __TRACY_CPP11OM_BENAPHORE_H__
     21 
     22 #include <cassert>
     23 #include <thread>
     24 #include <atomic>
     25 #include "tracy_sema.h"
     26 
     27 namespace tracy
     28 {
     29 
     30 class NonRecursiveBenaphore
     31 {
     32 private:
     33     std::atomic<int> m_contentionCount;
     34     DefaultSemaphoreType m_sema;
     35 
     36 public:
     37     NonRecursiveBenaphore() : m_contentionCount(0) {}
     38 
     39     void lock()
     40     {
     41         if (m_contentionCount.fetch_add(1, std::memory_order_acquire) > 0)
     42         {
     43             m_sema.wait();
     44         }
     45     }
     46 
     47     bool try_lock()
     48     {
     49         if (m_contentionCount.load(std::memory_order_relaxed) != 0)
     50             return false;
     51         int expected = 0;
     52         return m_contentionCount.compare_exchange_strong(expected, 1, std::memory_order_acquire);
     53     }
     54 
     55     void unlock()
     56     {
     57         int oldCount = m_contentionCount.fetch_sub(1, std::memory_order_release);
     58         assert(oldCount > 0);
     59         if (oldCount > 1)
     60         {
     61             m_sema.signal();
     62         }
     63     }
     64 };
     65 
     66 }
     67 
     68 #endif // __CPP11OM_BENAPHORE_H__