Subversion Repositories Kolibri OS

Rev

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