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 }
func (sch *aioScheduler) submit(iocb *C.iocb_t) (*event, error) { C.io_set_eventfd(iocb, C.int(sch.eventfd.Sysfd())) ev := NewEvent() sch.mu.Lock() sch.reqs[iocb] = ev sch.mu.Unlock() errno := C.io_submit(sch.ctx, 1, &iocb) if errno == 0 { return nil, errors.New("Failed to submit io") } else if errno < 0 { return nil, syscall.Errno(-errno) } return ev, 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 }