Subversion Repositories Kolibri OS

Rev

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