// ***********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
// ***********************************************************************
// -*-C++-*-
// ***********************************************************************
//
// File:         NAMemory.cpp
// Description:  The implementation of NAMemory classes
//
//
// Created:      12/13/96
// Language:     C++
//
//
// ***********************************************************************
//

// -----------------------------------------------------------------------
//  In July, 2006 replaced the allocation routines in this file 
//  with routines from the public domain malloc from Doug Lea. The Doug
//  Lea allocator is a better performer than the previous allocator and
//  prevents some of the bad memory fragmentation problems that existed
//  in the previous allocator.  For detailed information about the Doug
//  Lea allocator, do an Internet search on "Doug Lea malloc".
//
//  Most of the structures and function names in Doug Lea's allocator
//  are renamed to fit into the existing SQL/MX memory allocation
//  framework.  Most of the algorithms are the same, but are converted
//  from C functions and macros to C++ member functions that are often
//  inlined.
// -----------------------------------------------------------------------

#include <fstream>

#include <errno.h>
#include "seabed/fs.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>

#include "str.h"
#include "ComSpace.h"

#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>     // For mmap support
#include <seabed/ms.h>

#ifdef TRACE_DP2_MALLOCS  // Only works for NT.
#include <fstream>
#endif

#include "NAError.h"
#include "HeapLog.h"
#include "Platform.h"
#include "NAAssert.h"

#include "ComRtUtils.h"
#include "StmtCompilationMode.h"

#ifdef _DEBUG
//-------------------------------------------------------------------------//
// Using env variable TRACE_ALLOC_SIZE to record the call stacks when a 
// given size of memory block was allocated but not de-allocated later.
// The call stacks can be dumped to a file with name given by env variable
// TRACE_ALLOC_SIZE appended by the process id when the heap is destructed.
//
// The tracing/logging is done via backtrace() and backtrace_symbols()
// calls. The idea is when a specific size (specified by TRACE_ALLOC_SIZE)
// is intercepted at allocation, use backtrace() and backtrace_symbols()
// in saveTrafStack() to get the call stack at the time. The stack info is
// saved to a list in the heap. When such block is freed, the stack info of
// that block will be removed from the list. At the time when the heap is
// to be destroyed, it dumps whatever left in the list via dumpTrafStack()
// to a file or terminal.
//
// This can be combined with a memory debug method that detects memory
// overflow (set the env MEMDEBUG to 2, see checkForOverFlow()). Once
// memory overflow is found, use this tracing method to find where the
// allocation was done and check if the allocation is adequate.
//
// Note that env MEMDEBUG should not be set to 2 when tracing the
// allocation of specified size because the user specified size would
// be different comparing to the allocated size due to extra bytes needed
// for block overflow checking.
//
// As we may delete the entire heap without deallocating each individual
// block we ever allocated for some heaps, the trace file may contains
// blocks that are ok not to be explicitly deleted. One needs to separate
// these from the real issues.
//
// Limitation: we don't track allocations for blocks greater than the
// INT_MAX
//
// All related code are in common/NAMemory.h, common/NAMemory.cpp (this file),
// common/ComRtUtils.h, and common/ComRtUtils.cpp
//
// Todos:
//   1) Re-enabling Setting memory block to 0xfa after allocates and to 0xfc
//      after de-allocates when env MEMDEBUG is set to 2
//
//   2) Ensure existing memory debug methods specified by env MEMDEBUG
//      still work in multi-threaded environment
//-------------------------------------------------------------------------//
// static THREAD_P UInt32 TraceAllocSize = 0; ** defined in common/ComRtUtil.h
#endif // _DEBUG

const  UInt32 deallocTraceEntries = 4096;
struct DeallocTraceEntry
{
  void * begin_;
  void * end_;
};
UInt32 THREAD_P deallocTraceIndex = deallocTraceEntries - 1, deallocCount = 0;
THREAD_P DeallocTraceEntry (*deallocTraceArray)[deallocTraceEntries] = 0;


#include "NAMemory.h"
#ifdef _DEBUG
#include "Collections.h"
#endif // _DEBUG

class NAMutex
{
  bool threadSafe_;
  pthread_mutex_t *mutex_;
public:
  // Do not implement a default constructor. This will generate a link
  // error if anyone tries to call it.
  NAMutex();

  NAMutex(bool threadSafe, pthread_mutex_t *mutex)
    : threadSafe_(threadSafe),
      mutex_(mutex)
  {
    if (threadSafe_)
    {
      int rc = pthread_mutex_lock(mutex_);
      assert(rc == 0);
    }
  }
  ~NAMutex()
  {
    if (threadSafe_)
    {
      int rc = pthread_mutex_unlock(mutex_);
      assert(rc == 0);
    }
  }
};


#include "logmxevent.h"

#define NO_MERGE        0x0
#define BACKWARD_MERGE  0x1
#define FORWARD_MERGE   0x2

#include "logmxevent.h"

extern short getRTSSemaphore();     // Functions implemented in SqlStats.cpp
extern void releaseRTSSemaphore();
extern NABoolean checkIfRTSSemaphoreLocked();
extern void updateMemStats();
extern SB_Phandle_Type *getMySsmpPhandle();

//CollHeap *CTXTHEAP__ = NULL;     // a global, set by CmpContext ctor and used by
	              		 // Collections.cpp allocate method
const size_t DEFAULT_NT_HEAP_INIT_SIZE      = 524288; 
const size_t DEFAULT_NT_HEAP_MAX_SIZE       = (size_t)-1; // by default, heaps have no max size
const size_t DEFAULT_NT_HEAP_INCR_SIZE      = 524288;

// MIN_MMAP_ALLOC_SIZE defines the minimum user size that will be used to
// allocate a NABlock using mmap().
const size_t MIN_MMAP_ALLOC_SIZE = 524288;

// Ignore all HEAPLOG stuff if MUSE
#if defined(MUSE)
#undef HEAPLOG_ON
#undef HEAPLOG_OFF
#undef HEAPLOG_REINITIALIZE
#undef HEAPLOG_ADD_ENTRY
#undef HEAPLOG_DELETE_ENTRY
#define HEAPLOG_ON()
#define HEAPLOG_OFF()
#define HEAPLOG_REINITIALIZE(a)
#define HEAPLOG_ADD_ENTRY(a, b, c, d)
#define HEAPLOG_DELETE_ENTRY(a, b)
#endif 

// ****************************************************************************
// Numeric constants that are local to this file
// ****************************************************************************
const short  NA_FIRST_NONPRIV_SEG_ID        = 1600;
const short  NA_FIRST_IPC_SEG_ID            = 2150;
const size_t MEGABYTE                       = 1024 * 1024;
const size_t MAXFLATSEGSIZE                 = 128 * 1024 * 1024;
const size_t DEFAULT_THRESHOLD_BLOCK_COUNT  = 10;
const size_t DEFAULT_MAX_INCREMENT          = 4194304;

#if defined (NA_YOS) || defined (NA_YOS_SIMULATION)
#define FRAG_BYTE_ALIGN 16
#else
#define FRAG_BYTE_ALIGN 8
#endif
#define FRAG_ALIGN_MASK (FRAG_BYTE_ALIGN - 1)

#define HEAPFRAGMENT_SIZE sizeof(NAHeapFragment)
#define FRAGMENT_OVERHEAD sizeof(size_t)
#define MIN_FRAGMENT_SIZE ((HEAPFRAGMENT_SIZE + FRAG_ALIGN_MASK) & ~FRAG_ALIGN_MASK)

// PAD_REQUEST is used to calculated the needed fragment size based on
// a requested user size.  The "sizeof(size_t)" is added to the requested
// size to account for the "head_" field in the NAHeapSegment, and the
// sum is rounded up to the next byte aligned boundary (of either 8 or 16).
#define PAD_REQUEST(req) (((req) + sizeof(size_t) + FRAG_ALIGN_MASK) \
                          & ~FRAG_ALIGN_MASK)

// ALIGN_OFFSET is used to determine the alignment of the first fragment
// given the memory address A.  The memory address A is passed from the caller
// as the first location that memory could start.  If necessary, ALIGN_OFFSET
// will return a value that indicates how many additional bytes are needed
// to cause the memory to be aligned properly.
#define ALIGN_OFFSET(A) \
   ((((size_t)(A) & FRAG_ALIGN_MASK) == 0)? 0 :\
    ((FRAG_BYTE_ALIGN - ((size_t)(A) & FRAG_ALIGN_MASK)) & FRAG_ALIGN_MASK))

#define BLOCK_OVERHEAD (sizeof(NABlock) + 2 * sizeof(size_t))

#define MAX_REQUEST    (0x7fffffffffffff - FRAG_ALIGN_MASK - FRAGMENT_OVERHEAD)
#define MIN_REQUEST    (MIN_FRAGMENT_SIZE - FRAGMENT_OVERHEAD - 1)
#define SMALLBIN_SHIFT 3
#define TREEBIN_SHIFT  8

#define MIN_LARGE_SIZE (1 << TREEBIN_SHIFT)
#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - 1)
#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - FRAG_ALIGN_MASK - FRAGMENT_OVERHEAD)
#define MAX_SIZE_T     (~(size_t)0)
#define SIZE_T_BITSIZE (sizeof(size_t) << 3)

#define CMFAIL ((char*)(MAX_SIZE_T))

// ****************************************************************************
// Some helper macros from Doug Lea's malloc.

#define MIN_SMALL_INDEX     (small_index(MIN_FRAGMENT_SIZE))

// addressing by index. See above about smallbin repositioning

#if ( defined(_DEBUG) || defined(NSK_MEMDEBUG) )  
#define RTCHECK(e)                  (e)
#define CORRUPTION_ERROR_ACTION     assert(0)
#define USAGE_ERROR_ACTION          assert(0)
#define allocDebugProcess(P, S)     HEAPLOG_ADD_ENTRY(P->getMemory(), \
                                       (Lng32)userSize, heapID_.heapNum, \
                                       getName()); \
                                    if (debugLevel_) doAllocDebugProcess(P,S);
#define deallocDebugProcess(P)      if (debugLevel_) doDeallocDebugProcess(P)
#define checkFreeFragment(P)        doCheckFreeFragment(P)
#define checkInuseFragment(P)       doCheckInuseFragment(P)
#define checkTopFragment(P)         doCheckTopFragment(P)
#define checkMallocedFragment(P,N)  doCheckMallocedFragment(P,N)
#define checkMallocState()          doCheckMallocState()
#else
// If debugging is not turned on, then don't do any verification
#define RTCHECK(e)                  (1)
#define CORRUPTION_ERROR_ACTION
#define USAGE_ERROR_ACTION
#define allocDebugProcess(P, S)
#define deallocDebugProcess(P)
#define checkFreeFragment(P)
#define checkInuseFragment(P)
#define checkTopFragment(P)
#define checkMallocedFragment(P,N)
#define checkMallocState()
#endif // !( defined(_DEBUG) || defined(NSK_MEMDEBUG) )  
// ****************************************************************************

#ifdef NA_YOS_SIMULATION
// On Windows NT, use malloc16() and free16() to aligned memory like it
// is on NSK.
void * malloc16(Int32 size)
{
  Lng32 startAddr, retAddr, *saveStartAddr;
  startAddr = (Lng32)malloc(size + 20);
  if (startAddr == 0)
    return (void *) NULL;
  retAddr = startAddr + 4;
  retAddr = (((retAddr - 1) / 16 + 1) * 16);
  saveStartAddr = (Lng32 *)(retAddr - 4);
  *saveStartAddr = startAddr;
  return (void *)retAddr;
}

void free16(void *retAddr)
{
  void ** startAddr = (void **)((Lng32)retAddr - 4);
  free(*startAddr);
}

// Macros to use malloc16() and free16()
#define malloc(x) malloc16(x)
#define free(x) free16(x)

#endif // NA_YOS_SIMULATION

#include "muse.cpp"


NABlock::NABlock() :
  segmentId_(0),
  size_(0),
  next_(0),
  sflags_(0)
{}

// Does this NABlock contain the address?
inline NABoolean
NABlock::blockHolds(void *addr)
{
  return ((addr >= (void*)this) && ((char*)addr < (char*)this + size_));
}

// Find the NABlock that contains an address.
inline NABlock*
NABlock::blockHolding(NABlock *firstBlock, void *addr)
{
  while (firstBlock && !firstBlock->blockHolds(addr)) {
    firstBlock = firstBlock->next_;
  }
  return firstBlock;
}

// Return whether this NABlock allocated externally.  This only occurs
// for EXECUTOR_MEMORY when a segment is allocated externally to the
// NAMemory code and passed to the NAMemory within the NAHeap constructor.
// An externally allocated segment will never be freed.
inline NABoolean
NABlock::isExternSegment()
{
  return (sflags_ & EXTERN_BIT) != 0;
}

// Return whether this NABlock was allocated using mmap().
inline NABoolean
NABlock::isMMapped()
{
  return (sflags_ & MMAP_BIT) != 0;
}

// Return the offset of the first fragment in the block
inline size_t
NABlock::firstFragmentOffset()
{
  NAHeapFragment *p = (NAHeapFragment*)((char*)this + sizeof(NABlock));

  // Align the user memory
  return sizeof(NABlock) + ALIGN_OFFSET(p->getMemory());
}

// Return a pointer to the first fragment for this NABlock.
inline NAHeapFragment*
NABlock::alignAsFragment()
{
  return (NAHeapFragment*)((char*)this + firstFragmentOffset());
}

// Return the usable memory used for this NAHeapFragment.
inline void*
NAHeapFragment::getMemory(NABoolean cleanUpPrevNext)
{
  // Add 2 size_t sizes to account for prevFoot_ and head_ at
  // the beginning of the NAHeapFragment.
  Long *memPtr = (Long*)((char*)this + (sizeof(size_t) * 2));
  if (cleanUpPrevNext)
  {
    // clean up prev_ and next_ pointers before handing this 
    // memory to the user.
    memPtr[0] = 0;
    memPtr[1] = 0;
  }
  return (void *)memPtr;
}

// Convert usable memory pointer to an NAHeapFragment pointer.
inline NAHeapFragment*
NAHeapFragment::memToFragment(void *mem)
{
  // Subtract 2 size_t sizes to account for prevFoot_ and head_ at
  // the beginning of the NAHeapFragment.
  return (NAHeapFragment*)((char*)mem - (sizeof(size_t) * 2));
}

// Return whether the CINUSE_BIT (current fragment) is set.
inline NABoolean
NAHeapFragment::cinuse()
{
  return (head_ & CINUSE_BIT) != 0;
}

// Return whether the previous fragment is in use.
inline NABoolean
NAHeapFragment::pinuse()
{
  return (head_ & PINUSE_BIT) != 0;
}

// Return whether both PINUSE_BIT and CINUSE_BIT bits are set.
inline NABoolean
NAHeapFragment::cpinuse()
{
  return (head_ & INUSE_BITS) == INUSE_BITS;
}

// Return the size of the NAHeapFragment
inline size_t
NAHeapFragment::fragmentSize()
{
  return head_ & ~(INUSE_BITS|MMAPPED_BIT|FIRST_FRAGMENT_BIT);
}

// Clear CINUSE_BIT.
inline void 
NAHeapFragment::clearCinuse()
{
  head_ &= ~CINUSE_BIT;
}
  
// Clear PINUSE_BIT.
inline void
NAHeapFragment::clearPinuse()
{
  head_ &= ~PINUSE_BIT;
}

// Set the FIRST_FRAGMENT_BIT and prevFoot_ for the first fragment
// in an NABlock. The FIRST_FRAGMENT_BIT is used to determine quickly
// whether this fragment occupies an entire NABlock during deallocation.
inline void
NAHeapFragment::initializeFirstFragment(size_t s)
{
  head_ |= FIRST_FRAGMENT_BIT;
  prevFoot_ = s;
}

// Return the status of FIRST_FRAGMENT_BIT.
inline size_t
NAHeapFragment::getFirstFragmentBit()
{
  return head_ & FIRST_FRAGMENT_BIT;
}

// Set the head bits of a fragment by ORing them.
inline void
NAHeapFragment::setHeadBits(size_t bits)
{
  head_ |= bits;
}

// Does this fragment occupy the whole NABlock?
inline NABoolean
NAHeapFragment::occupiesCompleteNABlock()
{
  return ((head_ & FIRST_FRAGMENT_BIT) != 0
          && prevFoot_ == fragmentSize());
}

// Return the address of the header.
inline const size_t*
NAHeapFragment::getHeadAddr()
{
  return &head_;
}

// Set the "next_" pointer in the NAHeapFragment
inline void
NAHeapFragment::setNext(NAHeapFragment *next)
{
  next_ = next;
}

// Set the "prev_" pointer in the NAHeapFragment
inline void
NAHeapFragment::setPrev(NAHeapFragment *prev)
{
  prev_ = prev;
}

// Return the "next_" pointer.
inline NAHeapFragment*
NAHeapFragment::getNext()
{
  return next_;
}

// Return the "prev_" pointer.
inline NAHeapFragment*
NAHeapFragment::getPrev()
{
  return prev_;
}

// Return the size of the previous fragment (only valid if free).
inline size_t
NAHeapFragment::getPrevFoot()
{
  return prevFoot_;
}

// Adjust the size of the previous footer size.  For the first fragment
// in an NABlock, the prevFoot_ is used to indicate the size of the block.
// This function is only used to adjust the size of the prevFoot_ when the
// block is resized.
inline void
NAHeapFragment::adjustBlockSize(Lng32 s)
{
  prevFoot_ += s;
}

// Return pointer offset as a greater NAHeapFragment pointer
inline NAHeapFragment*
NAHeapFragment::fragmentPlusOffset(size_t s)
{
  return (NAHeapFragment*)((char*)this + s);
}

// Return pointer offset as a smaller NAHeapFragment pointer
inline NAHeapFragment*
NAHeapFragment::fragmentMinusOffset(size_t s)
{
  return (NAHeapFragment*)((char*)this - s);
}

// Return a pointer to the next fragment
inline NAHeapFragment*
NAHeapFragment::nextFragment()
{
  return (NAHeapFragment*)((char*)this 
          + (head_ & ~(INUSE_BITS|MMAPPED_BIT|FIRST_FRAGMENT_BIT)));
}

// Return a pointer to the previous fragment.  This code assumes
// that the caller has checked whether the previous fragment is
// not in use.
inline NAHeapFragment*
NAHeapFragment::prevFragment()
{
  return (NAHeapFragment*)((char*)this - prevFoot_);
}

// Return whether the next fragment has PINUSE_BIT set.
inline NABoolean
NAHeapFragment::nextPinuse()
{
  return nextFragment()->pinuse();
}

// Set the size at the footer.
inline void
NAHeapFragment::setFoot(size_t s)
{
  size_t size = s & ~FIRST_FRAGMENT_BIT;
  ((NAHeapFragment*)((char*)this + size))->prevFoot_ = s;
}

// Set the size, pinuse bit, and the size at the footer
inline void
NAHeapFragment::setSizeAndPinuseOfFreeFragment(size_t s)
{
  head_ = (s|PINUSE_BIT);
  setFoot(s);
}

// Set size, pinuse bit, foot, and clear next pinuse
inline void
NAHeapFragment::setFreeWithPinuse(size_t s, NAHeapFragment *next)
{
  next->clearPinuse();
  setSizeAndPinuseOfFreeFragment(s);
}

// Set size, inuse and pinuse of this fragment and pinuse of next
// fragment.
inline void
NAHeapFragment::setInuseAndPinuse(size_t s)
{
  head_ = (s|PINUSE_BIT|CINUSE_BIT);
  size_t size = (s & ~FIRST_FRAGMENT_BIT);
  ((NAHeapFragment*)((char*)this + size))->head_ |= PINUSE_BIT;
}

// Set head to the size passed in.  No inuse bits will be set.
inline void
NAHeapFragment::setSize(size_t s)
{
  head_ = s;
}

// Set the size and pinuse bits
inline void
NAHeapFragment::setSizeAndPinuse(size_t s)
{
  head_ = (s|PINUSE_BIT);
}

// Set size, cinuse and pinuse bit of this fragment.
inline void
NAHeapFragment::setSizeAndPinuseOfInuseFragment(size_t s)
{
  head_ = (s|PINUSE_BIT|CINUSE_BIT);
}

// Return whether the head is a fencepost
inline NABoolean
NAHeapFragment::isFencePost()
{
  return (head_ == FENCEPOST_HEAD ||
          (head_ == (sizeof(size_t) | CINUSE_BIT) &&
           (fragmentPlusOffset(sizeof(size_t)))->head_ == FENCEPOST_HEAD));
}

// Set fenceposts after the top fragment
inline void
NAHeapFragment::setFencePosts()
{
  head_ = sizeof(size_t) | CINUSE_BIT;
  NAHeapFragment *next = fragmentPlusOffset(sizeof(size_t));
  next->head_ = FENCEPOST_HEAD;
}

// Return whether the MMAPPED_BIT is set. This bit is only set when a
// NABlock contains a single large fragment and the NABlock was allocated
// using mmap().
inline NABoolean
NAHeapFragment::isMMapped()
{
  return (head_ & MMAPPED_BIT) != 0;
}

// Set the size in the head with the MMAP bit and initialize the trailing
// fenceposts.
inline void
NAHeapFragment::setSizeOfMMapFragment(size_t size)
{
  head_ = (size|PINUSE_BIT|CINUSE_BIT|MMAPPED_BIT); 
  ((NAHeapFragment*)((char*)this + size))->head_ = FENCEPOST_HEAD;
  ((NAHeapFragment*)((char*)this + size + sizeof(size_t)))->head_ = FENCEPOST_HEAD;
}

// mark free pages in this fragment as "non-dirty". Benefits are:
// 1) pages will become readily stealable if needed by the OS. 
// 2) When stolen, OS will not have to swap the contents to the disk. 
inline void
NAHeapFragment::cleanFreePages(size_t fragSize)
{
}

// Get either the left or right child of an NATreeFragment
inline NATreeFragment*
NATreeFragment::getChild(UInt32 childNo)
{
  return child_[childNo];
}

// Get address of either the left or right child of an NATreeFragment
inline NATreeFragment**
NATreeFragment::getChildAddr(UInt32 childNo)
{
  return &child_[childNo];
}

// Get the leftmost child of an NATreeFragment
inline NATreeFragment*
NATreeFragment::leftmostChild()
{
  return (child_[0] != 0 ? child_[0] : child_[1]);
} 

// Set either the left or right child of an NATreeFragment
inline void
NATreeFragment::setChild(Int32 childNo, NATreeFragment *p)
{
  child_[childNo] = p;
}

// Get the parent of an NATreeFragment
inline NATreeFragment*
NATreeFragment::getParent()
{
  return parent_;
}

// Set the parent of an NATreeFragment
inline void
NATreeFragment::setParent(NATreeFragment *p)
{
  parent_ = p;
}

// Return the index of an NATreeFragment.  This is the index into
// NAHeap.treebins_[].
inline NAHeap::bindex_t
NATreeFragment::getIndex()
{
  return index_;
}

// Set the index of the NATreeFragment.
inline void
NATreeFragment::setIndex(NAHeap::bindex_t idx)
{
  index_ = idx;
}

// Get/Set the freedNSKMemory_ flag

inline short
NATreeFragment::getFreedNSKMemory()
{
  return freedNSKMemory_;
}

inline void 
NATreeFragment::setFreedNSKMemory(short value)
{
  freedNSKMemory_ = value;
}

  Lng32 NAMemory::getVmSize()
  {
    pid_t myPid;
    char fileName[32], buffer[1024], *currPtr;
    size_t bytesRead;
    Int32 success;
    ULng32 memSize; // VMSize in KB
    if (procStatusFile_ == 0)
    {
      myPid = getpid();
      sprintf(fileName, "/proc/%d/status", myPid);
      procStatusFile_ = fopen(fileName, "r");
      char *envVar = getenv("EXECUTOR_VM_RESERVE_SIZE");
      if (envVar)
        executorVmReserveSize_ = atol(envVar);
      else
        executorVmReserveSize_ = 256;
    }
    else
      success = fseek(procStatusFile_, 0, SEEK_SET);
    bytesRead = fread(buffer, 1, 1024, procStatusFile_);
    currPtr = strstr(buffer, "VmSize");
    sscanf(currPtr, "%*s %u kB", &memSize);
    lastVmSize_ = memSize;
    if (memSize > maxVmSize_)
      maxVmSize_ = memSize;
    return memSize;
  }

  void NAMemory::allocationIncrement(Lng32 increment)
  {
    allocationDelta_ += increment;
    if (allocationDelta_ >= 128 * 1024 * 1024)
    {
      allocationDelta_ = 0ll;
      Lng32 vmSize = getVmSize();
      if (vmSize >= (4 * 1024 * 1024) - ((128 + executorVmReserveSize_) * 1024))
        crowdedTotalSize_ = (Int64)vmSize * 1024;
    }
  }

  void NAMemory::allocationDecrement(Lng32 decrement)
  {
    allocationDelta_ -= decrement;
    if (allocationDelta_ <= -128 * 1024 * 1024)
    {
      allocationDelta_ = 0ll;
      Lng32 vmSize = getVmSize();
      if (vmSize < (4 * 1024 * 1024) - ((128 + executorVmReserveSize_) * 1024))
       crowdedTotalSize_ = 0ll;
    }
  }

NABlock*
NAMemory::allocateMMapBlock(size_t s)
{
  NABlock *blk;
  blk = (NABlock*)mmap(0, s, (PROT_READ|PROT_WRITE),
                       (MAP_PRIVATE|MAP_ANONYMOUS), -1, 0);
  if (blk == (NABlock*)-1)
  {
    mmapErrno_ = errno;
    return NULL;
  }
  else
    allocationIncrement(s);

  // one more block allocated
  blockCnt_++;
  totalSize_+= s;

  blk->segmentId_ = 0;
  blk->size_ = s;
  blk->sflags_ = NABlock::MMAP_BIT;

  return blk;
}

// Free a NABlock back to the operating system using munmap() or the equivalent.
// The caller should have already modified the statistics on NAMemory before
// calling this function.
inline void
NAMemory::deallocateMMapBlock(NABlock *blk)
{
  allocationDecrement(blk->size_);
  Int32 munmapRetVal;
  munmapRetVal = munmap((void*)blk, blk->size_);
  if (munmapRetVal == -1)
    munmapErrno_ = errno;
}

// Either the correct call to free the memory used by a NABlock. This function
// prevents a lot of extra #ifdef code in later sections of code.
inline void
NAMemory::sysFreeBlock(NABlock *blk)
{
  if (blk->isMMapped())
    deallocateMMapBlock(blk);
  else
    free((void*)blk);
}

#ifndef MUSE
NAMemory::NAMemory(const char * name)
     : 
    type_(EXECUTOR_MEMORY),
    maximumSize_((size_t)-1),            // no maximum
    parent_(NULL),
    firstBlk_(NULL),
    allocSize_(0),
    upperLimit_(0),
    highWaterMark_(0),
    intervalWaterMark_(0),
    allocCnt_(0),
    totalSize_(0),
    blockCnt_(0),
    thBlockCnt_(DEFAULT_THRESHOLD_BLOCK_COUNT),
    memoryList_(NULL),
    lastListEntry_(NULL),
    nextEntry_(NULL),
    exhaustedMem_(FALSE),
    errorsMask_(0),
    crowdedTotalSize_(0ll)
    , allocationDelta_(0ll)
    , procStatusFile_(NULL)
    , mmapErrno_(0)
    , munmapErrno_(0)
    , lastVmSize_(0l)
    , maxVmSize_(0l)
    , sharedMemory_(FALSE)
{
  setType(type_, 0);
#if ( defined(_DEBUG) || defined(NSK_MEMDEBUG) )  
  char * debugLevel = getenv("MEMDEBUG");
  if (debugLevel)
    debugLevel_ = (Lng32)atoi(debugLevel);
  else
    debugLevel_ = 0;
#else // Release build with no debugging
  debugLevel_ = 0;
#endif
  if (name != NULL)
    setName(name);
  else
    setName("Unnamed memory");

  // need to initialize an NAStringRef object "on top" of the array
  // (don't touch this unless you know what you're doing!)
  NAStringRef * tmp = 
    new ( (void*) (&nullNAStringRep_[3]) ) 
    NAStringRef (NAStringRef::NULL_CTOR, this) ;
}

NAMemory::NAMemory(const char * name, NAHeap * parent, size_t blockSize,
                   size_t upperLimit)
     : 
   type_(DERIVED_MEMORY),
   maximumSize_((size_t)-1),            // no maximum
   parent_(parent),
   firstBlk_(NULL),
   allocSize_(0),
   upperLimit_(upperLimit),
   highWaterMark_(0),
   intervalWaterMark_(0),
   allocCnt_(0),
   totalSize_(0),
   blockCnt_(0),
   thBlockCnt_(DEFAULT_THRESHOLD_BLOCK_COUNT),
   memoryList_(NULL),
   lastListEntry_(NULL),
   nextEntry_(NULL),
   exhaustedMem_(FALSE),
   errorsMask_(0),
    crowdedTotalSize_(0ll)
    , allocationDelta_(0ll)
    , procStatusFile_(NULL)
    , mmapErrno_(0)
    , munmapErrno_(0)
    , lastVmSize_(0l)
    , maxVmSize_(0l)
    , sharedMemory_(FALSE)
{
  if (parent_->getSharedMemory())
     setSharedMemory();
  // a derived memory has to have a parent from which it is derived
  assert(parent_);
#if ( defined(_DEBUG) || defined(NSK_MEMDEBUG) )
  char * debugLevel = getenv("MEMDEBUG");
  if (debugLevel)
    debugLevel_ = (Lng32)atoi(debugLevel);
  else
    debugLevel_ = 0;
#else // Release build with no debugging
  debugLevel_ = 0;
#endif
  setName(name);

  if (blockSize <= 0)
    // illegal block size. Use default of 0.5 MB (adjusted).
    blockSize = (Lng32)524288;
  initialSize_ = incrementSize_ = blockSize;

  // need to initialize an NAStringRef object "on top" of the array
  // (don't touch this unless you know what you're doing!)
  NAStringRef * tmp = 
    new ( (void*) (&nullNAStringRep_[3]) ) 
    NAStringRef (NAStringRef::NULL_CTOR, this) ;
}

NAMemory::NAMemory(const char * name, NAMemoryType type, size_t blockSize,
                   size_t upperLimit)
     : 
    type_(type),
    maximumSize_((size_t)-1),            // no maximum
    parent_(NULL),
    firstBlk_(NULL),
    allocSize_(0),
    upperLimit_(upperLimit),
    highWaterMark_(0),
    intervalWaterMark_(0),
    allocCnt_(0),
    totalSize_(0),
    blockCnt_(0),
    thBlockCnt_(DEFAULT_THRESHOLD_BLOCK_COUNT),
    memoryList_(NULL),
    lastListEntry_(NULL),
    nextEntry_(NULL),
    exhaustedMem_(FALSE),
    errorsMask_(0),
    crowdedTotalSize_(0ll)
    , allocationDelta_(0ll)
    , procStatusFile_(NULL)
    , mmapErrno_(0)
    , munmapErrno_(0)
    , lastVmSize_(0l)
    , maxVmSize_(0l)
    , sharedMemory_(FALSE)
{
  // call setType to initialize the values of all the sizes
  setType(type_, blockSize);
#if ( defined(_DEBUG) || defined(NSK_MEMDEBUG) ) 
  char * debugLevel = getenv("MEMDEBUG");
  if (debugLevel)
    debugLevel_ = (Lng32)atoi(debugLevel);
  else
    debugLevel_ = 0;
#else // Release build with no debugging
  debugLevel_ = 0;
#endif
  setName(name);

  // need to initialize an NAStringRef object "on top" of the array
  // (don't touch this unless you know what you're doing!)
  NAStringRef * tmp = 
    new ( (void*) (&nullNAStringRep_[3]) ) 
    NAStringRef (NAStringRef::NULL_CTOR, this) ;
}

NAMemory::NAMemory(const char * name,
           SEG_ID  segmentId,
           void  * baseAddr,
           off_t   heapStartOffset,
           size_t  maxSize)
     : 
    type_(EXECUTOR_MEMORY),
    parent_(NULL),
    firstBlk_(NULL),
    allocSize_(0),
    upperLimit_(0),
    highWaterMark_(0),
    intervalWaterMark_(0),
    allocCnt_(0),
    totalSize_(0),
    blockCnt_(0),
    thBlockCnt_(DEFAULT_THRESHOLD_BLOCK_COUNT),
    memoryList_(NULL),
    lastListEntry_(NULL),
    nextEntry_(NULL),
    exhaustedMem_(FALSE),
    errorsMask_(0),
    crowdedTotalSize_(0ll)
    , allocationDelta_(0ll)
    , procStatusFile_(NULL)
    , mmapErrno_(0)
    , munmapErrno_(0)
    , lastVmSize_(0l)
    , maxVmSize_(0l)
    , sharedMemory_(FALSE)
{
  // call setType to initialize the values of all the sizes
  setType(type_, 0);

#if ( defined(_DEBUG) || defined(NSK_MEMDEBUG) ) 
  char * debugLevel = getenv("MEMDEBUG");
  if (debugLevel)
    debugLevel_ = (Lng32)atoi(debugLevel);
  else
    debugLevel_ = 0;
#else // Release build with no debugging
  debugLevel_ = 0;
#endif

  setName(name);

  // If a first segment was passed in and there is anough usable
  // space in the segment, then initialize the firstBlk_ within
  // the passed in memory.  The NAHeap constructor will initialize
  // the top NAHeapFragment.
  if (baseAddr != NULL) {
    blockCnt_ = 1;
    size_t tsize = maxSize - heapStartOffset - BLOCK_OVERHEAD;
    if (tsize > (8 * sizeof(size_t))) {
      firstBlk_ = (NABlock*)((char*)baseAddr + heapStartOffset);
      firstBlk_->size_ = maxSize - heapStartOffset;
      firstBlk_->sflags_ = NABlock::EXTERN_BIT;
      firstBlk_->next_ = NULL;
      firstBlk_->segmentId_ = segmentId;
      totalSize_ = initialSize_ = maximumSize_ = firstBlk_->size_;
    }
  }
  upperLimit_ = maxSize;
  // need to initialize an NAStringRef object "on top" of the array
  // (don't touch this unless you know what you're doing!)
  NAStringRef * tmp = 
    new ( (void*) (&nullNAStringRep_[3]) ) 
    NAStringRef (NAStringRef::NULL_CTOR, this) ;
}


void NAMemory::reInitialize()
{
  // delete all blocks allocated for this heap and re-set the heap
  // to the initial values

  HEAPLOG_REINITIALIZE(heapID_.heapNum)

  NABlock *externSegment = NULL;
  NABlock *p = firstBlk_;

  if (p != NULL) {

    switch (type_) {
    case EXECUTOR_MEMORY:
    case SYSTEM_MEMORY: 
    case IPC_MEMORY:
      {
        while (p) {
          assert(!p->isExternSegment());
          NABlock *q = p->next_;
          sysFreeBlock(p);
          p = q;
        }
      }
      break;
    case DERIVED_FROM_SYS_HEAP:
      {
        while (p) {
          NABlock *q = p->next_;
          sysFreeBlock(p);
          p = q;
        }
      }
      break;

    case DERIVED_MEMORY:
      {
        // make sure that we have a parent
        assert(parent_);
        HEAPLOG_OFF() // no recursive logging. (eric)

        // This code provides mutual exclusion for the runtime stats shared
        // memory segment.
        short semRetcode = 0;
        if (parent_->getType() == EXECUTOR_MEMORY && getSharedMemory()) {
          semRetcode = getRTSSemaphore();
        }
        while (p) {
          NABlock *q = p->next_;
          parent_->deallocateHeapMemory((void*)p);
          p = q;
        }
        if (semRetcode == 1)
          releaseRTSSemaphore();
        if (parent_->type_ == NAMemory::EXECUTOR_MEMORY &&
            parent_->parent_ == NULL)
        {
            updateMemStats();
        }
        HEAPLOG_ON()
      }
      break;
    default:
      assert(0);
    } // switch(_type)
  } // if (p != NULL)

  // reinitialize all data members.
  allocSize_ = highWaterMark_ = intervalWaterMark_ = allocCnt_ = 
    totalSize_ = blockCnt_ = 0;
    crowdedTotalSize_ = 0ll;
  thBlockCnt_ = DEFAULT_THRESHOLD_BLOCK_COUNT;
  incrementSize_ = initialSize_;

  if (externSegment == NULL) {
    firstBlk_ = NULL;
  } else {
    // This code is not executed by the current code, but exists so
    // it would be possible to call reInitialize() on the EXECUTOR_MEMORY
    // or any other type of memory that is allocated externally. The code
    // in NAHeap::reInitializeHeap() will make the necessary calls to
    // reinitialize the top fragment.
    firstBlk_ = externSegment;
    firstBlk_->next_ = NULL;
    blockCnt_ = 1;
    totalSize_ = firstBlk_->size_ ;
  }

  // If this is an NAHeap, then call reInitializeHeap() to reinitialize
  // the NAHeap fields.  This must be called after reInitializing the
  // NAMemory fields because code in reInitializeHeap() depends on setting
  // firstBlk_ correctly.
  if (derivedClass_ == NAHEAP_CLASS)
    ((NAHeap*)this)->reInitializeHeap();
}

NAMemory::~NAMemory()
{

}

void NAMemory::setType(NAMemoryType type, Lng32 blockSize)
{
  // upperLimit_ must be zero for EXECUTOR_MEMORY, IPC_MEMORY, SYSTEM_MEMORY,

  type_ = type;

  parent_ = NULL;

  // whenever we make changes to the following initial, increment, and
  // maximum sizes, we should make sure, that all values are divisible
  // by FRAG_BYTE_ALIGN. NAMemory::NAMemory also guarantees this. The
  // only exeption from this rule is EXECUTOR_MEMORY on NSK described
  // below. Also, if we have a maximumSize_, make sure that
  // initialSize_ + n * incrementSize_ = maximumSize_

  switch(type_) {
  case EXECUTOR_MEMORY:
    initialSize_   = DEFAULT_NT_HEAP_INIT_SIZE ; 
    maximumSize_   = DEFAULT_NT_HEAP_MAX_SIZE ;           // no maximum
    incrementSize_ = DEFAULT_NT_HEAP_INCR_SIZE ;
    break;
	
  case SYSTEM_MEMORY:
  case IPC_MEMORY:
    // just regular memory in any other environment
    initialSize_   = DEFAULT_NT_HEAP_INIT_SIZE ; 
    maximumSize_   = DEFAULT_NT_HEAP_MAX_SIZE ;           // no maximum
    incrementSize_ = DEFAULT_NT_HEAP_INCR_SIZE ;
    break;

  case DERIVED_MEMORY: {
    assert(parent_);
    if (blockSize == 0)
      blockSize = (Lng32)32768;
    initialSize_ = incrementSize_ = blockSize;
    maximumSize_ = (size_t)-1;            // no maximum
  }
  break;

  case DERIVED_FROM_SYS_HEAP: {
    // just regular memory in all environments. Even on NSK. Use 32K
    // if no blockSize is given
    if (blockSize == 0)
      blockSize = (Lng32)32768;
    initialSize_ = incrementSize_ = blockSize;
    maximumSize_ = (size_t)-1;            // no maximum
  }
  break;
  default:
    assert(0);
  }
}

// allocateMemory() calls the appropriate function for allocating memory based
// on the derivedClass.  This function provides similar functionality to virtual
// functions, which don't work correctly with runtime stats when the NAMemory
// objects exist in shared memory.
void * NAMemory::allocateMemory(size_t size, NABoolean failureIsFatal)
{
  switch (derivedClass_)
  {
  case NAHEAP_CLASS:
    return ((NAHeap *)this)->allocateHeapMemory(size, failureIsFatal);
  case COMSPACE_CLASS:
    return ((ComSpace *)this)->allocateSpaceMemory(size, failureIsFatal);
  case DEFAULTIPCHEAP_CLASS:
    return ((DefaultIpcHeap *)this)->allocateIpcHeapMemory(size, failureIsFatal);
  default:
    assert(0);
  }
  return NULL;
}

// deallocateMemory() frees memory based on the type of memory class this is.
// Virtual functions are avoided due to problems with runtime stats placing
// NAHeap objects within a shared memory segment.
void NAMemory::deallocateMemory(void* addr)
{
  switch (derivedClass_)
  {
  case NAHEAP_CLASS:
    ((NAHeap *)this)->deallocateHeapMemory(addr);
    break;
  case COMSPACE_CLASS:
    ((ComSpace *)this)->deallocateSpaceMemory(addr);
    break;
  case DEFAULTIPCHEAP_CLASS:
     ((DefaultIpcHeap *)this)->deallocateIpcHeapMemory(addr);
    break;
  default:
    assert(0);
  }
}

// dump() writes memory statistics to an output file that the caller must open.
// It is used as an aid for debugging memory problems and for saving memory
// statistics during certain tests.
#if (defined(_DEBUG) || defined(NSK_MEMDEBUG))
void NAMemory::dump(ostream* outstream, Lng32 indent)
{
  switch (derivedClass_)
  {
  case NAHEAP_CLASS:
    ((NAHeap *)this)->dumpHeapInfo(outstream, indent);
    break;
  case COMSPACE_CLASS:
    // ((ComSpace *)this)->dumpSpaceInfo(outstream, indent);
    break;
  case DEFAULTIPCHEAP_CLASS:
     ((DefaultIpcHeap *)this)->dumpIpcHeapInfo(outstream, indent);
    break;
  default:
    assert(0);
  }
}
#endif

// incrementStats() is called when memory is allocated and a current
// NAHeapFragment becomes in use.
inline void
NAMemory::incrementStats(size_t size)
{
  allocSize_ += size;
  allocCnt_++;
  if (highWaterMark_ < allocSize_)
    highWaterMark_ = allocSize_;   
  if (intervalWaterMark_ < allocSize_)
    intervalWaterMark_ = allocSize_;
}

// decrementStats() is called when memory is deallocated
inline void
NAMemory::decrementStats(size_t size)
{
  allocSize_ -= size;
  allocCnt_--;
}
#endif // !MUSE

// True if address has acceptable alignment
inline NABoolean
NAHeap::isAligned(void *addr)
{
  return ((size_t)addr & (FRAG_ALIGN_MASK)) == 0;
}

// Round a size up to the next byte alignment size.
inline size_t
NAHeap::granularityAlign(size_t size)
{
  return (size + FRAG_BYTE_ALIGN) & ~(FRAG_BYTE_ALIGN - 1);
}

// Check if address is at least the minimum.
inline NABoolean
NAHeap::okAddress(void *addr)
{
  return ((char*)addr >= least_addr_);
}

// Check if address of next fragment n is higher than base fragment p
inline NABoolean
NAHeap::okNext(NAHeapFragment *p, NAHeapFragment *n)
{
  return ((char*)p < (char*)n);
}

// Check if p has its cinuse bit on
inline NABoolean
NAHeap::okCinuse(NAHeapFragment *p)
{
  return p->cinuse();
}

// Check if p has its pinuse bit on
inline NABoolean
NAHeap::okPinuse(NAHeapFragment *p)
{
  return p->pinuse();
}

// bit corresponding to given index
inline NAHeap::binmap_t
NAHeap::idx2bit(bindex_t idx)
{
  return (binmap_t)1 << idx;
}

// Return index corresponding to given bit.  This function assumes
// that the caller has isolated a single bit and that exactly one
// bit is set.
inline NAHeap::bindex_t
NAHeap::bit2idx(binmap_t x)
{
#if defined(i386)
  UInt32 ret;
  __asm__("bsfl %1,%0\n\t" : "=r" (ret) : "rm" (x));
  return (NAHeap::bindex_t)ret;
#else
  // Set all bits right of the set bit.
  x--;

  // Quickly count the number of set bits using a well known
  // population count algorithm.
  x -= ((x >> 1) & 0x55555555);
  x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
  x = (((x >> 4) + x) & 0x0f0f0f0f);
  x += (x >> 8);
  x += (x >> 16);

  return x & 0x3f;
#endif
}

// Return whether this size should be treated as a small fragment
inline NABoolean
NAHeap::isSmall(size_t size)
{
  return (size >> SMALLBIN_SHIFT) < NSMALLBINS;
}

// Return the small bin index for this size
inline NAHeap::bindex_t
NAHeap::smallIndex(size_t size)
{
  return (size >> SMALLBIN_SHIFT);
}

// Return the maximum size for this small bin index
inline size_t
NAHeap::smallIndex2Size(bindex_t idx)
{
  return (idx << SMALLBIN_SHIFT);
}

// Set a bit in the small map to indicate this bin contains free fragments
inline void
NAHeap::markSmallmap(bindex_t idx)
{
   smallmap_ |= idx2bit(idx);
}

// Clear a bit in the small map to indicate this bin does not contain
// free fragments
inline void
NAHeap::clearSmallmap(bindex_t idx)
{
  smallmap_ &= ~idx2bit(idx);
}

// Return whether the bit for this index is set in the small map.
inline NABoolean
NAHeap::smallmapIsMarked(bindex_t idx)
{
  return (smallmap_ & idx2bit(idx)) != 0;
}

// Mark a bit in the tree map to indicate the tree contains free fragments
inline void
NAHeap::markTreemap(bindex_t idx)
{
  treemap_ |= idx2bit(idx);
}

// Clear a bit in the tree map to indicate the tree does not contain
// free fragments
inline void
NAHeap::clearTreemap(bindex_t idx)
{
  treemap_ &= ~idx2bit(idx);
}

// Return whether a bit for this index is set in the tree map
inline NABoolean
NAHeap::treemapIsMarked(bindex_t idx)
{
  return (treemap_ & idx2bit(idx)) != 0;
}

// Compute the tree index for a given size
inline NAHeap::bindex_t
NAHeap::computeTreeIndex(size_t size)
{
  size_t x = size >> TREEBIN_SHIFT;
  if (x == 0)
    return 0;
  else if (x > 0xFFFF)
    return NTREEBINS - 1;
  else {
    UInt32 k;
#if defined(i386)
    __asm__("bsrl %1,%0\n\t" : "=r" (k) : "rm" (x));
#else
    UInt32 y = (UInt32)x;
    UInt32 n = ((y - 0x100) >> 16) & 8;
    k = (((y <<= n) - 0x1000) >> 16) & 4;
    n += k;
    n += k = (((y <<= k) - 0x4000) >> 16) & 2;
    k = 14 - n + ((y <<= k) >> 15);
#endif
    return (k << 1) + ((size >> (k + (TREEBIN_SHIFT-1)) & 1));
  }
}

// Isolate the least set bit of a bitmap
inline NAHeap::binmap_t
NAHeap::leastBit(binmap_t bits)
{
  return bits & -(bits);
}

// Mask with all bits to left of least bit of "bits" on
inline NAHeap::binmap_t
NAHeap::leftBits(binmap_t bits)
{
  return (bits << 1) | -(bits<<1);
}

// Shift placing maximum resolved bit in a treebin at idx as sign bit
// This function is used during traversing the trees.  The right child of
// a node (child[1]) will have the next significant bit set, while the left
// child of a node will have the next signficant bit unset.  This function
// does the proper shifting to allow the first signficant bit to be set for
// the range of sizes used by the tree bin "idx".
inline UInt32
NAHeap::leftshiftForTreeIndex(bindex_t idx)
{
  if (idx == NTREEBINS-1)
    return 0;
  else
    return (SIZE_T_BITSIZE - 1) - ((idx >> 1) + TREEBIN_SHIFT - 2);
}

// The size of the smallest fragment held in bin with index idx
inline size_t
NAHeap::minsizeForTreeIndex(bindex_t idx)
{
  return ((1 << ((idx >> 1) + TREEBIN_SHIFT)) |
   (((size_t)(idx & 1)) << ((idx >> 1) + TREEBIN_SHIFT - 1)));
}

// Return the address of a small bin for a particular index
inline NAHeapFragment*
NAHeap::smallbinAt(bindex_t idx)
{
  return (NAHeapFragment*)&smallbins_[idx<<1];
}

// Return the head of a tree bin for a particular index
inline NATreeFragment**
NAHeap::treebinAt(bindex_t idx)
{
  return &treebins_[idx];
}

#ifndef MUSE
// Initialize bins
void
NAHeap::initBins()
{
  // Establish circular links for smallbins
  bindex_t i;
  for (i = 0; i < NSMALLBINS; ++i) {
    NAHeapFragment *bin = smallbinAt(i);
    bin->setNext(bin);
    bin->setPrev(bin);
  }
  for (i = 0; i < NTREEBINS; ++i)
    *treebinAt(i) = 0;
}

// Insert a small fragment into the small bins
inline void
NAHeap::insertSmallFragment(NAHeapFragment *p, size_t size)
{
  bindex_t idx = smallIndex(size);
  NAHeapFragment *binptr = smallbinAt(idx);
  NAHeapFragment *nextptr = binptr;
  assert(size >= MIN_FRAGMENT_SIZE);

  // If the smallmap is not marked, then mark it.  If it is not marked,
  // then set the next pointer to the first fragment on the list.
  // NOTE: For release mode builds, RTCHECK is defined as "1" so the
  // okAddress() check is not made, and nextptr is always set to the
  // first fragment in the list when the smallmap wasn't marked.
  if (!smallmapIsMarked(idx))
    markSmallmap(idx);
  else if (RTCHECK(okAddress(binptr->getNext())))
    nextptr = binptr->getNext();
  else {
    CORRUPTION_ERROR_ACTION;
  }
  binptr->setNext(p);
  nextptr->setPrev(p);
  p->setNext(nextptr);
  p->setPrev(binptr);
}

// Unlink a small fragment from the small bins
inline void
NAHeap::unlinkSmallFragment(NAHeapFragment *p, size_t size)
{
  NAHeapFragment *nextFrag = p->getNext();
  NAHeapFragment *prevFrag  = p->getPrev();
  bindex_t idx = smallIndex(size);

  // Verify a few things that may catch programming errors or data corruption
  assert(p != prevFrag);
  assert(p != nextFrag);
  assert(p->fragmentSize() == smallIndex2Size(idx));

  // If the next fragment pointer is equal to the previous fragment pointer,
  // then this indicates the fragment being unlinked is the only fragment in
  // the list.  The smallmap can be cleared without dealing with additional
  // pointers because it is initialized properly in insertSmallFragment().
  // If this is not the last fragment in the list, then the previous fragment
  // and next fragments pointers are modified to point to each other.
  // NOTE: RTCHECK is defined as "1" in release mode, so the checks within
  // the macro are not made.
  if (nextFrag == prevFrag) {
    clearSmallmap(idx);
  } else if (RTCHECK((nextFrag == smallbinAt(idx) || okAddress(nextFrag)) &&
                     (prevFrag  == smallbinAt(idx) || okAddress(prevFrag)))) {
    nextFrag->setPrev(prevFrag);
    prevFrag->setNext(nextFrag);
  } else {
    CORRUPTION_ERROR_ACTION;
  }
}

// Unlink the first small fragment from a small bin
inline void
NAHeap::unlinkFirstSmallFragment(NAHeapFragment *binPtr,
                                 NAHeapFragment *fragPtr,
                                 bindex_t  idx)
{
  NAHeapFragment *next = fragPtr->getNext();
  assert(fragPtr != binPtr);
  assert(fragPtr != next);
  assert(fragPtr->fragmentSize() == smallIndex2Size(idx));
  if (binPtr == next) {
    clearSmallmap(idx);
  } else if (RTCHECK(okAddress(next))) {
    binPtr->setNext(next);
    next->setPrev(binPtr);
  } else {
    CORRUPTION_ERROR_ACTION;
  }
}

// Insert fragment into tree
inline void
NAHeap::insertLargeFragment(NATreeFragment *treeFrag, size_t size)
{
  bindex_t idx = computeTreeIndex(size);        // Index for this tree
  NATreeFragment **treebinPtr = treebinAt(idx); // Treebin pointer

  // Initialize part of the tree fragment that is being inserted into
  // the tree.
  treeFrag->setIndex(idx);
  treeFrag->setChild(0, NULL);
  treeFrag->setChild(1, NULL);
  treeFrag->setFreedNSKMemory(0); // memory not yet released to NSK

  // If this is the first fragment inserted into the tree, then mark
  // the treemap, set the treebin pointer to point to this fragment, and
  // finish initializing the tree fragment.
  if (!treemapIsMarked(idx)) {
    markTreemap(idx);
    *treebinPtr = treeFrag;
    treeFrag->setParent((NATreeFragment*)treebinPtr);
    treeFrag->setNext(treeFrag);
    treeFrag->setPrev(treeFrag);
  }
  else {
    // If the code reaches here, then this is not the first fragment
    // inserted into this tree bin.  The code below looks at the bits
    // of the size for a tree fragment range.  For instance, there
    // could be a tree bin that deals with sizes of 769 bytes to 1024
    // bytes.  In this case, the most signficant bit would be the bit
    // set by 1024, or (1 << 10).  The leftshiftForTreeindex determines
    // the number of bits needed to shift the size so the most signficant
    // bit of the range is in the 32nd bit. Then the code below looks
    // at the most signficant bit in "sizebits" during each time through
    // the loop.  Each time through the "sizebits" is shifted left by one
    // so that the next significant bit can be examined.  This technique
    // allows for a theoretically balanced tree, and allows for quick
    // traversing of tree tree.
    NATreeFragment *treePtr = *treebinPtr;  // Pointer for tree traversal
    size_t sizebits = size << leftshiftForTreeIndex(idx);
    for (;;) {
      if (treePtr->fragmentSize() != size) {

        NATreeFragment **childPtr = treePtr->getChildAddr(
                          (sizebits >> (SIZE_T_BITSIZE - 1)) & 1);
        sizebits <<= 1;
        if (*childPtr != 0)
          treePtr = *childPtr;
        else if (RTCHECK(okAddress(childPtr))) {
          *childPtr = treeFrag;
          treeFrag->setParent(treePtr);
          treeFrag->setNext(treeFrag);
          treeFrag->setPrev(treeFrag);
          break;  // Break from for loop
        } else {
          CORRUPTION_ERROR_ACTION;
          break;  // Break from for loop
        }
      } else {
        NATreeFragment *next = (NATreeFragment*)treePtr->getNext();
        if (RTCHECK(okAddress(treePtr) && okAddress(next))) {
          treePtr->setNext(treeFrag);
          next->setPrev(treeFrag);
          treeFrag->setNext(next);
          treeFrag->setPrev(treePtr);
          treeFrag->setParent(NULL);
          break;  // Break from for loop
        } else {
          CORRUPTION_ERROR_ACTION;
          break;  // Break from for loop
        }
      }
    }
  }
}

// Unlink a large fragment from the tree
//  Steps:
//  1. If "treeFrag" is a chained node, unlink it from its same-sized
//     next/prev links and choose its prev node as its replacement.
//  2. If treeFrag was the last node of its size, but not a leaf node,
//     it must be replaced with a leaf node (not merely one with an
//     open left or right), to make sure that lefts and rights of
//     descendents correspond properly to bit masks.  We use the
//     rightmost descendent of treeFrag.  We could use any other leaf,
//     but this is easy to locate and tends to counteract removal of
//     leftmosts elsewhere, and so keeps paths shorter than minimally
//     guaranteed.  This doesn't loop much because on average a node
//     in a tree is near the bottom.
//  3. If x is the base of a chain (i.e., has parent links) relink
//     x's parent and children to x's replacement (or null if none).
inline void
NAHeap::unlinkLargeFragment(NATreeFragment *treeFrag)
{
  NATreeFragment *parent = treeFrag->getParent();
  NATreeFragment *prev;
  if (treeFrag->getPrev() != treeFrag) {
    NATreeFragment *next = (NATreeFragment*)treeFrag->getNext();
    prev = (NATreeFragment*)treeFrag->getPrev();
    if (RTCHECK(okAddress(next))) {
      next->setPrev(prev);
      prev->setNext(next);
    } else {
      CORRUPTION_ERROR_ACTION;
    }
  } else {
    // If the current node has any children, then the next section of
    // code searches for the rightmost descendent and sets "prev" to
    // the parent of this descendent, and "rightmostPtr" to the
    // descendent.  
    NATreeFragment **rightmostPtr;
    if (((prev = *(rightmostPtr = treeFrag->getChildAddr(1))) != 0) ||
        ((prev = *(rightmostPtr = treeFrag->getChildAddr(0))) != 0)) {
      NATreeFragment **childPtr;
      while ((*(childPtr = prev->getChildAddr(1)) != 0) ||
             (*(childPtr = prev->getChildAddr(0)) != 0)) {
        prev = *(rightmostPtr = childPtr);
      }
      if (RTCHECK(okAddress(rightmostPtr))) {
        *rightmostPtr = 0;
      } else {
        CORRUPTION_ERROR_ACTION;
      }
    }
  }

  if (parent != 0) {
    NATreeFragment **treebinPtr = treebinAt(treeFrag->getIndex());
    if (treeFrag == *treebinPtr) {
      if ((*treebinPtr = prev) == 0) 
        clearTreemap(treeFrag->getIndex());
    } else if (RTCHECK(okAddress(parent))) {
      if (parent->getChild(0) == treeFrag) 
        parent->setChild(0, prev);
      else 
        parent->setChild(1, prev);
    } else {
      CORRUPTION_ERROR_ACTION;
    }

    if (prev != 0) {
      if (RTCHECK(okAddress(prev))) {
        NATreeFragment *leftChild, *rightChild;
        prev->setParent(parent);
        if ((leftChild = treeFrag->getChild(0)) != 0) {
          if (RTCHECK(okAddress(leftChild))) {
            prev->setChild(0, leftChild);
            leftChild->setParent(prev);
          } else {
            CORRUPTION_ERROR_ACTION;
          }
        }
        if ((rightChild = treeFrag->getChild(1)) != 0) {
          if (RTCHECK(okAddress(rightChild))) {
            prev->setChild(1, rightChild);
            rightChild->setParent(prev);
          } else {
            CORRUPTION_ERROR_ACTION;
          }
        }
      } else {
        CORRUPTION_ERROR_ACTION;
      }
    }
  }
}

// Insert this fragment into either a large or small bin
inline void
NAHeap::insertFragment(NAHeapFragment *p, size_t size)
{
  if (isSmall(size)) {
    insertSmallFragment(p, size);
  } else {
    NATreeFragment *tp = (NATreeFragment*)p;
    insertLargeFragment(tp, size);
  }
}

// Unlink either a large or small fragment from the small bins or
// large trees
inline void
NAHeap::unlinkFragment(NAHeapFragment *p, size_t size)
{
  if (isSmall(size)) {
    unlinkSmallFragment(p, size);
  } else {
    NATreeFragment *tp = (NATreeFragment*)p;
    unlinkLargeFragment(tp);
  }
}

// Replace the designated victim with a different fragment
inline void
NAHeap::replaceDV(NAHeapFragment *p, size_t size)
{
  if (dvsize_ != 0)
    insertSmallFragment(dv_, dvsize_);

  dvsize_ = size;
  dv_ = p;
}

// Resize the top fragment when a segment changes size.
inline void
NAHeap::resizeTop(size_t newsize)
{
  topsize_ = newsize;

  size_t firstFragBit = top_->getFirstFragmentBit();
  top_->setSizeAndPinuse(newsize | firstFragBit);

  NAHeapFragment *next = top_->nextFragment();
  next->setFencePosts();
}

// Initialize the top fragment
inline void
NAHeap::initTop(NABlock *block)
{
  size_t offset = block->firstFragmentOffset();

  // Calculate topsize_ with rounding down to the FRAG_ALIGN boundary.
  topsize_ = (block->size_ - offset - MIN_FRAGMENT_SIZE) & ~FRAG_ALIGN_MASK;
  top_ = (NAHeapFragment*)((char*)block + offset);

  top_->setSizeAndPinuse(topsize_);

  // Set trailing fenceposts.  The assert insures that there is enough
  // space for the trailing fenceposts at the end of the block.
  NAHeapFragment *r = top_->nextFragment();
  assert((char*)r + (3 * sizeof(size_t)) <= (char*)block + block->size_);
  r->setFencePosts();
}

// initialize the fields in the NAHeapFragment structures when a new
// noncontiguous NABlock is allocated.
void
NAHeap::addBlock(NABlock *newBlock)
{
  // Insert the old top into a bin as an ordinary free fragment.
  if (topsize_ != 0) {
    size_t firstFragBit = top_->getFirstFragmentBit();
    NAHeapFragment *next = top_->fragmentPlusOffset(topsize_);

    top_->setFreeWithPinuse(topsize_, next);
    insertFragment(top_, topsize_);
    top_->setHeadBits(firstFragBit); // Set first fragment bit if it was set
  }

  // reset top to new space
  initTop(newBlock);
  top_->initializeFirstFragment(topsize_);
  checkTopFragment(top_);
}

// Free an NABlock if all of the memory becomes free.  This releases
// it to the operating system or frees it in the parent memory.
NABoolean
NAHeap::deallocateFreeBlock(NAHeapFragment *p)
{
  NABlock *prev = NULL;
  NABlock *curr = firstBlk_;

  // Find the NABlock containing this fragment
  while (curr != NULL && !curr->blockHolds(p)) {
    prev = curr;
    curr = curr->next_;
  }

  assert(curr != NULL); // A block had better contain this fragment

  // If this block was allocated externally, then it should not be
  // deallocated here.  This shouldn't really happen.  For a future
  // project it might make sense to resize this segment to something
  // smaller to save on memory.
  if (curr->isExternSegment())
    return FALSE;

  // Decrement statistics
  totalSize_ -= curr->size_;
  blockCnt_--;

  // Reset top_ if it is in this NABlock
  if (curr->blockHolds(top_)) {
    top_ = NULL;
    topsize_ = 0;
  }

  // Reset designated victim if it is within this NABlock
  if (curr->blockHolds(dv_)) {
    dv_ = NULL;
    dvsize_ = 0;
  }

  // Remove this NABlock from the NABlock list
  if (prev == NULL)
    firstBlk_ = curr->next_;
  else
    prev->next_ = curr->next_;

  // Now release the memory to the operating system.
  switch (type_)
  {
  case EXECUTOR_MEMORY:
  case SYSTEM_MEMORY:
  case IPC_MEMORY:
    sysFreeBlock(curr);
    break;
  case DERIVED_FROM_SYS_HEAP:
    sysFreeBlock(curr);
    break;
  case DERIVED_MEMORY:
    assert(parent_);
    HEAPLOG_OFF() // no recursive logging.
    // This code provides mutual exclusion for the runtime stats shared
    // memory segment.
    if (parent_->getType() == EXECUTOR_MEMORY && getSharedMemory()) {
       short retcode = getRTSSemaphore();
       parent_->deallocateHeapMemory((void*)curr);
       if (retcode == 1)
         releaseRTSSemaphore(); 
    } else {
      parent_->deallocateHeapMemory((void*)curr);
    }
    HEAPLOG_ON()
    break;
  default:
    assert(0);  // Shouldn't happen
    break;
  }

  return TRUE;
}

// Allocate a large request from the best fitting fragment in a treebin
// and return a pointer to the NAHeapFragment that best fits the request.
// If the allocation cannot be satisfied or if the designated victim is
// a better fit than the best fitting fragment in any of the trees, then
// a NULL pointer is returned.
NAHeapFragment*
NAHeap::tmallocLarge(size_t nb)
{
  NATreeFragment *v = NULL;
  size_t rsize = -nb; // Unsigned negation.
  NATreeFragment *t;
  bindex_t idx = computeTreeIndex(nb);

  if ((t = *treebinAt(idx)) != 0) {
    // Traverse tree for this bin looking for node with size == nb
    size_t sizebits = nb << leftshiftForTreeIndex(idx);
    NATreeFragment *rst = NULL;  // The deepest untaken right subtree
    for (;;) {
      size_t trem = t->fragmentSize() - nb;  // Can cause underflow
      if (trem < rsize) {
        v = t;
        if ((rsize = trem) == 0)
          break;
      }
      NATreeFragment *rt = t->getChild(1);
      t = t->getChild((sizebits >> (SIZE_T_BITSIZE - 1)) & 1);
      if (rt != 0 && rt != t)
        rst = rt;
      if (t == 0) {
        t = rst; // set t to least subtree holding sizes > nb
        break;
      }
      sizebits <<= 1;
    }
  }

  if (t == 0 && v == 0) { // set t to root of next non-empty treebin
    binmap_t leftbits = leftBits(idx2bit(idx)) & treemap_;
    if (leftbits != 0) {
      binmap_t leastbit = leastBit(leftbits);
      bindex_t i = bit2idx(leastbit);
      t = *treebinAt(i);
    }
  }

  while (t != 0) { // find smallest of tree or subtree
    size_t trem = t->fragmentSize() - nb;
    if (trem < rsize) {
      rsize = trem;
      v = t;
    }
    t = t->leftmostChild();
  }

  // If dv is a not a better fit, then use the tree fragment that was
  // found.  If necessary, split the tree fragment into two fragments,
  // and reinsert the remainder into a small bin or another tree.
  if (v != 0 && rsize < (dvsize_ - nb)) {
    if (RTCHECK(okAddress(v))) { // split
      NAHeapFragment *r = v->fragmentPlusOffset(nb);
      assert(v->fragmentSize() == rsize + nb);
      size_t firstFragBit = v->getFirstFragmentBit();
      if (RTCHECK(okNext(v, r))) {
        unlinkLargeFragment(v);
        if (rsize < MIN_FRAGMENT_SIZE) {
          v->setInuseAndPinuse((rsize + nb) | firstFragBit);
        } else {
          v->setSizeAndPinuseOfInuseFragment(nb | firstFragBit);
          r->setSizeAndPinuseOfFreeFragment(rsize);
          insertFragment(r, rsize);
        }
        return v;
      }
    }
    CORRUPTION_ERROR_ACTION;
  }
  // Return NULL because the designated victim is larger than the treebin
  // or there wasn't a tree fragment that satisfied the request.
  return NULL;
}

// allocate a small request from the best fitting fragment in a treebin
NAHeapFragment*
NAHeap::tmallocSmall(size_t nb)
{
  binmap_t leastbit = leastBit(treemap_);
  bindex_t idx = bit2idx(leastbit);

  NATreeFragment *t, *v;
  v = t = *treebinAt(idx);
  size_t rsize = t->fragmentSize() - nb;

  while ((t = t->leftmostChild()) != 0) {
    size_t trem = t->fragmentSize() - nb;
    if (trem < rsize) {
      rsize = trem;
      v = t;
    }
  }

  if (RTCHECK(okAddress(v))) {
    NAHeapFragment *r = v->fragmentPlusOffset(nb);
    assert(v->fragmentSize() == rsize + nb);
    size_t firstFragBit = v->getFirstFragmentBit();

    if (RTCHECK(okNext(v, r))) {
      unlinkLargeFragment(v);
      if (rsize < MIN_FRAGMENT_SIZE) {
        v->setInuseAndPinuse((rsize + nb) | firstFragBit);
      } else {
        v->setSizeAndPinuseOfInuseFragment(nb | firstFragBit);
        r->setSizeAndPinuseOfFreeFragment(rsize);
        replaceDV(r, rsize);
      }
      return v;
    }
  }

  CORRUPTION_ERROR_ACTION;
  return NULL;
}

Lng32 NAMemory::getAllocatedSpaceSize()
{
  assert(type_ != NO_MEMORY_TYPE);
  return allocSize_;
}

void NAMemory::setName(const char * name)
{
  Lng32 copyLen = str_len(name);
  if (copyLen > 20)
    copyLen = 20;
  memcpy(name_, name, copyLen);
  name_[copyLen] = 0;
}

void NAMemory::registerMemory(NAMemory * child)
{
  // put child at the end of the memoryList_
  if (lastListEntry_)
    lastListEntry_->nextEntry_ = child;
  else
    memoryList_ = child;

  lastListEntry_ = child;
}

void NAMemory::unRegisterMemory(NAMemory * child)
{
  NAMemory * p = memoryList_;
  NAMemory * q = NULL;  
  while (p && p != child) {
    q = p;
    p = p->nextEntry_;
  }
  assert(p);

  if (q == NULL)
    // we remove the first entry
    memoryList_ = p->nextEntry_;
  else
    q->nextEntry_ = p->nextEntry_;

  // adjust lastListEntry_
  if (child == lastListEntry_)
    lastListEntry_ = q;
}

// Return the resize segment size including the first seg offset
// (totalSize_, maximumSize_, etc does not include the first seg offset)


NABlock*
NAHeap::allocateBlock(size_t size, NABoolean failureIsFatal)
{
  assert(type_ != NO_MEMORY_TYPE);

  // if a limit is specified for this heap, make sure we don't pass it
  if ((IdentifyMyself::GetMyName() == I_AM_EMBEDDED_SQL_COMPILER) &&
      (upperLimit_ != 0) && 
      ((allocSize_ + size) > upperLimit_))
  {
     // reset the upper limit for now so testing can continue
     upperLimit_ = 0;
     handleExhaustedMemory();
  }


  void * addr = 0;
  short segmentId = (firstBlk_ == NULL ? 0 : firstBlk_->segmentId_);

  // for derived memories, double the incrementSize_ if we have
  // allocated 10 (20, 30, ...) blocks
  if ((type_ == DERIVED_MEMORY ||
      type_ == DERIVED_FROM_SYS_HEAP) &&
      thBlockCnt_ == (blockCnt_ + 1) &&
      incrementSize_ < DEFAULT_MAX_INCREMENT) {

    // next adjustment when we get 10 more blocks.
    incrementSize_ *= 2;
    if (incrementSize_ > DEFAULT_MAX_INCREMENT)
      incrementSize_ = DEFAULT_MAX_INCREMENT;
    thBlockCnt_ += DEFAULT_THRESHOLD_BLOCK_COUNT;
  }

  // allocate always at least blockSize bytes
  size_t blockSize = (firstBlk_ == NULL) ? initialSize_ : incrementSize_;



  // Ensure that the blockSize is at least large enough to hold the
  // requested size.
  if (blockSize < size) // Compare as unsigned integer
    blockSize = size;

  // make sure that the block size is a multiple of FRAG_BYTE_ALIGN
  blockSize = (blockSize + FRAG_ALIGN_MASK) & ~FRAG_ALIGN_MASK;

  NABlock *p = NULL;              // Pointer to the returned block.

  switch (type_) {
  case EXECUTOR_MEMORY: {

    // This could be either Global Executor Memory or Stats Globals
    // Don't add a block if Stats Globals!
    if (getSharedMemory())
      return NULL;

    // Try to allocate the NABlock using mmap(). If it succeeds return the
    // NABlock.  Otherwise, fall through and try to allocate the normal way.
    if (blockSize >= MIN_MMAP_ALLOC_SIZE &&
        (p = allocateMMapBlock(blockSize)) != NULL)
      return p;

    // allocate a block from the OS memory
    p = (NABlock*)malloc(blockSize);
    if (p)
      allocationIncrement(blockSize);
  }
  break;

  case SYSTEM_MEMORY: 
  case IPC_MEMORY:
  {
    // Try to allocate the NABlock using mmap(). If it succeeds return the
    // NABlock.  Otherwise, fall through and try to allocate the normal way.
    if (blockSize >= MIN_MMAP_ALLOC_SIZE &&
        (p = allocateMMapBlock(blockSize)) != NULL)
      return p;

    // allocate a block from the OS memory
    p = (NABlock*)malloc(blockSize);
    if (p)
      allocationIncrement(blockSize);
  }
  break;

  case DERIVED_FROM_SYS_HEAP: {
    // allocate a block from the OS memory
    // Try to allocate the NABlock using mmap(). If it succeeds return the
    // NABlock.  Otherwise, fall through and try to allocate the normal way.
    if (blockSize >= MIN_MMAP_ALLOC_SIZE &&
        (p = allocateMMapBlock(blockSize)) != NULL)
      return p;

    p = (NABlock*)malloc(blockSize);
    if (p)
      allocationIncrement(blockSize);
  }
  break;

  case DERIVED_MEMORY: {
    // make sure that we have a parent
    assert(parent_);
    // allocate a block from the parent
    HEAPLOG_OFF()  // no recursive logging. (eric)

    // This code provides mutual exclusion for the runtime stats shared
    // memory segment.
    // The IF condition below is not needed since we are checking if
    // semaphore is obtained in allocateHeapMemory or deallocateHeapMemory
    // for both global and process stats heap. But leaving it now
    // since it won't hurt other than extra cpu cycles
    if (getSharedMemory()) {
      short retcode = getRTSSemaphore();
      p = (NABlock*)parent_->allocateHeapMemory(blockSize, FALSE);

      if (p == NULL)
// Unit tested this code with the test case in QC 1387
// - 3/22/2012.
      {
        // Exhausted shared segment. Prevent cascade of core-files by
        // making one core-file of myself while holding semaphore.
        // Then bring down this node.
        genLinuxCorefile("Shared Segment might be full");
        Int32 nid = 0;
        Int32 pid = 0;
        if (XZFIL_ERR_OK == msg_mon_get_my_info(&nid, &pid, NULL,
                        0, NULL, NULL, NULL, NULL))
        {
          // The SSMP is responsible for preventing leaks. So get a 
          // corefile of it.
          char ssmpName[MS_MON_MAX_PROCESS_NAME];
          memset(ssmpName, 0, MS_MON_MAX_PROCESS_NAME);
          if (XZFIL_ERR_OK == XPROCESSHANDLE_DECOMPOSE_(
			      getMySsmpPhandle()
			    , NULL // cpu
			    , NULL // pin
			    , NULL // nodenumber
			    , NULL // nodename
			    , 0    // nodename_maxlen
			    , NULL // nodename_length
			    , ssmpName 
			    , sizeof(ssmpName)))
          {
            char coreFile[1024];
            msg_mon_dump_process_name(NULL, ssmpName, coreFile);
          }
          Int32 ndRetcode = msg_mon_node_down2(nid,
                              "RMS shared segment is exhausted.");
          sleep(30);
          NAExit(0);    // already made a core.
        }
        else
          assert(p != NULL);
      }

      if (retcode == 1)
        releaseRTSSemaphore();
    } else {
      p = (NABlock*)parent_->allocateHeapMemory(blockSize, failureIsFatal);
     if (parent_->type_ == NAMemory::EXECUTOR_MEMORY &&
            parent_->parent_ == NULL)
     {
        updateMemStats();
     }
    }
    segmentId = NABlock::DERIVED_SEGMENT_ID;  // Add another check for muse
    HEAPLOG_ON()
  }
  break;
  }  // switch(type_)

  // if the allocation was not sucessfull, we return a NULL
  if (p == NULL)
    return NULL;

  // one more block allocated
  blockCnt_++;
  totalSize_+= blockSize;

  // Initialize the returned NABlock information
  p->segmentId_ = segmentId;
  p->size_ = blockSize;
  p->next_ = NULL; // The caller is responsible for linking this
  p->sflags_ = 0;

  return p;
} // NAHeap::allocateBlock(size_t size, NABoolean failureIsFatal)
#endif // !MUSE

void NAMemory::showStats(ULng32 level)
{
  char indent[100];
  Int32 i = 0;
  for (; i < (2 + 2 * (Int32) level); i++)
    indent[i] = ' ';
  indent[i] = '\0';

  cerr << indent << "NAMemory: " << this << " is a ";
  switch(type_) {
  case NO_MEMORY_TYPE:
    cerr << "NO_MEMORY_TYPE";
    break;
  case EXECUTOR_MEMORY:
    cerr << "EXECUTOR_MEMORY";
    break;
  case SYSTEM_MEMORY:
    cerr << "SYSTEM_MEMORY";
    break;
  case IPC_MEMORY:
    cerr << "IPC_MEMORY";
    break;
  case DERIVED_MEMORY:
    cerr << "DERIVED_MEMORY";
    break;
  case DERIVED_FROM_SYS_HEAP:
    cerr << "DERIVED_FROM_SYS_HEAP";
    break;
  }
  cerr << endl
    << indent << "name of memory: " << name_ << endl
       << indent << "parent memory: " << parent_ << endl
       << indent << "initial size: " << initialSize_ << endl
       << indent << "maximum size: " << maximumSize_ << endl
       << indent << "increment size: " << incrementSize_ << endl
       << indent << "total size: " << totalSize_ << endl
       << indent << "#of blocks: " << blockCnt_ << endl
       << indent << "allocated size: " << allocSize_ << endl
       << indent << "high water mark: " << highWaterMark_ << endl
       << indent << "interval water mark: " << intervalWaterMark_ << endl
       << indent << "allocated fragments: " << allocCnt_ << endl
       << indent << "-------------------------------------------------" << endl;

  for (NAMemory * p = memoryList_; p != NULL; p = p->nextEntry_)
    p->showStats(level + 1);
}

// this method used to belong to CollHeap
#ifndef MUSE
void 
NAMemory::handleExhaustedMemory()
{
  exhaustedMem_ = TRUE;
}
#endif // MUSE


NABoolean NAMemory::getUsage(size_t * lastBlockSize, size_t * freeSize, size_t * totalSize)
{
  *freeSize = 0;
  NAMemory * memory = this;
  NABoolean crowded = FALSE;
  
  do
  {
    *freeSize += memory->totalSize_ - memory->allocSize_;
    *totalSize = memory->totalSize_;
   if (memory->type_ == EXECUTOR_MEMORY)
    {
      //if (memory->firstBlk_->next_ == NULL)
      *lastBlockSize = 0; 
        //*lastBlockSize = memory->firstBlk_->size_;
      //else
        //*lastBlockSize = memory->firstBlk_->next_->size_;
      if (memory->crowdedTotalSize_ > 0ll &&
	*freeSize < *totalSize / 2) // Free size is < half total alloc'd
        {
          // Simulate size on NSK when unable to allocate 128 MB flat segment
          *lastBlockSize = (Lng32)((4ll * 1024ll * 1024ll * 1024ll - memory->crowdedTotalSize_) / 2);
	  crowded = TRUE;
        }
    }
    memory = memory->parent_;
  } while (memory != NULL);
  return crowded;
}

NABoolean NAMemory::checkSize(size_t size, NABoolean failureIsFatal)
{
  if (size > MAX_MEMORY_SIZE_IN_AN_ALLOC) {
     if (failureIsFatal) 
        abort();
     else
        return FALSE;  
  }
  return TRUE;
}

// ---------------------------------------------------------------------------
// NAHeap methods
// ---------------------------------------------------------------------------
#ifndef MUSE
NAHeap::NAHeap()
  : NAMemory("Unknown Memory Type"),
    smallmap_(0),
    treemap_(0),
    dvsize_(0),
    topsize_(0),
    least_addr_(0),
    dv_(NULL),
    top_(NULL),
    errCallback_(NULL)
{
  initBins();
  derivedClass_ = NAHEAP_CLASS;

  threadSafe_ = false;
  memset(&mutex_, '\0', sizeof(mutex_));

#ifdef _DEBUG
  setAllocTrace();
#endif // _DEBUG
}

NAHeap::NAHeap(const char * name, 
	       NAHeap * parent, 
	       Lng32 blockSize, 
	       size_t upperLimit)
  : NAMemory(name, parent, blockSize, upperLimit),
    smallmap_(0),
    treemap_(0),
    dvsize_(0),
    topsize_(0),
    least_addr_(0),
    dv_(NULL),
    top_(NULL),
    errCallback_(NULL)
{
  initBins();
  derivedClass_ = NAHEAP_CLASS;

  threadSafe_ = false;
  memset(&mutex_, '\0', sizeof(mutex_));
  if (parent != NULL)
  {
     NAMutex mutex(parent->threadSafe_, &parent->mutex_);
     parent_->registerMemory(this);
  }

#ifdef _DEBUG
  setAllocTrace();
#endif // _DEBUG
}

NAHeap::NAHeap(const char * name, 
	       NAMemoryType type, 
	       Lng32 blockSize, 
	       size_t upperLimit) 
  : NAMemory(name, type, blockSize, upperLimit),
    smallmap_(0),
    treemap_(0),
    dvsize_(0),
    topsize_(0),
    least_addr_(0),
    dv_(NULL),
    top_(NULL),
    errCallback_(NULL)
{
  initBins();
  derivedClass_ = NAHEAP_CLASS;

  threadSafe_ = false;
  memset(&mutex_, '\0', sizeof(mutex_));

#ifdef _DEBUG
  setAllocTrace();
#endif // _DEBUG
}

NAHeap::NAHeap(const char  * name)
  : NAMemory(name),
    smallmap_(0),
    treemap_(0),
    dvsize_(0),
    topsize_(0),
    least_addr_(0),
    dv_(NULL),
    top_(NULL),
    errCallback_(NULL)
{
  initBins();
  derivedClass_ = NAHEAP_CLASS;

  if (firstBlk_) {
    initTop(firstBlk_);
    least_addr_ = (char*)firstBlk_;
  }

  if (deallocTraceArray == 0)
  {
    char *deallocTraceEnvvar = getenv("EXE_DEALLOC_MEM_TRACE");
    if (deallocTraceEnvvar != NULL)
    {
      deallocTraceArray =
        (DeallocTraceEntry (*) [deallocTraceEntries])malloc(sizeof(DeallocTraceEntry) * deallocTraceEntries);
      memset((void *)deallocTraceArray, '\0', sizeof(DeallocTraceEntry) * deallocTraceEntries);
    }
  }

  threadSafe_ = false;
  memset(&mutex_, '\0', sizeof(mutex_));

#ifdef _DEBUG
  setAllocTrace();
#endif // _DEBUG
}

// Constructor that imposes the NAHeap struture on already allocated memory 
NAHeap::NAHeap(const char * name,
       SEG_ID  segmentId,
       void  * baseAddr,
       off_t   heapStartOffset,
       size_t  maxSize)
  : NAMemory(name, segmentId, baseAddr, heapStartOffset, maxSize),
    smallmap_(0),
    treemap_(0),
    dvsize_(0),
    topsize_(0),
    least_addr_(0),
    dv_(NULL),
    top_(NULL),
    errCallback_(NULL)
{
  initBins();
  derivedClass_ = NAHEAP_CLASS;

  if (firstBlk_) {
    initTop(firstBlk_);
    least_addr_ = (char*)firstBlk_;
  }

  if (deallocTraceArray == 0)
  {
    char *deallocTraceEnvvar = getenv("EXE_DEALLOC_MEM_TRACE");
    if (deallocTraceEnvvar != NULL)
    {
      deallocTraceArray =
        (DeallocTraceEntry (*) [deallocTraceEntries])malloc(sizeof(DeallocTraceEntry) * deallocTraceEntries);
      memset((void *)deallocTraceArray, '\0', sizeof(DeallocTraceEntry) * deallocTraceEntries);
    }
  }

  threadSafe_ = false;
  memset(&mutex_, '\0', sizeof(mutex_));

#ifdef _DEBUG
  setAllocTrace();
#endif // _DEBUG
}

NAHeap::~NAHeap()
{
   destroy();
  if (threadSafe_)
     pthread_mutex_destroy(&mutex_);
}

void NAHeap::setThreadSafe()
{
  int rc;
  pthread_mutexattr_t attr;
  rc = pthread_mutexattr_init(&attr);
  assert(rc == 0);
  rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
  assert(rc == 0);
  NAHeap *heap = this;
  // set this heap and heaps it is derived from
  while (heap)
  {
    if (heap->threadSafe_ == false)
    {
      rc = pthread_mutex_init(&(heap->mutex_), &attr);
      assert(rc == 0);
      heap->threadSafe_ = true;
    }
    heap = heap->parent_;
  }
}

// destroy() is called by the NAMemory destructor to perform the
// derived class destructor.  It is part of the mechanism that
// prevents virtual functions, which cause problems when used with
// runtime statistics.
void NAHeap::destroy() 
{
  if (parent_ != NULL)
     NAMutex mutex(parent_->threadSafe_, &parent_->mutex_);

#ifdef _DEBUG
  if (la_)
    {
      char header[120];
      sprintf(header, "Stacks when block of %d bytes was asked from heap (%s)",
              TraceAllocSize, getName());
      dumpTrafStack(getSAL(), header, true);
      delete la_;
    }
#endif // _DEBUG
  reInitialize();

  // remove this memory from the parents memoryList_
  if (parent_)
    parent_->unRegisterMemory(this);
}

// reInitializeHeap reinitializes the NAHeap structures.  It is called from the
// NAMemory reInitialize(), which may either be called directly or from a destructor.
void NAHeap::reInitializeHeap()
{
  NAMutex mutex(threadSafe_, &mutex_);

#if (defined(_DEBUG) || defined(NSK_MEMDEBUG))
  // Before freeing the NABlocks in reInitialize(), check to see whether any
  // of the memory fragments in the blocks have overflowed
  if (debugLevel_ == 2)
    checkForOverflow();
#endif

  // Reinitialize the fields that are specific to the NAHeap class
  smallmap_ = treemap_ = dvsize_ = topsize_ = 0;
  dv_ = NULL;
  top_ = NULL;
  least_addr_ = NULL;

  initBins();

  // If a segment is still active, then reinitialize the top fragment
  // so that it can be used. This code is not currently called, but
  // is here to allow the EXECUTOR_MEMORY or any other memory that
  // will be allocated by an external means to be reinitialized.
  // The first part of reinitialization occurs in NAMemory::reInitialize().
  // That code frees the NABlocks and will reinitialize the firstBlk_
  // if it was allocated externally.
  if (firstBlk_ != NULL) {
     least_addr_ = (char*)firstBlk_;
     initTop(firstBlk_);
  }
}

// NAHeap::setErrorCallback() sets a pointer to a function that
// will be called if the heap cannot allocate an NABlock.  The
// callback function will be called with a NAHeap pointer argument
// and an argument that indicates the amount of memory that was
// being allocated.
void NAHeap::setErrorCallback(void (*errCallback)(NAHeap*,size_t))
{
  errCallback_ = errCallback;
}

void * NAHeap::allocateAlignedHeapMemory(size_t userSize, size_t alignment, NABoolean failureIsFatal)
{
  if (alignment & (sizeof(void *) - 1)) // Is alignment a multiple of sizeof(void *)?
    return NULL;
  if (alignment & (alignment - 1)) // Is alignment a power of 2?
    return NULL;
  size_t retAddr, alignedAddr;
  retAddr = (size_t)allocateHeapMemory(userSize + alignment, failureIsFatal);
  if (retAddr == (size_t) NULL)
    return NULL;
  alignedAddr = retAddr & ~(alignment - 1);
  if (alignedAddr != retAddr)
  {
    alignedAddr += alignment;
    if ((alignedAddr - retAddr) < (sizeof(size_t) * 2))
    { // need to double the alignment to avoid override header info
      deallocateHeapMemory((void *)retAddr);
      retAddr = (size_t)allocateHeapMemory(userSize + 2 * alignment, failureIsFatal);
      if (retAddr == (size_t) NULL)
        return NULL;
      alignedAddr = retAddr & ~(alignment - 1);
      if (alignedAddr == retAddr)
        return (void *)alignedAddr;
      alignedAddr += alignment;  // move to aligned addr inside the fragment
      if ((alignedAddr - retAddr) < (sizeof(size_t) * 2))
        alignedAddr += alignment;  // move to next alignment
    }
    NAHeapFragment *p = NAHeapFragment::memToFragment((void *)alignedAddr);
    p->initializeFirstFragment(alignedAddr - retAddr);
    p->setSizeAndPinuseOfInuseFragment(0); // Set inuse bits on and size = 0
   }
  return (void *)alignedAddr;
}

// NAHeap::allocateHeapMemory()
//   This algorithm is taken from Doug Lea's public domain malloc.
//     Basic algorithm:
//     If a small request (< 256 bytes minus per-fragment overhead):
//       1. If one exists, use a remainderless fragment in associated smallbin.
//          (Remainderless means that there are too few excess bytes to
//          represent as a fragment.)
//       2. If it is big enough, use the designated victim fragment.  The
//          designated fragment is used for quickly servicing small requests.
//       3. If one exists, split the smallest available fragment in a bin,
//          saving remainder in dv.
//       4. If the top fragment is not large enough to handle the request, then
//          call NAHeap::allocateBlock() to allocate another segment from the
//          OS or to increase the size of the last segment.  Set the size of or
//          resize the top fragment.
//       5. Allocate memory from the top fragment.
//     Otherwise, for a large request:
//       1. Find the smallest available binned fragment that fits, and use it
//          if it is better fitting than dv fragment, splitting if necessary.
//       2. If better fitting than any binned fragment, use the dv fragment.
//       3. If the top fragment is not large enough to handle the request, then
//          call NAHeap::allocateBlock() to allocate another segment from the
//          OS or to increase the size of the last segment.  Set the size of or
//          resize the top fragment.
//       4. Allocate memory from the top fragment.
//
void * NAHeap::allocateHeapMemory(size_t userSize, NABoolean failureIsFatal)
{

  NAMutex mutex(threadSafe_, &mutex_);

  assert(type_ != NO_MEMORY_TYPE);

  // allocation of size 0. We return a NULL. Alternative would be to
  // allocate 0 bytes. But this would waste memory to maintain a
  // heap fragment of size 0.
  if (userSize == 0)
     return NULL;

  if (! checkSize(userSize, failureIsFatal))
     return NULL;

  // getSharedMemory() check alone is enough since it will return for both
  // global and process stats heap. Leaving the rest of the condition here
  //
  if (getSharedMemory())
  {
    // Check if you are within semaphore
    if (! checkIfRTSSemaphoreLocked())
       NAExit(1);
  }

  // Some additional bytes are added in debug mode, but the original userSize
  // must be retained.
  size_t additionalUserSize = userSize;

#if (defined(_DEBUG) || defined(NSK_MEMDEBUG))  
  if (debugLevel_)
    dynamicAllocs.addEntry(userSize);

  // Allocate some additional memory to help with memory debugging. At
  // debug level 2 on Windows, there are 40 bytes allocated to store
  // 10 program counters of 4 bytes each.  There are 4 bytes to store
  // the original user size.  Finally, there are between 8 and 11
  // additional bytes that are set to a pattern to allow buffer overflow
  // detection. If the user asked for a number of bytes that is not
  // a multiple of 4, then the rest of the word will be used for
  // buffer flow detection (along with the next 8 bytes).  NSK is similar
  // to Windows, but doesn't store 40 extra bytes for program counters.
  // A lookup table is the quickest way to determine how many extra bytes
  // should be used.
  if (debugLevel_ == 2) {
    const size_t additionalBytes[4] = { 12, 15, 14, 13 };
    additionalUserSize += additionalBytes[userSize & 0x3];
  }
#endif // (defined(_DEBUG) || defined(NSK_MEMDEBUG)) 

  size_t nb;
  NAHeapFragment *p;
  // Clean up prev_ and next_ pointers only when debugLevel_ is 0.
  // When debugLevel_ is either 1 or 2, user memory gets reset to some
  // eye catching pattern and it must not be overwritten for overflow
  // checking logic to work.
  NABoolean cleanUpPrevNext = debugLevel_== 0 ? TRUE : FALSE;

  // If the user is allocating a large piece of memory from a non-derived
  // heap that is also not the runtime statistics shared memory segment,
  // then allocate a NABlock using mmap(). This prevents any changes
  // to the "top_" fragment and allows the memory used by the request to
  // be returned to the operating system when the user frees it.
  if (additionalUserSize >= MIN_MMAP_ALLOC_SIZE && parent_ == NULL && (! getSharedMemory()))
  {

    nb = PAD_REQUEST(additionalUserSize);
    size_t reqSize = NAHeap::granularityAlign(nb+(2*sizeof(size_t))+BLOCK_OVERHEAD+1);
    NABlock *mmappedBlock = allocateMMapBlock(reqSize);
    if (mmappedBlock != NULL) {
      // Insert this NABlock after firstBlk_ so it doesn't interfere with
      // logic that assumes firstBlk_ contains the top fragment
      if (firstBlk_ != NULL) {
        mmappedBlock->next_ = firstBlk_->next_;
        firstBlk_->next_ = mmappedBlock;
      } else {
        mmappedBlock->next_ = NULL;
        firstBlk_ = mmappedBlock;
      }

      // Adjust the least addr
      if (least_addr_ == NULL || (char*)mmappedBlock < least_addr_)
        least_addr_ = (char*)mmappedBlock;

      // Set up the NAHeapFragment, adjust more statistics and return the memory.
      p = mmappedBlock->alignAsFragment();
      p->setSizeOfMMapFragment(nb);
      incrementStats(nb);
      allocDebugProcess(p, userSize);
      return p->getMemory();
    }
    // Fall through and try to allocate the regular way.
  }

  if (additionalUserSize <= MAX_SMALL_REQUEST) {

    nb = (additionalUserSize < MIN_REQUEST) ?
           MIN_FRAGMENT_SIZE : PAD_REQUEST(additionalUserSize);
    bindex_t idx = smallIndex(nb);
    binmap_t smallbits = smallmap_ >> idx;

    if ((smallbits & 0x3) != 0) { // Remainderless fit to a smallbin.
      idx += ~smallbits & 1;       // Uses next bin if idx empty
      NAHeapFragment *b = smallbinAt(idx);
      p = b->getNext();
      size_t firstFragBit = p->getFirstFragmentBit();
      size_t fragSize = smallIndex2Size(idx);
      if (!(p->fragmentSize() == fragSize))
      assert(p->fragmentSize() == fragSize);
      unlinkFirstSmallFragment(b, p, idx);
      p->setInuseAndPinuse(fragSize | firstFragBit);
#ifdef _DEBUG
          if (p->fragmentSize() == TraceAllocSize)
            saveTrafStack(getSAL(), p);
#endif // _DEBUG
      incrementStats(fragSize);
      allocDebugProcess(p, userSize);
      checkMallocedFragment(p, nb);
      return p->getMemory(cleanUpPrevNext);
    } else if (nb > dvsize_) {

      if (smallbits != 0) { // Use fragment in next nonempty smallbin
        binmap_t leftbits = (smallbits << idx) & leftBits(idx2bit(idx));
        binmap_t leastbit = leastBit(leftbits);
        bindex_t i = bit2idx(leastbit);
        NAHeapFragment *b = smallbinAt(i);
        NAHeapFragment *p = b->getNext();
        size_t firstFragBit = p->getFirstFragmentBit();
        size_t fragSize = smallIndex2Size(i);

        assert(p->fragmentSize() == fragSize);
        unlinkFirstSmallFragment(b, p, i);
        size_t rsize = fragSize - nb;
        // Fit here cannot be remainderless if 4byte sizes
        if (sizeof(size_t) != 4 && rsize < MIN_FRAGMENT_SIZE) {
          p->setInuseAndPinuse(fragSize | firstFragBit);
          incrementStats(fragSize);
        } else {
          p->setSizeAndPinuseOfInuseFragment(nb | firstFragBit);
          NAHeapFragment *r = p->fragmentPlusOffset(nb);
          r->setSizeAndPinuseOfFreeFragment(rsize);
          replaceDV(r, rsize);
          incrementStats(nb);
        }
        allocDebugProcess(p, userSize);
        checkMallocedFragment(p, nb);
#ifdef _DEBUG
          if (p->fragmentSize() == TraceAllocSize)
            saveTrafStack(getSAL(), p);
#endif // _DEBUG
        return p->getMemory(cleanUpPrevNext);
      }

      // Try to allocate from the smallest tree fragment
      if (treemap_ != 0 && (p = tmallocSmall(nb)) != 0) {
        incrementStats(p->fragmentSize());
        allocDebugProcess(p, userSize);
        checkMallocedFragment(p, nb);
#ifdef _DEBUG
          if (p->fragmentSize() == TraceAllocSize)
            saveTrafStack(getSAL(), p);
#endif // _DEBUG
        return p->getMemory(cleanUpPrevNext);
      }
    }
  } else if (additionalUserSize >= MAX_REQUEST) {
    nb = MAX_REQUEST + 100L; // Too big to allocate. Force failure in allocateBlock.
  } else {
    nb = PAD_REQUEST(additionalUserSize);

    if (treemap_ != 0 && (p = tmallocLarge(nb)) != 0) {
      allocDebugProcess(p, userSize);
      checkMallocedFragment(p, nb);
      incrementStats(p->fragmentSize());
#ifdef _DEBUG
          if (p->fragmentSize() == TraceAllocSize)
            saveTrafStack(getSAL(), p);
#endif // _DEBUG
      return p->getMemory(cleanUpPrevNext);
    }
  }

  // The following code allocates memory from the designated victim if
  // possible.
  if (nb <= dvsize_) {
    size_t rsize = dvsize_ - nb;
    p = dv_;
    size_t firstFragBit = p->getFirstFragmentBit();

    if (rsize >= MIN_FRAGMENT_SIZE) { // split dv
      NAHeapFragment *r = dv_ = p->fragmentPlusOffset(nb);
      dvsize_ = rsize;
      r->setSizeAndPinuseOfFreeFragment(rsize);
      p->setSizeAndPinuseOfInuseFragment(nb | firstFragBit);
      incrementStats(nb);
    } else { // exhaust dv
      size_t dvs = dvsize_;
      dvsize_ = 0;
      dv_ = 0;
      p->setInuseAndPinuse(dvs | firstFragBit);
      incrementStats(dvs);
    }
    allocDebugProcess(p, userSize);
    checkMallocedFragment(p, nb);
#ifdef _DEBUG
          if (p->fragmentSize() == TraceAllocSize)
            saveTrafStack(getSAL(), p);
#endif // _DEBUG
    return p->getMemory(cleanUpPrevNext);
  }

  // If the top fragment is not large enough to hold the allocation,
  // then call allocateBlock to allocate memory from either the
  // operating system or the parent memory.
  if (nb > topsize_) {

    // Save the current size of the first block because it will be lost
    // if the first block is resized.  The size is needed later in this
    // function.
    size_t prevFirstBlockSize = firstBlk_ ? firstBlk_->size_ : 0;

    // reqSize is the maximum size that may be needed to satisfy
    // this request. NOTE: "+1" may not be nececessary but was part of
    // the Doug Lea malloc().
    size_t reqSize = NAHeap::granularityAlign(nb+(2*sizeof(size_t))+BLOCK_OVERHEAD+1);

    // allocateBlock allocates memory of at least reqSize.
    NABlock *newBlock = allocateBlock(reqSize, failureIsFatal);
    if (newBlock == NULL) {

      // If the caller set up an error callback, then call it here.
      if (errCallback_ != NULL)
        (*errCallback_)(this, userSize);

      if (failureIsFatal) {
        handleExhaustedMemory();
        abort();
      }

      // Caller will handle the error so just return null.
      return NULL;
    }

    if (least_addr_ == NULL || (char*)newBlock < least_addr_)
      least_addr_ = (char*)newBlock;

    // If the current block was resized, then adjust the top size and
    // adjust the size of prevFoot_ in the first fragment.
    if (newBlock == firstBlk_) {
      assert(newBlock->size_ > prevFirstBlockSize);
      Lng32 increasedSize = (Lng32)(newBlock->size_ - prevFirstBlockSize);
      resizeTop(topsize_ + increasedSize);

      // Adjust prevFoot_ in first fragment.
      NAHeapFragment *firstFrag = newBlock->alignAsFragment();
      firstFrag->adjustBlockSize(increasedSize);
    } else {
      // Chain the new block on the linked-list of NABlocks.
      newBlock->next_ = firstBlk_;
      firstBlk_ = newBlock;

      // If the top fragment has not been initialized or has been
      // exhausted in a previous allocation, then call initTop() to
      // initialized a new top fragment. In other cases, the top
      // fragment will contain useful memory that can be used
      // by later allocations. The code calls addBlock() to add
      // the top fragment to the freelist and to create a new top
      // fragment in the newly allocated NABlock.
      if (topsize_ == 0) {
        initTop(newBlock);
        top_->initializeFirstFragment(topsize_);
      } else {
        addBlock(newBlock);
      }
    }
  }

  assert(topsize_ >= nb);

  // If execution reaches here, then the request can be satisfied from
  // the top fragment.  If the top fragment is large enough to have useful
  // memory after satisfying the request, the top fragment will be split
  // into two fragments.  The first fragment will be returned to the caller,
  // and a pointer to the second fragment will be assigned to the top
  // fragment pointer.
  size_t rsize = topsize_ - nb;
  p = top_;

  size_t firstFragmentBit = p->getFirstFragmentBit();

  NAHeapFragment *r;

  if (rsize >= MIN_FRAGMENT_SIZE) {
    topsize_ = rsize;
    r = top_ = p->fragmentPlusOffset(nb);
    r->setSizeAndPinuse(rsize);
    p->setSizeAndPinuseOfInuseFragment(nb|firstFragmentBit);
  } else {
    // The top fragment has been exhausted. Set top_ to point to
    // the next fragment in case a later allocation resizes the
    // current NABlock.
    nb = topsize_;
    topsize_ = 0;
    top_ = p->fragmentPlusOffset(nb);
    p->setInuseAndPinuse(nb|firstFragmentBit);
  }
  checkTopFragment(top_);
  incrementStats(nb);
  allocDebugProcess(p, userSize);
  checkMallocedFragment(p, nb);
#ifdef _DEBUG
          if (p->fragmentSize() == TraceAllocSize)
            saveTrafStack(getSAL(), p);
#endif // _DEBUG
  return p->getMemory(cleanUpPrevNext);
}

// NAHeap::deallocateHeapMemory()
//   Memory is deallocated in this function.  The memory fragments
//   that may exist before and after this freed fragment are coalesced
//   with the freed memory if possible.  If the previous memory or
//   next memory is the designated victim, then the designated victim
//   will be adjusted to include this memory.  If the next memory is
//   the top fragment, then the top fragment will now include the
//   coalesced memory.  If all memory in an NABlock is freed, then
//   NAMemory::deallocateFreeBlock() will be called to either free
//   the block to the OS or to the parent memory.  If the memory
//   is not all freed and is not the designated victim or top fragment,
//   the fragment will be linked into a small bin or tree.
void NAHeap::deallocateHeapMemory(void* addr)
{
  // If addr is NULL, we are done.
  // This is apparently standard behavior. I don't like it, but some of
  // our code relies on it.
  if (addr == NULL)
    return;


  assert(type_ != NO_MEMORY_TYPE);

  NAMutex mutex(threadSafe_, &mutex_);
 
  if (getSharedMemory())
  {
    // Check if you are within semaphore
    if (! checkIfRTSSemaphoreLocked())
       NAExit(1);
  }

  HEAPLOG_DELETE_ENTRY(addr, heapID_.heapNum)

  // Get a pointer to the NAHeapFragement for this memory address
  NAHeapFragment *p  = NAHeapFragment::memToFragment(addr); 

  if (p->fragmentSize() == 0 && okCinuse(p) && okPinuse(p)) // allocateAlignedHeapMemory fragment?
  {
    p = (NAHeapFragment *)((size_t)(p) - p->getPrevFoot());
  }

#ifdef _DEBUG
  if (TraceAllocSize > 0 && p->fragmentSize() == TraceAllocSize)
    delTrafStack(getSAL(), p);
#endif // _DEBUG

  checkInuseFragment(p);
  if (!(RTCHECK(okAddress(p) && okCinuse(p)))) {
    USAGE_ERROR_ACTION;
    return;
  }

  // deallocDebugProcess() is only called in debug builds.  If
  // MEMDEBUG=1, then the freed memory is set to a 0xfdfdfdfd
  // pattern.  If MEMDEBUG=2, then a check is made to see if
  // there was a buffer overflow.
  deallocDebugProcess(p);

  // get the size of the current fragment
  size_t psize = p->fragmentSize();

  // update allocation statistics
  decrementStats(psize);

  if (type_ == EXECUTOR_MEMORY &&
      deallocTraceArray != NULL &&
      (memcmp(name_, "Global Executor Memo", 20) == 0))
  {
    deallocCount += 1;
    unsigned short i = deallocTraceIndex == deallocTraceEntries - 1 ? 0 : deallocTraceIndex + 1;
    (*deallocTraceArray)[i].begin_ = (void *)p;
    (*deallocTraceArray)[i].end_ = (void *)((char *)p + psize);
    deallocTraceIndex = i;
  }

  if (p->isMMapped()) {
    deallocateFreeBlock(p);
    return;
  }

  // Get a pointer to the next fragment
  NAHeapFragment *next = p->fragmentPlusOffset(psize);
  // Pointer to the previous fragment
  NAHeapFragment *prev = NULL;

  size_t firstFragmentBit;  // Is this the first fragment of a NABlock?

  // Save the pointer to this fragment and the size
  NAHeapFragment *q = p;
  size_t qsize = psize;

  Int32 mergeFlags = NO_MERGE;

  if (p->pinuse()) {
    firstFragmentBit = p->getFirstFragmentBit();
  } else {
    mergeFlags |= BACKWARD_MERGE;
    size_t prevsize = p->getPrevFoot();
    prev = p->fragmentMinusOffset(prevsize);
    firstFragmentBit = prev->getFirstFragmentBit();
    psize += prevsize;
    p = prev;
    if (RTCHECK(okAddress(prev))) { // consolidate backward
      if (p != dv_) {
        unlinkFragment(p, prevsize);
      } else if (next->cpinuse()) { // CINUSE_BIT and PINUSE_BIT set.
        // No further consolidation can take place.  The previous
        // fragment was the designated victim so update the dvsize.
        dvsize_ = psize;
        p->setFreeWithPinuse(psize, next);
        p->setHeadBits(firstFragmentBit);
        if (p->occupiesCompleteNABlock())
          deallocateFreeBlock(p);
        else
          q->releaseFreePages(prev, next, mergeFlags);
        return;
      }
    } else {
      USAGE_ERROR_ACTION;
      return;
    }
  }

  if (!(RTCHECK(okNext(p, next) && okPinuse(next)))) {
    USAGE_ERROR_ACTION;
    return;
  }

  if ((!next->cinuse()) || 
      ((next == top_) && (next->isFencePost()) && (topsize_ == 0))) 
  {  // consolidate forward
    mergeFlags |= FORWARD_MERGE;
    if (next == top_) {
      if ((top_->isFencePost()) && (topsize_ == 0))
         top_->clearPinuse(); // If top was set to fencepost because top was
                              // exhausted, reset the pinuse bit of the 
                              // fencepost, because the prev of the fencepost 
                              // is now top_, which should not be in use.
      size_t tsize = topsize_ += psize;
      top_ = p;
      p->setSizeAndPinuse(tsize);
      p->setHeadBits(firstFragmentBit);
      if (p == dv_) {
        dv_ = NULL;
        dvsize_ = 0;
      }
      if (p->occupiesCompleteNABlock())
        deallocateFreeBlock(p);
      else
        q->releaseFreePages(prev, next, mergeFlags);
      return;
    } else if (next == dv_) {
      size_t dsize = dvsize_ += psize;
      dv_ = p;
      p->setSizeAndPinuseOfFreeFragment(dsize);
      p->setHeadBits(firstFragmentBit);
      if (p->occupiesCompleteNABlock())
        deallocateFreeBlock(p);
      else
        q->releaseFreePages(prev, next, mergeFlags);
      return;
    } else {
      size_t nsize = next->fragmentSize();
      psize += nsize;
      unlinkFragment(next, nsize);
      p->setSizeAndPinuseOfFreeFragment(psize);
      p->setHeadBits(firstFragmentBit);
      if (p == dv_) {
        dvsize_ = psize;
        if (p->occupiesCompleteNABlock())
          deallocateFreeBlock(p);
        else
          q->releaseFreePages(prev, next, mergeFlags);
        return;
      }
    }
  } else {  // This fragment could not be consolidated forward
    p->setFreeWithPinuse(psize, next);
    p->setHeadBits(firstFragmentBit);
  }

  // If this fragment uses the whole NABlock, then deallocate it.
  if (p->occupiesCompleteNABlock()) {
    // Only return if the deallocation really occurred.
    if (deallocateFreeBlock(p))
      return;
  }
   
  q->releaseFreePages(prev, next, mergeFlags);

  // Insert the free fragment into either a small bin or tree
  insertFragment(p, psize);
  checkFreeFragment(p);

  return;
}

#endif // !MUSE

#if (defined(_DEBUG) || defined(NSK_MEMDEBUG))
void NAHeap::dumpHeapInfo(ostream* outstream, Lng32 indent)
{
  NAMutex mutex(threadSafe_, &mutex_);

  char ind[100];

  Lng32 indIdx = 0;
  for (; indIdx < indent; indIdx++)
    ind[indIdx] = ' ';
  ind[indIdx] = '\0';

  // Verify the malloc state.  This can be fairly heavyweight depending
  // on the number of allocations.
  checkMallocState();

  if (!outstream)
    outstream = &cerr;
  *outstream << ind << "Dump of Heap             " << this << ':' << endl
	     << ind << "Name:                    " << name_ << endl
	     << ind << "Parent:                  "
	     << ind << (parent_ ? parent_->name_ : " ") << endl
	     << ind << "Initial Size (Bytes):    " << initialSize_ << endl
	     << ind << "Maximum Size (Bytes):    " << maximumSize_ << endl
	     << ind << "Increment Size (Bytes):  " << incrementSize_ << endl
	     << ind << "Allocated Size (Bytes):  " << allocSize_ << endl
	     << ind << "High Water Mark (Bytes): " << highWaterMark_ << endl
             << ind << "Interval Water Mark (Bytes): " << intervalWaterMark_ << endl
	     << ind << "Allocated Units:         " << allocCnt_ << endl
	     << ind << "Total Size (Bytes):      " << totalSize_ << endl
	     << ind << "Block Count:             " << blockCnt_ << endl;
  
  MemoryStats freeStats;
  MemoryStats allocStats;
  NABlock * p = firstBlk_;
  while (p) {
    p->dump(outstream, debugLevel_, freeStats, allocStats, top_, indent);
    p = p->next_;
  }

  if (debugLevel_ == 0) {
    *outstream << "dynamicAllocs not kept because debugLevel_ == 0" << endl;
  } else {
    dynamicAllocs.dump(outstream, "all allocated", indent);
  }
  allocStats.dump(outstream, "leftover allocated", indent);
  freeStats.dump(outstream, "free", indent);
  *outstream << ind << "---------------------------------------------" << endl;

  // we are done with this heap. Go thru all the derived heaps
  // and dump their info too
  NAMemory *derivedHeap = memoryList_;
  while (derivedHeap) {
    derivedHeap->dump(outstream, indent + 2);
    derivedHeap = derivedHeap->nextEntry_;
  }
}
#endif // (defined(_DEBUG) || defined(NSK_MEMDEBUG))  ...

//////////////////////////////////////////////////////////////////////////////

// ---------------------------------------------------------------------------
// NABlock methods
// ---------------------------------------------------------------------------

#if (defined(_DEBUG) || defined(NSK_MEMDEBUG))
void NABlock::dump(ostream* outstream,
                   Lng32 debugLevel,
                   MemoryStats& freeStats,
                   MemoryStats& allocStats,
                   NAHeapFragment *top,
                   Lng32 indent)
{
  char ind[100];
  Lng32 indIdx = 0;
  for (; indIdx < indent; indIdx++)
    ind[indIdx] = ' ';
  ind[indIdx] = '\0';
  if (!outstream)
    outstream = &cerr;

  // go thru all allocated and free fragments and for Windows dump the
  // stack trace for allocated fragments
  NAHeapFragment *q = alignAsFragment();

  while (blockHolds(q) && q != top && !q->isFencePost()) {

    if (q->cinuse()) {
      // this is an allocated fragment.
      allocStats.addEntry(q->fragmentSize());


    } else {
      // this is a free fragment
      freeStats.addEntry(q->fragmentSize());
    }

    // Go to next fragment
    q = q->nextFragment();
  }
}
#endif // (defined(_DEBUG) || defined(NSK_MEMDEBUG))  ...

//////////////////////////////////////////////////////////////////////////////

MemoryStats::MemoryStats()
  : count_(0),
    sum_(0.0),
    sum2_(0.0)
{
  for (Lng32 i = 0; i < 18; i++)
    histBuckets_[i] = 0;
}

void MemoryStats::addEntry(size_t value)
{
  count_++;  // one more entry
  double fvalue = (double)value;
  sum_ += fvalue;
  sum2_ += (fvalue * fvalue);
  // determine the histogram bucket
  value = value >> 5;  // everything <= 32 ends up in the first bucket
  Lng32 i = 0;
  while(value) {
    value = value >> 1;
    i++;
  }
  // everything bigger than 2 MB ends up in the last bucket
  i = (i < 18) ? i : 17;
  histBuckets_[i]++;
}

#if (defined(_DEBUG) || defined(NSK_MEMDEBUG))
void MemoryStats::dump(ostream* outstream, const char * name, Lng32 indent)
{
  char ind[100];
  Lng32 indIdx = 0;
  for (; indIdx < indent; indIdx++)
    ind[indIdx] = ' ';
  ind[indIdx] = '\0';
  if (!outstream)
    outstream = &cerr;
  *outstream << ind << name << " units:" << endl
	     << ind << "# of entries: " << count_ << endl
	     << ind << "average size: " << (count_ ? (sum_/count_) : 0.0)
	     << endl
	     << ind << "variance:     " << ((count_ > 1) ?
    ((1.0/(double)(count_ - 1)) *
     (sum2_ - (1.0/(double)count_) * sum_ * sum_)) : 0.0) << endl;
  
  Lng32 size = 16;
  char unit = 'B';
  for (Lng32 i = 0; i < 17; i++) {
    size *= 2;
    if (i == 5) {
      unit = 'K';
      size /= 1024;
    }
    else if (i == 15) {
      size = size/1024;
      unit = 'M';
    }
    *outstream << ind << "# entries <= " << size << unit
	       << " : " << histBuckets_[i] << endl;
  }
  *outstream << ind << "# entries >  " << size << unit
	     << " : " << histBuckets_[17] << endl;
  
}
#endif // (defined(_DEBUG) || defined(NSK_MEMDEBUG)) 


// -------------------- Debugging Support ---------------------------
#if ( defined(_DEBUG) || defined(NSK_MEMDEBUG) )  

// The below values are used for buffer overflow detection. Lookup
// tables are used so that the logic for checking the remaining
// bytes in a word can be very quick.
const UInt32 buf_overflow_val = 0xF2F2F2F2; 
#ifdef NA_LITTLE_ENDIAN
const UInt32 overflow_mask[4] = { 0, 0xFFFFFF00, 0xFFFF0000, 0xFF000000 };
const UInt32 overflow_val[4] = { 0, 0xF2F2F200, 0xF2F20000, 0xF2000000 };
#else // NA_BIG_ENDIAN
const UInt32 overflow_mask[4] = { 0, 0xFFFFFF, 0xFFFF, 0xFF };
const UInt32 overflow_val[4] = { 0, 0xF2F2F2, 0xF2F2, 0xF2 };
#endif 

// doAllocDebugProcess() is called with debugLevel_ is set to at
// least 1.  It resets newly allocated memory to a 0xfafafafa. On
// Windows when debugLevel is set to 2, this function also adds
// information to indicate whether the end of the buffer has been
// overwritten and saves the last 10 levels of the stack frame.

void
NAHeap::doAllocDebugProcess(NAHeapFragment *p, size_t userSize)
{
  // Reset the user requested memory to a 0xfafafafa pattern.
  // Disabled for now, see Todo 1)
  // memset(p->getMemory(), 0xfa, userSize);

  if (debugLevel_ == 2 && p->fragmentSize() < INT_MAX) {

    // Determine location that the user requested size is stored
    // in the memory.
    size_t userSizeOffset = p->fragmentSize() - (2 * sizeof(size_t));
    UInt32 * userSizePtr = (UInt32 *)((char*)p->getMemory() + userSizeOffset);

    // Set the integer pointer to the last word in the user
    // requested memory
    UInt32 *lastWord = (UInt32*)((char*)p->getMemory() +
          ((userSize - 1) & ~(0x3))); 

    // Set the bits in the first word.  If the user memory uses the
    // whole word, then the user memory will not be modified.
    UInt32 remainder = userSize & 0x3;
    lastWord[0] = (lastWord[0] & ~overflow_mask[remainder])
                  | (buf_overflow_val & overflow_mask[remainder]); 
    // Set the bits in the next 2 words.
    lastWord[1] = buf_overflow_val; 
    lastWord[2] = buf_overflow_val; 
    // Store the userSize in the buffer.
    // Note that the userSizePtr may point to the same location of lastWord[2]
    *userSizePtr = (UInt32) userSize;

  }
}

// doDeallocDebugProcess() resets the deallocated memory to
// a 0xfdfdfdfd.  This function is only called when debugLevel_ is
// at set to at least 1.

void
NAHeap::doDeallocDebugProcess(NAHeapFragment *p)
{
  if (debugLevel_ == 2 && p->fragmentSize() < INT_MAX) {
    // Check for buffer overflows
    p->checkBufferOverflow();
  }

  // Reset the user memory to a 0xfdfdfdfd pattern.
  // size_t userSize = p->fragmentSize() - sizeof(size_t);
  // Disabled for now, see Todo 1)
  // memset(p->getMemory(), 0xfd, userSize);
}

// Check properties of any fragment, whether free, inuse, etc.
void
NAHeap::doCheckAnyFragment(NAHeapFragment *p)
{
  assert((isAligned(p->getMemory())) || (p->isFencePost()));
  assert(okAddress(p));
}

// Check properties of top fragment
void
NAHeap::doCheckTopFragment(NAHeapFragment *p)
{
  NABlock* sp = NABlock::blockHolding(firstBlk_,p);
  size_t  sz = p->fragmentSize();
  assert(sp != 0);
  assert(okAddress(p));
  assert(p->pinuse());
  if (topsize_ == 0) {
    assert(p->isFencePost());
  } else {
    assert(!p->isFencePost());
    assert(isAligned(p->getMemory()));
    assert(sz == topsize_);
    assert(sz > 0);
    assert(sz == (size_t)sp + sp->size_
               - (size_t)p - sp->firstFragmentOffset());
    assert(!p->nextPinuse());
  }
}

// Check properties of inuse fragments
void
NAHeap::doCheckInuseFragment(NAHeapFragment *p)
{
  doCheckAnyFragment(p);
  assert(p->cinuse());
  assert(p->nextPinuse());
  // If not pinuse, previous fragment has OK offset
  assert(p->pinuse() || p->prevFragment()->nextFragment() == p);
}

// Check properties of free fragments
void
NAHeap::doCheckFreeFragment(NAHeapFragment *p)
{
  size_t sz = p->fragmentSize();
  NAHeapFragment *next = p->fragmentPlusOffset(sz);
  doCheckAnyFragment(p);
  assert(!p->cinuse());
  assert(!p->nextPinuse());
  if (p != dv_ && p != top_) {
    if (sz >= MIN_FRAGMENT_SIZE) {
      assert((sz & FRAG_ALIGN_MASK) == 0);
      assert(isAligned(p->getMemory()));
      assert(next->getPrevFoot() == sz);
      assert(p->pinuse());
      assert (next == top_ || next->cinuse());
      assert(p->getNext()->getPrev() == p);
      assert(p->getPrev()->getNext() == p);
    }
    else  // markers are always of size size_t
      assert(sz == sizeof(size_t));
  }
}

// Check properties of malloced fragments at the point they are malloced
void
NAHeap::doCheckMallocedFragment(NAHeapFragment *p, size_t s)
{
  if (p != 0) {
    size_t sz = p->fragmentSize();
    doCheckInuseFragment(p);
    assert((sz & FRAG_ALIGN_MASK) == 0);
    assert(sz >= MIN_FRAGMENT_SIZE);
    assert(sz >= s);

    // size is less than MIN_FRAGMENT_SIZE more than request
    assert(sz < (s + MIN_FRAGMENT_SIZE));
  }
}

// Check a tree and its subtrees
void
NAHeap::doCheckTree(NATreeFragment *t)
{
  NATreeFragment *head = NULL;
  NATreeFragment *u = t; 
  bindex_t tindex = t->getIndex();
  size_t tsize = t->fragmentSize();
  bindex_t idx = computeTreeIndex(tsize);

  assert(tindex == idx);
  assert(tsize >= MIN_LARGE_SIZE);
  assert(tsize >= minsizeForTreeIndex(idx));
  assert((idx == NTREEBINS-1) || (tsize < minsizeForTreeIndex((idx+1))));
  
  do { // traverse through chain of same-sized nodes
    doCheckAnyFragment((NAHeapFragment*)u);
    assert(u->getIndex() == tindex);
    assert(u->fragmentSize() == tsize);
    assert(!u->cinuse());
    assert(!u->nextPinuse());
    assert(u->getNext()->getPrev() == u);
    assert(u->getPrev()->getNext() == u);
    if (u->getParent() == NULL) {
      assert(u->getChild(0) == NULL);
      assert(u->getChild(1) == NULL);
    }
    else {
      assert(head == 0); // only one node on chain has parent
      head = u;
      assert(u->getParent() != u);
      assert (u->getParent()->getChild(0) == u ||
              u->getParent()->getChild(1) == u ||
              *((NATreeFragment**)u->getParent()) == u);
      if (u->getChild(0) != NULL) {
        assert(u->getChild(0)->getParent() == u);
        assert(u->getChild(0) != u);
        doCheckTree(u->getChild(0));
      }
      if (u->getChild(1) != NULL) {
        assert(u->getChild(1)->getParent() == u);
        assert(u->getChild(1) != u);
        doCheckTree(u->getChild(1));
      }
      if (u->getChild(0) != NULL && u->getChild(1) != NULL) {
        assert(u->getChild(0)->fragmentSize() <
               u->getChild(1)->fragmentSize());
      }
    }
    u = (NATreeFragment*)u->getNext();
  } while (u != t);
  assert(head != NULL);
}

// Check all the fragments in a treebin
void
NAHeap::doCheckTreebin(bindex_t i)
{
  NATreeFragment **tb = treebinAt(i);
  NATreeFragment *t = *tb;
  NABoolean empty = (treemap_ & (1U << i)) == 0;
  if (t == 0)
    assert(empty);
  if (!empty)
    doCheckTree(t);
}

// Check all the fragments in a smallbin
void
NAHeap::doCheckSmallbin(bindex_t i)
{
  NAHeapFragment *b = smallbinAt(i);
  NAHeapFragment *p = b->getPrev();
  NABoolean empty = (smallmap_ & (1U << i)) == 0;
  if (p == b)
    assert(empty);
  if (!empty) {
    for (; p != b; p = p->getPrev()) {
      size_t size = p->fragmentSize();
      NAHeapFragment *q;
      // each fragment claims to be free
      doCheckFreeFragment(p);
      // fragment belongs in bin
      assert(smallIndex(size) == i);
      assert(p->getPrev() == b ||
             p->getPrev()->fragmentSize() == p->fragmentSize());
      // fragment is followed by an inuse fragment
      q = p->nextFragment();
      if (!q->isFencePost())
        doCheckInuseFragment(q);
    }
  }
}

// Check all of the properties in NAMemory related to Doug Lea's malloc()
void
NAHeap::doCheckMallocState()
{
  bindex_t i;
  size_t total;

  // check bins
  for (i = 0; i < NSMALLBINS; ++i)
    doCheckSmallbin(i);
  for (i = 0; i < NTREEBINS; ++i)
    doCheckTreebin(i);

  if (dvsize_ != 0)  { // check dv fragment
    doCheckAnyFragment(dv_);
    assert(dvsize_ == dv_->fragmentSize());
    assert(dvsize_ >= MIN_FRAGMENT_SIZE);
    assert(binFind(dv_) == 0);
  }

  if (top_ != NULL) {   // check top fragment
    doCheckTopFragment(top_);
    if (topsize_ == 0) {
      assert(top_->isFencePost());
    } else {
      assert(topsize_ == top_->fragmentSize());
    }
    assert(binFind(top_) == 0);
  }

  total = traverseAndCheck();
  assert(total <= totalSize_);
  assert(allocSize_ <= highWaterMark_);
  assert(allocSize_ <= intervalWaterMark_);

  // also check for overflow
  if (debugLevel_ == 2)
    checkForOverflow();

}

// Find x in a bin. Used in other check functions.
NABoolean
NAHeap::binFind(NAHeapFragment *x)
{
  size_t size = x->fragmentSize();
  if (isSmall(size)) {
    bindex_t sidx = smallIndex(size);
    NAHeapFragment *b = smallbinAt(sidx);
    if (smallmapIsMarked(sidx)) {
      NAHeapFragment *p = b;
      do {
        if (p == x)
          return TRUE;
      } while ((p = p->getNext()) != b);
    }
  } else {
    bindex_t tidx = computeTreeIndex(size);
    if (treemapIsMarked(tidx)) {
      NATreeFragment *t = *treebinAt(tidx);
      size_t sizebits = size << leftshiftForTreeIndex(tidx);
      while (t != 0 && t->fragmentSize() != size) {
        t = t->getChild((sizebits >> (SIZE_T_BITSIZE - 1)) & 1);
        sizebits <<= 1;
      }
      if (t != 0) {
        NATreeFragment *u = t;
        do {
          if (u == (NATreeFragment*)x)
            return TRUE;
        } while ((u = (NATreeFragment*)u->getNext()) != t);
      }
    }
  }
  return FALSE;
}

// Traverse each fragment and check it; return total
size_t
NAHeap::traverseAndCheck()
{
  size_t sum = 0;
  size_t blockCnt = 0;
  NABlock *s = firstBlk_;

  if (s != NULL) {
    sum += topsize_ + BLOCK_OVERHEAD;

    while (s != NULL) {
      ++blockCnt;
      NAHeapFragment *q = s->alignAsFragment();

      // The first fragment of an externally allocated segment should
      // not have the first fragment bit set. If the NABlock was allocated
      // using mmap, then either the first fragment should have the first
      // fragment bit set or should have the MMAPPED_BIT set. If mmap was
      // not used to allocate the NABlock, then the first fragment should
      // have the first fragment bit set. All other fragments should not
      // have either bit set.
      if (s->isExternSegment()) {
        assert(!q->getFirstFragmentBit());
      } else {
        if (s->isMMapped()) {
          assert(q->getFirstFragmentBit() || q->isMMapped());
        } else {
          assert(q->getFirstFragmentBit());
        }
      }

      NAHeapFragment *lastq = NULL;
      assert(q->pinuse());
      while (s->blockHolds(q) && q != top_) {
        sum += q->fragmentSize();
        if (q->cinuse()) {
          assert(!binFind(q));
          doCheckInuseFragment(q);
        } else {
          assert(q == dv_ || binFind(q));
          assert(lastq == NULL || lastq->cinuse()); // Not 2 consecutive free
          doCheckFreeFragment(q);
        }
        lastq = q;
        q = q->nextFragment();

        // Quit if this is a fencepost. This is put here because a fencepost
        // may have the same bit set as a mmap'ed fragment.
        if (q->isFencePost())
          break;
        assert(!q->getFirstFragmentBit());
        assert(!q->isMMapped());
      }
      s = (NABlock*)s->next_;
    }
  }
  assert (blockCnt == blockCnt_);
  return sum;
}

void
NAHeapFragment::checkBufferOverflow()
{
  size_t userSizeOffset = fragmentSize() - (2 * sizeof(size_t));
  UInt32 *userSizePtr = (UInt32*)((char*)getMemory() + userSizeOffset);
  UInt32 userSize = *userSizePtr;

  // Set pointer to the last word of the user allocated memory.
  UInt32 *lastWord = (UInt32*)((char*)getMemory() 
        + ((userSize - 1) & ~(0x3))); 

  // Check for buffer overflow;
  UInt32 remainder = userSize & 0x3;
  if ((lastWord[0] & overflow_mask[remainder]) != overflow_val[remainder] || 
      lastWord[1] != buf_overflow_val) {
//    char buf[128];
//    sprintf(buf, "Buffer overflow of memory allocated at %p (Size=" PFSZ ")\n",
//            getMemory(), userSize);
//    cerr << buf;
    assert(0);  // overflow detected
  }
  if (userSizePtr != &lastWord[2] && lastWord[2] != buf_overflow_val)
    assert(0);  // overflow detected
}

// Traverse over all of the blocks for this NAHeap to see if any of them contain
// buffers that have overflowed.
void
NAHeap::checkForOverflow()
{
  NABlock *bp = firstBlk_;
  while (bp != NULL) {
    NAHeapFragment *fp = bp->alignAsFragment();
    while (!fp->isFencePost()) {
      if (fp->cinuse()) {
        fp->checkBufferOverflow();
      }
      fp = fp->nextFragment();
    }
    bp = bp->next_;
  }
}

#endif // ( defined(_DEBUG) || defined(NSK_MEMDEBUG) )  

#ifdef _DEBUG
void
NAHeap::setAllocTrace()
{
  static THREAD_P bool traceEnvChecked = 0;

  if (!traceEnvChecked)
    {
      char *traceEnv = getenv("TRACE_ALLOC_SIZE");
      if (traceEnv != NULL && atol(traceEnv) > 0)
        TraceAllocSize = atol(traceEnv);
      else
        TraceAllocSize = 0;
      traceEnvChecked = true;
    }
  if (TraceAllocSize != 0 && memcmp(name_, "Process Stats Heap", 18))
    la_ = new LIST(TrafAddrStack *)(NULL); // on C++ heap
  else
    la_ = NULL;
}
#endif // _DEBUG


// -----------------------------------------------------------------------
// methods for class DefaultIpcHeap
// -----------------------------------------------------------------------

// This object is allocated on either global or a passed-in heap. 
// Its dstr (defined here) is never explicitly called. 
DefaultIpcHeap::~DefaultIpcHeap()
{
   destroy();
}
void DefaultIpcHeap::destroy()
{
  // This class can't delete anything because it doesn't keep track of
  // any of its allocations.
}

void * DefaultIpcHeap::allocateIpcHeapMemory(size_t size, NABoolean failureIsFatal)
{
  if (! checkSize(size, failureIsFatal))
     return NULL;

  void * rc = ::operator new(size);
  HEAPLOG_ADD_ENTRY(rc, size, heapID_.heapNum, getName())
  if (rc) return rc;
  if (failureIsFatal) 
    {
      handleExhaustedMemory();
      abort();
    }
  return rc; 
}

void DefaultIpcHeap::deallocateIpcHeapMemory(void * buffer)
{
  HEAPLOG_DELETE_ENTRY(buffer, heapID_.heapNum)
  ::operator delete(buffer);
}

#if (defined(_DEBUG) || defined(NSK_MEMDEBUG))
void DefaultIpcHeap::dumpIpcHeapInfo(ostream* outstream, Lng32 indent)
{
  // This class doesn't keep track of anything so it can't dump anything
  // useful.
}
#endif

// Release unused memory in the heap back to kernel. This will help
// reduce the memory pressure and increase the free page count.
void NAHeapFragment::releaseFreePages(NAHeapFragment *prev, 
                                      NAHeapFragment *next, 
                                      Int32 mergeFlags)
{
}

SEG_ID gStatsSegmentId_ = -1;
#define RMS_SEGMENT_ID_OFFSET 0x10000000

SEG_ID getStatsSegmentId()

{
  Int32 segid;
  Int32 error;
  if (gStatsSegmentId_ == -1)
  {
   error = msg_mon_get_my_segid(&segid);
   assert(error == 0);//XZFIL_ERR_OK);
   gStatsSegmentId_ = segid + RMS_SEGMENT_ID_OFFSET;
  }
  return gStatsSegmentId_; 
}

