src/Utility/Pool.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 #ifndef POOL_H
00012 #define POOL_H
00013 
00014 // include files
00015 #include <stddef.h>
00016 #ifndef __MWERKS__
00017 #include <memory.h>
00018 #endif
00019 #ifdef IPPL_STDSTL
00020 #include <vector>
00021 using std::vector;
00022 #else
00023 #include <vector.h>
00024 #endif
00025 
00026 class Pool 
00027 {
00028 private:
00029   struct Link { Link *next; };  // Point to the next pointer.
00030   static inline size_t page()       { return 4096-8; }
00031   static inline int blocks_in_page(size_t sz)
00032     {
00033       return (page()>sz)?(page()/sz):1;
00034     }
00035 
00036 public: 
00037 
00038   static inline size_t log2_align() { return 3; }
00039   static inline size_t align()      { return (1<<log2_align()); }
00040   static inline size_t align_mask() { return align()-1; }
00041 
00042   static inline size_t round_to_align(size_t s)
00043     {
00044       if (s)
00045         s = (s & ~align_mask()) + ((s&align_mask())?align():0);
00046       else
00047         s = align();
00048       return s;
00049     }
00050 
00051 
00052   // Null ctor creates an invalid Pool.
00053   Pool();
00054 
00055   // Make a new Pool for objects of a given size.
00056   Pool(size_t);
00057 
00058   // Destroy the Pool.
00059   ~Pool();
00060 
00061   // Allocate a block from the pool.
00062   inline void* alloc()
00063   {
00064     ++outstandingAllocs;        // Record an alloc.
00065     if ( head==0 ) grow();      // If we're out of space, get more.
00066     Link *p = head;             // get the top of the stack.
00067 
00068     // Make the next one the new head of the list.
00069     // We can't do head = p->next since p will soon be treated
00070     // as something other than a Link.  By doing this assignment
00071     // with memcpy, we ensure that p->next will be read before
00072     // it is clobbered. 
00073     memcpy(&head, &p->next, sizeof(head));
00074       
00075     // Return the requested block.
00076     return p;
00077   }
00078 
00079   // Release a block to the pool.
00080   inline void free(void *b)
00081   {
00082     --outstandingAllocs;        // Record a free.
00083     Link *p = (Link*)b;         // Cast this to a Link
00084     p->next = head;             // Makew it point to top of stack.
00085     head = p;                   // Make it the new top.
00086   }
00087 
00088 private:
00089   int outstandingAllocs;        // Number of blocks given to user.
00090   size_t bsize;                 // How big is each block.
00091   size_t nblock;                // How many to allocate at once.
00092   Link *head;                   // The first one.
00093   vector<char*> chunks;         // Currently allocated chunks
00094   void grow();                  // Allocate another chunk and put
00095                                 // its blocks in the free list
00096 };
00097 
00099 
00100 #endif // POOL_H
00101 
00102 /***************************************************************************
00103  * $RCSfile: Pool.h,v $   $Author: adelmann $
00104  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:33 $
00105  * IPPL_VERSION_ID: $Id: Pool.h,v 1.1.1.1 2003/01/23 07:40:33 adelmann Exp $ 
00106  ***************************************************************************/

Generated on Mon Jan 16 13:23:59 2006 for IPPL by  doxygen 1.4.6