Subversion Repositories Kolibri OS

Rev

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