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