From 12bb4d75fd02691cdabf91d32414a8c61bed0008 Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Tue, 17 Sep 2013 14:23:06 +0200 Subject: [PATCH] Adding shared memory data types --- DataStructures/SharedMemoryFactory.h | 165 +++++++++++++++++++++ DataStructures/SharedMemoryVectorWrapper.h | 96 ++++++++++++ Server/DataStructures/SharedDataType.h | 26 ++++ 3 files changed, 287 insertions(+) create mode 100644 DataStructures/SharedMemoryFactory.h create mode 100644 DataStructures/SharedMemoryVectorWrapper.h create mode 100644 Server/DataStructures/SharedDataType.h diff --git a/DataStructures/SharedMemoryFactory.h b/DataStructures/SharedMemoryFactory.h new file mode 100644 index 000000000..9c908a187 --- /dev/null +++ b/DataStructures/SharedMemoryFactory.h @@ -0,0 +1,165 @@ +/* + open source routing machine + Copyright (C) Dennis Luxen, others 2010 + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU AFFERO General Public License as published by +the Free Software Foundation; either version 3 of the License, or +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +or see http://www.gnu.org/licenses/agpl.txt. + */ + +#ifndef SHARED_MEMORY_FACTORY_H +#define SHARED_MEMORY_FACTORY_H + +#include "../Util/OSRMException.h" +#include "../Util/SimpleLogger.h" + +#include +#include +#include +#include + +#include +#include + +struct OSRMLockFile { + boost::filesystem::path operator()() { + boost::filesystem::path temp_dir = + boost::filesystem::temp_directory_path(); + SimpleLogger().Write(logDEBUG) << "creating lock file in " << temp_dir; + boost::filesystem::path lock_file = temp_dir / "osrm.lock"; + SimpleLogger().Write(logDEBUG) << "locking at " << lock_file; + return lock_file; + } +}; + +class SharedMemory : boost::noncopyable { + + //Remove shared memory on destruction + class shm_remove : boost::noncopyable { + private: + int m_shmid; + bool m_initialized; + public: + void SetID(int shmid) { + m_shmid = shmid; + m_initialized = true; + } + + shm_remove() : m_shmid(INT_MIN), m_initialized(false) {} + + ~shm_remove(){ + if(m_initialized) { + SimpleLogger().Write(logDEBUG) << + "automatic memory deallocation"; + boost::interprocess::xsi_shared_memory::remove(m_shmid); + } + } + + }; + +public: + void * Ptr() const { + return region.get_address(); + } + + template + SharedMemory( + const boost::filesystem::path & lock_file, + const IdentifierT id, + const unsigned size = 0 + ) : key( + lock_file.string().c_str(), + id + ) { + if( 0 == size ){ //read_only + shm = boost::interprocess::xsi_shared_memory ( + boost::interprocess::open_only, + key + ); + region = boost::interprocess::mapped_region ( + shm, + boost::interprocess::read_only + ); + } else { //writeable pointer + //remove previously allocated mem + RemoveSharedMemory(key); + shm = boost::interprocess::xsi_shared_memory ( + boost::interprocess::create_only, + key, + size + ); + region = boost::interprocess::mapped_region ( + shm, + boost::interprocess::read_write + ); + + remover.SetID( shm.get_shmid() ); + SimpleLogger().Write(logDEBUG) << + "writeable memory allocated " << size << " bytes"; + } + } + +private: + static void RemoveSharedMemory( + const boost::interprocess::xsi_key &key + ) { + try{ + SimpleLogger().Write(logDEBUG) << "deallocating prev memory"; + boost::interprocess::xsi_shared_memory xsi( + boost::interprocess::open_only, + key + ); + boost::interprocess::xsi_shared_memory::remove(xsi.get_shmid()); + } catch(boost::interprocess::interprocess_exception &e){ + if(e.get_error_code() != boost::interprocess::not_found_error) { + throw; + } + } + } + + boost::interprocess::xsi_key key; + boost::interprocess::xsi_shared_memory shm; + boost::interprocess::mapped_region region; + shm_remove remover; +}; + +template +class SharedMemoryFactory_tmpl : boost::noncopyable { +public: + template + static SharedMemory * Get( + const IdentifierT & id, + const unsigned size = 0 + ) { + try { + LockFileT lock_file; + if(0 == size && !boost::filesystem::exists(lock_file()) ) { + throw OSRMException("lock file does not exist, exiting"); + } + return new SharedMemory(lock_file(), id, size); + } catch(const boost::interprocess::interprocess_exception &e){ + SimpleLogger().Write(logWARNING) << + "caught exception: " << e.what() << + ", code " << e.get_error_code(); + throw OSRMException(e.what()); + } + }; + +private: + SharedMemoryFactory_tmpl() {} +}; + +typedef SharedMemoryFactory_tmpl<> SharedMemoryFactory; + +#endif /* SHARED_MEMORY_POINTER_FACTORY_H */ diff --git a/DataStructures/SharedMemoryVectorWrapper.h b/DataStructures/SharedMemoryVectorWrapper.h new file mode 100644 index 000000000..0773466d9 --- /dev/null +++ b/DataStructures/SharedMemoryVectorWrapper.h @@ -0,0 +1,96 @@ +/* + open source routing machine + Copyright (C) Dennis Luxen, others 2010 + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU AFFERO General Public License as published by +the Free Software Foundation; either version 3 of the License, or +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +or see http://www.gnu.org/licenses/agpl.txt. + */ + +#ifndef SHARED_MEMORY_VECTOR_WRAPPER_H +#define SHARED_MEMORY_VECTOR_WRAPPER_H + +#include +#include +#include + +#include +#include + +template +class ShMemIterator : public std::iterator { + boost::shared_ptr p; +public: + ShMemIterator(boost::shared_ptr & x) :p(x) {} + ShMemIterator(const ShMemIterator & mit) : p(mit.p) {} + ShMemIterator& operator++() { + ++p; + return *this; + } + ShMemIterator operator++(int) { + ShMemIterator tmp(*this); + operator++(); + return tmp; + } + bool operator==(const ShMemIterator& rhs) { + return p==rhs.p; + } + bool operator!=(const ShMemIterator& rhs) { + return p!=rhs.p; + } + DataT& operator*() { + return *p; + } +}; + +template +class SharedMemoryWrapper { +private: + boost::shared_ptr m_ptr; + std::size_t m_size; + + SharedMemoryWrapper() {}; +public: + SharedMemoryWrapper(const DataT * ptr, std::size_t size) : + m_ptr(ptr), + m_size(size) + { } + + ShMemIterator begin() const { + return ShMemIterator(m_ptr); + } + + ShMemIterator end() const { + return ShMemIterator(m_ptr+m_size); + } + + std::size_t size() const { return m_size; } + + DataT & operator[](const int index) { + BOOST_ASSERT_MSG(index < m_size, "invalid size"); + return m_ptr[index]; + } +}; + +template +class ShMemVector : public + boost::conditional< + SharedMemory, + SharedMemoryWrapper, + std::vector + >::type +{ }; + + +#endif //SHARED_MEMORY_VECTOR_WRAPPER_H diff --git a/Server/DataStructures/SharedDataType.h b/Server/DataStructures/SharedDataType.h new file mode 100644 index 000000000..83cc6da81 --- /dev/null +++ b/Server/DataStructures/SharedDataType.h @@ -0,0 +1,26 @@ +/* + open source routing machine + Copyright (C) Dennis Luxen, others 2010 + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU AFFERO General Public License as published by +the Free Software Foundation; either version 3 of the License, or +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +or see http://www.gnu.org/licenses/agpl.txt. + */ + +#ifndef SHARED_DATA_TYPE_H_ +#define SHARED_DATA_TYPE_H_ + +enum SharedDataType { NAMES_INDEX, NAMES_LIST }; + +#endif /* SHARED_DATA_TYPE_H_ */