Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

VMemPool.H

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 //
00020 // VMemPool.H
00021 // Last modified on Thu Jul 29 10:06:54 EDT 2004 by ken@xorian.net
00022 //      modified on Fri May 26 14:22:38 PDT 2000 by mann
00023 //
00024 // Memory pool for Vesta repository directory structure.  Confined to
00025 // a range of addresses that can be represented in 32 bits.
00026 //
00027 
00028 #ifndef _VMEMPOOL
00029 #define _VMEMPOOL 1
00030 
00031 #include "Basics.H"
00032 #include "SourceOrDerived.H"
00033 #include <assert.h>
00034 #include <fstream>
00035 
00036 // All memory allocated by VMemPool has the following format.
00037 // See VDirChangeable.H for an explanation of the notation.
00038 //
00039 // packed struct VMemPoolBlock {
00040 //     Bit8 clientBits: 4;           // Available to client.
00041 //     Bit8 typeCode: 4;             // Contains the typeCode for this
00042 //                                   //  block, as supplied by the
00043 //                                   //  client at allocation time.
00044 //     Bit8 clientData[];            // Arbitrary data; client must be
00045 //                                   //  able to determine the block's
00046 //                                   //  length by parsing the data. 
00047 // };
00048 
00049 extern "C" void VMemPool_init();
00050 
00051 class VMemPool {
00052   public:
00053     enum typeCode { freeByte = 0, freeBlock, vDirChangeable, vForward,
00054                     vDirEvaluator, vDirImmutable, vAttrib, vDirAppendable,
00055                     maxTypeCodes = 0x10, unspecified };
00056 
00057     // The blocks returned are always aligned to the following
00058     // multiple (must be at least 8 for the Alpha) so that it is safe
00059     // to protect different blocks with different locks.  This will
00060     // cause some space wastage if you allocate objects whose size is
00061     // not a multiple of the alignment.
00062     static int alignmentMask;
00063 
00064     // Allocate a block of memory with typeCode "type".  The first
00065     // byte of the allocated memory contains typeCode.  The caller
00066     // must remember the size of the block, or be able to determine it
00067     // by scanning the block's contents.
00068     //
00069     // Warning: the caller must be holding a lock that prevents
00070     // weeding and checkpointing, such as StableLock,
00071     // VolatileRootLock, or a lock on a volatile subtree.  Otherwise
00072     // the memory might be freed by the garbage collector or moved by
00073     // the checkpointer before the caller gets a chance to put a
00074     // pointer somewhere they will find it!
00075     //
00076     static void* allocate(typeCode type, Bit32 size) throw();
00077 
00078     // Explicitly free a block of memory, not waiting for the next
00079     // garbage collection.  If type is specified, assert that the
00080     // type code is as given; crash if it is not.
00081     static void free(void* addr, Bit32 size,
00082                      typeCode type =unspecified) throw();
00083 
00084     // Retrieve the type of a block.
00085     static typeCode type(void* addr) throw();
00086 
00087     // Because all memory allocated by VMemPool is within a range of
00088     // 2^32 addresses, pointers returned by allocate can be shortened
00089     // to 32 bits and lengthened again without loss of information.
00090     static inline Bit32 shortenPointer(const void* pointer) throw() {
00091         if (pointer == 0)
00092           return 0;
00093         else
00094           return (Bit32) (((Bit8*) pointer) - base + 1);
00095     }
00096     static inline void* lengthenPointer(Bit32 spointer) throw() {
00097         if (spointer == 0)
00098           return (void*) 0;
00099         else
00100           return base + spointer - 1;
00101     }
00102 
00103     // Perform a garbage collection, consisting of one mark phase and
00104     // one sweep phase.  In the mark phase, each registered
00105     // markCallback is invoked once.  A markCallback may be NULL if
00106     // none is needed.  In the sweep phase, the registered
00107     // sweepCallback is invoked once for each allocated block.  The
00108     // sweepCallback sets "size" to the block's size, and returns true
00109     // if the block is still in use.  A sweepCallback must be
00110     // registered for every typeCode that is used in an allocate call.
00111     // Do not register callbacks for freeByte or freeBlock.  The
00112     // rebuildCallback is used in an additional sweep pass that
00113     // rebuilds the DirShortId table.
00114     //
00115     static void gc(ShortIdsFile keepDerivedSid) throw();
00116     typedef void (*markCallback)(void* closure, typeCode type) /*throw ()*/;
00117     typedef bool (*sweepCallback)(void* closure, typeCode type, void* addr,
00118                                   Bit32& size) /*throw ()*/;
00119     typedef void (*rebuildCallback)(void* closure, typeCode type, void* addr,
00120                                     Bit32& size) /*throw ()*/;
00121     static void registerCallbacks(typeCode type,
00122                                   markCallback markcb, void* markcl,
00123                                   sweepCallback sweepcb, void* sweepcl,
00124                                   rebuildCallback rebuildcb, void* rebuildcl)
00125       throw();
00126 
00127     // Write and read checkpoints.  Writing a checkpoint destroys the
00128     // memory pool contents, so the checkpoint must be immediately
00129     // read back or the server must exit.  Volatile directories are
00130     // included in the checkpoint to support immediate rereading.
00131     // When reading a checkpoint, the volatile portion is ignored if
00132     // readVolatile is false.  These routines do not use callbacks as
00133     // with mark and sweep above; instead, they have built-in
00134     // knowledge of the roots (RepositoryRoot, MutableRoot, and
00135     // VolatileRoot).  Reading a checkpoint also rebuilds the
00136     // DirShortId table.
00137     //
00138     // The checkpoint methods that are called by these routines must
00139     // pad each object written to a multiple of 8 bytes, filling at
00140     // the end with freeByte objects (bytes with value 0) if needed.
00141     //
00142     static void writeCheckpoint(std::fstream& ckpt) throw();
00143     static void readCheckpoint(std::fstream& ckpt, bool readVolatile) throw();
00144 
00145   protected:
00146     static Bit8* base;
00147     static void init();
00148 
00149   private:
00150     static Bit32 totalSize, minGrowBy;
00151     static void rebuildDirShortIdTable() throw ();
00152     static void grow(Bit32 growBy) throw();
00153 
00154     friend void VMemPool_init();
00155 };
00156 
00157 #endif //_VMEMPOOL

Generated on Mon May 8 00:48:53 2006 for Vesta by  doxygen 1.4.2