github.com/dshulyak/uring@v0.0.0-20210209113719-1b2ec51f1542/fixed/allocator.go (about) 1 package fixed 2 3 import ( 4 "errors" 5 "syscall" 6 "unsafe" 7 ) 8 9 var ( 10 // ErrOverflow returned if requested buffer number larget then max number. 11 ErrOverflow = errors.New("buffer number overflow") 12 ) 13 14 var iovecSize = int(unsafe.Sizeof(syscall.Iovec{})) 15 16 type allocator struct { 17 max int // max number of buffers 18 bufferSize int // requested size of the buffer 19 20 // mem is splitted in two parts 21 // header - list of iovec structs. 22 // starts at mem[0]. current length is iovecSz*allocated 23 // buffers - list of buffers of the same size. 24 mem []byte 25 26 reg BufferRegistry 27 } 28 29 func (a *allocator) init() error { 30 prot := syscall.PROT_READ | syscall.PROT_WRITE 31 flags := syscall.MAP_ANON | syscall.MAP_PRIVATE 32 size := a.bufferSize * a.max 33 mem, err := syscall.Mmap(-1, 0, size, prot, flags) 34 if err != nil { 35 return err 36 } 37 a.mem = mem 38 iovec := []syscall.Iovec{{Base: &mem[0], Len: uint64(size)}} 39 return a.reg.RegisterBuffers(iovec) 40 } 41 42 func (a *allocator) close() error { 43 return syscall.Munmap(a.mem) 44 } 45 46 func (a *allocator) bufAt(pos int) []byte { 47 start := pos * a.bufferSize 48 return a.mem[start : start+a.bufferSize] 49 }