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