Subversion Repositories Kolibri OS

Rev

Rev 859 | Rev 887 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 864 $
  9.  
  10.  
  11. struc MEM_BLOCK
  12. {  .next_block  dd ?
  13.    .prev_block  dd ? ;+4
  14.    .list_fd     dd ? ;+8
  15.    .list_bk     dd ? ;+12
  16.    .base        dd ? ;+16
  17.    .size        dd ? ;+20
  18.    .flags       dd ? ;+24
  19.    .handle      dd ? ;+28
  20. }
  21.  
  22. MEM_LIST_OFFSET equ  8
  23. FREE_BLOCK      equ  4
  24. USED_BLOCK      equ  8
  25. DONT_FREE_BLOCK equ  10h
  26.  
  27. virtual at 0
  28.   MEM_BLOCK MEM_BLOCK
  29. end virtual
  30.  
  31. MEM_BLOCK_SIZE equ 8*4
  32.  
  33. block_next   equ MEM_BLOCK.next_block
  34. block_prev   equ MEM_BLOCK.prev_block
  35. list_fd      equ MEM_BLOCK.list_fd
  36. list_bk      equ MEM_BLOCK.list_bk
  37. block_base   equ MEM_BLOCK.base
  38. block_size   equ MEM_BLOCK.size
  39. block_flags  equ MEM_BLOCK.flags
  40.  
  41.  
  42. align 4
  43. proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
  44.  
  45.            ret
  46. endp
  47.  
  48.  
  49. align 4
  50. proc kernel_free stdcall, base:dword
  51.  
  52.            ret
  53. endp
  54.  
  55.  
  56.  
  57. restore block_next
  58. restore block_prev
  59. restore block_list
  60. restore block_base
  61. restore block_size
  62. restore block_flags
  63.  
  64. ;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
  65.  
  66. HEAP_TOP  equ 0x5FC00000
  67.  
  68. align 4
  69. proc init_heap
  70.  
  71.            mov ebx,[current_slot]
  72.            mov eax, [ebx+APPDATA.heap_top]
  73.            test eax, eax
  74.            jz @F
  75.            sub eax,[ebx+APPDATA.heap_base]
  76.            sub eax, 4096
  77.            ret
  78. @@:
  79.            mov esi, [ebx+APPDATA.mem_size]
  80.            add esi, 4095
  81.            and esi, not 4095
  82.            mov [ebx+APPDATA.mem_size], esi
  83.            mov eax, HEAP_TOP
  84.            mov [ebx+APPDATA.heap_base], esi
  85.            mov [ebx+APPDATA.heap_top], eax
  86.  
  87.            sub eax, esi
  88.            shr esi, 10
  89.            mov ecx, eax
  90.            sub eax, 4096
  91.            or ecx, FREE_BLOCK
  92.            mov [page_tabs+esi], ecx
  93.            ret
  94. endp
  95.  
  96. align 4
  97. proc user_alloc stdcall, alloc_size:dword
  98.  
  99.            push ebx
  100.            push esi
  101.            push edi
  102.  
  103.            mov ecx, [alloc_size]
  104.            add ecx, (4095+4096)
  105.            and ecx, not 4095
  106.  
  107.            mov ebx, [current_slot]
  108.            mov esi, dword [ebx+APPDATA.heap_base]  ; heap_base
  109.            mov edi, dword [ebx+APPDATA.heap_top]   ; heap_top
  110. l_0:
  111.            cmp esi, edi
  112.            jae m_exit
  113.  
  114.            mov ebx, esi
  115.            shr ebx, 12
  116.            mov eax, [page_tabs+ebx*4]
  117.            test al, FREE_BLOCK
  118.            jz test_used
  119.            and eax, 0xFFFFF000
  120.            cmp eax, ecx    ;alloc_size
  121.            jb  m_next
  122.            jz  @f
  123.  
  124.            lea edx, [esi+ecx]
  125.            sub eax, ecx
  126.            or al, FREE_BLOCK
  127.            shr edx, 12
  128.            mov [page_tabs+edx*4], eax
  129. @@:
  130.            or ecx, USED_BLOCK
  131.            mov [page_tabs+ebx*4], ecx
  132.            shr ecx, 12
  133.            inc ebx
  134.            dec ecx
  135.            jz  .no
  136. @@:
  137.            mov dword [page_tabs+ebx*4], 2
  138.            inc ebx
  139.            dec ecx
  140.            jnz @B
  141. .no:
  142.  
  143.            mov     edx, [current_slot]
  144.            mov     ebx, [alloc_size]
  145.            add     ebx, 0xFFF
  146.            and     ebx, not 0xFFF
  147.            add     ebx, [edx+APPDATA.mem_size]
  148.            call    update_mem_size
  149.  
  150.            lea eax, [esi+4096]
  151.  
  152.            pop edi
  153.            pop esi
  154.            pop ebx
  155.            ret
  156. test_used:
  157.            test al, USED_BLOCK
  158.            jz m_exit
  159.  
  160.            and eax, 0xFFFFF000
  161. m_next:
  162.            add esi, eax
  163.            jmp l_0
  164. m_exit:
  165.            xor eax, eax
  166.            pop edi
  167.            pop esi
  168.            pop ebx
  169.            ret
  170. endp
  171.  
  172. align 4
  173. proc user_free stdcall, base:dword
  174.  
  175.            push esi
  176.  
  177.            mov esi, [base]
  178.            test esi, esi
  179.            jz .exit
  180.  
  181.            push ebx
  182.  
  183.            xor ebx, ebx
  184.            shr esi, 12
  185.            mov eax, [page_tabs+(esi-1)*4]
  186.            test al, USED_BLOCK
  187.            jz .cantfree
  188.            test al, DONT_FREE_BLOCK
  189.            jnz .cantfree
  190.  
  191.            and eax, not 4095
  192.            mov ecx, eax
  193.            or al, FREE_BLOCK
  194.            mov [page_tabs+(esi-1)*4], eax
  195.            sub ecx, 4096
  196.            mov ebx, ecx
  197.            shr ecx, 12
  198.            jz .released
  199. .release:
  200.            xor eax, eax
  201.            xchg eax, [page_tabs+esi*4]
  202.            test al, 1
  203.            jz @F
  204.            call free_page
  205.            mov eax, esi
  206.            shl eax, 12
  207.            invlpg [eax]
  208. @@:
  209.            inc esi
  210.            dec ecx
  211.            jnz .release
  212. .released:
  213.            push edi
  214.  
  215.            mov edx, [current_slot]
  216.            mov esi, dword [edx+APPDATA.heap_base]
  217.            mov edi, dword [edx+APPDATA.heap_top]
  218.            sub ebx, [edx+APPDATA.mem_size]
  219.            neg ebx
  220.            call update_mem_size
  221.            call user_normalize
  222.            pop edi
  223.            pop ebx
  224.            pop esi
  225.            ret
  226. .exit:
  227.            xor eax, eax
  228.            inc eax
  229.            pop esi
  230.            ret
  231. .cantfree:
  232.            xor eax, eax
  233.            pop ebx
  234.            pop esi
  235.            ret
  236. endp
  237.  
  238. user_normalize:
  239. ; in: esi=heap_base, edi=heap_top
  240. ; out: eax=0 <=> OK
  241. ; destroys: ebx,edx,esi,edi
  242.            shr esi, 12
  243.            shr edi, 12
  244. @@:
  245.            mov eax, [page_tabs+esi*4]
  246.            test al, USED_BLOCK
  247.            jz .test_free
  248.            shr eax, 12
  249.            add esi, eax
  250.            jmp @B
  251. .test_free:
  252.            test al, FREE_BLOCK
  253.            jz .err
  254.            mov edx, eax
  255.            shr edx, 12
  256.            add edx, esi
  257.            cmp edx, edi
  258.            jae .exit
  259.  
  260.            mov ebx, [page_tabs+edx*4]
  261.            test bl, USED_BLOCK
  262.            jz .next_free
  263.  
  264.            shr ebx, 12
  265.            add edx, ebx
  266.            mov esi, edx
  267.            jmp @B
  268. .next_free:
  269.            test bl, FREE_BLOCK
  270.            jz .err
  271.            and dword [page_tabs+edx*4], 0
  272.            add eax, ebx
  273.            and eax, not 4095
  274.            or eax, FREE_BLOCK
  275.            mov [page_tabs+esi*4], eax
  276.            jmp @B
  277. .exit:
  278.            xor eax, eax
  279.            inc eax
  280.            ret
  281. .err:
  282.            xor eax, eax
  283.            ret
  284.  
  285. user_realloc:
  286. ; in: eax = pointer, ebx = new size
  287. ; out: eax = new pointer or NULL
  288.         test    eax, eax
  289.         jnz     @f
  290. ; realloc(NULL,sz) - same as malloc(sz)
  291.         push    ebx
  292.         call    user_alloc
  293.         ret
  294. @@:
  295.         push    ecx edx
  296.         lea     ecx, [eax - 0x1000]
  297.         shr     ecx, 12
  298.         mov     edx, [page_tabs+ecx*4]
  299.         test    dl, USED_BLOCK
  300.         jnz     @f
  301. ; attempt to realloc invalid pointer
  302. .ret0:
  303.         pop     edx ecx
  304.         xor     eax, eax
  305.         ret
  306. @@:
  307.         test    dl, DONT_FREE_BLOCK
  308.         jnz     .ret0
  309.         add     ebx, 0x1FFF
  310.         shr     edx, 12
  311.         shr     ebx, 12
  312. ; edx = allocated size, ebx = new size
  313.         add     edx, ecx
  314.         add     ebx, ecx
  315.         cmp     edx, ebx
  316.         jb      .realloc_add
  317. ; release part of allocated memory
  318. .loop:
  319.         cmp     edx, ebx
  320.         jz      .release_done
  321.         dec     edx
  322.         xor     eax, eax
  323.         xchg    eax, [page_tabs+edx*4]
  324.         test    al, 1
  325.         jz      .loop
  326.         call    free_page
  327.         mov     eax, edx
  328.         shl     eax, 12
  329.         invlpg  [eax]
  330.         jmp     .loop
  331. .release_done:
  332.         sub     ebx, ecx
  333.         cmp     ebx, 1
  334.         jnz     .nofreeall
  335.         mov     eax, [page_tabs+ecx*4]
  336.         and     eax, not 0xFFF
  337.         mov     edx, [current_slot]
  338.         mov     ebx, [APPDATA.mem_size+edx]
  339.         sub     ebx, eax
  340.         add     ebx, 0x1000
  341.         or      al, FREE_BLOCK
  342.         mov     [page_tabs+ecx*4], eax
  343.         push    esi edi
  344.         mov     esi, [APPDATA.heap_base+edx]
  345.         mov     edi, [APPDATA.heap_top+edx]
  346.         call    update_mem_size
  347.         call    user_normalize
  348.         pop     edi esi
  349.         jmp     .ret0   ; all freed
  350. .nofreeall:
  351.         sub     edx, ecx
  352.         shl     ebx, 12
  353.         or      ebx, USED_BLOCK
  354.         xchg    [page_tabs+ecx*4], ebx
  355.         shr     ebx, 12
  356.         sub     ebx, edx
  357.         push    ebx ecx edx
  358.         mov     edx, [current_slot]
  359.         shl     ebx, 12
  360.         sub     ebx, [APPDATA.mem_size+edx]
  361.         neg     ebx
  362.         call    update_mem_size
  363.         pop     edx ecx ebx
  364.         lea     eax, [ecx+1]
  365.         shl     eax, 12
  366.         push    eax
  367.         add     ecx, edx
  368.         lea     edx, [ecx+ebx]
  369.         shl     ebx, 12
  370.         jz      .ret
  371.         push    esi
  372.         mov     esi, [current_slot]
  373.         mov     esi, [APPDATA.heap_top+esi]
  374.         shr     esi, 12
  375. @@:
  376.         cmp     edx, esi
  377.         jae     .merge_done
  378.         mov     eax, [page_tabs+edx*4]
  379.         test    al, USED_BLOCK
  380.         jnz     .merge_done
  381.         and     dword [page_tabs+edx*4], 0
  382.         shr     eax, 12
  383.         add     edx, eax
  384.         shl     eax, 12
  385.         add     ebx, eax
  386.         jmp     @b
  387. .merge_done:
  388.         pop     esi
  389.         or      ebx, FREE_BLOCK
  390.         mov     [page_tabs+ecx*4], ebx
  391. .ret:
  392.         pop     eax edx ecx
  393.         ret
  394. .realloc_add:
  395. ; get some additional memory
  396.         mov     eax, [current_slot]
  397.         mov     eax, [APPDATA.heap_top+eax]
  398.         shr     eax, 12
  399.         cmp     edx, eax
  400.         jae     .cant_inplace
  401.         mov     eax, [page_tabs+edx*4]
  402.         test    al, FREE_BLOCK
  403.         jz      .cant_inplace
  404.         shr     eax, 12
  405.         add     eax, edx
  406.         sub     eax, ebx
  407.         jb      .cant_inplace
  408.         jz      @f
  409.         shl     eax, 12
  410.         or      al, FREE_BLOCK
  411.         mov     [page_tabs+ebx*4], eax
  412. @@:
  413.         mov     eax, ebx
  414.         sub     eax, ecx
  415.         shl     eax, 12
  416.         or      al, USED_BLOCK
  417.         mov     [page_tabs+ecx*4], eax
  418.         lea     eax, [ecx+1]
  419.         shl     eax, 12
  420.         push    eax
  421.         push    edi
  422.         lea     edi, [page_tabs+edx*4]
  423.         mov     eax, 2
  424.         sub     ebx, edx
  425.         mov     ecx, ebx
  426.         cld
  427.         rep     stosd
  428.         pop     edi
  429.         mov     edx, [current_slot]
  430.         shl     ebx, 12
  431.         add     ebx, [APPDATA.mem_size+edx]
  432.         call    update_mem_size
  433.         pop     eax edx ecx
  434.         ret
  435. .cant_inplace:
  436.         push    esi edi
  437.         mov     eax, [current_slot]
  438.         mov     esi, [APPDATA.heap_base+eax]
  439.         mov     edi, [APPDATA.heap_top+eax]
  440.         shr     esi, 12
  441.         shr     edi, 12
  442.         sub     ebx, ecx
  443. .find_place:
  444.         cmp     esi, edi
  445.         jae     .place_not_found
  446.         mov     eax, [page_tabs+esi*4]
  447.         test    al, FREE_BLOCK
  448.         jz      .next_place
  449.         shr     eax, 12
  450.         cmp     eax, ebx
  451.         jae     .place_found
  452.         add     esi, eax
  453.         jmp     .find_place
  454. .next_place:
  455.         shr     eax, 12
  456.         add     esi, eax
  457.         jmp     .find_place
  458. .place_not_found:
  459.         pop     edi esi
  460.         jmp     .ret0
  461. .place_found:
  462.         sub     eax, ebx
  463.         jz      @f
  464.         push    esi
  465.         add     esi, ebx
  466.         shl     eax, 12
  467.         or      al, FREE_BLOCK
  468.         mov     [page_tabs+esi*4], eax
  469.         pop     esi
  470. @@:
  471.         mov     eax, ebx
  472.         shl     eax, 12
  473.         or      al, USED_BLOCK
  474.         mov     [page_tabs+esi*4], eax
  475.         inc     esi
  476.         mov     eax, esi
  477.         shl     eax, 12
  478.         push    eax
  479.         mov     eax, [page_tabs+ecx*4]
  480.         and     eax, not 0xFFF
  481.         or      al, FREE_BLOCK
  482.         sub     edx, ecx
  483.         mov     [page_tabs+ecx*4], eax
  484.         inc     ecx
  485.         dec     ebx
  486.         dec     edx
  487.         jz      .no
  488. @@:
  489.         xor     eax, eax
  490.         xchg    eax, [page_tabs+ecx*4]
  491.         mov     [page_tabs+esi*4], eax
  492.         mov     eax, ecx
  493.         shl     eax, 12
  494.         invlpg  [eax]
  495.         inc     esi
  496.         inc     ecx
  497.         dec     ebx
  498.         dec     edx
  499.         jnz     @b
  500. .no:
  501.         push    ebx
  502.         mov     edx, [current_slot]
  503.         shl     ebx, 12
  504.         add     ebx, [APPDATA.mem_size+edx]
  505.         call    update_mem_size
  506.         pop     ebx
  507. @@:
  508.         mov     dword [page_tabs+esi*4], 2
  509.         inc     esi
  510.         dec     ebx
  511.         jnz     @b
  512.         pop     eax edi esi edx ecx
  513.         ret
  514.  
  515. if 0
  516. align 4
  517. proc alloc_dll
  518.            pushf
  519.            cli
  520.            bsf eax, [dll_map]
  521.            jnz .find
  522.            popf
  523.            xor eax, eax
  524.            ret
  525. .find:
  526.            btr [dll_map], eax
  527.            popf
  528.            shl eax, 5
  529.            add eax, dll_tab
  530.            ret
  531. endp
  532.  
  533. align 4
  534. proc alloc_service
  535.            pushf
  536.            cli
  537.            bsf eax, [srv_map]
  538.            jnz .find
  539.            popf
  540.            xor eax, eax
  541.            ret
  542. .find:
  543.            btr [srv_map], eax
  544.            popf
  545.            shl eax,0x02
  546.            lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
  547.            ret
  548. endp
  549.  
  550. end if
  551.