diff --git a/engine/shared/library/CMakeLists.txt b/engine/shared/library/CMakeLists.txt index eb93db24..01f77532 100644 --- a/engine/shared/library/CMakeLists.txt +++ b/engine/shared/library/CMakeLists.txt @@ -5,3 +5,4 @@ add_subdirectory(sharedFoundation) add_subdirectory(sharedFoundationTypes) add_subdirectory(sharedMemoryManager) add_subdirectory(sharedNetworkMessages) +add_subdirectory(sharedSynchronization) diff --git a/engine/shared/library/sharedSynchronization/CMakeLists.txt b/engine/shared/library/sharedSynchronization/CMakeLists.txt new file mode 100644 index 00000000..8f499d92 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 2.8) + +project(sharedSynchronization) + +if(WIN32) + add_definitions(/D_CRT_SECURE_NO_WARNINGS) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/public) + +add_subdirectory(src) diff --git a/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/BlockingPointer.h b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/BlockingPointer.h new file mode 100644 index 00000000..87c25383 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/BlockingPointer.h @@ -0,0 +1 @@ +#include "../../src/shared/BlockingPointer.h" diff --git a/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/BlockingQueue.h b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/BlockingQueue.h new file mode 100644 index 00000000..1816ab77 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/BlockingQueue.h @@ -0,0 +1 @@ +#include "../../src/shared/BlockingQueue.h" diff --git a/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/ConditionVariable.h b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/ConditionVariable.h new file mode 100644 index 00000000..9ac848da --- /dev/null +++ b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/ConditionVariable.h @@ -0,0 +1,7 @@ +#if defined(PLATFORM_WIN32) +#include "../../src/win32/ConditionVariable.h" +#elif defined(PLATFORM_LINUX) +#include "../../src/linux/ConditionVariable.h" +#else +#error unsupported platform +#endif diff --git a/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/CountingSemaphore.h b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/CountingSemaphore.h new file mode 100644 index 00000000..cc28f7eb --- /dev/null +++ b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/CountingSemaphore.h @@ -0,0 +1 @@ +#include "../../src/shared/CountingSemaphore.h" diff --git a/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/FirstSharedSynchronization.h b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/FirstSharedSynchronization.h new file mode 100644 index 00000000..a95540bc --- /dev/null +++ b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/FirstSharedSynchronization.h @@ -0,0 +1 @@ +#include "../../src/shared/FirstSharedSynchronization.h" diff --git a/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/Gate.h b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/Gate.h new file mode 100644 index 00000000..b71b5814 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/Gate.h @@ -0,0 +1,7 @@ +#if defined(PLATFORM_WIN32) +#include "../../src/win32/Gate.h" +#elif defined(PLATFORM_LINUX) +#include "../../src/linux/Gate.h" +#else +#error unsupported platform +#endif diff --git a/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/Guard.h b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/Guard.h new file mode 100644 index 00000000..a6209017 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/Guard.h @@ -0,0 +1,2 @@ +#include "../../src/shared/Guard.h" + diff --git a/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/InterlockedInteger.h b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/InterlockedInteger.h new file mode 100644 index 00000000..2e1b4736 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/InterlockedInteger.h @@ -0,0 +1,7 @@ +#if defined(PLATFORM_WIN32) +#include "../../src/win32/InterlockedInteger.h" +#elif defined(PLATFORM_LINUX) +#include "../../src/linux/InterlockedInteger.h" +#else +#error unsupported platform +#endif diff --git a/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/InterlockedVoidPointer.h b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/InterlockedVoidPointer.h new file mode 100644 index 00000000..55558105 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/InterlockedVoidPointer.h @@ -0,0 +1,7 @@ +#if defined(PLATFORM_WIN32) +#include "../../src/win32/InterlockedVoidPointer.h" +#elif defined(PLATFORM_LINUX) +#include "../../src/linux/InterlockedVoidPointer.h" +#else +#error unsupported platform +#endif diff --git a/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/Mutex.h b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/Mutex.h new file mode 100644 index 00000000..7f96a4ba --- /dev/null +++ b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/Mutex.h @@ -0,0 +1,7 @@ +#if defined(PLATFORM_WIN32) +#include "../../src/win32/Mutex.h" +#elif defined(PLATFORM_LINUX) +#include "../../src/linux/Mutex.h" +#else +#error unsupported platform +#endif diff --git a/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/RecursiveMutex.h b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/RecursiveMutex.h new file mode 100644 index 00000000..2a3cb5a0 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/RecursiveMutex.h @@ -0,0 +1,7 @@ +#if defined(PLATFORM_WIN32) +#include "../../src/win32/RecursiveMutex.h" +#elif defined(PLATFORM_LINUX) +#include "../../src/linux/RecursiveMutex.h" +#else +#error unsupported platform +#endif diff --git a/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/Semaphore.h b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/Semaphore.h new file mode 100644 index 00000000..9cdf6bb4 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/Semaphore.h @@ -0,0 +1,7 @@ +#if defined(PLATFORM_WIN32) +#include "../../src/win32/Semaphore.h" +#elif defined(PLATFORM_LINUX) +#include "../../src/linux/Semaphore.h" +#else +#error unsupported platform +#endif diff --git a/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/WriteOnce.h b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/WriteOnce.h new file mode 100644 index 00000000..bcea7ab8 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/include/public/sharedSynchronization/WriteOnce.h @@ -0,0 +1 @@ +#include "../../src/shared/WriteOnce.h" diff --git a/engine/shared/library/sharedSynchronization/src/CMakeLists.txt b/engine/shared/library/sharedSynchronization/src/CMakeLists.txt new file mode 100644 index 00000000..82434175 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/CMakeLists.txt @@ -0,0 +1,58 @@ + +set(SHARED_SOURCES + shared/BlockingPointer.h + shared/BlockingQueue.h + shared/CountingSemaphore.h + shared/Guard.h + shared/WriteOnce.h +) + +if(WIN32) + set(PLATFORM_SOURCES + win32/ConditionVariable.cpp + win32/ConditionVariable.h + win32/FirstSharedSynchronization.cpp + win32/Gate.cpp + win32/Gate.h + win32/InterlockedInteger.h + win32/InterlockedVoidPointer.h + win32/Mutex.cpp + win32/Mutex.h + win32/RecursiveMutex.cpp + win32/RecursiveMutex.h + win32/Semaphore.cpp + win32/Semaphore.h + ) + + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/win32) +else() + set(PLATFORM_SOURCES + linux/ConditionVariable.cpp + linux/ConditionVariable.h + linux/Gate.cpp + linux/Gate.h + linux/InterlockedInteger.h + linux/InterlockedVoidPointer.h + linux/Mutex.cpp + linux/Mutex.h + linux/RecursiveMutex.cpp + linux/RecursiveMutex.h + linux/Semaphore.cpp + linux/Semaphore.h + ) + + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/linux) +endif() + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/shared + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public +) + +add_library(sharedSynchronization STATIC + ${SHARED_SOURCES} + ${PLATFORM_SOURCES} +) diff --git a/engine/shared/library/sharedSynchronization/src/linux/ConditionVariable.cpp b/engine/shared/library/sharedSynchronization/src/linux/ConditionVariable.cpp new file mode 100644 index 00000000..7a01259d --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/linux/ConditionVariable.cpp @@ -0,0 +1,38 @@ +// ====================================================================== +// +// ConditionVariable.cpp +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedFoundation/FirstSharedFoundation.h" +#include "sharedSynchronization/ConditionVariable.h" + +ConditionVariable::ConditionVariable(Mutex &m) + : _mutex(m) +{ + pthread_cond_init(&cond, 0); +} + +ConditionVariable::~ConditionVariable() +{ + pthread_cond_destroy(&cond); +} + +void ConditionVariable::wait() +{ + pthread_cond_wait(&cond, &_mutex.getInternalMutex()); +} + +void ConditionVariable::signal() +{ + pthread_cond_signal(&cond); +} + +void ConditionVariable::broadcast() +{ + pthread_cond_broadcast(&cond); +} + diff --git a/engine/shared/library/sharedSynchronization/src/linux/ConditionVariable.h b/engine/shared/library/sharedSynchronization/src/linux/ConditionVariable.h new file mode 100644 index 00000000..5ce3bf17 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/linux/ConditionVariable.h @@ -0,0 +1,34 @@ +// ====================================================================== +// +// ConditionVariable.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_ConditionVariable_h +#define INCLUDED_ConditionVariable_h + +#include "sharedSynchronization/Mutex.h" + +class ConditionVariable +{ +public: + ConditionVariable(Mutex &m); + ~ConditionVariable(); + void wait(); + // You must own the mutex before calling signal. + void signal(); + void broadcast(); + Mutex &mutex() { return _mutex; } +private: + ConditionVariable(const ConditionVariable &o); + ConditionVariable &operator =(const ConditionVariable &o); + + Mutex &_mutex; + pthread_cond_t cond; +}; + + +#endif diff --git a/engine/shared/library/sharedSynchronization/src/linux/Gate.cpp b/engine/shared/library/sharedSynchronization/src/linux/Gate.cpp new file mode 100644 index 00000000..677df742 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/linux/Gate.cpp @@ -0,0 +1,45 @@ +// ====================================================================== +// +// Gate.cpp +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedFoundation/FirstSharedFoundation.h" +#include "sharedSynchronization/Gate.h" + +Gate::Gate(bool open) +: cond(lock) +{ + opened = open; +} + +Gate::~Gate() +{ +} + +void Gate::wait() +{ + lock.enter(); + while (!opened) + cond.wait(); + lock.leave(); +} + +void Gate::close() +{ + lock.enter(); + opened = false; + lock.leave(); +} + +void Gate::open() +{ + lock.enter(); + opened = true; + cond.broadcast(); + lock.leave(); +} + diff --git a/engine/shared/library/sharedSynchronization/src/linux/Gate.h b/engine/shared/library/sharedSynchronization/src/linux/Gate.h new file mode 100644 index 00000000..9f1266e1 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/linux/Gate.h @@ -0,0 +1,35 @@ +// ====================================================================== +// +// Gate.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_Gate_h +#define INCLUDED_Gate_h + +#include "sharedSynchronization/ConditionVariable.h" + +class Gate +{ +public: + Gate(bool open); + ~Gate(); + + void wait(); + + void close(); + void open(); +private: + Gate(const Gate &o); + Gate &operator =(const Gate &o); + + Mutex lock; + bool opened; + ConditionVariable cond; +}; + + +#endif diff --git a/engine/shared/library/sharedSynchronization/src/linux/InterlockedInteger.h b/engine/shared/library/sharedSynchronization/src/linux/InterlockedInteger.h new file mode 100644 index 00000000..85633395 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/linux/InterlockedInteger.h @@ -0,0 +1,63 @@ +// ====================================================================== +// +// InterlockedInteger.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_InterlockedInteger_h +#define INCLUDED_InterlockedInteger_h + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +class InterlockedInteger +{ +public: + explicit InterlockedInteger(int initialValue=0); + int operator =(int); // returns prior value (exchange) + int operator ++(); // returns new value + int operator --(); // returns new value + operator int() const { return value; } +private: + InterlockedInteger(const InterlockedInteger &o); + InterlockedInteger &operator =(const InterlockedInteger &o); + pthread_mutex_t lock; + volatile int value; +}; + +inline InterlockedInteger::InterlockedInteger(int i_value) +: value(i_value) +{ + pthread_mutex_init(&lock, 0); +} + +inline int InterlockedInteger::operator =(int i_value) +{ + pthread_mutex_lock(&lock); + int oldvalue = value; + value = i_value; + pthread_mutex_unlock(&lock); + return oldvalue; +} + +inline int InterlockedInteger::operator ++() +{ + pthread_mutex_lock(&lock); + int newvalue = value+1; + value = newvalue; + pthread_mutex_unlock(&lock); + return newvalue; +} + +inline int InterlockedInteger::operator --() +{ + pthread_mutex_lock(&lock); + int newvalue = value-1; + value = newvalue; + pthread_mutex_unlock(&lock); + return newvalue; +} + +#endif diff --git a/engine/shared/library/sharedSynchronization/src/linux/InterlockedVoidPointer.h b/engine/shared/library/sharedSynchronization/src/linux/InterlockedVoidPointer.h new file mode 100644 index 00000000..04da79ae --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/linux/InterlockedVoidPointer.h @@ -0,0 +1,53 @@ +// ====================================================================== +// +// InterlockedVoidPointer.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_InterlockedVoidPointer_h +#define INCLUDED_InterlockedVoidPointer_h + +#include "sharedSynchronization/Mutex.h" + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +class InterlockedVoidPointer +{ +public: + explicit InterlockedVoidPointer(void * initialValue=0); + void * compareExchange(void * compare, void * exchange); // compare and exchange if same + operator void * () const { return reinterpret_cast(value); } +private: + InterlockedVoidPointer(const InterlockedVoidPointer &o); + InterlockedVoidPointer &operator =(const InterlockedVoidPointer &o); + Mutex lock; + void * volatile value; +}; + +template +class InterlockedPointer: public InterlockedVoidPointer +{ +public: + explicit InterlockedPointer(T * initialValue): InterlockedVoidPointer(initialValue) {} + operator T * () const { return static_cast(value); } +}; + +inline InterlockedVoidPointer::InterlockedVoidPointer(void * initialValue) +: value(initialValue) +{ +} + +inline void * InterlockedVoidPointer::compareExchange(void * compare, void * exchange) +{ + lock.enter(); + void * temp = value; + if (temp == compare) + value = exchange; + lock.leave(); + return temp; +} + +#endif \ No newline at end of file diff --git a/engine/shared/library/sharedSynchronization/src/linux/Mutex.cpp b/engine/shared/library/sharedSynchronization/src/linux/Mutex.cpp new file mode 100644 index 00000000..d5114433 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/linux/Mutex.cpp @@ -0,0 +1,32 @@ +// ====================================================================== +// +// Mutex.cpp +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedFoundation/FirstSharedFoundation.h" +#include "sharedSynchronization/Mutex.h" + +Mutex::Mutex() +{ + pthread_mutex_init(&mutex, 0); +} + +Mutex::~Mutex() +{ + pthread_mutex_destroy(&mutex); +} + +void Mutex::enter() +{ + pthread_mutex_lock(&mutex); +} + +void Mutex::leave() +{ + pthread_mutex_unlock(&mutex); +} + diff --git a/engine/shared/library/sharedSynchronization/src/linux/Mutex.h b/engine/shared/library/sharedSynchronization/src/linux/Mutex.h new file mode 100644 index 00000000..be679dab --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/linux/Mutex.h @@ -0,0 +1,31 @@ +// ====================================================================== +// +// Mutex.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_Mutex_h +#define INCLUDED_Mutex_h + +class Mutex +{ +public: + Mutex(); + ~Mutex(); + + void enter(); + void leave(); + + pthread_mutex_t &getInternalMutex() { return mutex; } +private: + Mutex(const Mutex &o); + Mutex &operator =(const Mutex &o); + + pthread_mutex_t mutex; +}; + + +#endif diff --git a/engine/shared/library/sharedSynchronization/src/linux/RecursiveMutex.cpp b/engine/shared/library/sharedSynchronization/src/linux/RecursiveMutex.cpp new file mode 100644 index 00000000..a902b404 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/linux/RecursiveMutex.cpp @@ -0,0 +1,37 @@ +// ====================================================================== +// +// RecursiveMutex.cpp +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedFoundation/FirstSharedFoundation.h" +#include "sharedSynchronization/RecursiveMutex.h" + +RecursiveMutex::RecursiveMutex() +{ + pthread_mutexattr_t attributes; + + pthread_mutexattr_init(&attributes); + pthread_mutexattr_settype(&attributes,PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mutex,&attributes); + pthread_mutexattr_destroy(&attributes); +} + +RecursiveMutex::~RecursiveMutex() +{ + pthread_mutex_destroy(&mutex); +} + +void RecursiveMutex::enter() +{ + pthread_mutex_lock(&mutex); +} + +void RecursiveMutex::leave() +{ + pthread_mutex_unlock(&mutex); +} + diff --git a/engine/shared/library/sharedSynchronization/src/linux/RecursiveMutex.h b/engine/shared/library/sharedSynchronization/src/linux/RecursiveMutex.h new file mode 100644 index 00000000..49416010 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/linux/RecursiveMutex.h @@ -0,0 +1,31 @@ +// ====================================================================== +// +// RecursiveMutex.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_RecursiveMutex_h +#define INCLUDED_RecursiveMutex_h + +#include "sharedSynchronization/InterlockedInteger.h" + +class RecursiveMutex +{ +public: + RecursiveMutex(); + ~RecursiveMutex(); + + void enter(); + void leave(); +private: + RecursiveMutex(const RecursiveMutex &o); + RecursiveMutex &operator =(const RecursiveMutex &o); + + pthread_mutex_t mutex; +}; + +#endif + diff --git a/engine/shared/library/sharedSynchronization/src/linux/Semaphore.cpp b/engine/shared/library/sharedSynchronization/src/linux/Semaphore.cpp new file mode 100644 index 00000000..7950243d --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/linux/Semaphore.cpp @@ -0,0 +1,40 @@ +// ====================================================================== +// +// Semaphore.cpp +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedFoundation/FirstSharedFoundation.h" +#include "sharedSynchronization/Semaphore.h" + +Semaphore::Semaphore(int count, int initial) +{ + sem_init(&sem, false, initial); +} + +Semaphore::~Semaphore() +{ + sem_destroy(&sem); +} + +void Semaphore::wait() +{ + sem_wait(&sem); +} + +void Semaphore::wait(unsigned int maxDurationMs) +{ + timespec ts; + ts.tv_sec = maxDurationMs/1000000; + ts.tv_nsec = maxDurationMs%1000000; + sem_timedwait(&sem, &ts); +} + +void Semaphore::signal(int count) +{ + sem_post(&sem); +} + diff --git a/engine/shared/library/sharedSynchronization/src/linux/Semaphore.h b/engine/shared/library/sharedSynchronization/src/linux/Semaphore.h new file mode 100644 index 00000000..e108ae6f --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/linux/Semaphore.h @@ -0,0 +1,30 @@ +// ====================================================================== +// +// Semaphore.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_Semaphore_h +#define INCLUDED_Semaphore_h + +class Semaphore +{ +public: + Semaphore(int count=0x7FFFFFFF, int initial=0); + ~Semaphore(); + + void wait(); + void wait(unsigned int maxDurationMs); + void signal(int count=1); +private: + Semaphore(const Semaphore &o); + Semaphore &operator =(const Semaphore &o); + + sem_t sem; +}; + +#endif + diff --git a/engine/shared/library/sharedSynchronization/src/shared/BlockingPointer.h b/engine/shared/library/sharedSynchronization/src/shared/BlockingPointer.h new file mode 100644 index 00000000..b2826a3b --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/shared/BlockingPointer.h @@ -0,0 +1,78 @@ +// ====================================================================== +// +// BlockingPointer.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_BlockingPointer_h +#define INCLUDED_BlockingPointer_h + +#include "sharedSynchronization/Mutex.h" +#include "sharedSynchronization/Semaphore.h" + +template +class BlockingPointer +{ +public: + BlockingPointer(Mutex &m, T * begin, T * end); + T * operator ++(int); + T * operator --(); +private: + BlockingPointer(const BlockingPointer &o); + BlockingPointer &operator =(const BlockingPointer &o); + Mutex &_mutex; + T * volatile value; + T * begin, * end; + Semaphore high, low; +}; + +template +BlockingPointer::BlockingPointer(Mutex &m, T * i_begin, T * i_end) +: _mutex(m), value(i_begin), begin(i_begin), end(i_end) +{ +} + +template +T * BlockingPointer::operator ++(int) +{ + ++value; + if (value == begin) + { + low.release(); + } + else + { + if (value > end) + { + _mutex.leave(); + high.wait(); + _mutex.enter(); + } + } + return value-1; +} + +template +T * BlockingPointer::operator --() +{ + --value; + if (value == end - 1) + { + high.release(); + } + else + { + if (value < begin) + { + _mutex.leave(); + low.wait(); + _mutex.enter(); + } + } + return value; +} + +#endif \ No newline at end of file diff --git a/engine/shared/library/sharedSynchronization/src/shared/BlockingQueue.h b/engine/shared/library/sharedSynchronization/src/shared/BlockingQueue.h new file mode 100644 index 00000000..64bc407d --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/shared/BlockingQueue.h @@ -0,0 +1,87 @@ +// ====================================================================== +// +// BlockingQueue.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_BlockingQueue_h +#define INCLUDED_BlockingQueue_h + +template +class BlockingQueue +{ +public: + BlockingQueue(Mutex &m, T * begin, T * end); + T * operator ++(int); + T * operator --(); +private: + BlockingQueue(const BlockingQueue &o); + BlockingQueue &operator =(const BlockingQueue &o); + Mutex &_mutex; + T * volatile first, * volatile last; + T * begin, * end; + int size, maxsize; + Semaphore notFull, notEmpty; +}; + +template +BlockingQueue::BlockingQueue(Mutex &m, T * i_begin, T * i_end) +: _mutex(m), first(i_begin), last(i_begin), begin(i_begin), end(i_end), size(0), maxsize(i_end - i_begin) +{ +} + +template +T * BlockingQueue::operator ++(int) +{ + ++size; + if (size > maxsize) + { + _mutex.leave(); + notFull.wait(); + _mutex.enter(); + } + + T * oldlast = last; + ++last; + if (last == end) + { + last = begin; + } + + if (size == 1) + { + notEmpty.signal(); + } + + return oldlast; +} + +template +T * BlockingQueue::operator --() +{ + --size; + if (size == 0) + { + _mutex.leave(); + notEmpty.wait(); + _mutex.enter(); + } + + ++first; + if (first == end) + { + first = begin; + } + + if (size == maxsize - 1) + { + notFull.signal(); + } + + return first; +} + +#endif \ No newline at end of file diff --git a/engine/shared/library/sharedSynchronization/src/shared/CountingSemaphore.h b/engine/shared/library/sharedSynchronization/src/shared/CountingSemaphore.h new file mode 100644 index 00000000..c7dfa427 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/shared/CountingSemaphore.h @@ -0,0 +1,38 @@ +// ====================================================================== +// +// CountingSemaphore.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_CountingSemaphore_h +#define INCLUDED_CountingSemaphore_h + +#include "sharedSynchronization/Semaphore.h" +// this needs a little more thought + +class CountingSemaphore +{ +public: + CountingSemaphore(); + ~CountingSemaphore(); + + void wait() { ++waiters; sem.wait(); } + void signal(int i_count=1) + { + if (i_count > waiters) i_count = waiters; + sem.signal(i_count); + } + + int count() { return waiters; } +private: + CountingSemaphore(const CountingSemaphore &o); + CountingSemaphore &operator =(const CountingSemaphore &o); + Semaphore sem; + int waiters; +}; + + +#endif \ No newline at end of file diff --git a/engine/shared/library/sharedSynchronization/src/shared/FirstSharedSynchronization.h b/engine/shared/library/sharedSynchronization/src/shared/FirstSharedSynchronization.h new file mode 100644 index 00000000..52b63909 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/shared/FirstSharedSynchronization.h @@ -0,0 +1,19 @@ +// ====================================================================== +// +// FirstSynchronization.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_FirstSynchronization_H +#define INCLUDED_FirstSynchronization_H + +// ====================================================================== + +#include "sharedDebug/FirstSharedDebug.h" +#include "sharedFoundation/FirstSharedFoundation.h" + +// ====================================================================== + +#endif + diff --git a/engine/shared/library/sharedSynchronization/src/shared/Guard.h b/engine/shared/library/sharedSynchronization/src/shared/Guard.h new file mode 100644 index 00000000..dcaf05d7 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/shared/Guard.h @@ -0,0 +1,42 @@ +// ====================================================================== +// +// Guard.h +// +// Copyright 2003 Sony Online Entertainment +// +// ====================================================================== + +#ifndef _Guard_H_ +#define _Guard_H_ + +// ====================================================================== + +#include "sharedSynchronization/RecursiveMutex.h" + +// ====================================================================== + +class Guard +{ +public: + Guard(RecursiveMutex &mutex) : + m_mutex(mutex) + { + mutex.enter(); + } + ~Guard() + { + m_mutex.leave(); + } + +private: + Guard(Guard const &); + Guard &operator=(Guard const &); + +private: + RecursiveMutex &m_mutex; +}; + +// ====================================================================== + +#endif // _Guard_H_ + diff --git a/engine/shared/library/sharedSynchronization/src/shared/WriteOnce.h b/engine/shared/library/sharedSynchronization/src/shared/WriteOnce.h new file mode 100644 index 00000000..e223e248 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/shared/WriteOnce.h @@ -0,0 +1,31 @@ +// ====================================================================== +// +// WriteOnce.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_WriteOnce_h +#define INCLUDED_WriteOnce_h + +#include "sharedSynchronization/Gate.h" + +template +class WriteOnce +{ +public: + WriteOnce(): gate(false) {} + ~WriteOnce() {} + explicit WriteOnce(T &i_initial): gate(false), value(i_initial) {} + T &operator =(const T &i_value) { value = i_value; gate.open(); return value; } + operator T() { gate.wait(); return value; } +private: + WriteOnce(const WriteOnce &o); + WriteOnce &operator =(const WriteOnce &o); + Gate gate; + T value; +}; + +#endif \ No newline at end of file diff --git a/engine/shared/library/sharedSynchronization/src/win32/ConditionVariable.cpp b/engine/shared/library/sharedSynchronization/src/win32/ConditionVariable.cpp new file mode 100644 index 00000000..bdcb1a5f --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/win32/ConditionVariable.cpp @@ -0,0 +1,50 @@ +// ====================================================================== +// +// ConditionVariable.cpp +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedSynchronization/FirstSharedSynchronization.h" +#include "sharedSynchronization/ConditionVariable.h" + +#include "sharedSynchronization/Mutex.h" + +ConditionVariable::ConditionVariable(Mutex &m) +: sem(1), _mutex(m), count(0) +{ +} + +ConditionVariable::~ConditionVariable() +{ +} + +void ConditionVariable::wait() +{ + ++count; + _mutex.leave(); + sem.wait(); + _mutex.enter(); +} + +void ConditionVariable::signal() +{ + if (count) + { + --count; + sem.signal(); + } +} + +void ConditionVariable::broadcast() +{ + if (count) + { + int oldcount = count; + count = 0; + sem.signal(oldcount); + } +} + diff --git a/engine/shared/library/sharedSynchronization/src/win32/ConditionVariable.h b/engine/shared/library/sharedSynchronization/src/win32/ConditionVariable.h new file mode 100644 index 00000000..07ab3034 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/win32/ConditionVariable.h @@ -0,0 +1,42 @@ +// ====================================================================== +// +// ConditionVariable.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_ConditionVariable_h +#define INCLUDED_ConditionVariable_h + +class Mutex; + +#include "sharedSynchronization/Semaphore.h" + +/* Condition variable semantics follow pthreads semantics. You +must have the mutex locked before calling signal or broadcast. +When wait returns, the mutex is locked and you must unlock it. +*/ + +class ConditionVariable +{ +public: + ConditionVariable(Mutex &m); + ~ConditionVariable(); + void wait(); + // You must own the mutex before calling signal. + void signal(); + void broadcast(); + Mutex &mutex() { return _mutex; } +private: + ConditionVariable(const ConditionVariable &o); + ConditionVariable &operator =(const ConditionVariable &o); + + Semaphore sem; + Mutex &_mutex; + int count; +}; + + +#endif \ No newline at end of file diff --git a/engine/shared/library/sharedSynchronization/src/win32/FirstSharedSynchronization.cpp b/engine/shared/library/sharedSynchronization/src/win32/FirstSharedSynchronization.cpp new file mode 100644 index 00000000..12dd9b70 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/win32/FirstSharedSynchronization.cpp @@ -0,0 +1,8 @@ +// ====================================================================== +// +// FirstSynchronization.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedSynchronization/FirstSharedSynchronization.h" diff --git a/engine/shared/library/sharedSynchronization/src/win32/Gate.cpp b/engine/shared/library/sharedSynchronization/src/win32/Gate.cpp new file mode 100644 index 00000000..654ab4f6 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/win32/Gate.cpp @@ -0,0 +1,60 @@ +// ====================================================================== +// +// Gate.cpp +// +// Copyright 2001-2002 Sony Online Entertainment +// All Rights Reserved. +// +// ====================================================================== + +#include "sharedSynchronization/FirstSharedSynchronization.h" +#include "sharedSynchronization/Gate.h" + +// ====================================================================== + +Gate::Gate(bool open) +{ + handle = CreateEvent(0, true, open, 0); + DEBUG_FATAL(handle == NULL, ("CreateEvent failed")); +} + +// ---------------------------------------------------------------------- + +Gate::~Gate() +{ + CloseHandle(handle); +} + +// ---------------------------------------------------------------------- + +void Gate::wait() +{ + int errors = 0; + for (;;) + { + DWORD result = WaitForSingleObject(handle, INFINITE); + if (result == WAIT_OBJECT_0) + return; + + ++errors; + FATAL(errors >= 3, ("WaitForSingleObject failed multiple times")); + } +} + +// ---------------------------------------------------------------------- + +void Gate::close() +{ + const BOOL result = ResetEvent(handle); + FATAL(result == 0, ("ResetEvent failed")); +} + +// ---------------------------------------------------------------------- + +void Gate::open() +{ + const BOOL result = SetEvent(handle); + FATAL(result == 0, ("SetEvent failed")); +} + +// ====================================================================== diff --git a/engine/shared/library/sharedSynchronization/src/win32/Gate.h b/engine/shared/library/sharedSynchronization/src/win32/Gate.h new file mode 100644 index 00000000..a0d3116e --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/win32/Gate.h @@ -0,0 +1,39 @@ +// ====================================================================== +// +// Gate.h +// +// Copyright 2001-2002 Sony Online Entertainment +// All Rights Reseved. +// +// ====================================================================== + +#ifndef INCLUDED_Gate_h +#define INCLUDED_Gate_h + +// ====================================================================== + +class Gate +{ +public: + + Gate(bool initiallyOpen); + ~Gate(); + + void wait(); + + void close(); + void open(); + +private: + + Gate(const Gate &o); + Gate &operator =(const Gate &o); + +private: + + HANDLE handle; +}; + +// ====================================================================== + +#endif \ No newline at end of file diff --git a/engine/shared/library/sharedSynchronization/src/win32/InterlockedInteger.h b/engine/shared/library/sharedSynchronization/src/win32/InterlockedInteger.h new file mode 100644 index 00000000..0489c3f8 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/win32/InterlockedInteger.h @@ -0,0 +1,52 @@ +// ====================================================================== +// +// InterlockedInteger.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_InterlockedInteger_h +#define INCLUDED_InterlockedInteger_h + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +class InterlockedInteger +{ +public: + explicit InterlockedInteger(int initialValue=0); + int operator =(int); // returns prior value (exchange) + int operator ++(); // returns new value + int operator --(); // returns new value + operator int() const { return static_cast(value); } +private: + InterlockedInteger(const InterlockedInteger &o); + InterlockedInteger &operator =(const InterlockedInteger &o); + volatile int value; +}; + +inline InterlockedInteger::InterlockedInteger(int i_value) +: value(i_value) +{ +} + +inline int InterlockedInteger::operator =(int i_value) +{ + long * ptr = (long *)&value; + return static_cast(InterlockedExchange(ptr, static_cast(i_value))); +} + +inline int InterlockedInteger::operator ++() +{ + long * ptr = (long *)&value; + return static_cast(InterlockedIncrement(ptr)); +} + +inline int InterlockedInteger::operator --() +{ + long * ptr = (long *)&value; + return static_cast(InterlockedDecrement(ptr)); +} + +#endif \ No newline at end of file diff --git a/engine/shared/library/sharedSynchronization/src/win32/InterlockedVoidPointer.h b/engine/shared/library/sharedSynchronization/src/win32/InterlockedVoidPointer.h new file mode 100644 index 00000000..eff0a63e --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/win32/InterlockedVoidPointer.h @@ -0,0 +1,45 @@ +// ====================================================================== +// +// InterlockedVoidPointer.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_InterlockedVoidPointer_h +#define INCLUDED_InterlockedVoidPointer_h + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +class InterlockedVoidPointer +{ +public: + explicit InterlockedVoidPointer(void * initialValue=0); + void * compareExchange(void * compare, void * exchange); // compare and exchange if same + operator void * () const { return reinterpret_cast(value); } +private: + InterlockedVoidPointer(const InterlockedVoidPointer &o); + InterlockedVoidPointer &operator =(const InterlockedVoidPointer &o); + void * volatile value; +}; + +template +class InterlockedPointer: public InterlockedVoidPointer +{ +public: + explicit InterlockedPointer(T * initialValue): InterlockedVoidPointer(initialValue) {} + operator T * () const { return static_cast(value); } +}; + +inline InterlockedVoidPointer::InterlockedVoidPointer(void * initialValue) +{ + value = initialValue; +} + +inline void * InterlockedVoidPointer::compareExchange(void * compare, void * exchange) +{ + return (void *)InterlockedCompareExchange((void **)&value, exchange, compare); +} + +#endif \ No newline at end of file diff --git a/engine/shared/library/sharedSynchronization/src/win32/Mutex.cpp b/engine/shared/library/sharedSynchronization/src/win32/Mutex.cpp new file mode 100644 index 00000000..557412a7 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/win32/Mutex.cpp @@ -0,0 +1,53 @@ +// ====================================================================== +// +// Mutex.cpp +// +// Copyright 2001-2002 Sony Online Entertainment +// All Rights Reserved +// +// ====================================================================== + +#include "sharedSynchronization/FirstSharedSynchronization.h" +#include "sharedSynchronization/Mutex.h" + +// ====================================================================== + +void Mutex::install() +{ +} + +// ---------------------------------------------------------------------- + +void Mutex::remove() +{ +} + +// ====================================================================== + +Mutex::Mutex() +{ + InitializeCriticalSection(&m_criticalSection); +} + +// ---------------------------------------------------------------------- + +Mutex::~Mutex() +{ + DeleteCriticalSection(&m_criticalSection); +} + +// ---------------------------------------------------------------------- + +void Mutex::enter() +{ + EnterCriticalSection(&m_criticalSection); +} + +// ---------------------------------------------------------------------- + +void Mutex::leave() +{ + LeaveCriticalSection(&m_criticalSection); +} + +// ====================================================================== diff --git a/engine/shared/library/sharedSynchronization/src/win32/Mutex.h b/engine/shared/library/sharedSynchronization/src/win32/Mutex.h new file mode 100644 index 00000000..579b52c5 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/win32/Mutex.h @@ -0,0 +1,41 @@ +// ====================================================================== +// +// Mutex.h +// Copyright 2001-2002 Sony Online Entertainment +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_Mutex_H +#define INCLUDED_Mutex_H + +// ====================================================================== + +class Mutex +{ +public: + + static void install(); + static void remove(); + +public: + + Mutex(); + ~Mutex(); + + void enter(); + void leave(); + +private: + + Mutex(const Mutex &); + Mutex &operator =(const Mutex &); + +private: + + CRITICAL_SECTION m_criticalSection; +}; + +// ====================================================================== + +#endif diff --git a/engine/shared/library/sharedSynchronization/src/win32/RecursiveMutex.cpp b/engine/shared/library/sharedSynchronization/src/win32/RecursiveMutex.cpp new file mode 100644 index 00000000..fa39da6b --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/win32/RecursiveMutex.cpp @@ -0,0 +1,53 @@ +// ====================================================================== +// +// RecursiveMutex.cpp +// +// Copyright 2001-2002 Sony Online Entertainment +// All Rights Reserved +// +// ====================================================================== + +#include "sharedSynchronization/FirstSharedSynchronization.h" +#include "sharedSynchronization/RecursiveMutex.h" + +// ====================================================================== + +void RecursiveMutex::install() +{ +} + +// ---------------------------------------------------------------------- + +void RecursiveMutex::remove() +{ +} + +// ====================================================================== + +RecursiveMutex::RecursiveMutex() +{ + InitializeCriticalSection(&m_criticalSection); +} + +// ---------------------------------------------------------------------- + +RecursiveMutex::~RecursiveMutex() +{ + DeleteCriticalSection(&m_criticalSection); +} + +// ---------------------------------------------------------------------- + +void RecursiveMutex::enter() +{ + EnterCriticalSection(&m_criticalSection); +} + +// ---------------------------------------------------------------------- + +void RecursiveMutex::leave() +{ + LeaveCriticalSection(&m_criticalSection); +} + +// ====================================================================== diff --git a/engine/shared/library/sharedSynchronization/src/win32/RecursiveMutex.h b/engine/shared/library/sharedSynchronization/src/win32/RecursiveMutex.h new file mode 100644 index 00000000..6c056a6c --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/win32/RecursiveMutex.h @@ -0,0 +1,41 @@ +// ====================================================================== +// +// RecursiveMutex.h +// Copyright 2001-2002 Sony Online Entertainment +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_RecursiveMutex_H +#define INCLUDED_RecursiveMutex_H + +// ====================================================================== + +class RecursiveMutex +{ +public: + + static void install(); + static void remove(); + +public: + + RecursiveMutex(); + ~RecursiveMutex(); + + void enter(); + void leave(); + +private: + + RecursiveMutex(const RecursiveMutex &); + RecursiveMutex &operator =(const RecursiveMutex &); + +private: + + CRITICAL_SECTION m_criticalSection; +}; + +// ====================================================================== + +#endif diff --git a/engine/shared/library/sharedSynchronization/src/win32/Semaphore.cpp b/engine/shared/library/sharedSynchronization/src/win32/Semaphore.cpp new file mode 100644 index 00000000..47a385b4 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/win32/Semaphore.cpp @@ -0,0 +1,37 @@ +// ====================================================================== +// +// Semaphore.cpp +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedSynchronization/FirstSharedSynchronization.h" +#include "sharedSynchronization/Semaphore.h" + +Semaphore::Semaphore(int count, int initial) +{ + handle = CreateSemaphore(0, initial, count, 0); +} + +Semaphore::~Semaphore() +{ + CloseHandle(handle); +} + +void Semaphore::wait() +{ + WaitForSingleObject(handle, INFINITE); +} + +void Semaphore::wait(unsigned int maxDurationMs) +{ + WaitForSingleObject(handle, maxDurationMs); +} + +void Semaphore::signal(int count) +{ + ReleaseSemaphore(handle, count, 0); +} + diff --git a/engine/shared/library/sharedSynchronization/src/win32/Semaphore.h b/engine/shared/library/sharedSynchronization/src/win32/Semaphore.h new file mode 100644 index 00000000..744743a4 --- /dev/null +++ b/engine/shared/library/sharedSynchronization/src/win32/Semaphore.h @@ -0,0 +1,28 @@ +// ====================================================================== +// +// Semaphore.h +// Acy Stapp +// +// Copyright 6/19/2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_Semaphore_h +#define INCLUDED_Semaphore_h + +class Semaphore +{ +public: + Semaphore(int count=0x7FFFFFFF, int initial=0); + ~Semaphore(); + + void wait(); + void wait(unsigned int maxDurationMs); + void signal(int count=1); +private: + Semaphore(const Semaphore &o); + Semaphore &operator =(const Semaphore &o); + HANDLE handle; +}; + +#endif