•OT_Classes/TCachedStorage.h

//  TCachedStorage.h - Cached memory  managemnent
// 
// Apple Macintosh Developer Technical Support
// Written by:  Vinne Moscaritolo
//
//  Copyright (work in progress)  Apple Computer, Inc All rights reserved.
//
// You may incorporate this sample code into your applications without
// restriction, though the sample code has been provided "AS IS" and the
// responsibility for its operation is 100% yours.  However, what you are
// not permitted to do is to redistribute the source as "DSC Sample Code"
// after having made changes. If you're going to re-distribute the source,
// we require that you make it clear in the source that the code was
// descended from Apple Sample Code, but that you've made changes.
// 
 
//
//  define your class Tfoo as:
//      class  Tfoo  : public TCachedStorage<Tfoo>
//
 
 
#ifndef _H_CACHEDSTORAGE
#define _H_CACHEDSTORAGE
 
#ifndef VARIABLE_LENGTH_BLOCKS
#define VARIABLE_LENGTH_BLOCKS 0    // Do we support variable length objects..NO NO NO
#endif
 
#include "TList.h"
 
template <class T> class TCachedStorage {
    
public:
    void*   operator new    (size_t size);
    void    operator delete (void* deadObject) { fgCacheList.Enqueue((TLink*) deadObject); };
 
// CLASS VARIABLES
private:
    static  TLifo   fgCacheList;
    static  Boolean fgRegistered;
};
 
template <class T>  TLifo   TCachedStorage<T>::fgCacheList; 
template <class T>  Boolean TCachedStorage<T>::fgRegistered; 
 
// ---------------------------------------------------------------------------
//  TCachedStorage<T>::operator new 
// ---------------------------------------------------------------------------
//  create a TCachedStorage class from cache if possible
// 
//
 
 
template <class T> void* TCachedStorage<T>::operator new(size_t size)
{
    void *newObject;
    
    if(!fgRegistered) fgRegistered++, TStorageManager::Register(&fgCacheList);
    
#if VARIABLE_LENGTH_BLOCKS
     if( size != sizeof( TCachedStorage<T> )  ) return TStorageManager::Allocate(size);  // handle derived classes
#endif      
    if(! (newObject = fgCacheList.Dequeue()) )                              // if we have one cached  on stack
        if(! (newObject = TStorageManager::Allocate(size)))                 // else attempt to get it from heap
            { TStorageManager::Purge();                                     // try to free up some ram
                if(! (newObject = TStorageManager::Allocate(size)))         // one last try
                    DebugStr("\p TCachedStorage -- could not allocate "); } // Lose...
    return newObject;
    }
 
 
//
// TStorageManager - Interrupt safe memory free
//
 
class TStorageManager {
// CLASS METHODS
public:
    static void* Allocate(size_t size)      { return ::OTAllocMem (size); };
    static void  Free(void* deadObject)     { ::OTFreeMem(deadObject); };
    static void  Purge();                   // Purge all Stacks 
 
//private:
    static void  Register(TLifo*);          // register stack to purge
    static void  UnRegister(TLifo*);
 
 
// FINALIZATION CLASS
private:
    class Init
     {
        ~Init();        
        friend class TStorageManager;
    };
 
// CLASS VARIABLES
protected:
    static TList fgPurgeList;               // List of Stacks to purge
    static TStorageManager::Init fgInit;    // class initialisation object
 
};
 
 
#endif