?? shared_memory.h
字號:
// file: shared_memory.h// author: Marc Bumble// May 22, 2000// Page memory source for shared memory // Copyright (C) 2000 by Marc D. Bumble// This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License// as published by the Free Software Foundation; either version 2// of the License, or (at your option) 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 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.#ifndef SHARED_MEMORY_H#define SHARED_MEMORY_Hextern "C" {#include <fcntl.h> // for shm_open()#include <sys/mman.h> // for shm_open()#include <sys/types.h> // for shared memory shmget(),shmat(),ftok(),semop#include <unistd.h> // for fork(),getpid(),getppid(), shm_open()#include <sys/sem.h> // for semop}#include <iostream>#include <string>#include <fstream> // for std::ofstream to()#include <sstream> // string stream for stringstream#include <cerrno>#include <cstdlib>// #include <vector>#include <map>#include <alloc_exceptions.h>#include <allocator_bit_vector.h>#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)/* union semun is defined by including <sys/sem.h> */#else/* according to X/OPEN we have to define it ourselves */union semun { int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ unsigned short int *array; /* array for GETALL, SETALL */ struct seminfo *__buf; /* buffer for IPC_INFO */};#endifnamespace mem_space {// enum allocator_t {sharedpooled, persistentpooled}; enum {name_length=512}; // key string for ftok(), the filename typedef const char* allocator_key_t; // address process uses to attach to shared memory typedef const char* allocator_addr_t; // typedef const char* object_key_t; //////////////////////////////////////////////////////////////////// ////// Memory Locks //////////////////////////////////////////////////////////////////// ////// ////// Locks are mutual exclusion locks used to protect process ////// from writing simultaneously to shared memory. Each ////// allocator will get one semaphore set, and then with that ////// semaphore set, each chunk will individual elements from ////// that semaphore set. So each chunk is has access to the ////// semid and the semnum. A semid is common for all chunks ////// within a given allocator, and then each of the allocator's ////// chunks will have its own individual semnum which indicates ////// which semaphore in the semid array. ////// //////////////////////////////////////////////////////////////////// class locks { enum { num_of_arrays=128, num_in_array=250 }; int semid; public: // constructor locks(const mem_space::allocator_key_t& alloc_key, const int& proj_id); // destructor virtual ~locks(); // copy constructor locks(const locks& t); // assignment operator locks& operator=(const locks& t); // equality operator bool operator==(const locks& t); int get_num_of_arrays() {return num_of_arrays;} int get_num_in_array() {return num_in_array;} void lock(int semnum); void unlock(int semnum); void print() const; }; // class locks //////////////////////////////////////////////////////////////////////////////// ////// Class Memory_Index //////////////////////////////////////////////////////////////////////////////// ////// ////// Class Memory_Index is just an aggregation of information ////// about shared memory segments. This class is designed to ////// be passed back and forth as a parameter to carry ////// information. ////// ////// memory_ptr - a pointer to the beginning of the shared ////// memory segment ////// segment_num - the segment number ////// initialized - whether or not the segment is already in use ////// and initialized. ////// //////////////////////////////////////////////////////////////////////////////// class memory_index_t { void* memory_ptr; // pointer to returned memory, // address.// void* chunklist_ptr; // pointer to chunklist for an object.// // Needed by an attaching process// // which must make sure that its// // allocators point to the correct// // chunklist. char key[name_length]; // alloc_key used to retrieve shared // memory segment int proj_id; // shared memory number for this alloc // key. proj_id == segment_num bool initialized; // false if only one attached to // memory true if more than one // process attached int segment_page_num; // start page within shared memory // segment where chunk is located int element_offset; // offset from start of chunk to // element number int global_starting_element_num; // memory starts at element number. public: // constructor // memory_index_t(void* mem_ptr, int buff_num, bool init) { memory_index_t(void* mem_ptr, int proj_id_val, bool init) { memory_ptr=mem_ptr;// chunklist_ptr=0; for (int i=0; i < name_length; i++) key[i]=0; // proj_id identifies which segment within the series specified // by the alloc_key proj_id=proj_id_val; // proj_id == segment number initialized=init; // segment_page_num identifies which page within a given segment // Chunks are allocated on inter segment page boundaries. segment_page_num=-1; // page number within shared mem segment element_offset=-1; global_starting_element_num=-1; } memory_index_t(void* p, char* path_name, int project_id, int shared_mem_page_num, int elem_offset, int global_start_elem_num) { memory_ptr=p;// chunklist_ptr=0; strcpy(key,path_name); proj_id=project_id; initialized=true; segment_page_num=shared_mem_page_num; element_offset=elem_offset; global_starting_element_num=global_start_elem_num; } memory_index_t(void) { // initialize with null data memory_ptr=0;// chunklist_ptr=0; // memset(key,0,name_length); proj_id=-1; initialized=false; segment_page_num=-1; element_offset=-1; global_starting_element_num=-1; } // destructor virtual ~memory_index_t() {}; // copy constructor memory_index_t(const memory_index_t& t) { memory_ptr=t.memory_ptr;// chunklist_ptr=t.chunklist_ptr; proj_id=t.proj_id; initialized=t.initialized; strcpy(key,t.key); segment_page_num=t.segment_page_num; element_offset=t.element_offset; global_starting_element_num=t.global_starting_element_num; } // assignment operator memory_index_t& operator=(const memory_index_t& t) { if (this != &t) { // avoid self assignment: t=t memory_ptr=t.memory_ptr;// chunklist_ptr=t.chunklist_ptr; proj_id=t.proj_id; initialized=t.initialized; strcpy(key,t.key); segment_page_num=t.segment_page_num; element_offset=t.element_offset; global_starting_element_num=t.global_starting_element_num; } return *this; } void* get_memory_ptr(void) {return memory_ptr;} void set_memory_ptr(void* val) {memory_ptr=val;}// void* get_chunklist_ptr(void) {return chunklist_ptr;}// void set_chunklist_ptr(void* val) {chunklist_ptr=val;} int get_proj_id(void) {return proj_id;}// int get_segment_num(void) {return proj_id;} bool get_initialized(void) {return initialized;} void set_proj_id(int val) {proj_id=val;} void set_initialized(bool val) {initialized=val;} void get_key(char* output) {strcpy(output,key);} void set_key(char* input) {strcpy(key,input);} void set_segment_page_num(int val) {segment_page_num=val;} int get_segment_page_num() {return segment_page_num;} void set_element_offset(int val) {element_offset=val;} int get_element_offset() {return element_offset;} void set_global_starting_element_num(int val) {global_starting_element_num=val;} int get_global_starting_element_num() {return global_starting_element_num;} void print() const { std::clog << "Print: class memory_index_t() object:" << std::endl; std::clog << "\tmemory_ptr: " << memory_ptr << std::endl; std::clog << "\tkey: " << key << std::endl; std::clog << "\tproj_id: " << proj_id << std::endl; std::clog << "\tinitialized: " << initialized << std::endl; std::clog << "\tsegment_page_num: " << segment_page_num << std::endl; std::clog << "\telement_offset: " << element_offset << std::endl; std::clog << "\tglobal_starting_element_num: " << global_starting_element_num<< std::endl; } }; // class memory_index_t //////////////////////////////////////////////////////////////////// ////// Class map_index_t //////////////////////////////////////////////////////////////////// ////// ////// Class map_index_t is used to store and retrieve ////// pointers to chunk lists. 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 as the original allocator in ////// the original process. ////// //////////////////////////////////////////////////////////////////// class map_index_t : public memory_index_t { private: void* char_chunklist; void* map_pr_chunklist; void* map_chunklist; void* container_chunklist; void* object_chunklist; pid_t creator_pid; int ref_count; // How many process refer to this object? public: // constructor map_index_t(memory_index_t obj_idx, void* str_chk_list, void* map_pr_chk_list, void* map_chk_list, void* con_chk_list, void* obj_chk_list, pid_t pid) : memory_index_t(obj_idx), char_chunklist(str_chk_list), map_pr_chunklist(map_pr_chk_list), map_chunklist(map_chk_list), container_chunklist(con_chk_list), object_chunklist(obj_chk_list), creator_pid(pid){ ref_count=0; }; // constructor map_index_t(memory_index_t mem_idx) : memory_index_t(mem_idx) { char_chunklist=0; map_pr_chunklist=0; map_chunklist=0; container_chunklist=0; object_chunklist=0; creator_pid=0; ref_count=0; } // constructor map_index_t(void) : memory_index_t() { char_chunklist=0; map_pr_chunklist=0; map_chunklist=0; container_chunklist=0; object_chunklist=0; creator_pid=0; ref_count=0; } // destructor virtual ~map_index_t() { } // copy constructor map_index_t(const map_index_t& t) : memory_index_t(t), char_chunklist(t.char_chunklist), map_pr_chunklist(t.map_pr_chunklist), map_chunklist(t.map_chunklist), container_chunklist(t.container_chunklist), object_chunklist(t.object_chunklist), creator_pid(t.creator_pid) { ref_count=t.ref_count; } // assignment operator map_index_t& operator=(const map_index_t& t) { // Shows example of superclass assignment if (this != &t) { // avoid self assignment: t=t memory_index_t::operator=((memory_index_t&) t); // do superclass // assignment first. char_chunklist=t.char_chunklist; map_pr_chunklist=t.map_pr_chunklist; map_chunklist=t.map_chunklist; container_chunklist=t.container_chunklist; object_chunklist=t.object_chunklist; creator_pid=t.creator_pid; ref_count=t.ref_count; } return *this; } void* get_char_chunklist(void) {return char_chunklist;} void set_char_chunklist(void* val) {char_chunklist=val;} void* get_map_pr_chunklist(void) {return map_pr_chunklist;} void set_map_pr_chunklist(void* val) {map_pr_chunklist=val;} void* get_map_chunklist(void) {return map_chunklist;} void set_map_chunklist(void* val) {map_chunklist=val;} void* get_container_chunklist(void) {return container_chunklist;} void set_container_chunklist(void* val) {container_chunklist=val;} void* get_object_chunklist(void) {return object_chunklist;} void set_object_chunklist(void* val) {object_chunklist=val;} pid_t get_creator_pid(void) {return creator_pid;} void set_creator_pid(pid_t val) {creator_pid=val;} const int get_ref_count(void) {return ref_count;} void increment_ref_count(void) {ref_count++;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -