@@ -172,115 +172,6 @@ func (dt *DescriptorTable) releaseBuffers() error {
172172 return nil
173173}
174174
175- // createDescriptorChain creates a new descriptor chain within the descriptor
176- // table which contains a number of device-readable buffers (out buffers) and
177- // device-writable buffers (in buffers).
178- //
179- // All buffers in the outBuffers slice will be concatenated by chaining
180- // descriptors, one for each buffer in the slice. The size of the single buffers
181- // must not exceed the size of a memory page (see [os.Getpagesize]).
182- // When numInBuffers is greater than zero, the given number of device-writable
183- // descriptors will be appended to the end of the chain, each referencing a
184- // whole memory page.
185- //
186- // The index of the head of the new descriptor chain will be returned. Callers
187- // should make sure to free the descriptor chain using [freeDescriptorChain]
188- // after it was used by the device.
189- //
190- // When there are not enough free descriptors to hold the given number of
191- // buffers, an [ErrNotEnoughFreeDescriptors] will be returned. In this case, the
192- // caller should try again after some descriptor chains were used by the device
193- // and returned back into the free chain.
194- func (dt * DescriptorTable ) createDescriptorChain (outBuffers [][]byte , numInBuffers int ) (uint16 , error ) {
195- // Calculate the number of descriptors needed to build the chain.
196- numDesc := uint16 (len (outBuffers ) + numInBuffers )
197-
198- // Descriptor chains must always contain at least one descriptor.
199- if numDesc < 1 {
200- return 0 , ErrDescriptorChainEmpty
201- }
202-
203- // Do we still have enough free descriptors?
204- if numDesc > dt .freeNum {
205- return 0 , ErrNotEnoughFreeDescriptors
206- }
207-
208- // Above validation ensured that there is at least one free descriptor, so
209- // the free descriptor chain head should be valid.
210- if dt .freeHeadIndex == noFreeHead {
211- panic ("free descriptor chain head is unset but there should be free descriptors" )
212- }
213-
214- // To avoid having to iterate over the whole table to find the descriptor
215- // pointing to the head just to replace the free head, we instead always
216- // create descriptor chains from the descriptors coming after the head.
217- // This way we only have to touch the head as a last resort, when all other
218- // descriptors are already used.
219- head := dt .descriptors [dt .freeHeadIndex ].next
220- next := head
221- tail := head
222- for i , buffer := range outBuffers {
223- desc := & dt .descriptors [next ]
224- checkUnusedDescriptorLength (next , desc )
225-
226- if len (buffer ) > dt .itemSize {
227- // The caller should already prevent that from happening.
228- panic (fmt .Sprintf ("out buffer %d has size %d which exceeds desc length %d" , i , len (buffer ), dt .itemSize ))
229- }
230-
231- // Copy the buffer to the memory referenced by the descriptor.
232- // The descriptor address points to memory not managed by Go, so this
233- // conversion is safe. See https://github.com/golang/go/issues/58625
234- //goland:noinspection GoVetUnsafePointer
235- copy (unsafe .Slice ((* byte )(unsafe .Pointer (desc .address )), dt .itemSize ), buffer )
236- desc .length = uint32 (len (buffer ))
237-
238- // Clear the flags in case there were any others set.
239- desc .flags = descriptorFlagHasNext
240-
241- tail = next
242- next = desc .next
243- }
244- for range numInBuffers {
245- desc := & dt .descriptors [next ]
246- checkUnusedDescriptorLength (next , desc )
247-
248- // Give the device the maximum available number of bytes to write into.
249- desc .length = uint32 (dt .itemSize )
250-
251- // Mark the descriptor as device-writable.
252- desc .flags = descriptorFlagHasNext | descriptorFlagWritable
253-
254- tail = next
255- next = desc .next
256- }
257-
258- // The last descriptor should end the chain.
259- tailDesc := & dt .descriptors [tail ]
260- tailDesc .flags &= ^ descriptorFlagHasNext
261- tailDesc .next = 0 // Not necessary to clear this, it's just for looks.
262-
263- dt .freeNum -= numDesc
264-
265- if dt .freeNum == 0 {
266- // The last descriptor in the chain should be the free chain head
267- // itself.
268- if tail != dt .freeHeadIndex {
269- panic ("descriptor chain takes up all free descriptors but does not end with the free chain head" )
270- }
271-
272- // When this new chain takes up all remaining descriptors, we no longer
273- // have a free chain.
274- dt .freeHeadIndex = noFreeHead
275- } else {
276- // We took some descriptors out of the free chain, so make sure to close
277- // the circle again.
278- dt .descriptors [dt .freeHeadIndex ].next = next
279- }
280-
281- return head , nil
282- }
283-
284175func (dt * DescriptorTable ) CreateDescriptorForOutputs () (uint16 , error ) {
285176 //todo just fill the damn table
286177 // Do we still have enough free descriptors?
@@ -490,73 +381,6 @@ func (dt *DescriptorTable) getDescriptorInbuffers(head uint16, inBuffers *[][]by
490381 return nil
491382}
492383
493- func (dt * DescriptorTable ) getDescriptorChainContents (head uint16 , out []byte , maxLen int ) (int , error ) {
494- if int (head ) > len (dt .descriptors ) {
495- return 0 , fmt .Errorf ("%w: index out of range" , ErrInvalidDescriptorChain )
496- }
497-
498- // Iterate over the chain. The iteration is limited to the queue size to
499- // avoid ending up in an endless loop when things go very wrong.
500-
501- length := 0
502- //find length
503- next := head
504- for range len (dt .descriptors ) {
505- if next == dt .freeHeadIndex {
506- return 0 , fmt .Errorf ("%w: must not be part of the free chain" , ErrInvalidDescriptorChain )
507- }
508-
509- desc := & dt .descriptors [next ]
510-
511- if desc .flags & descriptorFlagWritable == 0 {
512- return 0 , fmt .Errorf ("receive queue contains device-readable buffer" )
513- }
514- length += int (desc .length )
515-
516- // Is this the tail of the chain?
517- if desc .flags & descriptorFlagHasNext == 0 {
518- break
519- }
520-
521- // Detect loops.
522- if desc .next == head {
523- return 0 , fmt .Errorf ("%w: contains a loop" , ErrInvalidDescriptorChain )
524- }
525-
526- next = desc .next
527- }
528- if maxLen > 0 {
529- //todo length = min(maxLen, length)
530- }
531- //set out to length:
532- out = out [:length ]
533-
534- //now do the copying
535- copied := 0
536- for range len (dt .descriptors ) {
537- desc := & dt .descriptors [next ]
538-
539- // The descriptor address points to memory not managed by Go, so this
540- // conversion is safe. See https://github.com/golang/go/issues/58625
541- //goland:noinspection GoVetUnsafePointer
542- bs := unsafe .Slice ((* byte )(unsafe .Pointer (desc .address )), min (uint32 (length - copied ), desc .length ))
543- copied += copy (out [copied :], bs )
544-
545- // Is this the tail of the chain?
546- if desc .flags & descriptorFlagHasNext == 0 {
547- break
548- }
549-
550- // we did this already, no need to detect loops.
551- next = desc .next
552- }
553- if copied != length {
554- panic (fmt .Sprintf ("expected to copy %d bytes but only copied %d bytes" , length , copied ))
555- }
556-
557- return length , nil
558- }
559-
560384// freeDescriptorChain can be used to free a descriptor chain when it is no
561385// longer in use. The descriptor chain that starts with the given index will be
562386// put back into the free chain, so the descriptors can be used for later calls
0 commit comments