Adding shared memory data types
This commit is contained in:
		
							parent
							
								
									d9e3c43c91
								
							
						
					
					
						commit
						da277d9816
					
				
							
								
								
									
										165
									
								
								DataStructures/SharedMemoryFactory.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								DataStructures/SharedMemoryFactory.h
									
									
									
									
									
										Normal file
									
								
							| @ -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 <boost/noncopyable.hpp> | ||||||
|  | #include <boost/filesystem.hpp> | ||||||
|  | #include <boost/interprocess/mapped_region.hpp> | ||||||
|  | #include <boost/interprocess/xsi_shared_memory.hpp> | ||||||
|  | 
 | ||||||
|  | #include <algorithm> | ||||||
|  | #include <exception> | ||||||
|  | 
 | ||||||
|  | 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<typename IdentifierT > | ||||||
|  | 		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 LockFileT = OSRMLockFile> | ||||||
|  | class SharedMemoryFactory_tmpl : boost::noncopyable { | ||||||
|  | public: | ||||||
|  | 	template<typename IdentifierT > | ||||||
|  | 	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 */ | ||||||
							
								
								
									
										96
									
								
								DataStructures/SharedMemoryVectorWrapper.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								DataStructures/SharedMemoryVectorWrapper.h
									
									
									
									
									
										Normal file
									
								
							| @ -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 <boost/assert.hpp> | ||||||
|  | #include <boost/shared_ptr.hpp> | ||||||
|  | #include <boost/type_traits.hpp> | ||||||
|  | 
 | ||||||
|  | #include <iterator> | ||||||
|  | #include <vector> | ||||||
|  | 
 | ||||||
|  | template<typename DataT> | ||||||
|  | class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT> { | ||||||
|  |     boost::shared_ptr<DataT> p; | ||||||
|  | public: | ||||||
|  |     ShMemIterator(boost::shared_ptr<DataT> & 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<typename DataT> | ||||||
|  | class SharedMemoryWrapper { | ||||||
|  | private: | ||||||
|  |     boost::shared_ptr<DataT> m_ptr; | ||||||
|  |     std::size_t m_size; | ||||||
|  | 
 | ||||||
|  |     SharedMemoryWrapper() {}; | ||||||
|  | public: | ||||||
|  |     SharedMemoryWrapper(const DataT * ptr, std::size_t size) : | ||||||
|  |         m_ptr(ptr), | ||||||
|  |         m_size(size) | ||||||
|  |     { } | ||||||
|  | 
 | ||||||
|  |     ShMemIterator<DataT> begin() const { | ||||||
|  |         return ShMemIterator<DataT>(m_ptr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ShMemIterator<DataT> end() const { | ||||||
|  |         return ShMemIterator<DataT>(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<typename DataT, bool SharedMemory = false> | ||||||
|  | class ShMemVector : public | ||||||
|  |     boost::conditional< | ||||||
|  |         SharedMemory, | ||||||
|  |         SharedMemoryWrapper<DataT>, | ||||||
|  |         std::vector<DataT> | ||||||
|  |     >::type | ||||||
|  | { }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #endif //SHARED_MEMORY_VECTOR_WRAPPER_H
 | ||||||
							
								
								
									
										26
									
								
								Server/DataStructures/SharedDataType.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Server/DataStructures/SharedDataType.h
									
									
									
									
									
										Normal file
									
								
							| @ -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_ */ | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user