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. Byte *allocmem( Dword reqsize )
  34. {
  35.         __asm
  36.         {
  37.                 mov eax, 68
  38.                 mov ebx, 12
  39.                 mov ecx, reqsize
  40.                 int 0x40
  41.         }
  42.  
  43. }
  44.  
  45. Dword freemem( void *vaddress )
  46. {
  47.         __asm
  48.         {
  49.                 mov eax, 68
  50.                 mov ebx, 13
  51.                 mov ecx, vaddress
  52.                 int 0x40
  53.         }
  54.  
  55. }
  56. /*
  57.  
  58. //
  59. Dword mmMutex = FALSE;
  60. MemBlock *rootfree = NULL;
  61. MemBlock *rootuser = NULL;
  62. bool mmInitialized = false;
  63. Byte *mmHeapTop = NULL;
  64.  
  65.  
  66. //
  67. Byte * AllocMemFromSystem( Dword reqSize )
  68. {
  69.         Byte *result;
  70.         sProcessInfo pInfo;
  71.        
  72.         //
  73.         if ( mmInitialized )
  74.         {
  75.                 result = mmHeapTop;
  76.         }
  77.         else
  78.         {
  79.                 //
  80.                 kos_ProcessInfo( &pInfo );
  81.                 //
  82.                 result = (Byte *)(pInfo.processInfo.used_memory + 1);
  83.                 //
  84.                 mmInitialized = true;
  85.         }
  86.         //
  87.         if ( ! kos_ApplicationMemoryResize( ((Dword)result) + reqSize ) )
  88.         {
  89.                 result = NULL;
  90.         }
  91.         //
  92.         mmHeapTop = result + reqSize;
  93.         //
  94.         return result;
  95. }
  96.  
  97.  
  98. //
  99. Byte *allocmem( Dword reqsize )
  100. {
  101.   MemBlock *BlockForCheck;
  102.   MemBlock *LastKnownGood;
  103.   Dword tail;
  104.   Byte *address;
  105.  
  106.   //ïîäðîâíÿåì ðàçìåð
  107.   if( ( tail = reqsize % SIZE_ALIGN ) != 0 )
  108.   {
  109.     reqsize += SIZE_ALIGN - tail;
  110.   }
  111.  
  112.   LastKnownGood = NULL;
  113.  
  114.   // æä¸ì îñâîáîæäåíèÿ ìüþòåêñà
  115.   while ( rtlInterlockedExchange( &mmMutex, TRUE ) )
  116.   {
  117.           //
  118.           kos_Pause( 1 );
  119.   }
  120.  
  121.   //èùåì ïîäõîäÿùèé ñâîáîäíûé áëîê
  122.   if( rootfree != NULL )
  123.   {
  124.     for ( BlockForCheck = rootfree; ; BlockForCheck = BlockForCheck->Next )
  125.     {
  126.       if ( BlockForCheck->Size >= reqsize )
  127.       {
  128.         //íàøëè
  129.         if ( LastKnownGood != NULL )
  130.         {
  131.           if ( LastKnownGood->Size >= BlockForCheck->Size )
  132.             LastKnownGood = BlockForCheck;
  133.         }
  134.         else
  135.           LastKnownGood = BlockForCheck;
  136.         if ( LastKnownGood->Size == reqsize )
  137.           break;
  138.       }
  139.       if ( BlockForCheck->Next == NULL )
  140.         break;
  141.     }
  142.   }
  143.  
  144.   if ( LastKnownGood != NULL )
  145.   {
  146.     //ïðîâåðèì íàéäåííûé áëîê íà âîçìîæíîñòü äåëåíèÿ
  147.     tail = LastKnownGood->Size - reqsize;
  148.     if ( tail >= ( sizeof(MemBlock) + SIZE_ALIGN ) )
  149.     {
  150.       //áóäåì ðàçáèâàòü
  151.       BlockForCheck = (MemBlock *)( ( (Byte *)LastKnownGood ) + tail );
  152.       BlockForCheck->Size = reqsize;
  153.       //âñòàâèì çàíÿòûé áëîê â íà÷àëî ñïèñêà çàíàòûõ áëîêîâ
  154.       if( rootuser != NULL )
  155.       {
  156.         BlockForCheck->Next = rootuser;
  157.         rootuser->Previous = BlockForCheck;
  158.         BlockForCheck->Previous = NULL;
  159.         rootuser = BlockForCheck;
  160.       }
  161.       else
  162.       {
  163.         rootuser = BlockForCheck;
  164.         BlockForCheck->Next = NULL;
  165.         BlockForCheck->Previous = NULL;
  166.       }
  167.  
  168.       //èçìåíèì ðàçìåð îñòàâøåéñÿ ÷àñòè
  169.       LastKnownGood->Size = tail - sizeof(MemBlock);
  170.       address = ( (Byte *)BlockForCheck ) + sizeof(MemBlock);
  171.  
  172.           // îòïóñòèì ìüþòåêñ
  173.       rtlInterlockedExchange( &mmMutex, FALSE );
  174.  
  175.       return address;
  176.     }
  177.     else
  178.     {
  179.       //ïåðåìåñòè áëîê èç î÷åðåäè ñâîáîäíûõ â íà÷àëî î÷åðåäè çàíÿòûõ
  180.       //ñíà÷àëà âûêèíåì åãî èç î÷åðåäè ñâîáîäíûõ
  181.       if ( LastKnownGood->Previous != NULL )
  182.       {
  183.         LastKnownGood->Previous->Next = LastKnownGood->Next;
  184.       }
  185.       else
  186.       {
  187.         //áëîê ñòîèò â íà÷àëå î÷åðåäè
  188.         rootfree = LastKnownGood->Next;
  189.       }
  190.       if( LastKnownGood->Next != NULL )
  191.       {
  192.         LastKnownGood->Next->Previous = LastKnownGood->Previous;
  193.       }
  194.       //òåïåðü âñòàâèì åãî â î÷åðåäü çàíÿòûõ
  195.       if( rootuser != NULL )
  196.       {
  197.         LastKnownGood->Next = rootuser;
  198.         rootuser->Previous = LastKnownGood;
  199.         LastKnownGood->Previous = NULL;
  200.         rootuser = LastKnownGood;
  201.       }
  202.       else
  203.       {
  204.         rootuser = LastKnownGood;
  205.         LastKnownGood->Next = NULL;
  206.         LastKnownGood->Previous = NULL;
  207.       }
  208.           //
  209.       address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock);
  210.  
  211.           // îòïóñòèì ìüþòåêñ
  212.       rtlInterlockedExchange( &mmMutex, FALSE );
  213.  
  214.       return address;
  215.     }
  216.   }
  217.   else
  218.   {
  219.     //íàäî ïîëó÷èòü åù¸ êóñî÷åê ïàìÿòè
  220.     LastKnownGood = (MemBlock *)AllocMemFromSystem( reqsize + sizeof(MemBlock) );
  221.         //
  222.     if( LastKnownGood != NULL )
  223.     {
  224.       LastKnownGood->Size = reqsize;
  225.       //òåïåðü âñòàâèì åãî â î÷åðåäü çàíÿòûõ
  226.       if( rootuser != NULL )
  227.       {
  228.         LastKnownGood->Next = rootuser;
  229.         rootuser->Previous = LastKnownGood;
  230.         LastKnownGood->Previous = NULL;
  231.         rootuser = LastKnownGood;
  232.       }
  233.       else
  234.       {
  235.         rootuser = LastKnownGood;
  236.         LastKnownGood->Next = NULL;
  237.         LastKnownGood->Previous = NULL;
  238.       }
  239.       address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock);
  240.  
  241.           // îòïóñòèì ìüþòåêñ
  242.       rtlInterlockedExchange( &mmMutex, FALSE );
  243.  
  244.       return address;
  245.     }
  246.   }
  247.  
  248.   // îòïóñòèì ìüþòåêñ
  249.   rtlInterlockedExchange( &mmMutex, FALSE );
  250.  
  251.   //
  252.   rtlDebugOutString( "allocmem failed." );
  253.   kos_ExitApp();
  254.   //
  255.   return NULL;
  256. }
  257.  
  258. //
  259. Dword freemem( void *vaddress )
  260. {
  261.   Dword result;
  262.  
  263.   Byte *checknext, *address = (Byte *)vaddress;
  264.                                
  265.   // æä¸ì îñâîáîæäåíèÿ ìüþòåêñà
  266.   while ( rtlInterlockedExchange( &mmMutex, TRUE ) )
  267.   {
  268.           //
  269.           kos_Pause( 1 );
  270.   }
  271.  
  272.   MemBlock *released = (MemBlock *)( address - sizeof(MemBlock) );
  273.  
  274.   result = released->Size;
  275.  
  276.   //óáèðàåì áëîê èç ñïèñêà çàíÿòûõ
  277.   if ( released->Previous != NULL )
  278.   {
  279.     released->Previous->Next = released->Next;
  280.   }
  281.   else
  282.   {
  283.     rootuser = released->Next;
  284.   }
  285.   if ( released->Next != NULL )
  286.   {
  287.     released->Next->Previous = released->Previous;
  288.   }
  289.   //çàêèíåì òåïåðü ýòîò áëîê â ñïèñîê ñâîáîäíûõ
  290.   released->Next = rootfree;
  291.   released->Previous = NULL;
  292.   rootfree = released;
  293.   if ( released->Next != NULL )
  294.   {
  295.     released->Next->Previous = released;
  296.   }
  297.  
  298.   //òåïåðü ïîèùåì ñìåæíûå ñâîáîäíûå áëîêè
  299.   checknext = (Byte *)(rootfree) + ( rootfree->Size + sizeof(MemBlock) );
  300.   //
  301.   for ( released = rootfree->Next; released != NULL; released = released->Next )
  302.   {
  303.     if ( checknext == (Byte *)released )
  304.     {
  305.       //ñîáèðàåì áëîêè âìåñòå
  306.       //ñíà÷àëà âûêèíåì èç î÷åðåäè ñâîáîäíûõ
  307.       released->Previous->Next = released->Next;
  308.       if( released->Next != NULL )
  309.       {
  310.         released->Next->Previous = released->Previous;
  311.       }
  312.       //òåïåðü óâåëè÷èì ðàçìåð êîðíåâîãî áëîêà
  313.       rootfree->Size += released->Size + sizeof(MemBlock);
  314.       break;
  315.     }
  316.   }
  317.   //åñëè íàäî, ïîèùåì áëîêè ïåðåä òåêùèì.
  318.   checknext = (Byte *)(rootfree);
  319.   //
  320.   if ( released == NULL )
  321.   {
  322.     for ( released = rootfree->Next; released != NULL; released = released->Next )
  323.     {
  324.       if ( checknext == (Byte *)released + ( released->Size + sizeof(MemBlock) ) )
  325.       {
  326.         //ñîáèðàåì áëîêè âìåñòå
  327.         //óâåëè÷èì ðàçìåð áëîêà
  328.         released->Size += rootfree->Size + sizeof(MemBlock);
  329.         //òåïåðü âûêèíåì èç î÷åðåäè ñâîáîäíûõ
  330.         released->Previous->Next = released->Next;
  331.         if ( released->Next != NULL )
  332.         {
  333.           released->Next->Previous = released->Previous;
  334.         }
  335.         //è çàêèíåì åãî â íà÷àëî î÷åðåäè âìåñòî ïðèñîåäèí¸ííîãî áëîêà èç êîðíÿ ñïèñêà
  336.         if ( rootfree->Next != NULL )
  337.         {
  338.           rootfree->Next->Previous = released;
  339.         }
  340.         released->Next = rootfree->Next;
  341.         released->Previous = NULL;
  342.         rootfree = released;
  343.         break;
  344.       }
  345.     }
  346.   }
  347.  
  348.   // îòïóñòèì ìüþòåêñ
  349.   rtlInterlockedExchange( &mmMutex, FALSE );
  350.  
  351.   return result;
  352. }
  353.  
  354. */