Subversion Repositories Kolibri OS

Rev

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