⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shared_memory.h

📁 简单的动态内存管理程序源代码
💻 H
📖 第 1 页 / 共 3 页
字号:
    void decrement_ref_count(void) {--ref_count;}  };  // class map_index_t    ////////////////////////////////////////////////////////////////////  //////           class shared_memory_header  ////////////////////////////////////////////////////////////////////  //////     //////    This class is embedded as  the first element in all shared  //////    memory segments.   It contains information  describing the  //////    state of the allocated memory segment.  This class uses no  //////    memory pointers as the  shared memory segment is mapped to  //////    different  addresses  for  different  processes.   So  all  //////    address values must be relative offsets from the beginning  //////    of the allocated segment.  //////      //////    The shared_memory_header is followed  in memory by the bit  //////    vector which  is used to  keep track of the  shared memory  //////    pages which  have been allocated versus  the shared memory  //////    pages which are free and available to be allocated.  //////      ////////////////////////////////////////////////////////////////////  class shared_memory_header_t {  private:    // This data must be visible to all shared segment users and it is    // stored at the beginning of the shared memory segment        const int num_of_pages;  // within the segment, tracked separately    const int page_size;     // segment size = num_of_pages*page_size +                             //                sizeof(header)    const int proj_id;  // NOTE: proj_id == segment_num    allocator_bit_vector::allocator_bit_vector_t bit_vec;	    const int bit_vec_size;	// size of the bit vector    const int mem_start_offset; // offset in bytes to usable memory                                // mem_start_offset = sizeof(header) +                                //                    sizeof(bit_vec)    const int object_size;	// total    size   including   header,                                // bit_vec, and available space    const int shared_memory_addr; // address of  shared memory segment				  // in memory.    const int shared_memory_size; // total  size  of allocated  shared				  // memory segment.    // Key value used by ftok, same as the alloc_key    char key[name_length];    int header_size;    // Create a reference to retrieve an object index    map_index_t object_index;    locks lock_set;    int ref_count; 		// Used  to  keep  track of  how  many				// objects  are  referencing or  using				// the  shared_memory_header_t object.				// When only one object is referencing				// the  segment,  the  value is  zero.				// When  the last  object  shuts down,				// the locks  object, lock_set is also				// destroyed by teh destructor.  public:    // constructor    // place the bit_vec at the address within the segment    // directly after the shared_memory_header_t    // so the address is from the beginning of this plus    // the size of this.    shared_memory_header_t(int num_of_pages,			   int page_size,			   allocator_key_t alloc_key,			   int shared_mem_addr,			   int sh_mem_size, 			   int proj_id) :// 			   int shmid_val) :      num_of_pages(num_of_pages),      page_size(page_size),      proj_id(proj_id),      bit_vec(num_of_pages,	// keeps track of  pages in shared mem				// segment	      reinterpret_cast<unsigned char*>(this)+	      sizeof(shared_memory_header_t)),      bit_vec_size((num_of_pages/8) + 1),      // mem_start_offset = sizeof(header) + sizeof(bit_vec)      mem_start_offset(sizeof(shared_memory_header_t) +  		       bit_vec_size),	// offset to  usable memory in					// segment      // includes header, bit_vec, and usable memory.      object_size(mem_start_offset +		  num_of_pages*page_size),      shared_memory_addr(shared_mem_addr),      shared_memory_size(sh_mem_size),      object_index(),      lock_set(alloc_key,proj_id) {      strcpy(key,alloc_key);//       shmid=shmid_val;      header_size=sizeof(this);      bit_vec.clear_items(0,num_of_pages);	// page free/allocated list      ref_count = 0;#ifdef DEBUG      std::cerr << __FILE__ << ":" << __LINE__ <<	" shared_memory_header_t()constructor : ref_count : " <<	ref_count << std::endl;#endif    } // constructor        // destructor    virtual ~shared_memory_header_t() {#ifdef DEBUG      std::cerr << __FILE__ << ":" << __LINE__ << " ~shared_memory_header_t()" << std::endl;#endif      lock_set.~locks();    };    // copy constructor    shared_memory_header_t(const shared_memory_header_t& t) :      num_of_pages(t.num_of_pages),      page_size(t.page_size),  //      proj_id(t.proj_id),      bit_vec(t.bit_vec),      bit_vec_size(t.bit_vec_size),      // mem_start_offset = sizeof(header) + sizeof(bit_vec)      mem_start_offset(t.mem_start_offset),	      // includes header, bit_vec, and usable memory.      object_size(t.object_size),      shared_memory_addr(t.shared_memory_addr),      shared_memory_size(t.shared_memory_size),      object_index(t.object_index),      lock_set(t.lock_set) {      strcpy(key,t.key);//       shmid=t.shmid;      header_size=t.header_size;      ref_count = 0;#ifdef DEBUG      std::cerr << __FILE__ << ":" << __LINE__ <<	" shared_memory_header_t()copyconstructor : ref_count : " <<	ref_count << std::endl;#endif    } // copy constructor        // assignment operator    shared_memory_header_t& operator=(const shared_memory_header_t& t) {      if (this != &t) {		// avoid self assignment: t=t 	lock_set=t.lock_set; 	bit_vec=t.bit_vec;	//	bit_vec_size=t.bit_vec_size;	strcpy(key,t.key);// 	shmid=t.shmid;	header_size=t.header_size;	ref_count = 0;#ifdef DEBUG	std::cerr << __FILE__ << ":" << __LINE__ <<	  " shared_memory_header_t<>operator= : ref_count : " <<	  ref_count << std::endl;#endif      }      return *this;    }  // assignment operator    const int get_bit_vec_size() {return bit_vec_size;}//     int get_shmid(void) {return shmid;}    int get_header_size(void) {return header_size;}    int get_proj_id(void) {return proj_id;}//     void set_shmid(int val) {shmid=val;}    void mark_pages(int page_num, int how_many) {bit_vec.mark_items(page_num,how_many);}    void clear_pages(int page_num, int how_many) {bit_vec.clear_items(page_num,how_many);}    int find_free_pages(int pages) {return bit_vec.find_free_items(pages);}    bool assigned(int page_num) {return bit_vec.assigned(page_num);}    int get_page_offset(int page_num);    void get_key(char* val) {strcpy(val,key);}    void set_key(std::string val) {strcpy(key,val.data());}//     // for semaphore locking    void lock(int segment_page_num) {lock_set.lock(segment_page_num);}    void unlock(int segment_page_num) {lock_set.unlock(segment_page_num);}    // for object index information    map_index_t     get_map_index(void) {      // object_index.print();      return object_index;    }    void set_map_index(map_index_t obj_idx) {      object_index=obj_idx;      // object_index.print();    }    void print_lock_set() const {lock_set.print();}    void print() const {      std::cerr << "class shared_memory_header_t<>::print()" << std::endl;      std::cerr << "\tnum_of_pages: " << num_of_pages << std::endl;      std::cerr << "\tpage_size: " << page_size << std::endl;      std::cerr << "\tproj_id: " << proj_id << std::endl;      std::cerr << "\tbit_vec_size: " << bit_vec_size << std::endl;//       std::cerr << "\tshmid: " << shmid << std::endl;      std::cerr << "\theader_size: " << header_size << std::endl;      lock_set.print();    }    // Shared memory synchronize through memory map    int sync(void) {      int return_val = msync((void*) shared_memory_addr,			     (size_t) shared_memory_size,			     MS_SYNC | MS_INVALIDATE);      if (return_val == -1) {	std::clog << "Status: " << __FILE__ << ':' << __LINE__ ;	std::clog << ": shared memory msync: " << strerror(errno) << std::endl;      }      return return_val;    };    const int get_shared_memory_addr() {return shared_memory_addr;}    const int get_shared_memory_size() {return shared_memory_size;}    int get_ref_count() const {return ref_count;}    void set_ref_count(int val) {ref_count=val;}    int get_segment_size(void) {      return sizeof(mem_space::shared_memory_header_t) + // size of header + 	((num_of_pages/8) +1) +          // seg bit_vec + 	num_of_pages*page_size;         // usable memory    }  }; // class shared_memory_header_t  ////////////////////////////////////////////////////////////////////  //////                       Shared Memory  ////////////////////////////////////////////////////////////////////  //////     //////    Shared  Memory  is the  class  interface  to the  specific  //////    operating system.  Class Shared is designed to be embedded  //////    as  an  attribute in  a  higher  level  class.  Shared  is  //////    expected to  be static  such that there  will be  only one  //////    instantiated global copy of this class per process.  //////      //////    The  same shared  memory segment  address space  is mapped  //////    differently  for each process.   Therefore, if  the memory  //////    view is  divided into the individual process  view and the  //////    overall shared memory segment  view which is shared by all  //////    the  processes, the  overall view  has  assigned different  //////    absolute  memory addresses  for the  same  physical memory  //////    space.   So at  the  overall shared  memory level,  memory  //////    addressing must be accomplished by generic numeric offsets  //////    from the  beginning memory address (or  base address).  No  //////    absolute  addressing  should  be  used.  Access  from  the  //////    process  level does  require absolute  addressing methods,  //////    and  within each  process,  the addressing  scheme of  the  //////    shared memory segment should be consistent.  //////      ////////////////////////////////////////////////////////////////////    template<allocator_key_t alloc_key, allocator_addr_t alloc_addr = 0>  class shared {  public:    const int num_of_pages; // number of pages per segment    const int page_size;    // segment_size = num_of_pages*page_size +                            //                sizeof(header)    enum {      num_of_segments=127,  // using the proj_id in ftok, 1-127 pages                            // possible.  Fixed by ftok      bit_vec_size=num_of_segments/8 + 1      // bit vector tracks segments not pages.    };  private:    const int segment_size;    // bit_vec will use bit_vector_buff    allocator_bit_vector::allocator_bit_vector_t bit_vec;    // Store a single memory segment pointer    void* mem_ptr;    // contains pointers to memory segments.  This is only valid on a    // per process basis where the memory pointers are consistent    // static void* buffers[num_of_segments];    // shared memory id from shmget on a per segment basis    // static int shmid[num_of_segments];        // use same bit_vec paradigm for shared memory but allocate memory    // in class  as bit_vector_buff for  its storage.  bit_vec  is not    // allocated in shared memory as the data is redundant and can be    // determined using shmat() to see if anyone else is yet attached    // to the memory.  This structure also keeps track of a collection    // of shared memory segments    static unsigned char bit_vector_buff[bit_vec_size];    typedef std::map<std::string,		    std::pair<void*,struct stat> > mappings_t;    static mappings_t mappings;    // typedef mappings_t::iterator map_it_t;  public:    // constructor    shared(int num_of_pages, int page_size);    // destructor    virtual ~shared();    // copy constructor    shared(const shared<alloc_key, alloc_addr>& t);    // assignment operator    shared<alloc_key, alloc_addr>& operator=(const shared<alloc_key, alloc_addr>& t);    // allocate does  a memory allocate  or if the memory  segment has    // already been  allocated, then it does the  attach function.  If    // proj_id  ==  0, then  allocate  return  the  next free,  unused    // segment.   If 1  <=  proj_id  < 128,  then  allocate returns  a    // pointer to the specified segment.    memory_index_t allocate(const int& proj_id);    //    memory_index_t allocate();    bool free();    void unlink(void) {      // locate all shared memory segments and unlink them      for(mappings_t::iterator it = mappings.begin(); it != mappings.end(); it++) {	// find each existing shared memory segement#ifdef DEBUG	std::clog << __FILE__ << ':' << __LINE__ << ':' <<	  "shared<>::unlink found and unlinking shared segment: " <<	  it->first << std::endl;#endif	shared_memory_header_t* smh =	  static_cast<shared_memory_header_t*>(it->second.first);	smh->~shared_memory_header_t();	shm_unlink(it->first.data());      }  // for(mappings_t::iterator it = mappings.begin(); it != mappings.end(); it++)          }  // void unlink(void)  };  // class shared  ////////////////////////////////////////////////////////////////////////////////  //////                             Shared Memory  ////////////////////////////////////////////////////////////////////////////////  //////     //////    Shared Memory is the class interface to the specific operating system.  //////    This is class is user defined and allows the Arena to generate the   //////    generic segments of memory which it will provide to the allocator.    //////      //////      //////      ////////////////////////////////////////////////////////////////////////////////  // The following variables are static, so there is one copy  // for all objects instantiated within a process//   template<allocator_key_t alloc_key, allocator_addr_t alloc_addr = 0>//   int shared<alloc_key, alloc_addr>::shmid[shared::num_of_segments] = {0};//   template<allocator_key_t alloc_key, allocator_addr_t alloc_addr = 0>//   void* shared<alloc_key, alloc_addr>::buffers[shared::num_of_segments] = {0};  template<allocator_key_t alloc_key, allocator_addr_t alloc_addr = 0>  unsigned char shared<alloc_key, alloc_addr>::bit_vector_buff[shared::bit_vec_size] = {0};  template<allocator_key_t alloc_key, allocator_addr_t alloc_addr = 0>  std::map<std::string,	   std::pair<void*,struct stat> > shared<alloc_key, alloc_addr>::mappings;  // constructor  template<allocator_key_t alloc_key, allocator_addr_t alloc_addr>  shared<alloc_key, alloc_addr>::shared(int number_of_pages, int page_sz) :    num_of_pages(number_of_pages),    page_size(page_sz),    // segment pages have no overhead, they are just space    // NOTE: the bit_vec in segment size is different than    //       the bit_vec local to class shared.  In shared,    //       the bit_vec keeps track of the total number of    //       segments allocated for alloc_key.  The bit_vec    //       used within the segment keeps track of sub-    //       segment pages of memory.    segment_size (sizeof(shared_memory_header_t) + // size of header + 		  ((num_of_pages/8) +1) +          // seg bit_vec + 		  num_of_pages*page_size),         // usable memory    // bit_vec is not allocated in shared memory, but on a    // per process basis.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -