func NewBIO(dev BlockDevice, N int, BSize uint64) (bio *BIO) { if (PAGESIZE % BSize) != 0 { f**k("BIO with non-divisors of the PAGESIZE not implemented") } bio = new(BIO) bio.BSize = BSize bio.BlockDevice = dev bio.free = make(chan *Buf, N) bio.all = make([]Buf, N) virt, phys := runtime.AlignAlloc(uint64(N) * BSize) for k := range bio.all { h := (*runtime.SliceHeader)(unsafe.Pointer(&bio.all[k].Data)) h.Data, bio.all[k].Phys = virt, phys virt += uintptr(BSize) phys += BSize h.Len = int(BSize) h.Cap = int(BSize) bio.all[k].Done = make(chan bool) bio.all[k].Want = make(chan bool) bio.all[k].BIO = bio bio.all[k].Block = ^uint64(0) bio.free <- &bio.all[k] } return }
// This produces (pseudo-) buffers for actually unbuffered I/O // DON'T use those with the buffer functions, use DoEet // DON'T use it in a large scale // You have been warned func MakeBuf(size uint64, dev BlockDevice) (b *Buf) { b = new(Buf) b.Done = make(chan bool) virt, phys := runtime.AlignAlloc(size) h := (*runtime.SliceHeader)(unsafe.Pointer(&b.Data)) h.Data, b.Phys = virt, phys h.Len, h.Cap = int(size), int(size) b.BIO = new(BIO) b.BIO.BlockDevice = dev return }