📄 pooled_allocator.h
字号:
template<class T, mem_space::allocator_key_t alloc_key, mem_space::allocator_addr_t alloc_addr> mem_space::memory_index_t Pool_alloc<T, alloc_key, alloc_addr>::allocate_with_index(size_type n) {#ifdef SHARED_MEMORY_MESG std::cerr << "allocate: " << n << " objects ********\n";#endif return mem.alloc(n); } //////////////////////////////////////////////////////////////////// ////// ////// Memory de-allocation starts here ////// //////////////////////////////////////////////////////////////////// template<class T, mem_space::allocator_key_t alloc_key, mem_space::allocator_addr_t alloc_addr> void Pool_alloc<T, alloc_key, alloc_addr>::deallocate(pointer p, size_type n) { if (n!=0) { mem.free(reinterpret_cast<unsigned char*>(p),n); return; } } ///////////////////////////////////////////////////////////////////////////// ////// Class Multi_Process_Pool_alloc ///////////////////////////////////////////////////////////////////////////// ////// ////// This class provide the generic allocator interface to the ////// outside world. ////// ////// ///////////////////////////////////////////////////////////////////////////// // Define template type parameters as follows // Container - The type of container used to store the objects, // like a map, list, set, etc. // Object - The type of object to be allocated. (ie the // allocator will hold ints) // alloc_key - the string key used to identify the // shared memory segment. // container_key - the string key used to identify the container. // alloc_addr - addr requested to place shared memory segment // becomes in shmaddr in shmat() call extern char none[]; extern unsigned char shmaddr; template<class Container, class Object, mem_space::allocator_key_t alloc_key, mem_space::allocator_key_t container_key = none, mem_space::allocator_addr_t alloc_addr = shmaddr> class Multi_Process_Pool_alloc : public Pool_alloc<Object, alloc_key, alloc_addr> { private: // map of a string index name vs. the block number in memory // can not save an actual pointer to the object, need to save // the block numbers which are really offsets into the block. // physical memory. Address vary across processes, so one // can not just save a physical memory addres. typedef Pool_alloc<char, alloc_key, alloc_addr> char_allocator_t; typedef std::basic_string<char, std::char_traits<char>, char_allocator_t> alloc_string_t;// // first = container's allocator chunk list// // second = contained objects' allocator chunk list// typedef std::pair<Chunk*,Chunk*> container_object_pr_t;// typedef std::pair<mem_space::memory_index_t,// container_object_pr_t> container_info_pair_t;// typedef std::pair<alloc_string_t,// container_info_pair_t> map_pair_t; typedef std::pair<alloc_string_t, mem_space::map_index_t> map_pair_t;// typedef std::pair<alloc_string_t,// mem_space::memory_index_t> map_pair_t; typedef Pool_alloc<map_pair_t, alloc_key, alloc_addr> map_pair_allocator_t; struct ltstr { bool operator()(const alloc_string_t s1, const alloc_string_t s2) const { return (s1 < s2); } };// typedef std::map<alloc_string_t,// container_info_pair_t,// ltstr,// map_pair_allocator_t> map_t; typedef std::map<alloc_string_t, mem_space::map_index_t, ltstr, map_pair_allocator_t> map_t; // map allocator used to instantiate reference map in constructor typedef Pool_alloc<map_t, alloc_key, alloc_addr> map_allocator_t; // map pointer to the index map initialized in the constructor map_t* map_p; // Also need a special allocator to allocate the Container in // shared memory. The container is created in shared memory to // allow multiple processes to easily use and share it. typedef Pool_alloc<Container, alloc_key, alloc_addr> container_allocator_t; typedef Pool_alloc<Object, alloc_key, alloc_addr> object_allocator_t; // keep track of all containers allocated by this object. If this // class allocated the object, then this class should destroy the // object during the destructor call. // For all objects allocated in shared memory, instantiate an // allocator which will be used to set the Chunk list pointer for // that allocator. The Chunk list is stored in the allocator's // Pool class as a static attribute. Attaching classes must first // initialize their chunk list to point to the correct address in // shared memory so that these attaching allocators can access the // same objects on the chunk list. // The following three allocators are needed just for the index map // Map index string allocator char_allocator_t char_alloc; // Map stored pair allocator map_pair_allocator_t map_pr_alloc; // Map container allocator map_allocator_t map_alloc; // The next two allocators are required by the stored containers container_allocator_t container_alloc; object_allocator_t object_alloc; public: typedef Object* pointer; typedef const Object* const_pointer; typedef size_t size_type; // constructor Multi_Process_Pool_alloc(); // destructor// virtual ~Multi_Process_Pool_alloc() throw() {}; virtual ~Multi_Process_Pool_alloc() throw(); // copy constructor Multi_Process_Pool_alloc(const Multi_Process_Pool_alloc< Container, Object, alloc_key, container_key, alloc_addr>& t) : char_alloc(t.char_alloc), map_pr_alloc(t.map_pr_alloc), map_alloc(t.map_alloc), container_alloc(t.container_alloc), object_alloc(t.object_alloc) { map_p = t.map_p; }; // copy constructor // assignment operator Multi_Process_Pool_alloc<Container, Object, alloc_key, container_key, alloc_addr>& operator=(const Multi_Process_Pool_alloc<Container, Object, alloc_key, container_key, alloc_addr>& t) { if (this != &t) { // avoid self assignment: t=t map_p = t.map_p; } // if (this != &t) return *this; }; // assignment operator Container* attach(void); mem_space::map_index_t get_map_index(void) { return mem.get_map_index(); }; // get_map_index(void) void set_map_index(mem_space::map_index_t mem_obj) { mem.set_map_index(mem_obj); }; // get_map_index(void) int get_proj_id() { mem_space::map_index_t mem_idx = mem.get_map_index(); return mem_idx.get_proj_id(); } int get_segment_page_num() { mem_space::map_index_t mem_idx = mem.get_map_index(); return mem_idx.get_segment_page_num(); } void lock(int segment_num, int segment_page_num) { // lock access to the shared memory container mem.lock(segment_num,segment_page_num); } void unlock(int segment_num, int segment_page_num) { // lock access to the shared memory container mem.unlock(segment_num,segment_page_num); } Chunk* get_chunks_list(void) { // return a pointer to the chunk list return mem.get_chunks_list(); } void set_chunks_list(Chunk* chunks) { // set the pointer to the chunks list mem.set_chunks_list(chunks); return; } void shutdown(void) { mem.shutdown(); return; } }; // class Multi_Process_Pool_alloc //////////////////////////////////////////////////////////////////// ////// ////// Multi_Process_Pool_alloc<Container<>::attach() ////// //////////////////////////////////////////////////////////////////// ////// ////// Allows the user to attach to the container object ////// instantiated in shared memory. This method gives the user ////// access to the container class. Returns a pointer to the ////// container object if OK or 0 on error. ////// //////////////////////////////////////////////////////////////////// template<class Container, class Object, mem_space::allocator_key_t alloc_key, mem_space::allocator_key_t container_key, mem_space::allocator_addr_t alloc_addr> Container* Multi_Process_Pool_alloc<Container, Object, alloc_key, container_key, alloc_addr>::attach(void) { // first, attempt to find the container key typename map_t::iterator it = map_p->find(container_key); if (it != map_p->end()) { // Set the container's chunklist to point to the correct chunks Chunk* container_chunklist = static_cast<Chunk*>(it->second.get_container_chunklist()); container_alloc.set_chunks_list(container_chunklist); // Set the objects' chunklist to point to the correct chunks Chunk* object_chunklist = static_cast<Chunk*>(it->second.get_object_chunklist()); object_alloc.set_chunks_list(object_chunklist); Chunk* char_chunklist = static_cast<Chunk*>(it->second.get_char_chunklist()); char_alloc.set_chunks_list(char_chunklist); // indicate that we are now attached it->second.increment_ref_count();#ifdef DEBUG std::clog << __FILE__ << ':' << __LINE__ << ':' << "Multi_Process_Pool_alloc<>::attach() ref_count: " << it->second.get_ref_count() << std::endl;#endif // found container, return pointer to requested object return static_cast<Container*>(it->second.get_memory_ptr()); } else { std::clog << "Error: " << __FILE__ << ':' << __LINE__ ; std::clog << ": Multi_Process_Pool_alloc<>::attach(): Container key " << container_key << " not found." << std::endl; } return 0; } //////////////////////////////////////////////////////////////////// ////// ////// Multi_Process_Pool_alloc<>::Multi_Process_Pool_alloc() ////// ////// constructor ////// ////// First the constructor determines from the ////// get_map_index() call whether or not the allocator has ////// been initialized for this shared memory segment. If the ////// segment created as opposed to just opened, then the ////// lookup map needs to be initialized. The map itself needs ////// to be instantiated in the shared memory segment. ////// ////// After establishing the the lookup map now exists, the ////// class needs to determine whether or not the particular ////// container class that the allocator was called to work ////// with exists yet in shared memory. If not, this class ////// needs to instantiate that class and register it in the ////// lookup map for later retrieval. ////// ////// ////// //////////////////////////////////////////////////////////////////// // constructor template<class Container, class Objec
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -