github.com/icexin/eggos@v0.4.2-0.20220216025428-78b167e4f349/kernel/mm/pool.go (about)

     1  package mm
     2  
     3  import (
     4  	"unsafe"
     5  
     6  	"github.com/icexin/eggos/kernel/sys"
     7  )
     8  
     9  //go:notinheap
    10  type memblk struct {
    11  	next uintptr
    12  }
    13  
    14  // Pool used to manage fixed size memory block
    15  //go:notinheap
    16  type Pool struct {
    17  	size uintptr
    18  	head uintptr
    19  }
    20  
    21  // size will align ptr size
    22  //go:nosplit
    23  func PoolInit(p *Pool, size uintptr) {
    24  	const align = sys.PtrSize - 1
    25  	size = (size + align) &^ align
    26  	p.size = size
    27  }
    28  
    29  //go:nosplit
    30  func (p *Pool) grow() {
    31  	start := kmm.alloc()
    32  	end := start + PGSIZE
    33  	for v := start; v+p.size <= end; v += p.size {
    34  		p.Free(v)
    35  	}
    36  }
    37  
    38  //go:nosplit
    39  func (p *Pool) Alloc() uintptr {
    40  	if p.head == 0 {
    41  		p.grow()
    42  	}
    43  	ret := p.head
    44  	h := (*memblk)(unsafe.Pointer(p.head))
    45  	p.head = h.next
    46  	sys.Memclr(ret, int(p.size))
    47  	return ret
    48  }
    49  
    50  //go:nosplit
    51  func (p *Pool) Free(ptr uintptr) {
    52  	v := (*memblk)(unsafe.Pointer(ptr))
    53  	v.next = p.head
    54  	p.head = ptr
    55  }