diff --git a/CHAOSFramework.xcodeproj/project.pbxproj b/CHAOSFramework.xcodeproj/project.pbxproj index d122df027bad6e49fa4ede319dc74444179d2614..3882d09027a4f321348a7f78f68c722471f7f962 100644 --- a/CHAOSFramework.xcodeproj/project.pbxproj +++ b/CHAOSFramework.xcodeproj/project.pbxproj @@ -195,6 +195,9 @@ 3297F22614D96F31004FFE4F /* DeviceMessageChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3297F22514D96F31004FFE4F /* DeviceMessageChannel.cpp */; }; 3297F22914D96F43004FFE4F /* DeviceMessageChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 3297F22814D96F43004FFE4F /* DeviceMessageChannel.h */; }; 3297F22B14D96F8D004FFE4F /* NetworkAddressMessageChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 3297F22A14D96F8D004FFE4F /* NetworkAddressMessageChannel.h */; }; + 3298487D1736814700C158DF /* ChannelValueAccessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3298487B1736814700C158DF /* ChannelValueAccessor.cpp */; }; + 3298487E1736814700C158DF /* ChannelValueAccessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 3298487C1736814700C158DF /* ChannelValueAccessor.h */; }; + 32984880173681BB00C158DF /* SlbCachedInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3298487F173681BB00C158DF /* SlbCachedInfo.h */; }; 329FFFD1170712CE00D69CDE /* ManagedMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 329FFFCF170712CE00D69CDE /* ManagedMemory.cpp */; }; 329FFFD2170712CE00D69CDE /* ManagedMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 329FFFD0170712CE00D69CDE /* ManagedMemory.h */; }; 32A51AFE167F95B30007E25A /* sqlite3.c in Sources */ = {isa = PBXBuildFile; fileRef = 32A51AFC167F95B30007E25A /* sqlite3.c */; }; @@ -557,6 +560,9 @@ 3297F22514D96F31004FFE4F /* DeviceMessageChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeviceMessageChannel.cpp; sourceTree = "<group>"; }; 3297F22814D96F43004FFE4F /* DeviceMessageChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceMessageChannel.h; sourceTree = "<group>"; }; 3297F22A14D96F8D004FFE4F /* NetworkAddressMessageChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkAddressMessageChannel.h; sourceTree = "<group>"; }; + 3298487B1736814700C158DF /* ChannelValueAccessor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ChannelValueAccessor.cpp; sourceTree = "<group>"; }; + 3298487C1736814700C158DF /* ChannelValueAccessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ChannelValueAccessor.h; sourceTree = "<group>"; }; + 3298487F173681BB00C158DF /* SlbCachedInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlbCachedInfo.h; sourceTree = "<group>"; }; 329FFFCF170712CE00D69CDE /* ManagedMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ManagedMemory.cpp; sourceTree = "<group>"; }; 329FFFD0170712CE00D69CDE /* ManagedMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ManagedMemory.h; sourceTree = "<group>"; }; 32A51AFC167F95B30007E25A /* sqlite3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sqlite3.c; sourceTree = "<group>"; }; @@ -1506,6 +1512,9 @@ 32A8F7D0172BE3FD0090DB78 /* DatasetCache.h */, 328E405B17287B82004E5938 /* ChannelCache.cpp */, 328E405C17287B82004E5938 /* ChannelCache.h */, + 3298487B1736814700C158DF /* ChannelValueAccessor.cpp */, + 3298487C1736814700C158DF /* ChannelValueAccessor.h */, + 3298487F173681BB00C158DF /* SlbCachedInfo.h */, ); path = cache; sourceTree = "<group>"; @@ -1729,6 +1738,8 @@ 32D421B417271572008A326E /* BsonFragment.h in Headers */, 328E405E17287B82004E5938 /* ChannelCache.h in Headers */, 32A8F7D2172BE3FD0090DB78 /* DatasetCache.h in Headers */, + 3298487E1736814700C158DF /* ChannelValueAccessor.h in Headers */, + 32984880173681BB00C158DF /* SlbCachedInfo.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2010,6 +2021,7 @@ 32D421B317271572008A326E /* BsonFragment.cpp in Sources */, 328E405D17287B82004E5938 /* ChannelCache.cpp in Sources */, 32A8F7D1172BE3FD0090DB78 /* DatasetCache.cpp in Sources */, + 3298487D1736814700C158DF /* ChannelValueAccessor.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/CMakeLists.txt b/CMakeLists.txt index a03dafc982e64238c022c5029f7fcff2dd20597a..a76994541a7c84dca10479a963aa801516ad9805 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,3 +112,6 @@ ADD_SUBDIRECTORY(example/UIToolkitCMDLineCWrapperExample bin/bin_example_uicmdli message(STATUS "Configure BenchTest simulation excutable") ADD_SUBDIRECTORY(example/BenchTest bin/bench_test) + +message(STATUS "Configure ChaosMemCacheTest test excutable") +ADD_SUBDIRECTORY(test/MemcachedEmbeddedTest/MemcachedEmbeddedTest bin/memcache_test) diff --git a/chaos/common/CMakeLists.txt b/chaos/common/CMakeLists.txt index de39477afee664d685803af13a8d7bea25cbd855..648002ee91482f45704d25b0149d1158fd718be4 100644 --- a/chaos/common/CMakeLists.txt +++ b/chaos/common/CMakeLists.txt @@ -1,4 +1,4 @@ -SET(common_lib_src log/LogManager.cpp action/ActionExecutionSafetySystem.cpp action/EventAction.cpp action/ActionDescriptor.cpp action/DeclareAction.cpp action/DomainActions.cpp bson/oid.cpp bson/bson_validate.cpp bson/base/parse_number.cpp bson/base/string_data.cpp bson/base/status.cpp bson/base/error_codes.cpp bson/platform/random.cpp bson/util/stringutils.cpp bson/util/md5.cpp bson/util/base64.cpp bson/util/timer.cpp bson/util/time_support.cpp bson/util/jsobj.cpp bson/util/json.cpp bson/util/assert_util.cpp bson/util/bson_extract.cpp configuration/GlobalConfiguration.cpp data/CDataWrapper.cpp data/CUSchemaDB.cpp data/entity_db/EntityDB.cpp data/entity_db/sqlite_impl/sqlite3.c data/entity_db/sqlite_impl/SQLiteEntityDB.cpp data/entity/Entity.cpp data/broker/DataBroker.cpp data/broker/publisher/PublisherDataService.cpp data/broker/reader/ReaderDataService.cpp data/cache/FastHash.cpp data/cache/DataCache.cpp data/cache/ChannelCache.cpp data/cache/DatasetCache.cpp memory/ManagedMemory.cpp dispatcher/DefaultEventDispatcher.cpp dispatcher/EventTypeScheduler.cpp dispatcher/AbstractEventDispatcher.cpp dispatcher/AbstractCommandDispatcher.cpp dispatcher/DefaultCommandDispatcher.cpp dispatcher/DomainActionsScheduler.cpp dispatcher/AbstractEventDispatcher.cpp event/EventClient.cpp event/AsioImplEventClient event/AsioEventForwarder.cpp event/EventServer.cpp event/AsioImplEventServer.cpp event/AsioEventHandler.cpp event/evt_desc/EventDescriptor.cpp event/evt_desc/AlertEventDescriptor.cpp event/evt_desc/InstrumentEventDescriptor.cpp event/evt_desc/CommandEventDescriptor.cpp event/evt_desc/CustomEventDescriptor.cpp event/channel/EventChannel.cpp event/channel/AlertEventChannel.cpp event/channel/InstrumentEventChannel.cpp io/IODataDriver.cpp io/IOMemcachedDriver.cpp io/OutputMongoDataDriver.cpp message/DeviceMessageChannel.cpp message/MDSMessageChannel.cpp network/NetworkBroker.cpp message/MessageChannel.cpp rpc/RpcClient.cpp rpc/RpcServer.cpp rpc/msgpack/MsgPackClient.cpp rpc//msgpack/MsgPackServer.cpp thread/CThread.cpp thread/CThreadGroup.cpp utility/NamedService.cpp utility/ISDInterface.cpp) +SET(common_lib_src log/LogManager.cpp action/ActionExecutionSafetySystem.cpp action/EventAction.cpp action/ActionDescriptor.cpp action/DeclareAction.cpp action/DomainActions.cpp bson/oid.cpp bson/bson_validate.cpp bson/base/parse_number.cpp bson/base/string_data.cpp bson/base/status.cpp bson/base/error_codes.cpp bson/platform/random.cpp bson/util/stringutils.cpp bson/util/md5.cpp bson/util/base64.cpp bson/util/timer.cpp bson/util/time_support.cpp bson/util/jsobj.cpp bson/util/json.cpp bson/util/assert_util.cpp bson/util/bson_extract.cpp configuration/GlobalConfiguration.cpp data/CDataWrapper.cpp data/CUSchemaDB.cpp data/entity_db/EntityDB.cpp data/entity_db/sqlite_impl/sqlite3.c data/entity_db/sqlite_impl/SQLiteEntityDB.cpp data/entity/Entity.cpp data/broker/DataBroker.cpp data/broker/publisher/PublisherDataService.cpp data/broker/reader/ReaderDataService.cpp data/cache/FastHash.cpp data/cache/DataCache.cpp data/cache/ChannelCache.cpp data/cache/ChannelValueAccessor.cpp data/cache/DatasetCache.cpp memory/ManagedMemory.cpp dispatcher/DefaultEventDispatcher.cpp dispatcher/EventTypeScheduler.cpp dispatcher/AbstractEventDispatcher.cpp dispatcher/AbstractCommandDispatcher.cpp dispatcher/DefaultCommandDispatcher.cpp dispatcher/DomainActionsScheduler.cpp dispatcher/AbstractEventDispatcher.cpp event/EventClient.cpp event/AsioImplEventClient event/AsioEventForwarder.cpp event/EventServer.cpp event/AsioImplEventServer.cpp event/AsioEventHandler.cpp event/evt_desc/EventDescriptor.cpp event/evt_desc/AlertEventDescriptor.cpp event/evt_desc/InstrumentEventDescriptor.cpp event/evt_desc/CommandEventDescriptor.cpp event/evt_desc/CustomEventDescriptor.cpp event/channel/EventChannel.cpp event/channel/AlertEventChannel.cpp event/channel/InstrumentEventChannel.cpp io/IODataDriver.cpp io/IOMemcachedDriver.cpp io/OutputMongoDataDriver.cpp message/DeviceMessageChannel.cpp message/MDSMessageChannel.cpp network/NetworkBroker.cpp message/MessageChannel.cpp rpc/RpcClient.cpp rpc/RpcServer.cpp rpc/msgpack/MsgPackClient.cpp rpc//msgpack/MsgPackServer.cpp thread/CThread.cpp thread/CThreadGroup.cpp utility/NamedService.cpp utility/ISDInterface.cpp) SET(common_lib_library boost_program_options boost_system boost_thread boost_chrono boost_regex boost_log boost_log_setup memcached msgpack msgpack-rpc mpio) diff --git a/chaos/common/data/cache/ChannelCache.cpp b/chaos/common/data/cache/ChannelCache.cpp index 6109ec431791cd97622fbe4f9debb3ac983ff133..1d9f7648eaf5f45aa50d953b4e62b7a193b614ae 100644 --- a/chaos/common/data/cache/ChannelCache.cpp +++ b/chaos/common/data/cache/ChannelCache.cpp @@ -30,9 +30,7 @@ void ChannelCache::swapRWIndex() { writeIndex = (writeIndex + 1) % 2; // put old readeable slba into garbageable index - boost::unique_lock<boost::mutex> lock(garbageMutext); garbageableSlab.push(rwPtr[writeIndex]); - lock.unlock(); // alloc new slab info rwPtr[writeIndex] = makeNewChachedInfoPtr(); @@ -53,14 +51,12 @@ void ChannelCache::garbageCache() { bool needToBeGarbaged = false; volatile boost::uint32_t *mem; boost::uint32_t oldMem, oldValue; - //lock the critical section - boost::unique_lock<boost::mutex> lock(garbageMutext); + if(garbageableSlab.empty()) return; - //cicle all slab to make it garbaged - SlbCachedInfoPtr tmpPtr; + SlbCachedInfoPtr tmpPtr = NULL; do { if((needToBeGarbaged=garbageableSlab.pop(tmpPtr))){ counter++; @@ -78,8 +74,6 @@ void ChannelCache::garbageCache() { } } } while(needToBeGarbaged); - - std::cout << counter << "garbage operation" << std::endl; } //! Initialize the channel cache @@ -161,4 +155,8 @@ SlbCachedInfoPtr ChannelCache::getCurrentCachedPtr() { //we have suceed to udpate the reference count without noone has modified it return result; -} \ No newline at end of file +} + +void ChannelCache::fillAccessorWithCurrentValue(ChannelValueAccessor& accessorPtr) { + accessorPtr.reset(getCurrentCachedPtr()); +} diff --git a/chaos/common/data/cache/ChannelCache.h b/chaos/common/data/cache/ChannelCache.h index 6a6e53c9c77e25e0406f25290c928be68fcb5953..45c0a8cf2baf1bacec62ce32ae3e183089411d90 100644 --- a/chaos/common/data/cache/ChannelCache.h +++ b/chaos/common/data/cache/ChannelCache.h @@ -16,8 +16,10 @@ #include <boost/detail/atomic_count.hpp> #include <boost/thread.hpp> -#include <chaos/common/memory/ManagedMemory.h> #include <chaos/common/cconstants.h> +#include <chaos/common/memory/ManagedMemory.h> +#include <chaos/common/data/cache/SlbCachedInfo.h> +#include <chaos/common/data/cache/ChannelValueAccessor.h> namespace chaos { @@ -28,34 +30,6 @@ namespace chaos { //forward declaration class DatasetCache; - /*! - Define the cached slab taht contain channel description - */ - typedef struct SlbCachedInfo { - //! busy flag indication - /*! - It is used to up the reference count at the moment that - rptr is read by array. It possible that the rptr that - is getting becam old and so the clean thread will try to clean - before the count is up of one. - Using this flag the thread can be hald in the moment - */ - //boost::atomic_flag busyFlag; - - //! element reference count - /*! - Mantain the number of the object that refere to this element of the cache, - the default value for the reference is "1" when it is 0 it ca be deallocated - */ - boost::uint32_t references; - - //!slab ptr for cached value - /*! - This ptr is the base address where the value is wrote to be cached - */ - void *valPtr; - } SlbCachedInfo, *SlbCachedInfoPtr; - //!Channel cache /*! @@ -68,15 +42,13 @@ namespace chaos { //!permit the DatasetCache class to use the private variable friend class DatasetCache; - boost::mutex garbageMutext; - //!index to identity the write ptr int writeIndex; //! index for identify read ptr boost::atomic_ushort readIndex; - //! writeble and readeble pointer array + //! writeble and readeble pointer array /*! The two element array is used to select where, the principal thread write the next "current" value, and the other is used for read the current value. @@ -94,6 +66,7 @@ namespace chaos { //! slab size uint32_t slabRequiredSize; + //!slab id to use uint16_t slabID; //! the type of the channel @@ -109,9 +82,22 @@ namespace chaos { */ inline void swapRWIndex(); + //! allocate and prepare a new slab + /*! + Allocate a new slab and prepare it to be used + \return a new SlbCachedInfo structure to cache + a new valu efor the channel + */ inline SlbCachedInfoPtr makeNewChachedInfoPtr(); public: + + //! Default constructor + /*! + Creathe the object with the memory manager assigned + */ ChannelCache(memory::ManagedMemory *_memoryPool); + + //! Default destructor ~ChannelCache(); /*! @@ -139,6 +125,11 @@ namespace chaos { /*! */ SlbCachedInfoPtr getCurrentCachedPtr(); + + //! return the current cached accessor + /*! + */ + void fillAccessorWithCurrentValue(ChannelValueAccessor& accessorPtr); }; } diff --git a/chaos/common/data/cache/ChannelValueAccessor.cpp b/chaos/common/data/cache/ChannelValueAccessor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ed8d32ee30d79daa1a046db8d4657d6ce44b8dcc --- /dev/null +++ b/chaos/common/data/cache/ChannelValueAccessor.cpp @@ -0,0 +1,30 @@ +// +// ChannelValueAccessor.cpp +// CHAOSFramework +// +// Created by Claudio Bisegni on 5/5/13. +// Copyright (c) 2013 INFN. All rights reserved. +// + + +#include <boost/interprocess/detail/atomic.hpp> + +#include <chaos/common/data/cache/ChannelValueAccessor.h> + +using namespace chaos::data::cache; + +ChannelValueAccessor::ChannelValueAccessor():slbPtr(NULL) { + +} + +ChannelValueAccessor::~ChannelValueAccessor() { + reset(NULL); +} + +void ChannelValueAccessor::reset(SlbCachedInfoPtr _slbPtr) { + if(slbPtr) { + boost::interprocess::ipcdetail::atomic_add32(&slbPtr->references, (boost::uint32_t)-1); + } + + slbPtr = _slbPtr; +} \ No newline at end of file diff --git a/chaos/common/data/cache/ChannelValueAccessor.h b/chaos/common/data/cache/ChannelValueAccessor.h new file mode 100644 index 0000000000000000000000000000000000000000..3ae63377b664720a8e6b74765c3d85da36c0de36 --- /dev/null +++ b/chaos/common/data/cache/ChannelValueAccessor.h @@ -0,0 +1,44 @@ +// +// ChannelValueAccessor.h +// CHAOSFramework +// +// Created by Claudio Bisegni on 5/5/13. +// Copyright (c) 2013 INFN. All rights reserved. +// + +#ifndef __CHAOSFramework__ChannelValueAccessor__ +#define __CHAOSFramework__ChannelValueAccessor__ + +#include <chaos/common/data/cache/SlbCachedInfo.h> + +namespace chaos { + + namespace data { + + namespace cache { + + class ChannelCache; + + class ChannelValueAccessor { + friend class ChannelCache; + + SlbCachedInfoPtr slbPtr; + + + public: + ChannelValueAccessor(); + ~ChannelValueAccessor(); + + void reset(SlbCachedInfoPtr _slbPtr); + + template<typename T> + T* getValuePtr() { + return static_cast<T*>(slbPtr->valPtr); + } + }; + + typedef ChannelValueAccessor *ChannelValueAccessorPtr; + } + } +} +#endif /* defined(__CHAOSFramework__ChannelValueAccessor__) */ diff --git a/chaos/common/data/cache/DatasetCache.cpp b/chaos/common/data/cache/DatasetCache.cpp index f1c9da2b9789a153bb68cd2267aaeaf6a05a8c58..02ca9990723f846a3c9439916999e7ec17cd299e 100644 --- a/chaos/common/data/cache/DatasetCache.cpp +++ b/chaos/common/data/cache/DatasetCache.cpp @@ -183,4 +183,21 @@ SlbCachedInfoPtr DatasetCache::getCurrentChannelCachedValue(uint16_t channelInde ChannelCache *ptr = chCachePtrArray[channelIndex]; if(!ptr) return NULL; return ptr->getCurrentCachedPtr(); +} + +void DatasetCache::getCurrentChannelValueAccessor(const char *channelName, ChannelValueAccessor& accessorPtr) { + if(!channelInfoMap.count(channelName)) { + accessorPtr.reset(NULL); + return; + } + getCurrentChannelValueAccessor(channelInfoMap[channelName]->index, accessorPtr); +} + +void DatasetCache::getCurrentChannelValueAccessor(uint16_t channelIndex, ChannelValueAccessor& accessorPtr) { + ChannelCache *ptr = chCachePtrArray[channelIndex]; + if(!ptr) { + accessorPtr.reset(NULL); + return; + } + ptr->fillAccessorWithCurrentValue(accessorPtr); } \ No newline at end of file diff --git a/chaos/common/data/cache/DatasetCache.h b/chaos/common/data/cache/DatasetCache.h index 06a49da873405d2bd2dc918a6e58fdd37b83f8d6..902a74d1c676b5ac1a4c6ecd2d095b8d67c28cb4 100644 --- a/chaos/common/data/cache/DatasetCache.h +++ b/chaos/common/data/cache/DatasetCache.h @@ -11,11 +11,13 @@ #include <map> #include <string> -#include <chaos/common/memory/ManagedMemory.h> -#include <chaos/common/data/cache/ChannelCache.h> + +#include <chaos/common/cconstants.h> #include <chaos/common/bson/util/builder.h> +#include <chaos/common/memory/ManagedMemory.h> #include <chaos/common/utility/ISDInterface.h> -#include <chaos/common/cconstants.h> +#include <chaos/common/data/cache/ChannelCache.h> +#include <chaos/common/data/cache/ChannelValueAccessor.h> namespace chaos { @@ -99,6 +101,10 @@ namespace chaos { SlbCachedInfoPtr getCurrentChannelCachedValue(const char *channelName); SlbCachedInfoPtr getCurrentChannelCachedValue(uint16_t channelIndex); + + void getCurrentChannelValueAccessor(const char *channelName, ChannelValueAccessor& accessorPtr); + + void getCurrentChannelValueAccessor(uint16_t channelIndex, ChannelValueAccessor& accessorPtr); }; } diff --git a/chaos/common/data/cache/SlbCachedInfo.h b/chaos/common/data/cache/SlbCachedInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..d74f2a45123e4536ee9528d4180abf7e28f86051 --- /dev/null +++ b/chaos/common/data/cache/SlbCachedInfo.h @@ -0,0 +1,42 @@ +// +// SlbCachedInfo.h +// CHAOSFramework +// +// Created by Claudio Bisegni on 5/5/13. +// Copyright (c) 2013 INFN. All rights reserved. +// + +#ifndef CHAOSFramework_SlbCachedInfo_h +#define CHAOSFramework_SlbCachedInfo_h + +#include <boost/cstdint.hpp> + +/*! + Define the cached slab taht contain channel description + */ +typedef struct SlbCachedInfo { + //! busy flag indication + /*! + It is used to up the reference count at the moment that + rptr is read by array. It possible that the rptr that + is getting becam old and so the clean thread will try to clean + before the count is up of one. + Using this flag the thread can be hald in the moment + */ + //boost::atomic_flag busyFlag; + + //! element reference count + /*! + Mantain the number of the object that refere to this element of the cache, + the default value for the reference is "1" when it is 0 it ca be deallocated + */ + boost::uint32_t references; + + //!slab ptr for cached value + /*! + This ptr is the base address where the value is wrote to be cached + */ + void *valPtr; +} SlbCachedInfo, *SlbCachedInfoPtr; + +#endif diff --git a/chaos/common/memory/ManagedMemory.cpp b/chaos/common/memory/ManagedMemory.cpp index ad0385216325aefe71b4b9df66a0c453a304eccc..db90b04835ed2135f77cd75229eb9ec9d70a4543 100644 --- a/chaos/common/memory/ManagedMemory.cpp +++ b/chaos/common/memory/ManagedMemory.cpp @@ -193,14 +193,18 @@ void ManagedMemory::deinit() { void *ManagedMemory::allocate(size_t size, unsigned int id) { void *ret; pthread_mutex_lock(&slabs_lock); + //while (atomicFlagLock.test_and_set(boost::memory_order_acquire)) {}; ret = do_slabs_alloc(size, id); + //atomicFlagLock.clear(boost::memory_order_release); pthread_mutex_unlock(&slabs_lock); return ret; } void ManagedMemory::deallocate(void *ptr, size_t size, unsigned int id) { pthread_mutex_lock(&slabs_lock); + //while (atomicFlagLock.test_and_set(boost::memory_order_acquire)) {}; do_slabs_free(ptr, size, id); + //atomicFlagLock.clear(boost::memory_order_release); pthread_mutex_unlock(&slabs_lock); } diff --git a/chaos/common/memory/ManagedMemory.h b/chaos/common/memory/ManagedMemory.h index cdcc9fef4710a8078136a1fad5c8a79ebef295d2..000736ac446ffd4b7646753b86d56d1b2a1bb53a 100644 --- a/chaos/common/memory/ManagedMemory.h +++ b/chaos/common/memory/ManagedMemory.h @@ -24,6 +24,7 @@ #include <unistd.h> #include <pthread.h> +#include <boost/atomic/atomic.hpp> namespace chaos { @@ -68,6 +69,7 @@ namespace chaos { * memcached protocol. */ class ManagedMemory { + boost::atomic_flag atomicFlagLock; slabclass_t slabclass[MAX_NUMBER_OF_SLAB_CLASSES]; size_t mem_malloced; @@ -98,14 +100,25 @@ namespace chaos { ManagedMemory(); ~ManagedMemory(); - /** Init the subsystem. 1st argument is the limit on no. of bytes to allocate, - 0 if no limit. 2nd argument is the growth factor; each slab will use a chunk - size equal to the previous slab's chunk size times this factor. - 3rd argument specifies if the slab allocator should allocate all memory - up front (if 1), or allocate memory in chunks as it is needed (if 0) + //! Inizialization of slab engine + /*! Init the slab memory engine + \param _chunkSize is the minimal number of byte for the slab + \param _itemMaxSize is the maximum size in byte of the slab + \param _memoryLimit if > 0 will put a barrier to the max memory to use + \param _growFactor argument is the growth factor; each slab will use a chunk + size equal to the previous slab's chunk size times this factor. + \param _prealloc allocate all mermoy for all slab (if 1) or allocate memory in chunks as it is needed (if 0) + \param _fixedNumberOfSlab if > 0 give a fixed number of slba to every class */ void init(int _chunkSize, size_t _itemMaxSize, size_t _memoryLimit, double _growFactor, int _prealloc, int _fixedNumberOfSlab = 0); + //! Inizialization of slab engine + /*! Init the slab memory engine for only one class of slab + \param _chunkSize is the minimal number of byte for the slab + \param _memoryLimit if > 0 will put a barrier to the max memory to use + \param _prealloc allocate all mermoy for all slab (if 1) or allocate memory in chunks as it is needed (if 0) + \param _fixedNumberOfSlab if > 0 give a fixed number of slba to every class + */ void init(int _chunkSize, size_t _memoryLimit, int fixedNumberOfSlabPerClass, int _prealloc); void deinit(); diff --git a/test/MemcachedEmbeddedTest/MemcachedEmbeddedTest.xcodeproj/project.pbxproj b/test/MemcachedEmbeddedTest/MemcachedEmbeddedTest.xcodeproj/project.pbxproj index 7b307460c043fe706cc1b8c4e6b4c059a8cba423..e2ea207b3b84b2b81c1f77d543041ffcfb91304f 100644 --- a/test/MemcachedEmbeddedTest/MemcachedEmbeddedTest.xcodeproj/project.pbxproj +++ b/test/MemcachedEmbeddedTest/MemcachedEmbeddedTest.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 329848811736C52300C158DF /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; }; 32BFCAB316FF1D3200C93D76 /* MemcachedEmbeddedTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = MemcachedEmbeddedTest; sourceTree = BUILT_PRODUCTS_DIR; }; 32BFCAB616FF1D3200C93D76 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; }; 32BFCAB816FF1D3200C93D76 /* MemcachedEmbeddedTest.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = MemcachedEmbeddedTest.1; sourceTree = "<group>"; }; @@ -60,6 +61,7 @@ 32BFCAB516FF1D3200C93D76 /* MemcachedEmbeddedTest */ = { isa = PBXGroup; children = ( + 329848811736C52300C158DF /* CMakeLists.txt */, 32BFCAB616FF1D3200C93D76 /* main.cpp */, 32BFCAB816FF1D3200C93D76 /* MemcachedEmbeddedTest.1 */, ); @@ -264,6 +266,7 @@ 32BFCABE16FF1D3200C93D76 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/test/MemcachedEmbeddedTest/MemcachedEmbeddedTest/CMakeLists.txt b/test/MemcachedEmbeddedTest/MemcachedEmbeddedTest/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2c95b23c901d4d006d77a09440a23cd713f78299 --- /dev/null +++ b/test/MemcachedEmbeddedTest/MemcachedEmbeddedTest/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 2.6) +option(BUILD_FORCE_32 "Set to ON to enable 32 bit compilation" OFF) + +IF( ($ENV{CHAOS32}) OR (BUILD_FORCE_32) ) + MESSAGE(STATUS "Enabling 32 bit Compilation") + set (CMAKE_C_FLAGS "-m32") + set (CMAKE_CXX_FLAGS "-m32") + set (CMAKE_LINK_FLAGS "-m32") +ENDIF() +ADD_DEFINITIONS(-g -O2 -Wall) + +SET(memcache_test main.cpp) +INCLUDE_DIRECTORIES(. ${PROJECT_SOURCE_DIR}/../../usr/local/include /usr/local/include /usr/include) +LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/../../usr/local/lib /usr/local/lib) +ADD_EXECUTABLE(ChaosMemCacheTest ${memcache_test}) +TARGET_LINK_LIBRARIES(ChaosMemCacheTest chaos_common boost_program_options boost_system boost_thread ) diff --git a/test/MemcachedEmbeddedTest/MemcachedEmbeddedTest/main.cpp b/test/MemcachedEmbeddedTest/MemcachedEmbeddedTest/main.cpp index bf180603526e55c1f475a6f3c16f1ef4ab463a7b..4d890d286db2ba50c91255530376bfc7aa89c7c9 100644 --- a/test/MemcachedEmbeddedTest/MemcachedEmbeddedTest/main.cpp +++ b/test/MemcachedEmbeddedTest/MemcachedEmbeddedTest/main.cpp @@ -24,12 +24,13 @@ #include <boost/chrono.hpp> #include <boost/random.hpp> #include <boost/shared_ptr.hpp> -#define STRUCT_NUM 200000 +#define STRUCT_NUM 10 -#define WRITE_THREAD_UPDATE_RATE 250 -#define READ_THREAD_NUMBER 1 -#define READ_THREAD_UPDATE_RATE_MS 500 -#define GARBAGE_THREAD_UPDATE_RATE_MS 250 +#define WRITE_THREAD_UPDATE_RATE 10 +#define READ_THREAD_NUMBER 10 +#define READ_THREAD_UPDATE_RATE_MS_MAX 10 +#define GARBAGE_THREAD_UPDATE_RATE_MS 100 +#define TEST_DURATION_IN_SEC 10 bool threadWriteExecution = true; bool threadReadExecution = true; @@ -69,13 +70,18 @@ void cacheUpdaterI32(chaos::data::cache::DatasetCache *cPtr) { do{ tmp = randI32(rng); cPtr->updateChannelValue((uint16_t)0, &tmp); + //std::cout << "cached int32 value->" << tmp << " on thread ->" << boost::this_thread::get_id() << std::endl; boost::this_thread::sleep_for(boost::chrono::milliseconds(WRITE_THREAD_UPDATE_RATE)); } while (threadWriteExecution); } void cacheReader(chaos::data::cache::DatasetCache *cPtr) { + chaos::data::cache::ChannelValueAccessor accessor; do { - boost::this_thread::sleep_for(boost::chrono::milliseconds(READ_THREAD_UPDATE_RATE_MS)); + cPtr->getCurrentChannelValueAccessor((uint16_t)0, accessor); + int32_t readed = *accessor.getValuePtr<int32_t>(); + //std::cout << "read int32 value->" << readed << " on thread->" << boost::this_thread::get_id() << std::endl; + boost::this_thread::sleep_for(boost::chrono::milliseconds(READ_THREAD_UPDATE_RATE_MS_MAX)); } while (threadReadExecution); } @@ -91,102 +97,82 @@ int main(int argc, const char * argv[]) { boost::thread_group tWriterGroup; boost::thread_group tGarbageGroup; boost::thread_group tReadersGroup; - uint32_t faultAllocation = 0; - timespec prevTS = {0,0}; - timespec ts = {0,0}; + uint32_t bsize; void *buff = NULL; - - - //test slab memory allocation - auto_ptr<chaos::memory::ManagedMemory> mm(new chaos::memory::ManagedMemory()); - mm->init(sizeof(DemoStruct), 0, STRUCT_NUM, 0); - unsigned int sID = mm->getSlabIdBySize(sizeof(DemoStruct)); - - DemoStruct *structPtr[STRUCT_NUM]; - - size_t structDim = sizeof(DemoStruct); - memset(structPtr, 0, sizeof(DemoStruct*)*STRUCT_NUM); - current_utc_time(&prevTS); - for (int idx = 0; idx < STRUCT_NUM; idx++) { - structPtr[idx] = static_cast<DemoStruct*>(mm->allocate(structDim, sID)); - if(structPtr[idx] != NULL) { - structPtr[idx]->a = idx; - structPtr[idx]->b[5] = idx*3; - } else { - faultAllocation++; + try { + //test dataset chache + std::cout << "Start DatasetCache with " << " for " << TEST_DURATION_IN_SEC << " seconds " << std::endl; + std::cout << "Number of writer " << 1 << std::endl; + std::cout << "Number of reader " << READ_THREAD_NUMBER << std::endl; + auto_ptr<chaos::data::cache::DatasetCache> dsCache(new chaos::data::cache::DatasetCache()); + dsCache->addChannel("ch_i32", chaos::DataType::TYPE_INT32); + dsCache->init(NULL); + dsCache->start(); + + + // allocate and start writer thread + //tWriter.reset(new boost::thread(boost::bind(cacheUpdaterI32, dsCache.get()))); + tWriterGroup.create_thread(boost::bind(cacheUpdaterI32, dsCache.get())); + //start garbage thread + tGarbageGroup.create_thread(boost::bind(cacheGarbage, dsCache.get())); + //start all reader thread + for (int idx = 0; idx < READ_THREAD_NUMBER; idx++) { + tReadersGroup.create_thread(boost::bind(cacheReader, dsCache.get())); } + + boost::this_thread::sleep_for(boost::chrono::seconds(TEST_DURATION_IN_SEC)); + threadReadExecution = false; + std::cout << "Stop all threads" << std::endl; + //join on read thread + tReadersGroup.join_all(); + + //stop writer and garbag thread + threadWriteExecution = false; + tGarbageGroup.join_all(); + tWriterGroup.join_all(); + + //deinit all cache + dsCache->stop(); + dsCache->deinit(); + std::cout << "Thread stopped and DatasetCache deinitialized" << std::endl; + + //test memcached implementation + chaos::data::cache::CacheSettings settings; + + settings.factor = 1.25; + settings.maxbytes = 1 * 1024 * 1024; //default is 64MB + settings.chunk_size = 48; //48; /* space for a modest key and value */ + settings.item_size_max = 1024 * 1024; //1024 * 1024; + settings.evict_to_free = 1; + settings.oldest_live = 0; + settings.use_cas = 1; + settings.preallocation = 0; + std::cout << "Start DataCache test (Memcached embedded)" << std::endl; + auto_ptr<chaos::data::cache::DataCache> fc(new chaos::data::cache::DataCache()); + fc->init(&settings); + fc->start(); + fc->storeItem("key", "value", (int32_t)strlen("value")); + fc->getItem("key", bsize, &buff); + std::cout << (const char *)buff << std::endl; + + fc->storeItem("key", "value2", (int32_t)strlen("value2")); + fc->getItem("key", bsize, &buff); + std::cout << (const char *)buff << std::endl; + + fc->deleteItem("key"); + fc->storeItem("key", "value3", (int32_t)strlen("value3")); + fc->getItem("key", bsize, &buff); + std::cout << (const char *)buff << std::endl; + fc->stop(); + fc->deinit(); + std::cout << "DataCache test ended" << std::endl; + } catch(chaos::CException& ex) { + std::cout << ex.what() << std::endl; + return 1; + } catch(...) { + return 1; } - for (int idx = 0; idx < 1000; idx++) { - if(structPtr[idx] != NULL) mm->deallocate(structPtr[idx], structDim, sID); - } - current_utc_time(&ts); - uint64_t d = diff(&prevTS, &ts); - printf("fault allocations: %d\n", faultAllocation); - printf("%lld.%.9ld\n", (long long)prevTS.tv_sec, prevTS.tv_nsec); - printf("%lld.%.9ld (%lld)\n", (long long)ts.tv_sec, ts.tv_nsec, d); - mm.reset(); - - //test dataset chache - auto_ptr<chaos::data::cache::DatasetCache> dsCache(new chaos::data::cache::DatasetCache()); - dsCache->addChannel("ch_i32", chaos::DataType::TYPE_INT32); - dsCache->init(NULL); - dsCache->start(); - - - // allocate and start writer thread - //tWriter.reset(new boost::thread(boost::bind(cacheUpdaterI32, dsCache.get()))); - tWriterGroup.create_thread(boost::bind(cacheUpdaterI32, dsCache.get())); - //start garbage thread - tGarbageGroup.create_thread(boost::bind(cacheGarbage, dsCache.get())); - //start all reader thread - for (int idx = 0; idx < READ_THREAD_NUMBER; idx++) { - tReadersGroup.create_thread(boost::bind(cacheReader, dsCache.get())); - } - - boost::this_thread::sleep_for(boost::chrono::seconds(10)); - threadReadExecution = false; - //join on read thread - tReadersGroup.join_all(); - - //stop writer and garbag thread - threadWriteExecution = false; - tGarbageGroup.join_all(); - tWriterGroup.join_all(); - - //deinit all cache - dsCache->stop(); - dsCache->deinit(); - - //test memcached implementation - chaos::data::cache::CacheSettings settings; - - settings.factor = 1.25; - settings.maxbytes = 1 * 1024 * 1024; //default is 64MB - settings.chunk_size = 48; //48; /* space for a modest key and value */ - settings.item_size_max = 1024 * 1024; //1024 * 1024; - settings.evict_to_free = 1; - settings.oldest_live = 0; - settings.use_cas = 1; - settings.preallocation = 0; - auto_ptr<chaos::data::cache::DataCache> fc(new chaos::data::cache::DataCache()); - fc->init(&settings); - fc->start(); - fc->storeItem("key", "value", (int32_t)strlen("value")); - fc->getItem("key", bsize, &buff); - std::cout << (const char *)buff << std::endl; - - fc->storeItem("key", "value2", (int32_t)strlen("value2")); - fc->getItem("key", bsize, &buff); - std::cout << (const char *)buff << std::endl; - - fc->deleteItem("key"); - fc->storeItem("key", "value3", (int32_t)strlen("value3")); - fc->getItem("key", bsize, &buff); - std::cout << (const char *)buff << std::endl; - fc->stop(); - fc->deinit(); - return 0; }