www.pudn.com > allocator.rar > pooled_allocator.cc


// file: pooled_allocator.cc
// author: Marc Bumble
// May 12, 2000
// Memory allocator for shared memory access
// 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.

#include 

namespace pooled_allocator {

  char none[] = "my_x_key";
  unsigned char shmaddr = 0x00000000;
  
  ////////////////////////////////////////////////////////////////////
  //////                    Class Chunk
  ////////////////////////////////////////////////////////////////////
  //////        
  //////        Unit of  pooled memory composed  of multiple elements.
  //////        The  Pool class  defined below  retrieve a  portion of
  //////        UNIX  shared  memory  using  the shared  class.   That
  //////        retrived memory is formated using the class chunk into
  //////        element sized portions.
  //////        
  //////        
  //////        
  ////////////////////////////////////////////////////////////////////


  // constructor
  // constructor
  // elem_size         - element   size    in    bytes.
  // total_chunk_size  - The  chunk is  instantiated in  a  piece of
  //                     memory which is total_chunk_size in bytes.

  // Need to  do some calculatons  of memory sizes to  instantiate the
  // chunk.  The goal is to  determine how many elements can be stored
  // in the chunk, and then setup the space to hold the maximum number
  // of elements:
  //
  //      total_chunk_size = header + bit_vec + elements (1)
  //
  // where total_chunk_size is defined  above, the header is the Chunk
  // overhead or  sizeof(Chunk).  The bit_vec is the  data buffer used
  // by the bit  vector.  The rest of the bit  vector overhead is part
  // of the header or normal chunk overhead.  Finally, elements is the
  // space occupied by the elements stored in the Chunk.
  //
  // Known quantities:
  //
  // total_chunk_size - this is a given parameter, the amount of space
  //                    allocated to hold the chunk.
  //
  // header - sizeof(Chunk), the chunk class overhead.
  //
  // Use equation 1 above to solve for the number of elements:
  //
  //   total_chunk_size = header + (nelem/8 + 1) + (nelem*esize)
  //
  // Where:
  //
  //   nelem - number of elements
  //   esize - size of elements
  //
  // Solve for nelem:
  //
  //   nelem = (8*(chunk - header - 1))/(1 + 8*esize)       (2)
  // 
  
  Chunk::Chunk(const int& elem_size,
	       const int& total_chunk_size,
 	       const int project_id,
	       const int segment_page_number)
    // elem_size - element size in bytes.
    // pg_size   - page size in bytes.

    : element_size(elem_size),
      // see derivation of num_of_elements above equation 2
      num_of_elements((8*(total_chunk_size - sizeof(Chunk) - 1))/(1 + 8*element_size)),
      memory_size(num_of_elements*element_size),
      bit_vec_size((num_of_elements/8) + 1),
      proj_id(project_id),
      segment_page_num(segment_page_number),
      num_of_segment_pages(total_chunk_size/page_size),
      // bit vector monitors num_of_elements elements
      // bit vector is stored after this class, which is
      //    at the address (this + sizeof(Chunk))
      bit_vec(num_of_elements,
	      reinterpret_cast(this)+
	      sizeof(Chunk)) {
    // first_elem_num is initially unknown    
    first_elem_num=-1;
    // set the start of the data segment
    mem = reinterpret_cast(this) +
      sizeof(Chunk) + bit_vec_size;
    prev=0;
    next=0;
  };  // Chunk::Chunk()  constructor

  // copy constructor
  Chunk::Chunk(const Chunk& t)
    : element_size(t.element_size),
      num_of_elements(t.num_of_elements),
      memory_size(t.memory_size),
      bit_vec_size(t.bit_vec_size),
      proj_id(t.proj_id),
      segment_page_num(t.segment_page_num),
      num_of_segment_pages(t.num_of_segment_pages),
      bit_vec(t.bit_vec) {

    first_elem_num=t.first_elem_num;

    mem=reinterpret_cast(this)+sizeof(Chunk)+bit_vec_size;
    for (int i=0; i(this) +
	sizeof(Chunk) +
	bit_vec_size;
      for (int i=0; i(p-lower_bound))/element_size;
    }  // if ((lower_bound<=p)&&(p