Subversion Repositories Kolibri OS

Rev

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

  1. if ~defined memmanager_inc
  2. memmanager_inc_fix:
  3. memmanager_inc fix memmanager_inc_fix
  4. ;for testing in applications
  5. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  6. ;; Memory allocator for MenuetOS kernel
  7. ;; Andrey Halyavin, halyavin@land.ru 2005
  8. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  9.  
  10. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  11. ;; heap block structure -
  12. ;; you can handle several ranges of
  13. ;; pages simultaneosly.
  14. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  15. .heap_linear_address   equ 0
  16. .heap_block_size       equ 4
  17. .heap_physical_address equ 8
  18. .heap_reserved         equ 12
  19. .heap_block_info       equ 16
  20. max_heaps equ 8
  21. .range_info            equ 36
  22. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  23. ;; memory manager data
  24. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  25. uglobal
  26.   MEM_heap_block    rd .heap_block_info*max_heaps/4
  27.   MEM_heap_count    rd 1
  28.   MEM_cli_count     rd 1
  29.   MEM_cli_prev      rd 1
  30.   MEM_FreeSpace     rd 1
  31. ;  MEM_AllSpace      rd 1
  32. endg
  33. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  34. ;;MEM_Init
  35. ;;Initialize memory manager structures.
  36. ;;Must be called first.
  37. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  38. MEM_Init:
  39.     push  eax
  40.     xor   eax,eax
  41.     mov   [MEM_cli_prev],eax     ;init value = 0
  42.     dec   eax
  43.     mov   [MEM_cli_count],eax    ;init value = -1
  44.     pop   eax
  45.     ret
  46. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  47. ;;MEM_Heap_Lock
  48. ;;Wait until all operations with heap will be finished.
  49. ;;Between MEM_Heap_Lock and MEM_Heap_UnLock operations
  50. ;;with heap are forbidden.
  51. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  52. MEM_Heap_Lock:
  53.     pushfd
  54.     cli
  55.     inc   dword [MEM_cli_count]  
  56.     jz    MEM_Heap_First_Lock
  57.     add   esp,4
  58.     ret
  59. MEM_Heap_First_Lock:             ;save interrupt flag
  60.     shr  dword [esp],9
  61.     and  dword [esp],1
  62.     pop  dword [MEM_cli_prev]
  63.     ret
  64. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  65. ;;MEM_Heap_UnLock
  66. ;;After this routine operations with heap are allowed.
  67. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  68. MEM_Heap_UnLock:
  69.     dec   dword [MEM_cli_count]
  70.     js    MEM_Heap_UnLock_last
  71.     ret
  72. MEM_Heap_UnLock_last:
  73.     cmp   dword [MEM_cli_prev],0 ;restore saved interrupt flag
  74.     jz    MEM_Heap_UnLock_No_sti
  75.     sti
  76. MEM_Heap_UnLock_No_sti:
  77.     ret
  78. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  79. ;;MEM_Add_Heap
  80. ;;Add new range to memory manager.
  81. ;;eax - linear address
  82. ;;ebx - size in pages
  83. ;;ecx - physical address
  84. ;;Result:
  85. ;; eax=1 - success
  86. ;; eax=0 - failed
  87. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  88. MEM_Add_Heap:
  89.     push  edx
  90.     call  MEM_Heap_Lock
  91.     mov   edx,[MEM_heap_count]
  92.     cmp   edx,max_heaps
  93.     jz    MEM_Add_Heap_Error
  94.     inc   dword [MEM_heap_count]
  95.     shl   edx,4
  96.     mov   [MEM_heap_block+edx+.heap_linear_address],eax
  97.     mov   [MEM_heap_block+edx+.heap_block_size],ebx
  98.     shl   dword [MEM_heap_block+edx+.heap_block_size],12
  99.     mov   [MEM_heap_block+edx+.heap_physical_address],ecx
  100.     lea   edx,[4*ebx+.range_info+4095]   ;calculate space for page info table
  101.     and   edx,0xFFFFF000
  102.  
  103.     push  edi  
  104.     mov   edi,edx
  105.     shr   edi,12
  106.     sub   edi,ebx                ;edi=-free space
  107.     sub   [MEM_FreeSpace],edi
  108. ;    sub   [MEM_AllSpace],edi
  109.  
  110.     mov   [eax],eax
  111.     add   [eax],edx              ;first 4 bytes - pointer to first free page
  112. ;clean page info area    
  113.     lea   edi,[eax+4]
  114.     mov   ecx,edx
  115.     shr   ecx,2
  116.     push  eax
  117.     xor   eax,eax
  118.     rep   stosd                          
  119.     pop   eax
  120.     pop   edi
  121. ;create free pages list.    
  122.     mov   ecx,[eax]
  123.     shl   ebx,12
  124.     add   eax,ebx                ;eax - address after block
  125. MEM_Add_Heap_loop:
  126.     add   ecx,4096
  127.     mov   [ecx-4096],ecx         ;set forward pointer
  128.     cmp   ecx,eax
  129.     jnz   MEM_Add_Heap_loop
  130.     mov   dword [ecx-4096],0     ;set end of list
  131. MEM_Add_Heap_ret:
  132.     call  MEM_Heap_UnLock
  133.     pop   edx    
  134.     ret
  135. MEM_Add_Heap_Error:
  136.     xor   eax,eax
  137.     jmp   MEM_Add_Heap_ret
  138. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  139. ;;MEM_Get_Physical_Address
  140. ;;Translate linear address to physical address
  141. ;;Parameters:
  142. ;; eax - linear address
  143. ;;Result:
  144. ;; eax - physical address
  145. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  146. if used MEM_Get_Physical_Address
  147. MEM_Get_Physical_Address:
  148.     push   ecx
  149.     call   MEM_Heap_Lock
  150.     mov    ecx,[MEM_heap_count]
  151.     dec    ecx
  152.     shl    ecx,4
  153. MEM_Get_Physical_Address_loop:
  154.     sub    eax,[MEM_heap_block+ecx+.heap_linear_address]
  155.     jl     MEM_Get_Physical_Address_next
  156.     cmp    eax,[MEM_heap_block+ecx+.heap_block_size]
  157.     jge    MEM_Get_Physical_Address_next
  158.     add    eax,[MEM_heap_block+ecx+.heap_physical_address]
  159.     jmp    MEM_Get_Physical_Address_loopend
  160. MEM_Get_Physical_Address_next:
  161.     add    eax,[MEM_heap_block+ecx+.heap_linear_address]
  162.     sub    ecx,16
  163.     jns    MEM_Get_Physical_Address_loop
  164.     xor    eax,eax               ;address not found
  165. MEM_Get_Physical_Address_loopend:
  166.     call   MEM_Heap_UnLock
  167.     pop    ecx
  168.     ret
  169. end if
  170. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  171. ;;MEM_Get_Linear_Address
  172. ;;Translate physical address to linear address.
  173. ;;Parameters:
  174. ;; eax - physical address
  175. ;;Result:
  176. ;; eax - linear address
  177. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  178. if used MEM_Get_Linear_Address
  179. MEM_Get_Linear_Address:
  180.     push   ecx
  181.     call   MEM_Heap_Lock
  182.     mov    ecx,[MEM_heap_count]
  183.     dec    ecx
  184.     shl    ecx,4
  185. MEM_Get_Linear_Address_loop:
  186.     sub    eax,[MEM_heap_block+ecx+.heap_physical_address]
  187.     jl     MEM_Get_Linear_Address_Next
  188.     cmp    eax,[MEM_heap_block+ecx+.heap_block_size]
  189.     jge    MEM_Get_Linear_Address_Next
  190.     add    eax,[MEM_heap_block+ecx+.heap_linear_address]
  191.     call   MEM_Heap_UnLock
  192.     pop    ecx
  193.     ret
  194. MEM_Get_Linear_Address_Next:
  195.     add    eax,[MEM_heap_block+ecx+.heap_physical_address]
  196.     sub    ecx,16
  197.     jns    MEM_Get_Linear_Address_loop
  198.     call   MEM_Heap_UnLock
  199.     pop    ecx
  200.     xor    eax,eax               ;address not found
  201.     ret
  202. end if
  203. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  204. ;;MEM_Alloc_Page
  205. ;;Allocate and add reference to page
  206. ;;Result:
  207. ;; eax<>0 - physical address of page
  208. ;; eax=0  - not enough memory
  209. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  210. if used MEM_Alloc_Page
  211. MEM_Alloc_Page:
  212.     push   ecx
  213.     call   MEM_Heap_Lock
  214.     mov    ecx,[MEM_heap_count]
  215.     dec    ecx
  216.     shl    ecx,4
  217. MEM_Alloc_Page_loop:
  218.     push   ecx
  219.     mov    ecx,[MEM_heap_block+ecx+.heap_linear_address]
  220.     cmp    dword [ecx],0
  221.     jz     MEM_Alloc_Page_loopend
  222.     mov    eax,[ecx]
  223.     push   dword [eax]
  224.     pop    dword [ecx]
  225.     sub    eax,ecx
  226.     push   eax
  227.     shr    eax,10
  228.     mov    word [ecx+.range_info+eax],1
  229.     pop    eax
  230.     pop    ecx
  231.     add    eax,[MEM_heap_block+ecx+.heap_physical_address]
  232.     dec    [MEM_FreeSpace]
  233.     jmp    MEM_Alloc_Page_ret
  234. MEM_Alloc_Page_loopend:
  235.     pop    ecx
  236.     sub    ecx,16
  237.     jns    MEM_Alloc_Page_loop
  238.     xor    eax,eax
  239. MEM_Alloc_Page_ret:
  240.     call   MEM_Heap_UnLock
  241.     pop    ecx
  242.     ret
  243. end if
  244. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  245. ;;MEM_Alloc_Page_Linear
  246. ;;Allocate and add reference to page
  247. ;;Result:
  248. ;; eax<>0 - linear address of page
  249. ;; eax=0  - not enough memory
  250. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  251. if used MEM_Alloc_Page_Linear
  252. MEM_Alloc_Page_Linear:
  253.     push  ecx
  254.     call  MEM_Heap_Lock
  255.     mov   ecx,[MEM_heap_count]
  256.     dec   ecx
  257.     shl   ecx,4
  258. MEM_Alloc_Page_Linear_loop:
  259.     push  ecx
  260.     mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
  261.     cmp   dword [ecx],0
  262.     jz    MEM_Alloc_Page_Linear_loopend
  263.     mov   eax,[ecx]
  264.     push  dword [eax]
  265.     pop   dword [ecx]
  266.     push  eax
  267.     sub   eax,ecx
  268.     shr   eax,10
  269.     mov   word [ecx+.range_info+eax],1
  270.     pop   eax
  271.     pop   ecx
  272.     dec   [MEM_FreeSpace]
  273.     jmp   MEM_Alloc_Page_Linear_ret
  274. MEM_Alloc_Page_Linear_loopend:
  275.     pop   ecx
  276.     sub   ecx,16
  277.     jns   MEM_Alloc_Page_Linear_loop
  278.     xor   eax,eax
  279. MEM_Alloc_Page_Linear_ret:
  280.     call  MEM_Heap_UnLock
  281.     pop   ecx
  282.     ret
  283. end if
  284. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  285. ;;MEM_Free_Page
  286. ;;Remove reference and free page if number of
  287. ;;references is equal to 0
  288. ;;Parameters:
  289. ;;  eax - physical address of page
  290. ;;Result:
  291. ;;  eax - 1 success
  292. ;;  eax - 0 failed
  293. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  294. if (used MEM_Free_Page) | (used MEM_Free_Page_Linear)
  295. MEM_Free_Page:
  296.     test  eax,eax
  297.     jz    MEM_Free_Page_Zero
  298.     test  eax,0xFFF
  299.     jnz   MEM_Free_Page_Not_Aligned
  300.     push  ebx
  301.     push  ecx
  302.     push  edx
  303.     call  MEM_Heap_Lock
  304.     mov   ecx,[MEM_heap_count]
  305.     dec   ecx
  306.     shl   ecx,4
  307. MEM_Free_Page_Heap_loop:
  308.     sub   eax,[MEM_heap_block+ecx+.heap_physical_address]
  309.     js    MEM_Free_Page_Heap_loopnext
  310.     cmp   eax,[MEM_heap_block+ecx+.heap_block_size]
  311.     jl    MEM_Free_Page_Heap_loopend
  312. MEM_Free_Page_Heap_loopnext:
  313.     add   eax,[MEM_heap_block+ecx+.heap_physical_address]
  314.     sub   ecx,16
  315.     jns   MEM_Free_Page_Heap_loop
  316.     xor   eax,eax
  317.     inc   eax
  318.     jmp   MEM_Free_Page_ret
  319. MEM_Free_Page_Heap_loopend:
  320.     mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
  321.     mov   ebx,eax
  322.     add   eax,ecx
  323.     shr   ebx,10
  324.     mov   edx,[ecx+.range_info+ebx]
  325.     test  edx,0x80000000
  326.     jnz   MEM_Free_Page_Bucket
  327.     test  dx,dx
  328.     jz    MEM_Free_Page_Error
  329.     dec   word [ecx+.range_info+ebx]
  330.     jnz   MEM_Free_Page_OK
  331. MEM_Free_Page_Bucket:
  332.     push  dword [ecx]
  333.     mov   [ecx],eax
  334.     pop   dword [eax]
  335.     mov   dword [ecx+.range_info+ebx],0
  336.     inc   [MEM_FreeSpace]
  337. MEM_Free_Page_OK:
  338.     mov   eax,1
  339. MEM_Free_Page_ret:    
  340.     call  MEM_Heap_UnLock
  341.     pop   edx
  342.     pop   ecx
  343.     pop   ebx
  344.     ret
  345. MEM_Free_Page_Error:
  346.     xor   eax,eax
  347.     jmp   MEM_Free_Page_ret
  348. MEM_Free_Page_Zero:
  349.     inc   eax
  350.     ret
  351. MEM_Free_Page_Not_Aligned:
  352.     xor   eax,eax
  353.     ret
  354. end if
  355. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  356. ;;MEM_Free_Page_Linear
  357. ;;Remove reference and free page if number of
  358. ;;references is equal to 0
  359. ;;Parameters:
  360. ;;  eax - linear address of page
  361. ;;Result:
  362. ;;  eax - 1 success
  363. ;;  eax - 0 failed
  364. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  365. if used MEM_Free_Page_Linear
  366. MEM_Free_Page_Linear:
  367.     test  eax,eax
  368.     jz    MEM_Free_Page_Zero
  369.     test  eax,0xFFF
  370.     jnz   MEM_Free_Page_Not_Aligned
  371.     push  ebx
  372.     push  ecx
  373.     push  edx
  374.     call  MEM_Heap_Lock
  375.     mov   ecx,[MEM_heap_count]
  376.     dec   ecx
  377.     shl   ecx,4
  378.    
  379. MEM_Free_Page_Linear_Heap_loop:
  380.     sub   eax,[MEM_heap_block+ecx+.heap_linear_address]
  381.     js    MEM_Free_Page_Linear_Heap_loopnext
  382.     cmp   eax,[MEM_heap_block+ecx+.heap_block_size]
  383.     jl    MEM_Free_Page_Heap_loopend
  384. MEM_Free_Page_Linear_Heap_loopnext:
  385.     add   eax,[MEM_heap_block+ecx+.heap_linear_address]
  386.     sub   ecx,16
  387.     jns   MEM_Free_Page_Linear_Heap_loop
  388.     xor   eax,eax
  389.     inc   eax
  390.     jmp   MEM_Free_Page_ret
  391. end if
  392. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  393. ;;MEM_Alloc_Pages
  394. ;;Allocates set of pages.
  395. ;;Parameters:
  396. ;; eax - number of pages
  397. ;; ebx - buffer for physical addresses
  398. ;;Result:
  399. ;; eax - number of allocated pages
  400. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  401. if used MEM_Alloc_Pages
  402. MEM_Alloc_Pages:
  403.     push  eax
  404.     push  ebx
  405.     push  ecx
  406.     mov   ecx,eax
  407.     test  ecx,ecx
  408.     jz    MEM_Alloc_Pages_ret
  409. MEM_Alloc_Pages_loop:
  410.     call  MEM_Alloc_Page
  411.     test  eax,eax
  412.     jz    MEM_Alloc_Pages_ret
  413.     mov   [ebx],eax
  414.     add   ebx,4
  415.     dec   ecx
  416.     jnz   MEM_Alloc_Pages_loop
  417. MEM_Alloc_Pages_ret:
  418.     sub   [esp+8],ecx
  419.     pop   ecx
  420.     pop   ebx
  421.     pop   eax
  422.     ret
  423. end if
  424. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  425. ;;MEM_Alloc_Pages_Linear
  426. ;;Allocates set of pages.
  427. ;;Parameters:
  428. ;; eax - number of pages
  429. ;; ebx - buffer for linear addresses
  430. ;;Result:
  431. ;; eax - number of allocated pages
  432. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  433. if used MEM_Alloc_Pages_Linear
  434. MEM_Alloc_Pages_Linear:
  435.     push  eax
  436.     push  ebx
  437.     push  ecx
  438.     mov   ecx,eax
  439.     test  ecx,ecx
  440.     jz    MEM_Alloc_Pages_Linear_ret
  441. MEM_Alloc_Pages_Linear_loop:
  442.     call  MEM_Alloc_Page_Linear
  443.     test  eax,eax
  444.     jz    MEM_Alloc_Pages_Linear_ret
  445.     mov   [ebx],eax
  446.     add   ebx,4
  447.     dec   ecx
  448.     jnz   MEM_Alloc_Pages_Linear_loop
  449. MEM_Alloc_Pages_Linear_ret:
  450.     sub   [esp+8],ecx
  451.     pop   ecx
  452.     pop   ebx
  453.     pop   eax
  454.     ret
  455. end if
  456. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  457. ;;MEM_Free_Pages
  458. ;;Parameters:
  459. ;; eax - number of pages
  460. ;; ebx - array of addresses
  461. ;;Result:
  462. ;; eax=1 - succcess
  463. ;; eax=0 - failed
  464. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  465. if used MEM_Free_Pages
  466. MEM_Free_Pages:
  467.     push  ebx
  468.     push  ecx
  469.     mov   ecx,eax
  470.     test  ecx,ecx
  471.     jz    MEM_Free_Pages_ret
  472. MEM_Free_Pages_loop:
  473.     mov   eax,[ebx]
  474.     call  MEM_Free_Page
  475.     add   ebx,4
  476.     test  eax,eax
  477.     jz    MEM_Free_Pages_ret
  478.     dec   ecx
  479.     jnz   MEM_Free_Pages_loop
  480. MEM_Free_Pages_ret:
  481.     pop   ecx
  482.     pop   ebx
  483.     ret
  484. end if
  485. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  486. ;;MEM_Free_Pages_Linear
  487. ;;Parameters:
  488. ;; eax - number of pages
  489. ;; ebx - array of addresses
  490. ;;Result:
  491. ;; eax=1 - succcess
  492. ;; eax=0 - failed
  493. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  494. if used MEM_Free_Pages_Linear
  495. MEM_Free_Pages_Linear:
  496.     push  ebx
  497.     push  ecx
  498.     mov   ecx,eax
  499.     test  ecx,ecx
  500.     jz    MEM_Free_Pages_Linear_ret
  501. MEM_Free_Pages_Linear_loop:
  502.     mov   eax,[ebx]
  503.     call  MEM_Free_Page_Linear
  504.     add   ebx,4
  505.     test  eax,eax
  506.     jz    MEM_Free_Pages_Linear_ret
  507.     dec   ecx
  508.     jnz   MEM_Free_Pages_Linear_loop
  509. MEM_Free_Pages_Linear_ret:
  510.     pop   ecx
  511.     pop   ebx
  512.     ret
  513. end if
  514. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  515. ;;MEM_Get_Heap_Number
  516. ;;Calculate number of heap which pointer belongs to.
  517. ;;Parameter:
  518. ;; eax - address
  519. ;;Result:
  520. ;; ecx - number of heap*16.
  521. ;; eax=0 if address not found.
  522. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  523. if used MEM_Get_Heap_Number
  524. MEM_Get_Heap_Number:
  525.     call  MEM_Heap_Lock
  526.     mov   ecx,[MEM_heap_count]
  527.     dec   ecx
  528.     shl   ecx,4
  529. MEM_Get_Heap_loop:
  530.     sub   eax,[MEM_heap_block+ecx+.heap_physical_address]
  531.     jl    MEM_Get_Heap_loopnext
  532.     cmp   eax,[MEM_heap_block+ecx+.heap_block_size]
  533.     jl    MEM_Get_Heap_loopend
  534. MEM_Get_Heap_loopnext:
  535.     add   eax,[MEM_heap_block+ecx+.heap_physical_address]
  536.     sub   ecx,16
  537.     jns   MEM_Get_Heap_loop
  538.     call  MEM_Heap_UnLock
  539.     xor   eax,eax
  540.     ret
  541. MEM_Get_Heap_loopend:
  542.     add   eax,[MEM_heap_block+ecx+.heap_physical_address]
  543.     call  MEM_Heap_UnLock
  544.     ret
  545. end if
  546. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  547. ;;MEM_Get_Heap_Number_Linear
  548. ;;Calculate number of heap which pointer belongs to.
  549. ;;Parameter:
  550. ;; eax - address
  551. ;;Result:
  552. ;; ecx - number of heap*16.
  553. ;; eax=0 if address not found.
  554. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  555. if used MEM_Get_Heap_Number_Linear
  556. MEM_Get_Heap_Number_Linear:
  557.     call  MEM_Heap_Lock
  558.     mov   ecx,[MEM_heap_count]
  559.     dec   ecx
  560.     shl   ecx,4
  561. MEM_Get_Heap_Linear_loop:
  562.     sub   eax,[MEM_heap_block+ecx+.heap_linear_address]
  563.     jl    MEM_Get_Heap_Linear_loopnext
  564.     cmp   eax,[MEM_heap_block+ecx+.heap_block_size]
  565.     jl    MEM_Get_Heap_Linear_loopend
  566. MEM_Get_Heap_Linear_loopnext:
  567.     add   eax,[MEM_heap_block+ecx+.heap_linear_address]
  568.     sub   ecx,16
  569.     jns   MEM_Get_Heap_Linear_loop
  570.     call  MEM_Heap_UnLock
  571.     xor   eax,eax
  572.     ret
  573. MEM_Get_Heap_Linear_loopend:
  574.     add   eax,[MEM_heap_block+ecx+.heap_linear_address]
  575.     call  MEM_Heap_UnLock
  576.     ret
  577. end if
  578. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  579. ;;MEM_Alloc
  580. ;;Allocate small region.
  581. ;;Parameters:
  582. ;; eax - size (0<eax<=4096)
  583. ;;Result:
  584. ;; eax - linear address
  585. ;; eax=0 - not enough memory
  586. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  587. if used MEM_Alloc
  588. MEM_Alloc:
  589. ;find chain
  590.     test  eax,eax
  591.     jng   MEM_Alloc_Wrong_Size
  592.     cmp   eax,4096
  593.     jg    MEM_Alloc_Wrong_Size
  594.     push  ebx
  595.     push  ecx
  596.     push  edx
  597.     push  esi
  598.     dec   eax
  599.     shr   eax,4
  600.     xor   edx,edx
  601. MEM_Alloc_Find_Size:
  602.     add   edx,4
  603.     shr   eax,1
  604.     jnz   MEM_Alloc_Find_Size
  605. MEM_Alloc_Size_Found:
  606.     mov   ecx,edx
  607.     shr   ecx,2
  608.     add   ecx,4
  609.     mov   eax,1
  610.     shl   eax,cl
  611.     mov   esi,eax
  612. ;esi - block size
  613. ;edx - offset
  614.     call  MEM_Heap_Lock
  615.     mov   ecx,[MEM_heap_count]
  616.     dec   ecx
  617.     shl   ecx,4
  618. MEM_Alloc_Find_Heap:
  619.     mov   eax,[MEM_heap_block+ecx+.heap_linear_address]
  620.     cmp   dword [eax+edx],0
  621.     jnz   MEM_Alloc_Use_Existing
  622.     sub   ecx,16
  623.     jns   MEM_Alloc_Find_Heap
  624. ;create new bucket page
  625.     call  MEM_Alloc_Page_Linear
  626.     call  MEM_Get_Heap_Number_Linear
  627.     mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
  628.     mov   [ecx+edx],eax
  629.     lea   ebx,[eax+4096]
  630. MEM_Alloc_List_loop:
  631.     mov   [eax],eax
  632.     mov   [eax+4],eax
  633.     add   [eax],esi
  634.     sub   [eax+4],esi
  635.     add   eax,esi
  636.     cmp   eax,ebx
  637.     jnz   MEM_Alloc_List_loop
  638.     sub   ebx,esi
  639.     mov   dword [ebx],0
  640.     sub   eax,4096
  641.     mov   dword [eax+4],0
  642.     mov   eax,ecx
  643.        
  644. MEM_Alloc_Use_Existing:
  645.     mov   ebx,eax
  646.     mov   eax,[eax+edx]
  647.     mov   ecx,[eax]
  648.     mov   [ebx+edx],ecx
  649.     test  ecx,ecx
  650.     jz    MEM_Alloc_Became_Empty
  651.     mov   dword [ecx+4],0
  652. MEM_Alloc_Became_Empty:
  653.     mov   ecx,eax
  654.     sub   ecx,ebx
  655.     shr   ecx,10
  656.     and   ecx,0xFFFFFFFC
  657.     inc   byte [ebx+.range_info+ecx+2]
  658.     shr   edx,2
  659.     add   edx,128
  660.     dec   edx
  661.     mov   [ebx+.range_info+ecx+3],dl
  662.    
  663. MEM_Alloc_ret:
  664.     call  MEM_Heap_UnLock
  665.     pop   esi
  666.     pop   edx
  667.     pop   ecx
  668.     pop   ebx
  669.     ret
  670. MEM_Alloc_Wrong_Size:
  671.     xor   eax,eax
  672.     ret
  673. end if
  674. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  675. ;;MEM_Free
  676. ;;Parameters:
  677. ;; eax - linear address
  678. ;;Result:
  679. ;; eax=1 - success
  680. ;; eax=0 - failed
  681. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  682. if used MEM_Free
  683. MEM_Free:
  684.     test  eax,eax
  685.     jz    MEM_Free_Zero
  686.     push  ebx
  687.     push  ecx
  688.     push  edx
  689.     push  esi
  690.     push  edi
  691.     push  ebp
  692.     call  MEM_Heap_Lock
  693.     call  MEM_Get_Heap_Number_Linear
  694.     test  eax,eax
  695.     jz    MEM_Free_ret
  696.     mov   edx,eax
  697.     mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
  698.     sub   edx,ecx
  699.     shr   edx,10
  700.     and   edx,0xFFFFFFFC
  701.     mov   ebx,[ecx+.range_info+edx]
  702.     mov   esi,ebx
  703.     shr   esi,24
  704.     sub   esi,128
  705.     mov   edi,[ecx+4+4*esi]
  706.     mov   [eax],edi
  707.     mov   dword [eax+4],0
  708.     test  edi,edi
  709.     jz    MEM_Free_Empty_List
  710.     mov   [edi+4],eax
  711. MEM_Free_Empty_List:
  712.     mov   [ecx+4+4*esi],eax
  713.     sub   ebx,0x10000
  714.     mov   [ecx+.range_info+edx],ebx
  715.     test  ebx,0xFF0000
  716.     jnz   MEM_Free_ret
  717. ;delete empty blocks on the page
  718.     lea   edx,[esi+5]
  719.     and   eax,0xFFFFF000
  720.     mov   edi,eax
  721.     mov   eax,1
  722.     xchg  ecx,edx
  723.     shl   eax,cl
  724.     mov   ecx,edx
  725.     mov   edx,eax
  726. ;edx - size of block
  727. ;edi - start of page
  728.     mov   eax,edi
  729.     lea   ebx,[eax+4096]
  730. MEM_Free_Block_loop:
  731.     cmp   dword [eax+4],0
  732.     jnz   MEM_Free_Block_Not_First
  733.     mov   ebp,dword [eax]
  734.     mov   [ecx+4+4*esi],ebp
  735.     test  ebp,ebp
  736.     jz    MEM_Free_Block_Last
  737.     mov   dword [ebp+4],0
  738. MEM_Free_Block_Last:
  739.     jmp   MEM_Free_Block_loop_end
  740. MEM_Free_Block_Not_First:
  741.     mov   ebp,dword [eax]
  742.     push  ebp
  743.     mov   ebp,dword [eax+4]
  744.     pop   dword [ebp]
  745.     mov   ebp,dword [eax]
  746.     test  ebp,ebp
  747.     jz    MEM_Free_Block_loop_end
  748.     push  dword [eax+4]
  749.     pop   dword [ebp+4]
  750. ;    jmp   MEM_Free_Block_loop_end
  751. MEM_Free_Block_loop_end:
  752.     add   eax,edx
  753.     cmp   eax,ebx
  754.     jnz   MEM_Free_Block_loop
  755.     mov   eax,edi
  756.     call  MEM_Free_Page_Linear    
  757. MEM_Free_ret:
  758.     call  MEM_Heap_UnLock
  759.     pop   ebp
  760.     pop   edi
  761.     pop   esi
  762.     pop   edx
  763.     pop   ecx
  764.     pop   ebx
  765.     ret
  766. MEM_Free_Zero:
  767.     inc   eax
  768.     ret
  769. end if
  770. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  771. ;;MEM_Add_Reference
  772. ;; eax - physical address of page
  773. ;;Result:
  774. ;; eax=1 - success
  775. ;; eax=0 - failed
  776. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  777. if used MEM_Add_Reference
  778. MEM_Add_Reference:
  779.     push  ebx
  780.     push  ecx
  781.     call  MEM_Heap_Lock
  782.     call  MEM_Get_Heap_Number
  783.     test  eax,eax
  784.     jz    MEM_Add_Reference_ret
  785.     sub   eax,[MEM_heap_block+ecx+.heap_physical_address]
  786.     mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
  787.     shr   eax,10
  788.     and   eax,0xFFFFFFFC
  789.     test  dword [ecx+eax+.range_info],0x80000000
  790.     jnz   MEM_Add_Reference_failed
  791.     inc   dword [ecx+eax+.range_info]
  792. MEM_Add_Reference_ret:  
  793.     call  MEM_Heap_UnLock
  794.     pop   ecx
  795.     pop   ebx
  796.     ret
  797. MEM_Add_Reference_failed:
  798.     xor   eax,eax
  799.     jmp   MEM_Add_Reference_ret
  800. end if
  801. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  802. ;;MEM_Add_Reference_Linear
  803. ;; eax - linear address of page
  804. ;;Result:
  805. ;; eax=1 - success
  806. ;; eax=0 - failed
  807. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  808. if used MEM_Add_Reference_Linear
  809. MEM_Add_Reference_Linear:
  810.     push  ebx
  811.     push  ecx
  812.     call  MEM_Heap_Lock
  813.     call  MEM_Get_Heap_Number_Linear
  814.     test  eax,eax
  815.     jz    MEM_Add_Reference_Linear_ret
  816.     mov   ecx,[MEM_heap_block+ecx+.heap_linear_address]
  817.     sub   eax,ecx
  818.     shr   eax,10
  819.     and   eax,0xFFFFFFFC
  820.     test  dword [ecx+eax+.range_info],0x80000000
  821.     jnz   MEM_Add_Reference_Linear_failed
  822.     inc   dword [ecx+eax+.range_info]
  823.     mov   eax,1
  824. MEM_Add_Reference_Linear_ret:  
  825.     call  MEM_Heap_UnLock
  826.     pop   ecx
  827.     pop   ebx
  828.     ret
  829. MEM_Add_Reference_Linear_failed:
  830.     xor   eax,eax
  831.     jmp   MEM_Add_Reference_Linear_ret
  832. end if
  833. end if ;memmanager.inc
  834.