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

📄 shared_memory.h

📁 简单的动态内存管理程序源代码
💻 H
📖 第 1 页 / 共 3 页
字号:
// 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 + -