1
0
mirror of https://github.com/taigrr/gopher-os synced 2025-01-18 04:43:13 -08:00

Define memory Size and implement optimized memset

This commit is contained in:
Achilleas Anagnostopoulos 2017-05-10 06:59:48 +01:00
parent ca36793782
commit 61314a9c33
4 changed files with 81 additions and 0 deletions

View File

@ -0,0 +1,13 @@
// +build amd64
package mem
const (
// PageShift is equal to log2(PageSize). This constant is used when
// we need to convert a physical address to a page number (shift right by PageShift)
// and vice-versa.
PageShift = 12
// PageSize defines the system's page size in bytes.
PageSize = Size(1 << PageShift)
)

29
kernel/mem/memset.go Normal file
View File

@ -0,0 +1,29 @@
package mem
import (
"reflect"
"unsafe"
)
// Memset sets size bytes at the given address to the supplied value. The implementation
// is based on bytes.Repeat; instead of using a for loop, this function uses
// log2(size) copy calls which should give us a speed boost as page addresses
// are always aligned.
func Memset(addr uintptr, value byte, size Size) {
if size == 0 {
return
}
// overlay a slice on top of this address region
target := *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Len: int(size),
Cap: int(size),
Data: addr,
}))
// Set first element and make log2(size) optimized copies
target[0] = value
for index := Size(1); index < size; index *= 2 {
copy(target[index:], target[:index])
}
}

27
kernel/mem/memset_test.go Normal file
View File

@ -0,0 +1,27 @@
package mem
import (
"testing"
"unsafe"
)
func TestMemset(t *testing.T) {
// memset with a 0 size should be a no-op
Memset(uintptr(0), 0x00, 0)
for pageCount := uint32(1); pageCount <= 10; pageCount++ {
buf := make([]byte, PageSize<<pageCount)
for i := 0; i < len(buf); i++ {
buf[i] = 0xFE
}
addr := uintptr(unsafe.Pointer(&buf[0]))
Memset(addr, 0x00, Size(len(buf)))
for i := 0; i < len(buf); i++ {
if got := buf[i]; got != 0x00 {
t.Errorf("[block with %d pages] expected byte: %d to be 0x00; got 0x%x", pageCount, i, got)
}
}
}
}

12
kernel/mem/size.go Normal file
View File

@ -0,0 +1,12 @@
package mem
// Size represents a memory block size in bytes.
type Size uint64
// Common memory block sizes.
const (
Byte Size = 1
Kb = 1024 * Byte
Mb = 1024 * Kb
Gb = 1024 * Mb
)