StupidOS/kernel/mm/vmem.inc

383 lines
6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;; File: vmem.inc
;;
;; General purpose resource allocator.
;; Based on <tinyvmem at https://github.com/rdmsr/tinyvmem> and on <Bonwick's paper at https://www.usenix.org/legacy/event/usenix01/full_papers/bonwick/bonwick.pdf>
;;; MARK: macros and structs
VM_BESTFIT = (1 shl 0)
VM_INSTANTFIT = (1 shl 1)
VM_NEXTFIT = (1 shl 2)
VM_SLEEP = (1 shl 3)
VM_NOSLEEP = (1 shl 4)
VM_BOOTSTRAP = (1 shl 5)
STATIC_SEG_COUNT = 64
FREELISTS_N = 4 * 8
HASHTABLE_N = 16
SEGMENT_ALLOCATED = 0
SEGMENT_FREE = 1
SEGMENT_SPAN = 2
macro GET_LIST reg, N {
bsr reg, reg
xor reg, 31
add reg, -N
sub reg, 1
}
struc VmSegment {
.type db ?
.imported db ?
.base dd ?
.size dd ?
.spanlist ListEntry
.seglist ListEntry
}
DEFN VmSegment
;; Struc: Vmem
struc Vmem {
.name db 16 dup(0)
.base dd ?
.size dd ?
.quantum dd ?
.alloc dd ?
.free dd ?
.source dd ?
.flags dd ?
.freelist dd FREELISTS_N dup(0)
.hashtable dd HASHTABLE_N dup(0)
.spanlist ListHead 0
}
DEFN Vmem
;;; MARK: private functions
;; Function: _murmur32
;;
;; In:
;; EAX - Address
;;
;; Out:
;; EAX - Hash
;;
_murmur32:
; hash hash XOR (hash >> 16)
mov ecx, eax
shr ecx, 16
xor eax, ecx
; hash hash × 0x85ebca6b
mov ecx, 0x85ebca6b
mul ecx
; hash hash XOR (hash >> 13)
mov ecx, eax
shr ecx, 13
xor eax, ecx
; hash hash × 0xc2b2ae35
mov ecx, 0xc2b2ae35
mul ecx
; hash hash XOR (hash >> 16)
mov ecx, eax
shr ecx, 16
xor eax, ecx
ret
;; Function: _hash_table_addr
;;
;; In:
;; EAX - Vmem
;; EDX - ADDR
__hash_table_addr:
push ebp
mov ebp, esp
push esi
mov esi, eax
mov eax, edx
call _murmur32
and eax, HASHTABLE_N-1 ; x % y (y is a power of two)
shl eax, 2
mov edx, esi
add edx, Vmem.hashtable
add edx, eax
mov eax, [edx]
pop esi
leave
ret
;; Function: _vmem_segfree
;;
;; In:
;; EAX - Segment address
;;
_vmem_segfree:
; XXX: lock
add eax, VmSegment.seglist
mov edx, pVmemFreeSegHead
xchg eax, edx
call list_insert_head
inc [iVmemFreeSegCount]
; XXX: unlock
ret
;; Function: _vmem_segalloc
;;
;; Out:
;; EAX - Pointer to <VmSegment> object on success, 0 on error
_vmem_segalloc:
push ebp
mov ebp, esp
; XXX: lock
mov eax, [pVmemFreeSegHead]
or eax, eax
jz .end
push ebx
mov ebx, eax
call list_remove
sub ebx, VmSegment.seglist
dec [iVmemFreeSegCount]
pop ebx
.end:
; XXX: unlock
leave
ret
;;; MARK: public functions
;; Function: vmem_create
;;
;; Creates a new <Vmem> arena whose initial span is [Base, Base + Size).
;;
;; In:
;; EAX - Pointer to a <Vmem> object.
;; EDX - String.
;; ECX - Base.
;; ESP[4] - Size in bytes.
;; ESP[8] - Quantum.
;; ESP[12] - Alloc function.
;; ESP[16] - Free function.
;; ESP[20] - Source.
;; ESP[24] - Flags. (<VM_SLEEP> or <VM_NOSLEEP>)
vmem_create:
push ebp
mov ebp, esp
sub esp, 8
push esi
push edi
mov [ebp - 8], eax
mov [ebp - 4], ecx
; zero Vmem object
cld
mov edi, eax
xor eax, eax
mov ecx, sizeof.Vmem shr 2
cld
rep stosd
; copy name
mov esi, edx
mov edx, [ebp - 8]
xor cl, cl
@@:
lodsb
or al, al
jz @f
mov [edx], al
inc edx
inc cl
cmp cl, 15
jl @b
@@:
mov edi, [ebp - 8]
mov ecx, [ebp - 4]
mov [edi + Vmem.base], ecx
; copy other from stack to struct
mov ecx, 28 shr 2
mov esi, ebp
add esi, 8
mov edi, [ebp - 8]
add edi, Vmem.size
rep movsd
mov eax, [ebp - 8]
mov edx, [ebp - 4]
or edx, edx
jnz @f
mov ecx, [eax + Vmem.size]
or ecx, ecx
jz @f
push dword [eax + Vmem.flags]
call vmem_add
add esp, 4
@@:
if CONFIG_TRACE_VMEM
mov esi, [ebp - 8]
mov edx, [esi + Vmem.base]
mov ecx, [esi + Vmem.size]
add ecx, edx
TRACE szTraceVmemCreate, esi, edx, ecx
end if
pop edi
pop esi
leave
ret
;; Function: vmem_destroy
;;
;; Destroys an arena
;;
;; In:
;; EAX - Pointer to a <Vmem> object.
vmem_destroy:
ret
;; Function: vmem_alloc
;;
;; Allocates n-bytes from arena.
;;
;; In:
;; EAX - Pointer to a <Vmem> object.
;; EDX - Size in bytes.
;; ECX - Flags
;;
;; Out:
;; EAX - Allocated address on succes, 0 on failure.
vmem_alloc:
ret
;; Function: vmem_free
;;
;; Free n-bytes at address to arena
;;
;; In:
;; EAX - Pointer to a <Vmem> object.
;; EDX - Address.
;; ECX - Size in bytes.
vmem_free:
ret
;; Function: vmem_xalloc
;;
;; In:
;; EAX - Pointer to a <Vmem> object.
;; EDX - Size in bytes.
;; ECX - Alignment boundary.
;; ESP[4] - Phase.
;; ESP[8] - Nocross.
;; ESP[12] - Min address.
;; ESP[16] - Max address.
;; ESP[20] - Flags. (<VM_BESTFIT>, <VM_INSTANTFIT>, <VM_NEXTFIT>, <VM_SLEEP>, <VM_NOSLEEP>)
;;
;; Out:
;; EAX - Allocated address on succes, 0 on failure.
vmem_xalloc:
ret
;; Function: vmem_xfree
;;
;; Frees n-bytes at address.
;;
;; In:
;; EAX - Pointer to <Vmem> object.
;; EDX - Address.
;; ECX - Size in bytes.
vmem_xfree:
ret
;; Function: vmem_add
;;
;; Adds a span [Address, Address + Size) to an arena.
;;
;; In:
;; EAX - Pointer to <Vmem> object.
;; EDX - Address.
;; ECX - Size in bytes.
;; ESP[4] - Flags. (<VM_SLEEP> or <VM_NOSLEEP>)
;;
;; Out:
;; EAX - Return Address on success, 0 on failure.
vmem_add:
push ebp
mov ebp, esp
push esi
push edi
push ebx
mov esi, eax
mov edi, ebx
mov ebx, ecx
pop ebx
pop edi
pop esi
leave
ret
;; Function: vmem_bootstrap
;;
;; Initialize static segments
;;
vmem_bootstrap:
push ebp
mov ebp, esp
if CONFIG_TRACE_VMEM
TRACE szTraceVmemBootstrap
end if
push ebx
xor ebx, ebx
@@:
mov eax, aVmemStaticSegs
add eax, ebx
call _vmem_segfree
add ebx, sizeof.VmSegment
cmp ebx, STATIC_SEG_COUNT*sizeof.VmSegment
jl @b
pop ebx
leave
ret
;;; MARK: variables
aVmemStaticSegs db STATIC_SEG_COUNT*sizeof.VmSegment dup(0)
pVmemFreeSegHead dd 0
iVmemFreeSegCount dd 0
if CONFIG_TRACE_VMM
szTraceVmemBootstrap db "Trace(VMEM): Bootstrap vmem", 0
szTraceVmemCreate db "Trace(VMEM): Create %s [%x, %x)", 0
szTraceVmemAdd db "Trace(VMEM): %s: Add span [%x, %x)", 0
szTraceVmemDestroy db "Trace(VMEM): Destroy %s", 0
end if