// Version: $Id: 467e169f12880ce7936cdaf871b8bb170da49b73 $ // // // Commentary: // // // Change Log: // // // Code: #pragma once #include #include #include // /////////////////////////////////////////////////////////////////// // Helpers // /////////////////////////////////////////////////////////////////// template struct dtkNegate { T operator() (const T& lhs, const T& rhs) const { Q_UNUSED(lhs); return -rhs; } }; template struct dtkInvert { T operator() (const T& lhs, const T& rhs) const { Q_UNUSED(lhs); return 1 / rhs; } }; template <> struct dtkInvert { }; // /////////////////////////////////////////////////////////////////// // dtkDistributedBufferOperationManager // /////////////////////////////////////////////////////////////////// struct DTKDISTRIBUTED_EXPORT dtkDistributedBufferOperationManager { public: virtual ~dtkDistributedBufferOperationManager(void) { ; } public: virtual void addAssign(char *result, void *source, qlonglong count) = 0; virtual void subAssign(char *result, void *source, qlonglong count) = 0; virtual void mulAssign(char *result, void *source, qlonglong count) = 0; virtual void divAssign(char *result, void *source, qlonglong count) = 0; virtual bool compareAndSwap(char *result, void *source, void *compare) = 0; public: virtual void negate(void *result, void *source, qlonglong count) = 0; virtual void invert(void *result, void *source, qlonglong count) = 0; }; // /////////////////////////////////////////////////////////////////// // dtkDistributedBufferOperationManagerTyped // /////////////////////////////////////////////////////////////////// template struct dtkDistributedBufferOperationManagerTyped : public dtkDistributedBufferOperationManager { public: void addAssign(char *result, void *source, qlonglong count); void subAssign(char *result, void *source, qlonglong count); void mulAssign(char *result, void *source, qlonglong count); void divAssign(char *result, void *source, qlonglong count); bool compareAndSwap(char *result, void *source, void *compare); public: void negate(void *result, void *source, qlonglong count); void invert(void *result, void *source, qlonglong count); private: QMutex mutex; }; // /////////////////////////////////////////////////////////////////// template inline void dtkDistributedBufferOperationManagerTyped::addAssign(char *result, void *source, qlonglong count) { T *Tresult = reinterpret_cast(result); T *Tsource = reinterpret_cast(source); std::transform(Tresult, Tresult + count, Tsource, Tresult, std::plus()); } template inline void dtkDistributedBufferOperationManagerTyped::subAssign(char *result, void *source, qlonglong count) { T *Tresult = reinterpret_cast(result); T *Tsource = reinterpret_cast(source); std::transform(Tresult, Tresult + count, Tsource, Tresult, std::minus()); } template inline void dtkDistributedBufferOperationManagerTyped::mulAssign(char *result, void *source, qlonglong count) { T *Tresult = reinterpret_cast(result); T *Tsource = reinterpret_cast(source); std::transform(Tresult, Tresult + count, Tsource, Tresult, std::multiplies()); } template inline void dtkDistributedBufferOperationManagerTyped::divAssign(char *result, void *source, qlonglong count) { T *Tresult = reinterpret_cast(result); T *Tsource = reinterpret_cast(source); std::transform(Tresult, Tresult + count, Tsource, Tresult, std::divides()); } template inline bool dtkDistributedBufferOperationManagerTyped::compareAndSwap(char *result, void *source, void *compare) { T *Tresult = reinterpret_cast(result); T *Tsource = reinterpret_cast(source); T *Tcompare = reinterpret_cast(compare); mutex.lock(); if (*Tresult == *Tcompare) { *Tresult = *Tsource ; mutex.unlock(); return true; } else { mutex.unlock(); return false; } /* m_atomic_value.store(Tresult) */ /* if ( std::atomic_compare_exchange_strong( &m_atomic_value, Tcompare , *Tsource ) ) { */ /* *Tresult = m_atomic_value.load(); */ } template inline void dtkDistributedBufferOperationManagerTyped::negate(void *result, void *source, qlonglong count) { T *Tresult = reinterpret_cast(result); T *Tsource = reinterpret_cast(source); std::transform(Tresult, Tresult + count, Tsource, Tresult, dtkNegate()); } template inline void dtkDistributedBufferOperationManagerTyped::invert(void *result, void *source, qlonglong count) { T *Tresult = reinterpret_cast(result); T *Tsource = reinterpret_cast(source); std::transform(Tresult, Tresult + count, Tsource, Tresult, dtkInvert()); } // /////////////////////////////////////////////////////////////////// // dtkDistributedBufferManager // /////////////////////////////////////////////////////////////////// class DTKDISTRIBUTED_EXPORT dtkDistributedBufferManager { public: dtkDistributedBufferManager(void); virtual ~dtkDistributedBufferManager(void); public: template T *allocate(qlonglong capacity); template void deallocate(T *&buffer); public: virtual bool shouldCache(const qint32& owner) = 0; protected: virtual void *allocate(qlonglong objectSize, qlonglong capacity, int metatype_id) = 0; virtual void deallocate(void *buffer, qlonglong objectSize) = 0; public: virtual void rlock(qlonglong wid) = 0; virtual void rlock(void) = 0; virtual void wlock(qlonglong wid) = 0; virtual void wlock(void) = 0; virtual void unlock(qlonglong wid) = 0; virtual void unlock(void) = 0; virtual bool locked(qlonglong wid) = 0; public: virtual void get(qint32 from, qlonglong position, void *array, qlonglong count = 1) = 0; virtual void put(qint32 dest, qlonglong position, void *array, qlonglong count = 1) = 0; virtual void addAssign(qint32 dest, qlonglong position, void *array, qlonglong nelements = 1) = 0; virtual void subAssign(qint32 dest, qlonglong position, void *array, qlonglong nelements = 1) = 0; virtual void mulAssign(qint32 dest, qlonglong position, void *array, qlonglong nelements = 1) = 0; virtual void divAssign(qint32 dest, qlonglong position, void *array, qlonglong nelements = 1) = 0; virtual bool compareAndSwap(qint32 dest, qlonglong position, void *array, void *compare) = 0; protected: virtual bool canHandleOperationManager(void); protected: dtkDistributedBufferOperationManager *operation_manager; }; // /////////////////////////////////////////////////////////////////// // dtkDistributedBufferManager templated member functions // /////////////////////////////////////////////////////////////////// inline dtkDistributedBufferManager::dtkDistributedBufferManager(void) : operation_manager(NULL) { } inline dtkDistributedBufferManager::~dtkDistributedBufferManager(void) { } inline bool dtkDistributedBufferManager::canHandleOperationManager(void) { return true; } template inline T *dtkDistributedBufferManager::allocate(qlonglong capacity) { if (this->canHandleOperationManager() && !this->operation_manager) this->operation_manager = new dtkDistributedBufferOperationManagerTyped(); return static_cast(this->allocate(sizeof(T), capacity, qMetaTypeId())); } template inline void dtkDistributedBufferManager::deallocate(T *&buffer) { if (this->operation_manager && this->canHandleOperationManager()) { delete this->operation_manager; this->operation_manager = NULL; } this->deallocate(buffer, sizeof(T)); buffer = NULL; } // // dtkDistributedBufferManager.h ends here