github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/buffer.go (about) 1 package machine 2 3 import ( 4 "runtime/volatile" 5 ) 6 7 // RingBuffer is ring buffer implementation inspired by post at 8 // https://www.embeddedrelated.com/showthread/comp.arch.embedded/77084-1.php 9 type RingBuffer struct { 10 rxbuffer [bufferSize]volatile.Register8 11 head volatile.Register8 12 tail volatile.Register8 13 } 14 15 // NewRingBuffer returns a new ring buffer. 16 func NewRingBuffer() *RingBuffer { 17 return &RingBuffer{} 18 } 19 20 // Used returns how many bytes in buffer have been used. 21 func (rb *RingBuffer) Used() uint8 { 22 return uint8(rb.head.Get() - rb.tail.Get()) 23 } 24 25 // Put stores a byte in the buffer. If the buffer is already 26 // full, the method will return false. 27 func (rb *RingBuffer) Put(val byte) bool { 28 if rb.Used() != bufferSize { 29 rb.head.Set(rb.head.Get() + 1) 30 rb.rxbuffer[rb.head.Get()%bufferSize].Set(val) 31 return true 32 } 33 return false 34 } 35 36 // Get returns a byte from the buffer. If the buffer is empty, 37 // the method will return a false as the second value. 38 func (rb *RingBuffer) Get() (byte, bool) { 39 if rb.Used() != 0 { 40 rb.tail.Set(rb.tail.Get() + 1) 41 return rb.rxbuffer[rb.tail.Get()%bufferSize].Get(), true 42 } 43 return 0, false 44 } 45 46 // Clear resets the head and tail pointer to zero. 47 func (rb *RingBuffer) Clear() { 48 rb.head.Set(0) 49 rb.tail.Set(0) 50 }