Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. // memman.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "kosSyst.h"
  5. #include "mcsmemm.h"
  6.  
  7.  
  8. void * __cdecl operator new ( size_t count, size_t element_size )
  9. {
  10.         return allocmem( (Dword)(count * element_size) );
  11. }
  12.  
  13. void * __cdecl operator new [] ( size_t amount )
  14. {
  15.         return allocmem( (Dword)amount );
  16. }
  17.  
  18. void * __cdecl operator new ( size_t amount )
  19. {
  20.         return allocmem( (Dword)amount );
  21. }
  22.  
  23. void __cdecl operator delete ( void *pointer )
  24. {
  25.         if ( pointer != NULL ) freemem( pointer );
  26. }
  27.  
  28. void __cdecl operator delete [] ( void *pointer )
  29. {
  30.         if ( pointer != NULL ) freemem( pointer );
  31. }
  32.  
  33.  
  34. //
  35. Dword mmMutex = FALSE;
  36. MemBlock *rootfree = NULL;
  37. MemBlock *rootuser = NULL;
  38. bool mmInitialized = false;
  39. Byte *mmHeapTop = NULL;
  40.  
  41.  
  42. //
  43. Byte *allocmem( Dword reqsize )
  44. {
  45.   MemBlock *BlockForCheck;
  46.   MemBlock *LastKnownGood;
  47.   Dword tail;
  48.   Byte *address;
  49.  
  50.   //ïîäðîâíÿåì ðàçìåð
  51.   if( ( tail = reqsize % SIZE_ALIGN ) != 0 )
  52.   {
  53.     reqsize += SIZE_ALIGN - tail;
  54.   }
  55.  
  56.   LastKnownGood = NULL;
  57.  
  58.   // æä¸ì îñâîáîæäåíèÿ ìüþòåêñà
  59.   while ( rtlInterlockedExchange( &mmMutex, TRUE ) )
  60.   {
  61.           //
  62.           kos_Pause( 1 );
  63.   }
  64.  
  65.   //èùåì ïîäõîäÿùèé ñâîáîäíûé áëîê
  66.   if( rootfree != NULL )
  67.   {
  68.     for ( BlockForCheck = rootfree; ; BlockForCheck = BlockForCheck->Next )
  69.     {
  70.       if ( BlockForCheck->Size >= reqsize )
  71.       {
  72.         //íàøëè
  73.         if ( LastKnownGood != NULL )
  74.         {
  75.           if ( LastKnownGood->Size >= BlockForCheck->Size )
  76.             LastKnownGood = BlockForCheck;
  77.         }
  78.         else
  79.           LastKnownGood = BlockForCheck;
  80.         if ( LastKnownGood->Size == reqsize )
  81.           break;
  82.       }
  83.       if ( BlockForCheck->Next == NULL )
  84.         break;
  85.     }
  86.   }
  87.  
  88.   if ( LastKnownGood != NULL )
  89.   {
  90.     //ïðîâåðèì íàéäåííûé áëîê íà âîçìîæíîñòü äåëåíèÿ
  91.     tail = LastKnownGood->Size - reqsize;
  92.     if ( tail >= ( sizeof(MemBlock) + SIZE_ALIGN ) )
  93.     {
  94.       //áóäåì ðàçáèâàòü
  95.       BlockForCheck = (MemBlock *)( ( (Byte *)LastKnownGood ) + tail );
  96.       BlockForCheck->Size = reqsize;
  97.       //âñòàâèì çàíÿòûé áëîê â íà÷àëî ñïèñêà çàíàòûõ áëîêîâ
  98.       if( rootuser != NULL )
  99.       {
  100.         BlockForCheck->Next = rootuser;
  101.         rootuser->Previous = BlockForCheck;
  102.         BlockForCheck->Previous = NULL;
  103.         rootuser = BlockForCheck;
  104.       }
  105.       else
  106.       {
  107.         rootuser = BlockForCheck;
  108.         BlockForCheck->Next = NULL;
  109.         BlockForCheck->Previous = NULL;
  110.       }
  111.  
  112.       //èçìåíèì ðàçìåð îñòàâøåéñÿ ÷àñòè
  113.       LastKnownGood->Size = tail - sizeof(MemBlock);
  114.       address = ( (Byte *)BlockForCheck ) + sizeof(MemBlock);
  115.  
  116.           // îòïóñòèì ìüþòåêñ
  117.       rtlInterlockedExchange( &mmMutex, FALSE );
  118.  
  119.       return address;
  120.     }
  121.     else
  122.     {
  123.       //ïåðåìåñòè áëîê èç î÷åðåäè ñâîáîäíûõ â íà÷àëî î÷åðåäè çàíÿòûõ
  124.       //ñíà÷àëà âûêèíåì åãî èç î÷åðåäè ñâîáîäíûõ
  125.       if ( LastKnownGood->Previous != NULL )
  126.       {
  127.         LastKnownGood->Previous->Next = LastKnownGood->Next;
  128.       }
  129.       else
  130.       {
  131.         //áëîê ñòîèò â íà÷àëå î÷åðåäè
  132.         rootfree = LastKnownGood->Next;
  133.       }
  134.       if( LastKnownGood->Next != NULL )
  135.       {
  136.         LastKnownGood->Next->Previous = LastKnownGood->Previous;
  137.       }
  138.       //òåïåðü âñòàâèì åãî â î÷åðåäü çàíÿòûõ
  139.       if( rootuser != NULL )
  140.       {
  141.         LastKnownGood->Next = rootuser;
  142.         rootuser->Previous = LastKnownGood;
  143.         LastKnownGood->Previous = NULL;
  144.         rootuser = LastKnownGood;
  145.       }
  146.       else
  147.       {
  148.         rootuser = LastKnownGood;
  149.         LastKnownGood->Next = NULL;
  150.         LastKnownGood->Previous = NULL;
  151.       }
  152.           //
  153.       address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock);
  154.  
  155.           // îòïóñòèì ìüþòåêñ
  156.       rtlInterlockedExchange( &mmMutex, FALSE );
  157.  
  158.       return address;
  159.     }
  160.   }
  161.   else
  162.   {
  163.         // íàäî ïîëó÷èòü åù¸ áëîê ïàìÿòè
  164.         LastKnownGood = (MemBlock *)kos_malloc(
  165.                 (reqsize > 0x10000 - sizeof(MemBlock)) ? (reqsize + sizeof(MemBlock)) : 0x10000);
  166.         if (LastKnownGood != NULL)
  167.         {
  168.                 LastKnownGood->Size = reqsize;
  169.                 // òåïåðü âñòàâèì åãî â î÷åðåäü çàíÿòûõ
  170.                 LastKnownGood->Next = rootuser;
  171.                 LastKnownGood->Previous = NULL;
  172.                 if (rootuser != NULL)
  173.                         rootuser->Previous = LastKnownGood;
  174.                 rootuser = LastKnownGood;
  175.                 // à òàêæå äîáàâèì õâîñò ñâåæåâûäåëåííîãî áîëüøîãî áëîêà â ñïèñîê ñâîáîäíûõ
  176.                 if (reqsize < 0x10000 - sizeof(MemBlock))
  177.                 {
  178.                         MemBlock* free = (MemBlock*)((Byte*)LastKnownGood + sizeof(MemBlock) + reqsize);
  179.                         free->Next = rootfree;
  180.                         free->Previous = NULL;
  181.                         if (rootfree != NULL)
  182.                                 rootfree->Previous = free;
  183.                         rootfree = free;
  184.                 }
  185.                 address = (Byte*)LastKnownGood + sizeof(MemBlock);
  186.                 // îòïóñòèì ìüþòåêñ
  187.                 rtlInterlockedExchange(&mmMutex, FALSE);
  188.  
  189.                 return address;
  190.         }
  191.   }
  192.  
  193.   // îòïóñòèì ìüþòåêñ
  194.   rtlInterlockedExchange( &mmMutex, FALSE );
  195.  
  196.   //
  197.   rtlDebugOutString( "allocmem failed." );
  198.   kos_ExitApp();
  199.   //
  200.   return NULL;
  201. }
  202.  
  203. //
  204. Dword freemem( void *vaddress )
  205. {
  206.   Dword result;
  207.  
  208.   Byte *checknext, *address = (Byte *)vaddress;
  209.                                
  210.   // æä¸ì îñâîáîæäåíèÿ ìüþòåêñà
  211.   while ( rtlInterlockedExchange( &mmMutex, TRUE ) )
  212.   {
  213.           //
  214.           kos_Pause( 1 );
  215.   }
  216.  
  217.   MemBlock *released = (MemBlock *)( address - sizeof(MemBlock) );
  218.  
  219.   result = released->Size;
  220.  
  221.   //óáèðàåì áëîê èç ñïèñêà çàíÿòûõ
  222.   if ( released->Previous != NULL )
  223.   {
  224.     released->Previous->Next = released->Next;
  225.   }
  226.   else
  227.   {
  228.     rootuser = released->Next;
  229.   }
  230.   if ( released->Next != NULL )
  231.   {
  232.     released->Next->Previous = released->Previous;
  233.   }
  234.   //çàêèíåì òåïåðü ýòîò áëîê â ñïèñîê ñâîáîäíûõ
  235.   released->Next = rootfree;
  236.   released->Previous = NULL;
  237.   rootfree = released;
  238.   if ( released->Next != NULL )
  239.   {
  240.     released->Next->Previous = released;
  241.   }
  242.  
  243.   //òåïåðü ïîèùåì ñìåæíûå ñâîáîäíûå áëîêè
  244.   checknext = (Byte *)(rootfree) + ( rootfree->Size + sizeof(MemBlock) );
  245.   //
  246.   for ( released = rootfree->Next; released != NULL; released = released->Next )
  247.   {
  248.     if ( checknext == (Byte *)released )
  249.     {
  250.       //ñîáèðàåì áëîêè âìåñòå
  251.       //ñíà÷àëà âûêèíåì èç î÷åðåäè ñâîáîäíûõ
  252.       released->Previous->Next = released->Next;
  253.       if( released->Next != NULL )
  254.       {
  255.         released->Next->Previous = released->Previous;
  256.       }
  257.       //òåïåðü óâåëè÷èì ðàçìåð êîðíåâîãî áëîêà
  258.       rootfree->Size += released->Size + sizeof(MemBlock);
  259.       break;
  260.     }
  261.   }
  262.   //åñëè íàäî, ïîèùåì áëîêè ïåðåä òåêùèì.
  263.   checknext = (Byte *)(rootfree);
  264.   //
  265.   if ( released == NULL )
  266.   {
  267.     for ( released = rootfree->Next; released != NULL; released = released->Next )
  268.     {
  269.       if ( checknext == (Byte *)released + ( released->Size + sizeof(MemBlock) ) )
  270.       {
  271.         //ñîáèðàåì áëîêè âìåñòå
  272.         //óâåëè÷èì ðàçìåð áëîêà
  273.         released->Size += rootfree->Size + sizeof(MemBlock);
  274.         //òåïåðü âûêèíåì èç î÷åðåäè ñâîáîäíûõ
  275.         released->Previous->Next = released->Next;
  276.         if ( released->Next != NULL )
  277.         {
  278.           released->Next->Previous = released->Previous;
  279.         }
  280.         //è çàêèíåì åãî â íà÷àëî î÷åðåäè âìåñòî ïðèñîåäèí¸ííîãî áëîêà èç êîðíÿ ñïèñêà
  281.         if ( rootfree->Next != NULL )
  282.         {
  283.           rootfree->Next->Previous = released;
  284.         }
  285.         released->Next = rootfree->Next;
  286.         released->Previous = NULL;
  287.         rootfree = released;
  288.         break;
  289.       }
  290.     }
  291.   }
  292.  
  293.   // îòïóñòèì ìüþòåêñ
  294.   rtlInterlockedExchange( &mmMutex, FALSE );
  295.  
  296.   return result;
  297. }
  298.  
  299.