Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 8037 → Rev 5363

/kernel/trunk/bus/usb/memory.inc/slab.inc
7,12 → 7,13
 
$Revision$
 
; Memory management for slab structures.
; The allocator meets special requirements:
; * memory blocks are properly aligned
; * memory blocks do not cross page boundary
; The allocator manages fixed-size blocks.
; Thus, the specific allocator works as follows:
; Memory management for USB structures.
; Protocol layer uses the common kernel heap malloc/free.
; Hardware layer has special requirements:
; * memory blocks should be properly aligned
; * memory blocks should not cross page boundary
; Hardware layer allocates fixed-size blocks.
; Thus, the specific allocator is quite easy to write:
; allocate one page, split into blocks, maintain the single-linked
; list of all free blocks in each page.
 
22,7 → 23,7
 
; Allocator for fixed-size blocks: allocate a block.
; [ebx-4] = pointer to the first page, ebx = pointer to MUTEX structure.
proc slab_alloc
proc usb_allocate_common
push edi ; save used register to be stdcall
virtual at esp
dd ? ; saved edi
54,9 → 55,9
; 2f. Update the pointer to the first free block from eax to ecx.
; Normally [edx-8] still contains eax, if so, atomically set it to ecx
; and proceed to 3.
; However, the price of simplicity of slab_free (in particular, it doesn't take
; the lock) is that [edx-8] could (rarely) be changed while we processed steps
; 2d+2e. If so, return to 2d and retry.
; However, the price of simplicity of usb_free_common (in particular, it
; doesn't take the lock) is that [edx-8] could (rarely) be changed while
; we processed steps 2d+2e. If so, return to 2d and retry.
lock cmpxchg [edx-8], ecx
jnz @b
.return:
98,13 → 99,13
; 8. Return (start of page).
jmp .return
.nomemory:
dbgstr 'no memory for slab allocation'
dbgstr 'no memory for USB descriptor'
xor eax, eax
jmp .return
endp
 
; Allocator for fixed-size blocks: free a block.
proc slab_free
proc usb_free_common
push ecx edx
virtual at esp
rd 2 ; saved registers
123,3 → 124,30
pop edx ecx
ret 4
endp
 
; Helper procedure: translate physical address in ecx
; of some transfer descriptor to linear address.
; in: eax = address of first page
proc usb_td_to_virt
; Traverse all pages used for transfer descriptors, looking for the one
; with physical address as in ecx.
@@:
test eax, eax
jz .zero
push eax
call get_pg_addr
sub eax, ecx
jz .found
cmp eax, -0x1000
ja .found
pop eax
mov eax, [eax+0x1000-4]
jmp @b
.found:
; When found, combine page address from eax with page offset from ecx.
pop eax
and ecx, 0xFFF
add eax, ecx
.zero:
ret
endp