github.com/pawelgaczynski/giouring@v0.0.0-20230826085535-69588b89acb9/buffer.go (about) 1 // MIT License 2 // 3 // Copyright (c) 2023 Paweł Gaczyński 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining a 6 // copy of this software and associated documentation files (the 7 // "Software"), to deal in the Software without restriction, including 8 // without limitation the rights to use, copy, modify, merge, publish, 9 // distribute, sublicense, and/or sell copies of the Software, and to 10 // permit persons to whom the Software is furnished to do so, subject to 11 // the following conditions: 12 // 13 // The above copyright notice and this permission notice shall be included 14 // in all copies or substantial portions of the Software. 15 // 16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 24 package giouring 25 26 import ( 27 "sync/atomic" 28 "unsafe" 29 ) 30 31 var RingBufStructSize = uint16(unsafe.Sizeof(BufAndRing{})) 32 33 // liburing: io_uring_buf_ring_add - https://manpages.debian.org/unstable/liburing-dev/io_uring_buf_ring_add.3.en.html 34 func (br *BufAndRing) BufRingAdd(addr uintptr, length uint32, bid uint16, mask, bufOffset int) { 35 buf := (*BufAndRing)( 36 unsafe.Pointer(uintptr(unsafe.Pointer(br)) + 37 (uintptr(((br.Tail + uint16(bufOffset)) & uint16(mask)) * RingBufStructSize)))) 38 buf.Addr = uint64(addr) 39 buf.Len = length 40 buf.Bid = bid 41 } 42 43 const bit16offset = 16 44 45 // liburing: io_uring_buf_ring_advance - https://manpages.debian.org/unstable/liburing-dev/io_uring_buf_ring_advance.3.en.html 46 func (br *BufAndRing) BufRingAdvance(count int) { 47 newTail := br.Tail + uint16(count) 48 // FIXME: implement 16 bit version of atomic.Store 49 bidAndTail := (*uint32)(unsafe.Pointer(&br.Bid)) 50 bidAndTailVal := uint32(newTail)<<bit16offset + uint32(br.Bid) 51 atomic.StoreUint32(bidAndTail, bidAndTailVal) 52 } 53 54 // liburing: __io_uring_buf_ring_cq_advance - https://manpages.debian.org/unstable/liburing-dev/__io_uring_buf_ring_cq_advance.3.en.html 55 func (ring *Ring) internalBufRingCQAdvance(br *BufAndRing, bufCount, cqeCount int) { 56 br.Tail += uint16(bufCount) 57 ring.CQAdvance(uint32(cqeCount)) 58 } 59 60 // liburing: io_uring_buf_ring_cq_advance - https://manpages.debian.org/unstable/liburing-dev/io_uring_buf_ring_cq_advance.3.en.html 61 func (ring *Ring) BufRingCQAdvance(br *BufAndRing, count int) { 62 ring.internalBufRingCQAdvance(br, count, count) 63 } 64 65 // liburing: io_uring_buf_ring_init - https://manpages.debian.org/unstable/liburing-dev/io_uring_buf_ring_init.3.en.html 66 func (br *BufAndRing) BufRingInit() { 67 br.Tail = 0 68 } 69 70 // liburing: io_uring_buf_ring_mask - https://manpages.debian.org/unstable/liburing-dev/io_uring_buf_ring_mask.3.en.html 71 func BufRingMask(entries uint32) int { 72 return int(entries - 1) 73 }