| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- /****************************************************************************************
-
- Copyright (C) 2015 Autodesk, Inc.
- All rights reserved.
-
- Use of this software is subject to the terms of the Autodesk license agreement
- provided at the time of installation or download, or which otherwise accompanies
- this software in either electronic or hard copy form.
-
- ****************************************************************************************/
- //! \file fbxsync.h
- #ifndef _FBXSDK_CORE_SYNC_H_
- #define _FBXSDK_CORE_SYNC_H_
- #include <fbxsdk/fbxsdk_def.h>
- #if !defined(FBXSDK_ENV_WINSTORE) && !defined(FBXSDK_ENV_EMSCRIPTEN)
- #include <fbxsdk/core/sync/fbxclock.h>
- #include <fbxsdk/core/sync/fbxthread.h>
- #include <fbxsdk/fbxsdk_nsbegin.h>
- class FbxMutexImpl;
- class FbxSemaphoreImpl;
- class FbxGateImpl;
- /** A spinlock is the fastest and most simple thread lock mechanism available.
- * It is very efficient since it does not use any operating system calls; it is only a test and set on an atomic variable,
- * thus it is the fastest thread lock available. Spinlocks are efficient if threads are only likely to be blocked for a
- * short period of time, as they avoid overhead from operating system process re-scheduling or context switching. However,
- * spinlocks become wasteful if held for longer durations, both preventing other threads from running and requiring
- * re-scheduling.
- * \note Spinlocks does not support recursive locking. A thread attempting to lock the same spinlock twice will wait
- * indefinitely.
- */
- class FBXSDK_DLL FbxSpinLock
- {
- public:
- FbxSpinLock();
- /** Acquire the lock; thread will wait indefinitely until it is available. */
- void Acquire();
- /** Release the lock; this will allow other threads to acquire the lock if they are waiting. */
- void Release();
- private:
- FbxAtomic mSpinLock;
- };
- /** Mutually excluding thread lock mechanism.
- * While the mutex is a much heavier implementation than a spinlock, it supports recursive locking; the same thread
- * can safely lock the same mutex more than once without blocking. But it will have to be released as many times as
- * it as been acquired before other threads can acquire the context. It is sometimes referred as a critical section.
- * This is the heaviest thread lock implementation, but also the most secure.
- */
- class FBXSDK_DLL FbxMutex
- {
- public:
- /** Constructor
- * \param pInitialOwnership If pInitialOwnership is true, the lock will be initialized as being locked by the
- * current thread.
- */
- FbxMutex(bool pInitialOwnership=false);
- virtual ~FbxMutex(); //!< Destructor
- /** Acquire the lock; thread will wait indefinitely until it is available.
- * \remarks The same thread can acquire the lock multiple times without blocking.
- */
- void Acquire();
- /** Try acquiring the lock; thread will not wait if it is not available.
- * \param pRetryCount The number of retries in case the lock is not available.
- * \return True if the lock is acquired, false otherwise.
- * \remarks The same thread can acquire the lock multiple times without blocking.
- */
- bool TryAcquire(unsigned int pRetryCount);
- /** Release the lock; this will allow other threads to acquire the lock if they are waiting.
- * \remarks Only the owner thread should call Release(), and it needs to be released as many times as it was
- * acquired.
- */
- void Release();
- private:
- FbxMutexImpl* mImpl;
- };
- /** Mutually excluding thread waiting mechanism with a counter.
- * Semaphore are generally used in situations when the current thread needs to wait for other threads before
- * proceeding to the next step. In other words, that thread waits a number of signals from other threads. This
- * is the best mechanism to use to synchronize threads since it doesn't require an heavy critical section.
- */
- class FBXSDK_DLL FbxSemaphore
- {
- public:
- FbxSemaphore(); //!< Constructor
- virtual ~FbxSemaphore(); //!< Destructor
- /** Wait indefinitely until the semaphore as been signaled as many times as specified.
- * \param pCount Number of signal to wait before this function returns.
- * \return True if the wait exit without errors.
- * \remarks If pCount is set to zero, this function returns immediately without waiting.
- */
- bool Wait(unsigned int pCount=1);
- /** Signal the semaphore as many times as specified.
- * \param pCount The number of signal to send to the semaphore.
- * \return True if the semaphore was signaled without errors.
- */
- bool Signal(unsigned int pCount=1);
- private:
- FbxSemaphoreImpl* mImpl;
- };
- /** A gate thread locking mechanism is very similar to a semaphore, except that when it is opened, any
- * further call to wait will not wait until it is closed. It is generally used to block multiple threads
- * until one of them open the gate to release them all.
- */
- class FBXSDK_DLL FbxGate
- {
- public:
- FbxGate(); //!< Constructor
- virtual ~FbxGate(); //!< Destructor
- /** Open the gate to release all threads waiting.
- * \remarks All waiting threads will unblock until the gate is closed.
- */
- void Open();
- /** Close the gate so that the next time a thread call Wait() it will be blocked. */
- void Close();
- /** Check if the gate is open.
- * \return True if the gate is open, otherwise false.
- */
- bool IsOpen();
- /** Wait indefinitely until the gate open.
- * \return True if the wait completed without errors.
- * \remarks If the gate is already open, this function returns immediately.
- */
- bool Wait();
- private:
- FbxGateImpl* mImpl;
- };
- /** A simple stack of linked items that is multi-thread safe, protected by a spinlock.
- */
- class FBXSDK_DLL FbxSyncStack
- {
- public:
- //! A single link item to be used to construct the stack
- struct Item
- {
- Item* mNext;
- inline Item(){ mNext = NULL; }
- inline Item* Set(Item* pNext){ return mNext = pNext; }
- inline Item* Next(){ return mNext; }
- };
- //! Constructor
- FbxSyncStack();
- /** Add an item on the top of the stack.
- * \param pItem The item to add on top of the stack.
- */
- void Push(Item* pItem);
- /** Remove the item on the top of the stack.
- * \return Returns the item on top of the stack, otherwise NULL if stack empty.
- */
- Item* Pop();
- private:
- FbxSpinLock mLock;
- Item* mTop;
- };
- #include <fbxsdk/fbxsdk_nsend.h>
- #endif /* !FBXSDK_ENV_WINSTORE && !FBXSDK_ENV_EMSCRIPTEN */
- #endif /* _FBXSDK_CORE_SYNC_H_ */
|