size.go 988 B

123456789101112131415161718192021222324252627282930313233
  1. package virtqueue
  2. import (
  3. "errors"
  4. "fmt"
  5. )
  6. // ErrQueueSizeInvalid is returned when a queue size is invalid.
  7. var ErrQueueSizeInvalid = errors.New("queue size is invalid")
  8. // CheckQueueSize checks if the given value would be a valid size for a
  9. // virtqueue and returns an [ErrQueueSizeInvalid], if not.
  10. func CheckQueueSize(queueSize int) error {
  11. if queueSize <= 0 {
  12. return fmt.Errorf("%w: %d is too small", ErrQueueSizeInvalid, queueSize)
  13. }
  14. // The queue size must always be a power of 2.
  15. // This ensures that ring indexes wrap correctly when the 16-bit integers
  16. // overflow.
  17. if queueSize&(queueSize-1) != 0 {
  18. return fmt.Errorf("%w: %d is not a power of 2", ErrQueueSizeInvalid, queueSize)
  19. }
  20. // The largest power of 2 that fits into a 16-bit integer is 32768.
  21. // 2 * 32768 would be 65536 which no longer fits.
  22. if queueSize > 32768 {
  23. return fmt.Errorf("%w: %d is larger than the maximum possible queue size 32768",
  24. ErrQueueSizeInvalid, queueSize)
  25. }
  26. return nil
  27. }