text: //
  // memcache.h
  //
  
  #ifndef MEMCACHE_H
  #define MEMCACHE_H
  
  #include "mem.h"
  #include "globals.h"
  
  extern LONG g_lMemCacheMutex;
  
  typedef struct _MEMCACHE
  {
      ULONG uMaxPtrs;
      ULONG iNextFree;
      void *rgPtrs[1]; // 1 or more...
  } MEMCACHE;
  
  MEMCACHE *MemCache_New(ULONG uMaxPtrs);
  
  void MemCache_Delete(MEMCACHE *pMemCache);
  
  //+---------------------------------------------------------------------------
  //
  // MemCache_Add
  //
  //----------------------------------------------------------------------------
  
  inline BOOL MemCache_Add(MEMCACHE *pMemCache, void *pv)
  {
      BOOL fRet = FALSE;
  
      if (InterlockedIncrement(&g_lMemCacheMutex) != 0)
          goto Exit;
  
      if (pMemCache->iNextFree >= pMemCache->uMaxPtrs)
          goto Exit; // cache is full!
  
      pMemCache->rgPtrs[pMemCache->iNextFree++] = pv;
  
      fRet = TRUE;
  
  Exit:
      InterlockedDecrement(&g_lMemCacheMutex);
      return fRet;
  }
  
  //+---------------------------------------------------------------------------
  //
  // MemCache_Remove
  //
  //----------------------------------------------------------------------------
  
  inline void *MemCache_Remove(MEMCACHE *pMemCache)
  {
      void *pv = NULL;
  
      if (InterlockedIncrement(&g_lMemCacheMutex) != 0)
          goto Exit;
  
      if (pMemCache->iNextFree == 0)
          goto Exit;
  
      pv = pMemCache->rgPtrs[--pMemCache->iNextFree];
  
  Exit:
      InterlockedDecrement(&g_lMemCacheMutex);
      return pv;
  }
  
  //+---------------------------------------------------------------------------
  //
  // MemCache_NewOp
  //
  //----------------------------------------------------------------------------
  
  #ifdef DEBUG
  inline void *MemCache_NewOp(MEMCACHE *pMemCache, size_t nSize, const TCHAR *pszFile, int iLine)
  #else
  inline void *MemCache_NewOp(MEMCACHE *pMemCache, size_t nSize)
  #endif
  {
      void *pv = NULL;
  
      if (pMemCache != NULL)
      {
          if (pv = MemCache_Remove(pMemCache))
          {   // Issue: update debug mem track info
              memset(pv, 0, nSize);
          }
      }
  
      if (pv == NULL)
      {
  #ifdef DEBUG
          pv = Dbg_MemAllocClear(nSize, pszFile, iLine);
  #else
          pv = cicMemAllocClear(nSize);
  #endif
      }
  
      return pv;
  }
  
  //+---------------------------------------------------------------------------
  //
  // MemCache_DeleteOp
  //
  //----------------------------------------------------------------------------
  
  inline void MemCache_DeleteOp(MEMCACHE *pMemCache, void *pv)
  {
      if (pMemCache == NULL ||
          !MemCache_Add(pMemCache, pv))
      {
          cicMemFree(pv);
      }
  }
  
  #ifdef DEBUG
  #define DECLARE_CACHED_NEW                                                              \
      void *operator new(size_t nSize, const TCHAR *pszFile, int iLine) { return MemCache_NewOp(_s_pMemCache, nSize, pszFile, iLine); }  \
      void operator delete(void *pv) { MemCache_DeleteOp(_s_pMemCache, pv); }             \
      static _MEMCACHE *_s_pMemCache;
  
  #else // !DEBUG
  #define DECLARE_CACHED_NEW                                                              \
      void *operator new(size_t nSize) { return MemCache_NewOp(_s_pMemCache, nSize); }    \
      void operator delete(void *pv) { MemCache_DeleteOp(_s_pMemCache, pv); }             \
      static _MEMCACHE *_s_pMemCache;
  #endif
  
  #define DECLARE_CACHED_NEW_STATIC(the_class)   \
      MEMCACHE *the_class::_s_pMemCache = NULL;
  
  #endif // MEMCACHE_H
  