/* ------------------------------------------------------------------
 * Copyright (C) 2008 PacketVideo
 *
 * Licensed 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.
 * -------------------------------------------------------------------
 */

/*! \file oscl_mem_audit.cpp
    \brief This file contains the implementation of MM_Audit class
*/
#include "osclconfig_memory.h"

#if (!OSCL_BYPASS_MEMMGT)

#include "oscl_types.h"
#include "oscl_mem.h"
#include "oscl_mem_audit.h"
#include "oscl_mem_audit_internals.h"
#include "oscl_assert.h"
#include "oscl_stdstring.h"


#if MM_AUDIT_FENCE_SUPPORT
const uint32 PRE_PAD_SIZE = sizeof(MM_AllocBlockFence);
const uint32 POST_FENCE_SIZE = sizeof(MM_AllocBlockFence);
#else
const uint32 PRE_PAD_SIZE = 0;
const uint32 POST_FENCE_SIZE = 0;
#endif

const uint32 CONTROL_HEADER_SIZE = sizeof(MM_AllocBlockHdr);
const uint32 BLOCK_HDR_SIZE = CONTROL_HEADER_SIZE + PRE_PAD_SIZE;
const uint32 BLOCK_OVERHEAD_SIZE = BLOCK_HDR_SIZE + POST_FENCE_SIZE;


/**
 * MM_Audit_Imp constructor and descontructor
 */

/* ======================================================================== */
/*	Function : MM_Audit()													*/
/*	Date     : 10/08/2002													*/
/*	Purpose  : Constructor, create the root node in statistics table		*/
/*	In/out   :																*/
/*	Return   :																*/
/*	Modified :																*/
/* ======================================================================== */

const char root_tag[] = "";

MM_Audit_Imp::MM_Audit_Imp()
{
    mpCurrAllocNode = mpAllocNode = NULL;
    mNumAllocNodes = 0;

    prefill_pattern = DEFAULT_PREFILL_PATTERN;
    postfill_pattern = DEFAULT_POSTFILL_PATTERN;

    mpStatsNode = NULL;
    mnAllocNum = 0;
    mnMaxTagLevel = 10;

    mm_audit_per_block_overhead = 0;
    mm_audit_stats_overhead = 0;

    mode = DEFAULT_MM_AUDIT_MODE;

    /* create root node in memory statistics table */
    mpStatsNode = createStatsNode(root_tag);
}

/* ======================================================================== */
/*	Function : ~MM_Audit()													*/
/*	Date     : 10/08/2002													*/
/*	Purpose  : destructor, remove all the nodes in allocation and			*/
/*			   statistics table												*/
/*	In/out   :																*/
/*	Return   :																*/
/*	Modified :																*/
/* ======================================================================== */

MM_Audit_Imp::~MM_Audit_Imp()
{

#if MM_AUDIT_ALLOC_NODE_SUPPORT
    /**
     * Delete all the allocation nodes
     */
    removeALLAllocNodes();
    mpAllocNode = mpCurrAllocNode = NULL;
    mnAllocNum = 0;
#endif

    /**
     * Delete all the statistics nodes
     */
    mpStatsNode = NULL;

    mTagTree.clear();
}


/*
* ===================== API FUNCTIONS: MM_xxx() ==================================
*/

/* ============================================================================ */
/*	Function : MM_allocate()													*/
/*	Date     : 10/08/2002														*/
/*	Purpose  : API for a memory allocation attempt: create a new node in		*/
/*			   allocation table and update/create the corresponding node in		*/
/*			   statistics table													*/
/*	In/out   : all parameters are input											*/
/*	Return   : memory pointer, if something is wrong, the pointer will be NULL	*/
/*	Modified :																	*/
/* ============================================================================	*/

OSCL_EXPORT_REF void* MM_Audit_Imp::MM_allocate(const OsclMemStatsNode* pInStatsNode,
        uint32 sizeIn,
        const char *pFileName,
        uint32 lineNumber,
        bool allocNodeTracking)
{

#if defined(DEBUG_ENABLE)
    PVUStackTrace();
    if (pFileName)
    {
        printf("In MM_allocate, nBytes %d, file_name is %s, line_num is %d\n", sizeIn, pFileName, lineNumber);
    }
    else
    {
        printf("In MM_allocate with tag %s operator, nBytes %d\n", sizeIn);
    }
#endif

    MMAuditUint8AutoPtr pMem;
    void  *pMem_out = NULL;

#if (MM_AUDIT_ALLOC_NODE_SUPPORT && MM_AUDIT_INCLUDE_ALL_HEAP_VALIDATION)
    if (mode & MM_AUDIT_VALIDATE_ALL_HEAP_FLAG)
    {
        validate_all_heap();
    }
#endif

    OsclMemStatsNode* pStatsNode;
    if (pInStatsNode)
    {
        // remove "constness" of the stats node so it can be updated.
        pStatsNode = const_cast<OsclMemStatsNode*>(pInStatsNode);
    }
    else
    {
        pStatsNode = mpStatsNode; // set to the root node.
    }

    uint32 full_size = sizeIn + BLOCK_OVERHEAD_SIZE;

#if MM_AUDIT_FAILURE_SIMULATION_SUPPORT
    if (!isSetFailure(pStatsNode))
    {
        pMem.allocate(full_size);
    }
#else
    if (full_size > sizeIn)
    {
        pMem.allocate(full_size);
    }
#endif

    if (!pMem.get())
    {
        updateStatsNodeInFailure(pStatsNode);
        return NULL;
    }


    MM_AllocNode* pAllocNode = NULL;
#if MM_AUDIT_ALLOC_NODE_SUPPORT

    if ((mode & MM_AUDIT_ALLOC_NODE_ENABLE_FLAG) || allocNodeTracking ||
            (sizeIn & MM_AllocBlockHdr::ALLOC_NODE_FLAG))
    {
        if ((pAllocNode = addAllocNode((void *)pMem.get(), sizeIn, pStatsNode, pFileName, lineNumber)) == NULL)
        {
            updateStatsNodeInFailure(pStatsNode);
            return NULL;
        }
    }
#endif

    // now write the header to the block
    MM_AllocBlockHdr *block_hdr =
        static_cast<MM_AllocBlockHdr *>(static_cast<void*>(pMem.get()));
    block_hdr->size = sizeIn;
    if (pAllocNode)
    {
        block_hdr->setAllocNodeFlag();
        block_hdr->pNode = pAllocNode;
    }
    else
    {
        block_hdr->pNode =  pStatsNode;
    }

    /**
    * Save the root audit node pointer in the header.
    * This pointer will be used when the block is deallocated.
    */
    OsclAuditCB audit;
    OsclMemInit(audit);
    block_hdr->pRootNode = audit.pAudit;

#if MM_AUDIT_FILL_SUPPORT
    if ((mode & MM_AUDIT_PREFILL_FLAG))
    {
        oscl_memset(pMem.get() + BLOCK_HDR_SIZE, prefill_pattern, sizeIn);
    }
#endif


#if MM_AUDIT_FENCE_SUPPORT
    /* fill the pre-fence */
    MM_AllocBlockFence *pFence =
        static_cast<MM_AllocBlockFence*>(static_cast<void*>(pMem.get() +
                                         CONTROL_HEADER_SIZE));
    pFence->fill_fence();

    /* fill the post-fence */
    uint32 post_fence_offset = sizeIn + BLOCK_HDR_SIZE;
    pFence =
        static_cast<MM_AllocBlockFence*>(static_cast<void*>(pMem.get() +
                                         post_fence_offset));
    pFence->fill_fence();
#endif


    /* 8-byte alignment */
    pMem_out = pMem.get() + BLOCK_HDR_SIZE;
    MM_Stats_t delta;
    delta.numBytes = sizeIn;
    delta.numAllocs = 1;
    delta.numAllocFails = 0;
    updateStatsNode(pStatsNode, delta, true);

    pMem.release(); // release so it doesn't free up memory on exit

    // account for the per-block overhead
    mm_audit_per_block_overhead += BLOCK_OVERHEAD_SIZE;
    return pMem_out;

}

/* ============================================================================ */
/*	Function : MM_deallocate()													*/
/*	Date     : 10/08/2002														*/
/*	Purpose  : API for a memory de-allocation attempt: remove a node in			*/
/*			   allocation table and update the corresponding node in			*/
/*			   statistics table													*/
/*	In/out   : all parameters are input											*/
/*	Return   :																	*/
/*	Modified :																	*/
/* ============================================================================	*/

OSCL_EXPORT_REF bool  MM_Audit_Imp::MM_deallocate(void *pMemBlockIn)
{
    if (!pMemBlockIn)  return false;

    if (mpStatsNode == NULL ||
            (mpStatsNode && mpStatsNode->pMMStats && mpStatsNode->pMMStats->peakNumBytes == 0)) /* No actual allocation happens */
    {
        return true;
    }

#if (MM_AUDIT_ALLOC_NODE_SUPPORT && MM_AUDIT_INCLUDE_ALL_HEAP_VALIDATION)
    if (mode & MM_AUDIT_VALIDATE_ALL_HEAP_FLAG)
    {
        validate_all_heap();
    }
#endif

    bool status = true;
#if MM_AUDIT_VALIDATE_BLOCK
    if (mode & MM_AUDIT_VALIDATE_ON_FREE_FLAG)
    {
        if (!validate(pMemBlockIn))
        {
            return false;
        }
    }
#endif

    uint8 *pMem = static_cast<uint8 *>(pMemBlockIn);
    pMem -= BLOCK_HDR_SIZE;

    OsclMemStatsNode *pStatsNode = NULL;
    MM_AllocBlockHdr *pMemBlockHdr =
        static_cast<MM_AllocBlockHdr*>(static_cast<void*>(pMem));
    uint32 size = pMemBlockHdr->size;

#if MM_AUDIT_ALLOC_NODE_SUPPORT
    if (size & MM_AllocBlockHdr::ALLOC_NODE_FLAG)
    {
        pStatsNode = removeAllocNode((void *)pMem, size);
        OSCL_ASSERT(pStatsNode);
    }
#endif

    if (!pStatsNode)
    {
        pStatsNode = static_cast<OsclMemStatsNode*>(pMemBlockHdr->pNode);
    }
    /**
     * 3/1. update the node in memory statistics table
     */
    MM_Stats_t delta;
    delta.numAllocs = 1;
    delta.numBytes = size;
    delta.numAllocFails = 0;
    status = updateStatsNode(pStatsNode, delta, false);

#if MM_AUDIT_FILL_SUPPORT
    if ((mode & MM_AUDIT_POSTFILL_FLAG))
    {
        oscl_memset(pMem + BLOCK_HDR_SIZE, postfill_pattern, size);
    }
#endif


    MMAuditUint8AutoPtr::deallocate(pMem);

    // account for the per-block overhead
    mm_audit_per_block_overhead -= BLOCK_OVERHEAD_SIZE;


    return status;
}


/* ============================================================================ */
/*	Function : MM_GetTreeNodes()												*/
/*	Date     : 10/31/2002														*/
/*	Purpose  : API to get the number of tree nodes including the tag node and   */
/*			   its subtree														*/
/*	In/out   : all parameters are input											*/
/*	Return   : 0 means no tag node ; >0 means the number of tree nodes			*/
/*	Modified :																	*/
/* ============================================================================	*/

OSCL_EXPORT_REF uint32 MM_Audit_Imp::MM_GetTreeNodes(const char *  tagIn)
{
    int32 count = 0;

    MMAuditCharAutoPtr tag;
    makeValidTag(tagIn, tag); //tagIn = NULL means root tag
    OsclTagTreeType::iterator iter = mTagTree.find(tag.get());

    if (iter != mTagTree.end())
    {
        count++; //to account for the parent
        count = iter->children.size();
    }
    return ((uint32)count);
}



/* ================================================================================ */
/*	Function : MM_GetStats()														*/
/*	Date     : 10/08/2002															*/
/*	Purpose  : API to get memory statistics through context string(tag)				*/
/*	In/out   : all parameters are input												*/
/*	Return   : the statistics (pointer) for the current tag node					*/
/*			   if something is wrong, return NULL									*/
/*	Modified :																		*/
/* ================================================================================ */


OSCL_EXPORT_REF MM_Stats_t* MM_Audit_Imp::MM_GetStats(const char * const  tagIn)
{
    MM_Stats_t *pMMStats = NULL;
    MMAuditCharAutoPtr tag;
    makeValidTag(tagIn, tag); //tagIn = NULL means root tag
    OsclTagTreeType::iterator iter = mTagTree.find(tag.get());

    if (iter != mTagTree.end())
    {
        /* Got it! */
        OsclMemStatsNode *pStatsNode = (iter->value).get();
        if (pStatsNode)
        {
            pMMStats = pStatsNode->pMMStats;
        }
    }
    return pMMStats;
}


OSCL_EXPORT_REF uint32 MM_Audit_Imp::MM_GetStatsInDepth(const char *tagIn,
        MM_Stats_CB *array_ptr,
        uint32 max_nodes)
{
    uint32 curr_array_index = 0;
    populateChildren(tagIn, array_ptr, curr_array_index, max_nodes);
    return (curr_array_index);
}


/* ============================================================================ */
/*	Function : getNodeChildren()												*/
/*	Date     : 10/08/2002														*/
/*	Purpose  : recursive function to go throught each child node for the 		*/
/*			   current node and counter it										*/
/*	In/out   : all parameters are input											*/
/*	Return   :																	*/
/*	Modified :																	*/
/* ============================================================================	*/

void MM_Audit_Imp::populateChildren(const char *tagIn,
                                    MM_Stats_CB *array_ptr,
                                    uint32 &curr_array_index,
                                    uint32 max_nodes)
{
    MMAuditCharAutoPtr tag;
    makeValidTag(tagIn, tag); //tagIn = NULL means root tag
    OsclTagTreeType::iterator miter = mTagTree.find(tag.get());

    if (curr_array_index > max_nodes)
    {
        return;
    }

    if (miter != mTagTree.end() && max_nodes > 0)
    {
        uint32 num_children = miter->children.size();

        miter->sort_children();

        array_ptr[curr_array_index].num_child_nodes = num_children;

        for (uint32 i = 0; i < num_children; i++)
        {
            array_ptr[curr_array_index].tag = (miter->tag).tag;

            OsclMemStatsNode *pStatsNode = (miter->value).get();
            if (pStatsNode)
            {
                array_ptr[curr_array_index].pStats = pStatsNode->pMMStats;
            }
            curr_array_index++;

            if (curr_array_index > max_nodes)
            {
                return;
            }
        }

        /* access its children nodes */
        if (!miter->children.empty())
        {
            /* recursive search */
            for (uint32 i = 0; i < num_children; i++)
            {
                populateChildren((miter->children[i]->tag).tag,
                                 array_ptr,
                                 curr_array_index,
                                 max_nodes);
            }
        }
    }

    return;
}

/* ============================================================================ */
/*	Function : MM_GetTag()														*/
/*	Date     : 10/08/2002														*/
/*	Purpose  : API to get an StatsNode or creates one if it doesn't exist */
/*	In/out   : all parameters are input											*/
/*	Return   : pointer to OsclMemStatsNode if operation succeeds, NULL otherwise										*/
/*	Modified :																	*/
/* ============================================================================	*/

OSCL_EXPORT_REF const OsclMemStatsNode* MM_Audit_Imp::MM_GetTagNode(const char * tagIn)
{
    MMAuditCharAutoPtr tag;
    makeValidTag(tagIn, tag); //tagIn = NULL means root tag
    OsclTagTreeType::iterator iter = mTagTree.find(tag.get());
    if (iter != mTagTree.end())
        return ((iter->value).get());
    else
        return createStatsNode(tag.get()); /* create a new empty node */
}

/* ============================================================================ */
/*	Function : MM_GetTag()														*/
/*	Date     : 10/08/2002														*/
/*	Purpose  : API to get an existing node  */
/*	In/out   : all parameters are input											*/
/*	Return   : pointer to OsclMemStatsNode if operation succeeds, NULL otherwise										*/
/*	Modified :																	*/
/* ============================================================================	*/

OSCL_EXPORT_REF const OsclMemStatsNode* MM_Audit_Imp::MM_GetExistingTag(const char * tagIn)
{
    MMAuditCharAutoPtr tag;
    makeValidTag(tagIn, tag); //tagIn = NULL means root tag
    OsclTagTreeType::iterator iter = mTagTree.find(tag.get());
    if (iter != mTagTree.end())
        return ((iter->value).get());
    else
        return NULL;
}




/* ============================================================================ */
/*	Function : MM_Validate()													*/
/*	Date     : 10/08/2002														*/
/*	Purpose  : API to check the input pointer is a valid pointer to a chunk of  */
/*			   memory															*/
/*	In/out   : all parameters are input											*/
/*	Return   :																	*/
/*	Modified :																	*/
/* ============================================================================	*/

OSCL_EXPORT_REF bool MM_Audit_Imp::MM_Validate(const void *ptrIn)
{
    bool status = validate(const_cast<void*>(ptrIn));
    return status;
}

/* ============================================================================ */
/*	Function : MM_SetTagLevel()													*/
/*	Date     : 10/08/2002														*/
/*	Purpose  : API to set the maximum tag level,i.e. tag level for a.b.c.d = 4	*/
/*	In/out   : all parameters are input											*/
/*	Return   :																	*/
/*	Modified :																	*/
/* ============================================================================	*/

OSCL_EXPORT_REF void MM_Audit_Imp::MM_SetTagLevel(uint32 level)
{
    if (level >= 1) mnMaxTagLevel = level;
}


OSCL_EXPORT_REF void MM_Audit_Imp::MM_SetMode(uint32 in_mode)
{
    mode = in_mode;
}


OSCL_EXPORT_REF void MM_Audit_Imp::MM_SetPrefillPattern(uint8 pattern)
{
    prefill_pattern = pattern;
}


OSCL_EXPORT_REF void MM_Audit_Imp::MM_SetPostfillPattern(uint8 pattern)
{
    postfill_pattern = pattern;
}

OSCL_EXPORT_REF MM_AllocQueryInfo* MM_Audit_Imp::MM_CreateAllocNodeInfo(uint32 array_size)
{
    return(MM_AllocQueryInfo*)_oscl_malloc(array_size*sizeof(MM_AllocQueryInfo));
}

OSCL_EXPORT_REF void MM_Audit_Imp::MM_ReleaseAllocNodeInfo(MM_AllocQueryInfo* output_array)
{
    _oscl_free(output_array);
}

OSCL_EXPORT_REF uint32 MM_Audit_Imp::MM_GetAllocNodeInfo(MM_AllocQueryInfo* output_array,
        uint32 max_array_size, uint32 offset)
{
    uint32 num_nodes = 0;

    if (!output_array)
    {
        return 0;
    };


    if (offset >= mNumAllocNodes)
    {
        return 0;
    }

    MM_AllocNode *pAllocNode = mpAllocNode;

    // skip the leading nodes
    uint32 ii;
    for (ii = 0; pAllocNode && ii < offset; ++ii, pAllocNode = pAllocNode->pNext)
    {
    }

    if (ii != offset)
    {
        return 0;
    }

    MM_AllocQueryInfo* pOutNode = output_array;

    while (pAllocNode && (num_nodes < max_array_size))
    {

        pOutNode->allocNum = pAllocNode->pAllocInfo->allocNum;
        pOutNode->lineNo = pAllocNode->pAllocInfo->lineNo;
        pOutNode->size = pAllocNode->pAllocInfo->size;
        pOutNode->pMemBlock = pAllocNode->pAllocInfo->pMemBlock;
        pOutNode->size = pAllocNode->pAllocInfo->size;

        if (pAllocNode->pAllocInfo->pFileName)
        {
            oscl_strncpy(pOutNode->fileName, pAllocNode->pAllocInfo->pFileName,
                         oscl_strlen(pAllocNode->pAllocInfo->pFileName) + 1);
            pOutNode->fileName[MM_ALLOC_MAX_QUERY_FILENAME_LEN-1] = '\0';
        }
        else
        {
            pOutNode->fileName[0] = '\0';
        }

        if (pAllocNode->pAllocInfo->pStatsNode->tag)
        {
            oscl_strncpy(pOutNode->tag, pAllocNode->pAllocInfo->pStatsNode->tag,
                         oscl_strlen(pAllocNode->pAllocInfo->pStatsNode->tag) + 1);
            pOutNode->tag[MM_ALLOC_MAX_QUERY_TAG_LEN-1] = '\0';
        }
        else
        {
            pOutNode->tag[0] = '\0';
        }

        ++num_nodes;
        ++pOutNode;
        pAllocNode = pAllocNode->pNext;
    }
    return num_nodes;
}

/* ============================================================================ */
/*	Function : MM_SetFailurePoint()												*/
/*	Date     : 11/05/2002														*/
/*	Purpose  : API to insert allocation failure deterministically according to  */
/*			   allocation number associated with tag							*/
/*	In/out   : all parameters are input											*/
/*	Return   : true if operation succeeds										*/
/*	Modified :																	*/
/* ============================================================================	*/

OSCL_EXPORT_REF bool MM_Audit_Imp::MM_SetFailurePoint(const char * tagIn, uint32 alloc_number)
{
    if (alloc_number == 0) return false;

    bool status = true;
    MMAuditCharAutoPtr tag;
    makeValidTag(tagIn, tag); //tagIn = NULL means root tag
    OsclTagTreeType::iterator miter = mTagTree.find(tag.get());

    if (miter != mTagTree.end())
    {
        /* found */
        OsclMemStatsNode *pStatsNode = (miter->value).get();

        if (pStatsNode == NULL || pStatsNode->pMMFIParam == NULL)
        {
            return false;
        }
        pStatsNode->pMMFIParam->nAllocNum = alloc_number;
    }
    else
    {
        /* Needs to create a new node */
        OsclMemStatsNode *pStatsNode = createStatsNode(tag.get());
        if (pStatsNode == NULL || pStatsNode->pMMFIParam == NULL)
        {
            return false;
        }
        pStatsNode->pMMFIParam->nAllocNum = alloc_number;
    }

    return status;
}


/* ============================================================================ */
/*	Function : MM_UnsetFailurePoint()											*/
/*	Date     : 11/05/2002														*/
/*	Purpose  : API to cancel the allocation failure point associated with tag	*/
/*	In/out   : all parameters are input											*/
/*	Return   :																	*/
/*	Modified :																	*/
/* ============================================================================	*/

OSCL_EXPORT_REF void MM_Audit_Imp::MM_UnsetFailurePoint(const char * tagIn)
{
    MMAuditCharAutoPtr tag;
    makeValidTag(tagIn, tag); //tagIn = NULL means root tag
    OsclTagTreeType::iterator miter = mTagTree.find(tag.get());

    if (miter != mTagTree.end())
    {
        /* found */
        OsclMemStatsNode *pStatsNode = (miter->value).get();
        if (pStatsNode && pStatsNode->pMMFIParam)
        {
            pStatsNode->pMMFIParam->nAllocNum = 0;
        }
    }
}


/*
* ===================== PRIVATE (SUPPORTING) FUNCTIONS ===========================
*/


#if MM_AUDIT_ALLOC_NODE_SUPPORT
/* ============================================================================ */
/*	Function : addAllocNode()													*/
/*	Date     : 10/08/2002														*/
/*	Purpose  : add a node in memory allocation table triggered by an allocation	*/
/*			   attempt, i.e. MM_allocate(); then update/creat the corresponding */
/*			   node in memory statistics table									*/
/*	In/out   : all parameters are input											*/
/*	Return   : true if operation succeeds										*/
/*	Modified :																	*/
/* ============================================================================	*/

MM_AllocNode* MM_Audit_Imp::addAllocNode(void *pMemBlockIn, uint32 sizeIn,
        OsclMemStatsNode *pStatsNode,
        const char *pFileName, uint32 lineNumber
                                        )
{
    uint32 tmp_overhead_size = 0;

    /**
     * 1. allocate memory for a new node
     */

    MM_AllocNodeAutoPtr currAllocAutoPtr(new MM_AllocNode);
    if (! currAllocAutoPtr.get())
    {
        return NULL;
    }
    tmp_overhead_size += sizeof(MM_AllocNode);

    MM_AllocInfo* pAllocInfo = currAllocAutoPtr->pAllocInfo = new MM_AllocInfo;
    if (pAllocInfo == NULL)
    {
        return NULL;
    }
    tmp_overhead_size += sizeof(MM_AllocInfo);

    // allocate space for the filename in AllocInfo
    if (pFileName)
    {
        int len = oscl_strlen(pFileName);
        Oscl_TAlloc<char, OsclMemBasicAllocator> charAlloc;
        if ((pAllocInfo->pFileName =
                    charAlloc.allocate(len + 1)) == NULL)
        {
            return NULL;
        }
        oscl_strncpy(const_cast<char*>(pAllocInfo->pFileName), pFileName, oscl_strlen(pFileName) + 1);
        tmp_overhead_size += len + 1;
    }

    pAllocInfo->allocNum  = mnAllocNum;

    //To find memory leaks by allocation number, put a debug breakpoint here, like this:
    //if(mnAllocNum==113)
    //{
    //  mnAllocNum++;
    //  mnAllocNum--;
    //}

    //To find allocations with a NULL filename, put a debug breakpoint here, like this:
    //if(pFileName==NULL)
    //{
    //  mnAllocNum++;
    //  mnAllocNum--;
    //}

    mnAllocNum++;

    pAllocInfo->pMemBlock = pMemBlockIn;
    pAllocInfo->size	  = sizeIn;
    pAllocInfo->lineNo  = lineNumber;
    pAllocInfo->pStatsNode = pStatsNode;

    if (!mpCurrAllocNode)  /* First node */
    {
        /* mpAllocNode always represents the very first node */
        mpAllocNode = mpCurrAllocNode = currAllocAutoPtr.release();
    }
    else
    {
        OSCL_ASSERT(!mpCurrAllocNode->pNext);
        mpCurrAllocNode->pNext = currAllocAutoPtr.release();
        currAllocAutoPtr->pPrev = mpCurrAllocNode;
        mpCurrAllocNode = mpCurrAllocNode->pNext;
    }

#if 0
    //for debug & analysis-- print all allocations as they occur...
    fprintf(stderr, "Alloc Info:\n");
    fprintf(stderr, "  allocNum %d\n", pAllocInfo->allocNum);
    fprintf(stderr, "  fileName %s\n", pAllocInfo->pFileName);
    fprintf(stderr, "  lineNo %d\n", pAllocInfo->lineNo);
    fprintf(stderr, "  size %d\n", pAllocInfo->size);
    fprintf(stderr, "  pMemBlock 0x%x\n", pAllocInfo->pMemBlock);
    fprintf(stderr, "  tag %s\n", pAllocInfo->pStatsNode->tag);
#endif

    /* increment the list counter */
    ++mNumAllocNodes;

    mm_audit_per_block_overhead += tmp_overhead_size;
    return mpCurrAllocNode;

}

/* ============================================================================ */
/*	Function : removeAllocNode()												*/
/*	Date     : 10/08/2002														*/
/*	Purpose  : remove a node in memory allocation table triggered by an			*/
/*			   de-allocationattempt, i.e. MM_deallocate()						*/
/*	In/out   : all parameters are input											*/
/*	Return   : true if operation succeeds										*/
/*	Modified :																	*/
/* ============================================================================	*/

OsclMemStatsNode* MM_Audit_Imp::removeAllocNode(void *pMemBlockIn, uint32& size)
{

    if (pMemBlockIn == NULL)
        return NULL;

    OsclMemStatsNode *pStatsNode = NULL;

    OSCL_ASSERT(mpAllocNode);
    OSCL_ASSERT(mpCurrAllocNode);
    OSCL_ASSERT(mNumAllocNodes);

    /* take the allocation node pointer from the control info header */
    MM_AllocBlockHdr *pMemBlockHdr = static_cast<MM_AllocBlockHdr*>(pMemBlockIn);
    MM_AllocNode *pAllocNode = static_cast<MM_AllocNode*>(pMemBlockHdr->pNode);
    if (!pAllocNode)  return NULL;

    /*
     * 1. remove the current node from the list
     */
    if (pAllocNode == mpAllocNode)
    {
        /* head of the list*/
        mpAllocNode = mpAllocNode->pNext;
        if (mpAllocNode)
        {
            mpAllocNode->pPrev = NULL;
        }
        else
        {
            // list is empty
            mpCurrAllocNode = mpAllocNode = NULL;
        }
    }
    else if (pAllocNode == mpCurrAllocNode) /* end of the list */
    {
        mpCurrAllocNode = mpCurrAllocNode->pPrev;
        if (mpCurrAllocNode)
        {
            mpCurrAllocNode->pNext = NULL;
        }
        else
        {
            // list is empty
            mpCurrAllocNode = mpAllocNode = NULL;
        }
    }
    else   /* somewhere in the list */
    {
        MM_AllocNode *pPrevNode = pAllocNode->pPrev;
        MM_AllocNode *pNextNode = pAllocNode->pNext;

        OSCL_ASSERT(pPrevNode && pNextNode);

        pPrevNode->pNext = pNextNode;
        pNextNode->pPrev = pPrevNode;
    }

    /**
     * 2. free the memory for the current node
     */
    OSCL_ASSERT(pAllocNode->pAllocInfo);
    pStatsNode = pAllocNode->pAllocInfo->pStatsNode;
    size = pAllocNode->pAllocInfo->size;

    // adjust the overhead accounting
    uint32 filename_len = (pAllocNode->pAllocInfo->pFileName) ? oscl_strlen(pAllocNode->pAllocInfo->pFileName) + 1 : 0;
    mm_audit_per_block_overhead -= sizeof(MM_AllocNode) + sizeof(MM_AllocInfo) +
                                   filename_len;


    OSCL_DELETE(pAllocNode);



    /*
     * decrement the list counter
     */
    --mNumAllocNodes;




    return pStatsNode;

}

/* ============================================================================ */
/*	Function : removeALLAllocNodes()											*/
/*	Date     : 10/08/2002														*/
/*	Purpose  : remove all the nodes in memory allocation table needed in 		*/
/*			   destructor														*/
/*	In/out   :																	*/
/*	Return   :																	*/
/*	Modified :																	*/
/* ============================================================================	*/

void MM_Audit_Imp::removeALLAllocNodes()
{

    while (mpCurrAllocNode)
    {
        MM_AllocNode *pTmpNode = mpCurrAllocNode;
        mpCurrAllocNode = mpCurrAllocNode->pPrev;
        if (mpCurrAllocNode)
            mpCurrAllocNode->pNext = NULL;
        --mNumAllocNodes;
        OSCL_DELETE(pTmpNode);
    }
}


bool MM_Audit_Imp::validate_all_heap()
{

    // walk the list of allocated nodes
    MM_AllocNode *ptr = mpAllocNode;

    if (!ptr)
    {
        OSCL_ASSERT(mNumAllocNodes == 0);
        return true;
    }

    uint32 counter;

    OSCL_ASSERT(ptr->pPrev == NULL);
    for (counter = 0; ptr; ptr = ptr->pNext, ++counter)
    {
        MM_AllocBlockHdr *pMemBlockHdr = static_cast<MM_AllocBlockHdr*>(ptr->pAllocInfo->pMemBlock);

        OSCL_ASSERT(pMemBlockHdr->pNode == (void *)ptr);
        if (ptr->pNext)
        {
            OSCL_ASSERT(ptr->pNext->pPrev == ptr);
        }
        else
        {
            OSCL_ASSERT(ptr == mpCurrAllocNode);
        }

        uint8* pMem = static_cast<uint8*>(static_cast<void*>(pMemBlockHdr));
        pMem += BLOCK_HDR_SIZE;
        bool status = validate(pMem);
        OSCL_ASSERT(status);
        if (!status)
        {
            return false;
        }
    }

    OSCL_ASSERT(counter == mNumAllocNodes);

    return true;

}


#endif // #if MM_AUDIT_ALLOC_NODE_SUPPORT

/* ============================================================================ */
/*	Function : validate()														*/
/*	Date     : 11/05/2002														*/
/*	Purpose  : validate the input pointer to a chunk of memory					*/
/*	In/out   : input the memory pointer						*/
/*	Return   : true if operation succeeds										*/
/*	Modified :																	*/
/* ============================================================================	*/

bool MM_Audit_Imp::validate(void *ptrIn)
{
    if (!ptrIn) return false;

    uint8 *pMem = static_cast<uint8*>(const_cast<void*>(ptrIn));

    pMem -= BLOCK_HDR_SIZE;

    MM_AllocBlockHdr *pMemBlockHdr =
        static_cast<MM_AllocBlockHdr*>((void *)pMem);

    OSCL_ASSERT(pMemBlockHdr->pNode);
    if (!pMemBlockHdr->pNode)
    {
        return false;
    }


    OsclMemStatsNode *pStatsNode = NULL;
#if MM_AUDIT_ALLOC_NODE_SUPPORT
#if MM_AUDIT_FENCE_SUPPORT
    uint32 size = pMemBlockHdr->size;
#endif
    if (pMemBlockHdr->isAllocNodePtr())
    {
        MM_AllocNode *pAllocNode = NULL;
        pAllocNode = static_cast<MM_AllocNode*>(pMemBlockHdr->pNode);
        OSCL_ASSERT(pAllocNode->pAllocInfo);
#if MM_AUDIT_FENCE_SUPPORT
        OSCL_ASSERT(((size ^ pAllocNode->pAllocInfo->size) & (~MM_AllocBlockHdr::ALLOC_NODE_FLAG)) == 0);
        size = pAllocNode->pAllocInfo->size;
#endif
        pStatsNode =  pAllocNode->pAllocInfo->pStatsNode;
    }
#endif

    if (!pStatsNode)
    {
        // must be a stats node
        pStatsNode = static_cast<OsclMemStatsNode*>(pMemBlockHdr->pNode);
    }

    OSCL_ASSERT(pStatsNode->pMMStats);

#if MM_AUDIT_FENCE_SUPPORT
    bool status;

    // check the pre-fence
    MM_AllocBlockFence *fence =
        static_cast<MM_AllocBlockFence*>(static_cast<void*>(pMem +
                                         CONTROL_HEADER_SIZE));
    status = fence->check_fence();
    OSCL_ASSERT(status);
    if (!status)
    {
        return status;
    }

    // check the post fence
    fence =
        static_cast<MM_AllocBlockFence*>(static_cast<void*>(pMem +
                                         BLOCK_HDR_SIZE
                                         + size));
    status = fence->check_fence();
    OSCL_ASSERT(status);
    if (!status)
    {
        return status;
    }
#endif

    return true;
}

/** Retrieve the audit root pointer from within an allocation block*/
OsclMemAudit * MM_Audit_Imp::getAuditRoot(void *ptrIn)
{
    if (!ptrIn) return false;

    uint8 *pMem = static_cast<uint8*>(const_cast<void*>(ptrIn));

    pMem -= BLOCK_HDR_SIZE;

    MM_AllocBlockHdr *pMemBlockHdr =
        static_cast<MM_AllocBlockHdr*>((void *)pMem);

    return (OsclMemAudit*)pMemBlockHdr->pRootNode;
}

uint32 MM_Audit_Imp::getSize(void *ptrIn)
{//get original allocation size.

    if (!ptrIn)
        return 0;

    uint8 *pMem = static_cast<uint8*>(const_cast<void*>(ptrIn));

    pMem -= BLOCK_HDR_SIZE;

    MM_AllocBlockHdr *pMemBlockHdr = static_cast<MM_AllocBlockHdr*>((void *)pMem);

    //if it's an alloc node we have to strip out the alloc node bit
    //from the size field.
    if (pMemBlockHdr->isAllocNodePtr())
    {
        return pMemBlockHdr->size & ~MM_AllocBlockHdr::ALLOC_NODE_FLAG;
    }
    else
    {
        return pMemBlockHdr->size;
    }
}


/* ============================================================================ */
/*	Function : createStatsNode()												*/
/*	Date     : 10/08/2002														*/
/*	Purpose  : creat a new node in memory statistics table triggered by an		*/
/*			   allocation attempt,												*/
/*	In/out   : all parameters are input											*/
/*	Return   : true if operation succeeds										*/
/*	Modified :																	*/
/* ============================================================================	*/


OsclMemStatsNode* MM_Audit_Imp::createStatsNode(const char *  tagIn)
{
    OsclTagTreeType::iterator iter;
    MMAuditCharAutoPtr currentTag;
    OsclMemStatsNode* statsNode;

    /* If the input tag already exists in the tagtree, it should have a pointer value of NULL */
    OSCL_ASSERT((mTagTree.find(const_cast<char* const&>(tagIn)) == mTagTree.end()) ||
                (mTagTree.find(const_cast<char* const&>(tagIn)))->value.get() == 0);

#if 1
    statsNode = new OsclMemStatsNode;
    if (statsNode == NULL) return NULL;

    currentTag.allocate(oscl_strlen(tagIn) + 1);
    if (!currentTag.get()) return NULL;
    oscl_strncpy(currentTag.get(), tagIn, oscl_strlen(tagIn) + 1);
    statsNode->tag = currentTag.release();

    if ((statsNode->pMMStats = new MM_Stats_t) == NULL) return NULL;

    if ((statsNode->pMMFIParam = new MM_FailInsertParam) == NULL) return NULL;

    OsclMemStatsNodeAutoPtr statsNodeAutoPtr(statsNode);

    // reassign ownership of the StatsNode to the tag tree
    mTagTree[statsNodeAutoPtr->tag] = statsNodeAutoPtr;

    // account for the overhead memory
    mm_audit_stats_overhead += sizeof(MM_Stats_t) +
                               sizeof(MM_FailInsertParam) +
                               sizeof(OsclMemStatsNode) +
                               oscl_strlen(currentTag.get()) + 1;

    // how many levels deep is the node we just inserted?
    iter = mTagTree.find(statsNodeAutoPtr->tag);
    uint32 depth = iter->depth();

    // the tag tree will automatically create the parent, grandparent, etc.
    // make sure each ancestor's stats node is initialized, i.e. initialize each ancestor
    // until you reach one that is already initialized.
    OsclTagTreeType::node_ptr parent = iter->parent;
    for (uint32 ii = 0; ii < depth; ii++)
    {

        OSCL_ASSERT(parent != 0);

        // if initialized then we're done
        OsclMemStatsNode* tmpStatsNode = (parent->value).get();
        if (tmpStatsNode != NULL) break;

        // create new stats node
        tmpStatsNode = new OsclMemStatsNode;
        if (tmpStatsNode == NULL) return NULL;

        // copy tag already created by the tag tree
        currentTag.allocate(oscl_strlen(parent->tag.tag) + 1);
        if (!currentTag.get()) return NULL;
        oscl_strncpy(currentTag.get(), parent->tag.tag, oscl_strlen(parent->tag.tag) + 1);
        tmpStatsNode->tag = currentTag.release();

        if ((tmpStatsNode->pMMStats = new MM_Stats_t) == NULL) return NULL;

        if ((tmpStatsNode->pMMFIParam = new MM_FailInsertParam) == NULL) return NULL;

        // set the new stats node to be held by the tag tree
        parent->value.takeOwnership(tmpStatsNode);

        // account for the overhead memory
        mm_audit_stats_overhead += sizeof(OsclMemStatsNode) +
                                   oscl_strlen(currentTag.get()) + 1 +
                                   sizeof(MM_Stats_t) +
                                   sizeof(MM_FailInsertParam);

        parent = parent->parent;
    }

    return statsNode;
#else
    OsclMemStatsNodeAutoPtr pCurrentStatsAutoPtr;
    OsclMemStatsNode* pStatsNodePtr = NULL;
    uint32 len = oscl_strlen(tagIn) + 1;

    do
    {
        if ((iter = mTagTree.find(currentTag.get())) == mTagTree.end())
        {
            // printf("Didn't find tag %s.  Creating a new stats node\n", currentTag.get());
            OsclMemStatsNodeAutoPtr statsNodeAutoPtr(new OsclMemStatsNode);
            if (statsNodeAutoPtr.get() == NULL)
            {
                return NULL;
            }

            // statsNodeAutoPtr will now "own" the tag string. It will
            // be responsible for freeing it.
            statsNodeAutoPtr->tag = currentTag.release();

            if ((statsNodeAutoPtr->pMMStats = new MM_Stats_t) == NULL)
            {
                return NULL;
            }

            if ((statsNodeAutoPtr->pMMFIParam = new MM_FailInsertParam) == NULL)
            {
                return NULL;
            }

            // reassign ownership of the StatsNode to the map class
            mTagTree[statsNodeAutoPtr->tag] = statsNodeAutoPtr;

            // account for the overhead memory
            mm_audit_stats_overhead += sizeof(MM_Stats_t) +
                                       sizeof(MM_FailInsertParam) + sizeof(OsclMemStatsNode) +
                                       oscl_strlen(currentTag.get()) + 1;

            pStatsNodePtr = statsNodeAutoPtr.get();

            // update the current ptr
            pCurrentStatsAutoPtr = statsNodeAutoPtr;

            // Get the parent tag length
            len = retrieveParentTagLength(tagIn, len - 1);

            if (len > 0)
            {
                currentTag.allocate(len);
                if (! currentTag.get())
                {
                    return NULL;
                }
                strncpy(currentTag.get(), tagIn, len);
                *(currentTag.get() + (len - 1)) = '\0';
            }

        }
        else
        {
            break;
        }
    }
    while (len > 0);

    return pStatsNodePtr;
#endif
}


/* ============================================================================ */
/*	Function : updateStatsNode()												*/
/*	Date     : 10/08/2002														*/
/*	Purpose  : update the node in memory statistics table triggered by an		*/
/*			   allocation/de-alocation attempt,									*/
/*	In/out   : all parameters are input											*/
/*	Return   : true if operation succeeds										*/
/*	Modified :																	*/
/* ============================================================================	*/


bool MM_Audit_Imp::updateStatsNode(OsclMemStatsNode *pCurrStatsNode, const MM_Stats_t& delta, bool add)
{
    MMAuditCharAutoPtr tag;
    makeValidTag((const char*)(pCurrStatsNode->tag), tag);

    //Update
    if (!pCurrStatsNode->pMMStats) return false;
    pCurrStatsNode->pMMStats->update(delta, add);

    OsclTagTreeType::iterator miter = mTagTree.find(tag.get());

    uint32 depth = miter->depth();

    OsclTagTreeType::node_ptr parent = miter->parent;

    for (uint32 i = 0; i < depth; i++)
    {
        if (!parent->value->pMMStats) return false;
        parent->value->pMMStats->update(delta, add);
        parent = miter->parent;
    }

    return true;
}


/* ============================================================================ */
/*	Function : updateStatsNodeInFailure()										*/
/*	Date     : 11/05/2002														*/
/*	Purpose  : update "pMMStats->numAllocFails" for the current tag node with 	*/
/*			   its parent tag nodes												*/
/*	In/out   : all parameters are input											*/
/*	Return   : true if operation succeeds										*/
/*	Modified :																	*/
/* ============================================================================	*/
bool MM_Audit_Imp::updateStatsNodeInFailure(const char * tagIn)
{
    MMAuditCharAutoPtr tag;
    makeValidTag(tagIn, tag);
    OsclTagTreeType::iterator miter = mTagTree.find(tag.get());
    OsclMemStatsNode *pStatsNode;
    if (miter != mTagTree.end())
    {/* found */
        pStatsNode = (miter->value).get();
    }
    else
    {
        pStatsNode = mpStatsNode; // update the root node
    }

    return updateStatsNodeInFailure(pStatsNode);
}

bool MM_Audit_Imp::updateStatsNodeInFailure(OsclMemStatsNode * pStatsNode)
{
    MMAuditCharAutoPtr tag;

    if (!pStatsNode) return false;

    makeValidTag((const char*)(pStatsNode->tag), tag);

    if (!pStatsNode->pMMStats) return false;
    pStatsNode->pMMStats->numAllocFails++;

    OsclTagTreeType::iterator miter = mTagTree.find(tag.get());

    uint32 depth = miter->depth();

    OsclTagTreeType::node_ptr parent = miter->parent;

    for (uint32 i = 0; i < depth; i++)
    {
        if (!parent->value->pMMStats) return false;
        parent->value->pMMStats->numAllocFails++;
        parent = miter->parent;
    }

    return true;
}

/* ============================================================================ */
/*	Function : isSetFailure()													*/
/*	Date     : 11/05/2002														*/
/*	Purpose  : do allocation failure check										*/
/*	In/out   : all parameters are input											*/
/*	Return   : true if operation succeeds										*/
/*	Modified :																	*/
/* ============================================================================	*/

bool MM_Audit_Imp::isSetFailure(const char * tagIn)
{
    MMAuditCharAutoPtr tag;
    makeValidTag(tagIn, tag);
    OsclTagTreeType::iterator miter = mTagTree.find(tag.get());
    if (miter != mTagTree.end()) /* found */
    {
        OsclMemStatsNode *pStatsNode = (miter->value).get();
        return isSetFailure(pStatsNode);
    }

    return false;
}

bool MM_Audit_Imp::isSetFailure(OsclMemStatsNode* pStatsNode)
{
    if (pStatsNode == NULL) return false;

    if (pStatsNode->pMMFIParam == NULL) return false;

    /* decision for deterministic failure insertion */
    if (pStatsNode->pMMFIParam->nAllocNum > 0)
    {
        /* the "+ 1" term in the computation of total_allocs is to
         * count the current allocation
         */
        uint32 total_allocs = pStatsNode->pMMStats->peakNumAllocs + 1 +
                              pStatsNode->pMMStats->numAllocFails ;

        if (total_allocs == pStatsNode->pMMFIParam->nAllocNum)
            return true;
    }

    return false;
}
/* ========================================================================================== */
/*	Function : retrieveParentTagLength()													  */
/*	Date     : 10/16/2002																	  */
/*	Purpose  : get the length of the parent tag(i.e."a.b.c") of the input tag(i.e. "a.b.c.d") */
/*			   current node and counter it													  */
/*	In/out   : all parameters are input														  */
/*	Return   : length of the parent tag(sub-string)	of an input tag							  */
/*	Modified :																				  */
/* ========================================================================================== */

int32 MM_Audit_Imp::retrieveParentTagLength(const char *tag, int32 bound)
{
    if (!tag)  return 0;

#define PV_MIN(a,b)	  ((a)<(b)? (a):(b))

    int count = 0;
    int len = PV_MIN((int32)(oscl_strlen(tag)), bound);
    if (len <= 0)
        return 0;
    else
    {
        bool bFound = false;
        for (count = len - 1; count >= 0; count--)
        {
            if (tag[count] == '.')
            {
                bFound = true;
                break;
            }
        }
        if (!bFound)	 count = 0;
    }

    return count + 1;
}

void MM_Audit_Imp::retrieveParentTag(char *tag)
{
    if (!tag)  return;

    int32 len = oscl_strlen(tag);
    if (len == 1)
        tag[0] = '\0';
    else
    {
        bool bFound = false;
        for (int32 i = len - 1; i >= 0; i--)
        {
            if (tag[i] == '.')
            {
                tag[i] = '\0';
                bFound = true;
                break;
            }
        }
        if (!bFound)
            tag[0] = '\0';
    }
}

/* ========================================================================================== */
/*	Function : makeValidTag()																  */
/*	Date     : 10/25/2002																	  */
/*	Purpose  : check the input tag and make sure its level would be bounded in maximum tag    */
/*			   level, if its level is larger, then truncate it								  */
/*			   Note that level of "a.b.c.d" = 4												  */
/*	In/out   : In: tagIn ; Out: *bFree														  */
/*	Return   : a valid tag within the maximum tag level constraint							  */
/*	Modified :																				  */
/* ========================================================================================== */

void MM_Audit_Imp::makeValidTag(const char * tagIn, MMAuditCharAutoPtr& autoptr)
{

    if (tagIn == NULL)
    {
        //tagIn = NULL means root tag
        autoptr.setWithoutOwnership(const_cast<char*>(root_tag));
    }

    else
    {
        uint32 len = getTagActualSize(tagIn);
        if (len == 0)
        {
            /* len = 0 meaning no need of truncation */
            autoptr.setWithoutOwnership(const_cast<char*>(tagIn));
        }

        else
        {
            autoptr.allocate(len + 1);
            oscl_strncpy(autoptr.get(), tagIn, len);
            *(autoptr.get() + len) = '\0';
        }
    }
}

/* ========================================================================================== */
/*	Function : getTagActualSize()															  */
/*	Date     : 10/25/2002																	  */
/*	Purpose  : get the actual size of an input tag within the maximum tag level constraint    */
/*			   Note that level of "a.b.c.d" = 4												  */
/*	In/out   : In: tagIn ; Out: *bFree														  */
/*	Return   : 0 means no truncation ; >0 means truncated size								  */
/*	Modified :																				  */
/* ========================================================================================== */

uint32 MM_Audit_Imp::getTagActualSize(const char * tagIn)
{
    uint32 i, len;
    uint32 level = 0, count = 0;

    len = oscl_strlen(tagIn);
    if (len <= 2*mnMaxTagLevel - 1)
        return 0; /* no truncation */

    for (i = 0; i < len; i++)
    {
        if (tagIn[i] == '.')
        {
            if (++level == mnMaxTagLevel)
            {
                count = i;
                break;
            }
        }
    }
    return count;
}


#endif //if OSCL_BYPASS_MEMMGT



