Subversion Repositories Kolibri OS

Rev

Rev 887 | Rev 889 | 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: 888 $
  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.            test al, DONT_FREE_BLOCK
  150.            jnz .cantfree
  151.  
  152.            push edi
  153.  
  154.            and eax, not 4095
  155.            mov edi, eax
  156.            or al, FREE_BLOCK
  157.            mov [page_tabs+(esi-1)*4], eax
  158.            sub edi, 4096
  159.            mov ebx, edi
  160.            shr edi, 12
  161.            jz .released
  162. .release:
  163.            xor ecx, ecx
  164.            xchg ecx, [page_tabs+esi*4]
  165.            test cl, 1
  166.            jz @F
  167.  
  168.            call @core_free@4
  169.            mov eax, esi
  170.            shl eax, 12
  171.            invlpg [eax]
  172. @@:
  173.            inc esi
  174.            dec edi
  175.            jnz .release
  176. .released:
  177.            mov edx, [current_slot]
  178.            mov esi, dword [edx+APPDATA.heap_base]
  179.            mov edi, dword [edx+APPDATA.heap_top]
  180.            sub ebx, [edx+APPDATA.mem_size]
  181.            neg ebx
  182.            call update_mem_size
  183.            call user_normalize
  184.            pop edi
  185.            pop ebx
  186.            pop esi
  187.            ret
  188. .exit:
  189.            xor eax, eax
  190.            inc eax
  191.            pop esi
  192.            ret
  193. .cantfree:
  194.            xor eax, eax
  195.            pop ebx
  196.            pop esi
  197.            ret
  198. endp
  199.  
  200. user_normalize:
  201. ; in: esi=heap_base, edi=heap_top
  202. ; out: eax=0 <=> OK
  203. ; destroys: ebx,edx,esi,edi
  204.            shr esi, 12
  205.            shr edi, 12
  206. @@:
  207.            mov eax, [page_tabs+esi*4]
  208.            test al, USED_BLOCK
  209.            jz .test_free
  210.            shr eax, 12
  211.            add esi, eax
  212.            jmp @B
  213. .test_free:
  214.            test al, FREE_BLOCK
  215.            jz .err
  216.            mov edx, eax
  217.            shr edx, 12
  218.            add edx, esi
  219.            cmp edx, edi
  220.            jae .exit
  221.  
  222.            mov ebx, [page_tabs+edx*4]
  223.            test bl, USED_BLOCK
  224.            jz .next_free
  225.  
  226.            shr ebx, 12
  227.            add edx, ebx
  228.            mov esi, edx
  229.            jmp @B
  230. .next_free:
  231.            test bl, FREE_BLOCK
  232.            jz .err
  233.            and dword [page_tabs+edx*4], 0
  234.            add eax, ebx
  235.            and eax, not 4095
  236.            or eax, FREE_BLOCK
  237.            mov [page_tabs+esi*4], eax
  238.            jmp @B
  239. .exit:
  240.            xor eax, eax
  241.            inc eax
  242.            ret
  243. .err:
  244.            xor eax, eax
  245.            ret
  246.  
  247. user_realloc:
  248. ; in: eax = pointer, ebx = new size
  249. ; out: eax = new pointer or NULL
  250.         test    eax, eax
  251.         jnz     @f
  252. ; realloc(NULL,sz) - same as malloc(sz)
  253.         push    ebx
  254.         call    user_alloc
  255.         ret
  256. @@:
  257.         push    ecx edx
  258.         lea     ecx, [eax - 0x1000]
  259.         shr     ecx, 12
  260.         mov     edx, [page_tabs+ecx*4]
  261.         test    dl, USED_BLOCK
  262.         jnz     @f
  263. ; attempt to realloc invalid pointer
  264. .ret0:
  265.         pop     edx ecx
  266.         xor     eax, eax
  267.         ret
  268. @@:
  269.         test    dl, DONT_FREE_BLOCK
  270.         jnz     .ret0
  271.         add     ebx, 0x1FFF
  272.         shr     edx, 12
  273.         shr     ebx, 12
  274. ; edx = allocated size, ebx = new size
  275.         add     edx, ecx
  276.         add     ebx, ecx
  277.         cmp     edx, ebx
  278.         jb      .realloc_add
  279. ; release part of allocated memory
  280.  
  281.         push ecx
  282. .loop:
  283.         cmp     edx, ebx
  284.         jz      .release_done
  285.         dec     edx
  286.         xor     ecx, ecx
  287.         xchg    ecx, [page_tabs+edx*4]
  288.         test    al, 1
  289.         jz      .loop
  290.  
  291.         push edx
  292.         call    @core_free@4
  293.         pop edx
  294.         mov     eax, edx
  295.         shl     eax, 12
  296.         invlpg  [eax]
  297.         jmp     .loop
  298. .release_done:
  299.  
  300.         pop ecx
  301.  
  302.         sub     ebx, ecx
  303.         cmp     ebx, 1
  304.         jnz     .nofreeall
  305.         mov     eax, [page_tabs+ecx*4]
  306.         and     eax, not 0xFFF
  307.         mov     edx, [current_slot]
  308.         mov     ebx, [APPDATA.mem_size+edx]
  309.         sub     ebx, eax
  310.         add     ebx, 0x1000
  311.         or      al, FREE_BLOCK
  312.         mov     [page_tabs+ecx*4], eax
  313.         push    esi edi
  314.         mov     esi, [APPDATA.heap_base+edx]
  315.         mov     edi, [APPDATA.heap_top+edx]
  316.         call    update_mem_size
  317.         call    user_normalize
  318.         pop     edi esi
  319.         jmp     .ret0   ; all freed
  320. .nofreeall:
  321.         sub     edx, ecx
  322.         shl     ebx, 12
  323.         or      ebx, USED_BLOCK
  324.         xchg    [page_tabs+ecx*4], ebx
  325.         shr     ebx, 12
  326.         sub     ebx, edx
  327.         push    ebx ecx edx
  328.         mov     edx, [current_slot]
  329.         shl     ebx, 12
  330.         sub     ebx, [APPDATA.mem_size+edx]
  331.         neg     ebx
  332.         call    update_mem_size
  333.         pop     edx ecx ebx
  334.         lea     eax, [ecx+1]
  335.         shl     eax, 12
  336.         push    eax
  337.         add     ecx, edx
  338.         lea     edx, [ecx+ebx]
  339.         shl     ebx, 12
  340.         jz      .ret
  341.         push    esi
  342.         mov     esi, [current_slot]
  343.         mov     esi, [APPDATA.heap_top+esi]
  344.         shr     esi, 12
  345. @@:
  346.         cmp     edx, esi
  347.         jae     .merge_done
  348.         mov     eax, [page_tabs+edx*4]
  349.         test    al, USED_BLOCK
  350.         jnz     .merge_done
  351.         and     dword [page_tabs+edx*4], 0
  352.         shr     eax, 12
  353.         add     edx, eax
  354.         shl     eax, 12
  355.         add     ebx, eax
  356.         jmp     @b
  357. .merge_done:
  358.         pop     esi
  359.         or      ebx, FREE_BLOCK
  360.         mov     [page_tabs+ecx*4], ebx
  361. .ret:
  362.         pop     eax edx ecx
  363.         ret
  364. .realloc_add:
  365. ; get some additional memory
  366.         mov     eax, [current_slot]
  367.         mov     eax, [APPDATA.heap_top+eax]
  368.         shr     eax, 12
  369.         cmp     edx, eax
  370.         jae     .cant_inplace
  371.         mov     eax, [page_tabs+edx*4]
  372.         test    al, FREE_BLOCK
  373.         jz      .cant_inplace
  374.         shr     eax, 12
  375.         add     eax, edx
  376.         sub     eax, ebx
  377.         jb      .cant_inplace
  378.         jz      @f
  379.         shl     eax, 12
  380.         or      al, FREE_BLOCK
  381.         mov     [page_tabs+ebx*4], eax
  382. @@:
  383.         mov     eax, ebx
  384.         sub     eax, ecx
  385.         shl     eax, 12
  386.         or      al, USED_BLOCK
  387.         mov     [page_tabs+ecx*4], eax
  388.         lea     eax, [ecx+1]
  389.         shl     eax, 12
  390.         push    eax
  391.         push    edi
  392.         lea     edi, [page_tabs+edx*4]
  393.         mov     eax, 2
  394.         sub     ebx, edx
  395.         mov     ecx, ebx
  396.         cld
  397.         rep     stosd
  398.         pop     edi
  399.         mov     edx, [current_slot]
  400.         shl     ebx, 12
  401.         add     ebx, [APPDATA.mem_size+edx]
  402.         call    update_mem_size
  403.         pop     eax edx ecx
  404.         ret
  405. .cant_inplace:
  406.         push    esi edi
  407.         mov     eax, [current_slot]
  408.         mov     esi, [APPDATA.heap_base+eax]
  409.         mov     edi, [APPDATA.heap_top+eax]
  410.         shr     esi, 12
  411.         shr     edi, 12
  412.         sub     ebx, ecx
  413. .find_place:
  414.         cmp     esi, edi
  415.         jae     .place_not_found
  416.         mov     eax, [page_tabs+esi*4]
  417.         test    al, FREE_BLOCK
  418.         jz      .next_place
  419.         shr     eax, 12
  420.         cmp     eax, ebx
  421.         jae     .place_found
  422.         add     esi, eax
  423.         jmp     .find_place
  424. .next_place:
  425.         shr     eax, 12
  426.         add     esi, eax
  427.         jmp     .find_place
  428. .place_not_found:
  429.         pop     edi esi
  430.         jmp     .ret0
  431. .place_found:
  432.         sub     eax, ebx
  433.         jz      @f
  434.         push    esi
  435.         add     esi, ebx
  436.         shl     eax, 12
  437.         or      al, FREE_BLOCK
  438.         mov     [page_tabs+esi*4], eax
  439.         pop     esi
  440. @@:
  441.         mov     eax, ebx
  442.         shl     eax, 12
  443.         or      al, USED_BLOCK
  444.         mov     [page_tabs+esi*4], eax
  445.         inc     esi
  446.         mov     eax, esi
  447.         shl     eax, 12
  448.         push    eax
  449.         mov     eax, [page_tabs+ecx*4]
  450.         and     eax, not 0xFFF
  451.         or      al, FREE_BLOCK
  452.         sub     edx, ecx
  453.         mov     [page_tabs+ecx*4], eax
  454.         inc     ecx
  455.         dec     ebx
  456.         dec     edx
  457.         jz      .no
  458. @@:
  459.         xor     eax, eax
  460.         xchg    eax, [page_tabs+ecx*4]
  461.         mov     [page_tabs+esi*4], eax
  462.         mov     eax, ecx
  463.         shl     eax, 12
  464.         invlpg  [eax]
  465.         inc     esi
  466.         inc     ecx
  467.         dec     ebx
  468.         dec     edx
  469.         jnz     @b
  470. .no:
  471.         push    ebx
  472.         mov     edx, [current_slot]
  473.         shl     ebx, 12
  474.         add     ebx, [APPDATA.mem_size+edx]
  475.         call    update_mem_size
  476.         pop     ebx
  477. @@:
  478.         mov     dword [page_tabs+esi*4], 2
  479.         inc     esi
  480.         dec     ebx
  481.         jnz     @b
  482.         pop     eax edi esi edx ecx
  483.         ret
  484.  
  485. if 0
  486. align 4
  487. proc alloc_dll
  488.            pushf
  489.            cli
  490.            bsf eax, [dll_map]
  491.            jnz .find
  492.            popf
  493.            xor eax, eax
  494.            ret
  495. .find:
  496.            btr [dll_map], eax
  497.            popf
  498.            shl eax, 5
  499.            add eax, dll_tab
  500.            ret
  501. endp
  502.  
  503. align 4
  504. proc alloc_service
  505.            pushf
  506.            cli
  507.            bsf eax, [srv_map]
  508.            jnz .find
  509.            popf
  510.            xor eax, eax
  511.            ret
  512. .find:
  513.            btr [srv_map], eax
  514.            popf
  515.            shl eax,0x02
  516.            lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
  517.            ret
  518. endp
  519.  
  520. end if
  521.