func ReadAt(fd int, off int64, size int) ([]byte, error) { idx := <-idle_event retch := aio_result_map[idx] defer func() { idle_event <- idx }() var cb *C.struct_iocb = &cbs[idx] var read_buf unsafe.Pointer C.posix_memalign(&read_buf, pagesize, C.size_t(size)) defer C.free(read_buf) C.io_prep_pread(cb, C.int(fd), read_buf, C.size_t(size), C.longlong(off)) cbs[idx].data = unsafe.Pointer(&idx) aio_lock.Lock() rt := C.io_submit(ctx, 1, &cb) if int(rt) < 0 { aio_lock.Unlock() return nil, errors.New("io submit failed") } aiocount++ aio_lock.Unlock() select { case have_aio_event <- 0: default: } ret := <-retch return ret.buf, ret.err }
// The function allocates size bytes. The address of the allocated memory will // be a multiple of alignment, which must be a power of two and a multiple of // sizeof(void *). Alignment or size must not be 0 or the method will // intentionally panic. func NewAlignedBuffer(alignment int64, size int) (AlignedBuffer, error) { if alignment == 0 || size == 0 { panic(error(syscall.EINVAL)) } // Allocate memory var ptr unsafe.Pointer pbuff := &ptr rv := C.posix_memalign(pbuff, (C.size_t)(alignment), (C.size_t)(size)) if rv < 0 { err := (syscall.Errno)(rv) return nil, err } // Create a slice on top of allocated memory return &_AlignedBuffer{uintptr(ptr), size}, nil }
func WriteAt(fd int, off int64, buf []byte) (int, error) { size := len(buf) if size == 0 { return 0, nil } idx := <-idle_event retch := aio_result_map[idx] defer func() { idle_event <- idx }() var cb *C.struct_iocb = &cbs[idx] var write_buf unsafe.Pointer C.posix_memalign(&write_buf, pagesize, C.size_t(size)) defer C.free(write_buf) for i := 0; i < size; i++ { *(*byte)(unsafe.Pointer(uintptr(write_buf) + uintptr(i))) = buf[i] } C.io_prep_pwrite(cb, C.int(fd), write_buf, C.size_t(size), C.longlong(off)) cbs[idx].data = unsafe.Pointer(&idx) aio_lock.Lock() rt := C.io_submit(ctx, 1, &cb) if int(rt) < 0 { aio_lock.Unlock() return 0, errors.New("io submit failed") } aiocount++ aio_lock.Unlock() select { case have_aio_event <- 0: default: } ret := <-retch return ret.size, ret.err }
func posixMemalign(alignment uint64, size uint64) []byte { var ptr C.void ptr2 := unsafe.Pointer(&ptr) writesize := C.posix_memalign(&ptr2, C.size_t(uintptr(alignment)), C.size_t(uintptr(size))) return []byte(C.GoBytes(unsafe.Pointer(&ptr), writesize)) }