MemoryManager.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:9k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. #include "MemoryManager.hxx"
  51. #include "global.h"
  52. MemoryManager* MemoryManager::mInstance = 0;    
  53.     
  54.     
  55. MemoryManager::MemoryManager()
  56. {
  57.     mAllocList = NULL;
  58.     mFreeList = NULL;
  59.     mAvail = false;
  60. }
  61.     
  62. MemoryManager* MemoryManager::getInstance()
  63. {
  64.     if (mInstance == 0)
  65.     {
  66.         mInstance = new MemoryManager();
  67.        
  68.         
  69.     }
  70.     return mInstance;
  71. }
  72.     
  73. void* MemoryManager::alloc(size_t size)
  74. {
  75.     HEADER* p;
  76.  //calculate the number of HEADER sizes we need to fit size bytes.
  77.     //one more for the HEADER itself.
  78.     int nUnits = 1+ (size + sizeof(HEADER) )/ sizeof(HEADER);
  79.     
  80.     if (mAllocList == NULL)
  81.     {
  82.         //no allocation done yet.
  83.         mAllocList = (HEADER*)(moreCore(nUnits));
  84.     }
  85.     p = mAllocList;
  86.     
  87.     //allocate size blocks from mAllocList.
  88.     if (p->size > nUnits)
  89.     {
  90.         p->size -= nUnits;
  91.         HEADER* q = p+p->size;
  92.         q->size = nUnits;
  93.         q->next = p->next;
  94.         p->next = q;
  95.         p = q;
  96.         
  97.     }
  98.     else if (p->size == nUnits)
  99.     {
  100.         if (p == mAllocList)
  101.         {
  102.             mAvail = false;
  103.         }
  104.     }
  105.     else  //p.size < nUnits
  106.     {
  107.         //check out free list , or allocate more.
  108.         p = getFromFreeList(nUnits);
  109.     }
  110.     return (void*) (p+1);
  111. }
  112.     
  113.     
  114. HEADER* MemoryManager::getFromFreeList(int nBlocks)
  115. {
  116.     //detach from free list and attach to alloc list.
  117.     if (mFreeList != NULL)
  118.     {
  119.        HEADER* prev = NULL;
  120.        HEADER* current = mFreeList;
  121.        while (current != NULL)
  122.        {
  123.            //find one that fits nBlocks.
  124.            if (current->size >= nBlocks)
  125.            {
  126.        if (current->size > nBlocks)
  127.                {
  128.    //form the correct size
  129.                     current->size -= nBlocks;
  130.     HEADER* q = current+current->size;
  131.     q->size = nBlocks;
  132.     q->next = current->next;
  133.     
  134.     current->next = q;
  135.     current = q;
  136.                }
  137.                //detach current from freeList and attach to allocList
  138.                if (prev != NULL)
  139.                {
  140.                    prev->next = current->next;
  141.                }
  142.                else //this is the first item.
  143.                {
  144.                    mFreeList = current->next;
  145.                }
  146.        //attach to allocList.
  147.        current->next = mAllocList->next;
  148.                mAllocList->next = current;
  149.                return ( (HEADER*)(current) );
  150.            }
  151.            prev = current;
  152.            current = current->next;
  153.        }
  154.        //came here. So, not found a big enough block.
  155.        //allocate more.
  156.        current = moreCore(nBlocks);
  157.        return ((HEADER*) (current));
  158.     }
  159.     else // no free list.
  160.     {
  161.         HEADER* p;
  162.         //allocate more.
  163.         p = moreCore(nBlocks);
  164.         return ( (HEADER*) (p) );
  165.     }
  166. }
  167.     
  168.     
  169. HEADER* MemoryManager::moreCore(int nBlocks)
  170. {
  171.     //get a block of memory.
  172.     int numChunks = ALLOC_BLOCK * ( (ALLOC_BLOCK + nBlocks -1)/ALLOC_BLOCK);
  173.     int nBytes = numChunks * sizeof(HEADER);
  174.     
  175.     HEADER* p = (HEADER*)(malloc(nBytes));  //calling system new.
  176.     
  177.     //attach to mAllocList.
  178.     if (mAllocList != NULL)
  179.     {
  180.         if (mAvail) //available, but small, then coalesce them.
  181.         {
  182.             p->next = mAllocList->next;
  183.             p->size = numChunks+mAllocList->size;
  184.         }
  185.         else
  186.         {
  187.             p->next = mAllocList;
  188.             p->size = numChunks;
  189.         }
  190.     }
  191.     else
  192.     {
  193.         p->next = NULL;
  194.         p->size = numChunks;
  195.     }
  196.     mAvail = true;
  197.     mAllocList = p;
  198.     //return the correct block size.
  199.     if (p->size > nBlocks)
  200.     {
  201.         p->size -= nBlocks;
  202.         HEADER* q = p+p->size;
  203.         q->size = nBlocks;
  204.         q->next = p->next;
  205.         p->next = q;
  206.         return q;
  207.     }
  208.     else if (p->size == nBlocks)
  209.     {
  210.         return p;
  211.     }
  212.     else
  213.     {
  214.         //should not come here.
  215.         return NULL;
  216.     }
  217. }
  218. bool MemoryManager::dealloc(void* ptr)
  219. {
  220.     //detach from allocList, and attach to freeList.
  221.    
  222.     //get the HEADER ptr.
  223.     HEADER* removeItem = (HEADER*)(ptr)-1; 
  224.     
  225.     if (removeItem == NULL)
  226.     {
  227.         return false;
  228.     }
  229.     HEADER* prev = NULL;
  230.     HEADER* current = mAllocList;
  231.     while ( (current != NULL) && (current != removeItem) )
  232.     {
  233.         prev = current;
  234.         current = current->next;
  235.     }
  236.     if (current == NULL)
  237.     {
  238. return false;  //item not a valid ptr.
  239.     }
  240.     if (current != mAllocList)
  241.     {
  242.         //have some value in prev.
  243.         prev->next = current->next;
  244.     }
  245.     else
  246.     {
  247.         mAllocList = mAllocList->next;
  248.     }
  249.     current->next = mFreeList;
  250.     mFreeList = current;
  251.     
  252.     return true;
  253. }
  254.     
  255. void* MemoryManager::mynew(size_t size)
  256. {
  257.     MemoryManager* manager = MemoryManager::getInstance();
  258.     void* p = manager->alloc(size);
  259.     //cout << "in my new" << endl;
  260.    // cout << "size:" << size << endl;
  261.     return p;
  262. }
  263.     
  264. void* MemoryManager::mynew(size_t size, void* type)
  265. {
  266.     MemoryManager* manager = MemoryManager::getInstance();
  267.     void* p = manager->alloc(sizeof(type)*size);
  268.     //cout << "in my new" << endl;
  269.     //cout << "size:" << size << endl;
  270.     
  271.     return p;
  272. }    
  273. void MemoryManager::mydelete(void* p, void* type)
  274. {
  275.     mydelete(p);
  276. }
  277. #if 0
  278. void* MemoryManager::mynew[](size_t size, void* type)
  279. {
  280.     MemoryManager* manager = MemoryManager::getInstance();
  281.     void* p = manager->alloc(sizeof(type)*size);
  282.     //cout << "in my new" << endl;
  283.     return p;     
  284. }
  285. void MemoryManager::mydelete[](void* p, void* type)
  286. {
  287.     mydelete(p);
  288. }
  289. #endif
  290.     
  291. void MemoryManager::mydelete(void* p)
  292. {
  293.     //cout << "in my delete" << endl;
  294.     MemoryManager* manager = MemoryManager::getInstance();
  295.     if (p != NULL)
  296.     {
  297.         manager->dealloc(p);
  298.      //dealloc(p);
  299.     }
  300. }
  301. void MemoryManager::displayAllocList()
  302. {
  303.     cout << "Displaying size of ALLOC LIST: "<< endl;
  304.     MemoryManager* manager = MemoryManager::getInstance();
  305.     HEADER* p = manager->mAllocList;
  306.     while (p != NULL)
  307.     {
  308.         cout << "size:" << p->size << endl;
  309.         p = p->next; 
  310.     }
  311. }
  312.  
  313. void MemoryManager::displayFreeList()
  314. {
  315.     cout << "Displaying size of FREE LIST:" << endl;
  316.     MemoryManager* manager = MemoryManager::getInstance();
  317.     HEADER* p = manager->mFreeList;
  318.     while (p != NULL)
  319.     {
  320.         cout << "size:" << p->size << endl;
  321.         p = p->next;
  322.     }
  323. }