View Javadoc
1   /*
2    * Copyright 2025 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.channel.uring;
17  
18  import io.netty.util.internal.ObjectUtil;
19  
20  import java.util.Objects;
21  
22  /**
23   * Configuration class for an {@link IoUringBufferRing}.
24   * It will configure the buffer ring size, buffer group id and the chunk size.
25   */
26  public final class IoUringBufferRingConfig {
27      private final short bgId;
28      private final short bufferRingSize;
29      private final int maxUnreleasedBuffers;
30      private final boolean incremental;
31      private final IoUringBufferRingAllocator allocator;
32  
33      /**
34       * Create a new configuration.
35       *
36       * @param bgId                  the buffer group id to use (must be non-negative).
37       * @param bufferRingSize        the size of the ring
38       * @param maxUnreleasedBuffers  the maximum buffers that were allocated out of this buffer ring and are
39       *                              unreleased yet. Once this threshold is hit the usage of the buffer ring will
40       *                              be temporary disabled.
41       * @param allocator             the {@link IoUringBufferRingAllocator} to use to allocate
42       *                              {@link io.netty.buffer.ByteBuf}s.
43       */
44      public IoUringBufferRingConfig(short bgId, short bufferRingSize, int maxUnreleasedBuffers,
45                                     IoUringBufferRingAllocator allocator) {
46          this(bgId, bufferRingSize, maxUnreleasedBuffers, IoUring.isRegisterBufferRingIncSupported(), allocator);
47      }
48  
49      /**
50       * Create a new configuration.
51       *
52       * @param bgId                  the buffer group id to use (must be non-negative).
53       * @param bufferRingSize        the size of the ring
54       * @param maxUnreleasedBuffers  the maximum buffers that can be allocated out of this buffer ring and are
55       *                              unreleased yet. Once this threshold is hit the usage of the buffer ring will
56       *                              be temporarily disabled.
57       * @param incremental           {@code true} if the buffer ring is using incremental buffer consumption.
58       * @param allocator             the {@link IoUringBufferRingAllocator} to use to allocate
59       *                              {@link io.netty.buffer.ByteBuf}s.
60       */
61      public IoUringBufferRingConfig(short bgId, short bufferRingSize, int maxUnreleasedBuffers,
62                                     boolean incremental, IoUringBufferRingAllocator allocator) {
63          this.bgId = (short) ObjectUtil.checkPositiveOrZero(bgId, "bgId");
64          this.bufferRingSize = checkBufferRingSize(bufferRingSize);
65          this.maxUnreleasedBuffers = ObjectUtil.checkInRange(
66                  maxUnreleasedBuffers, bufferRingSize, Integer.MAX_VALUE, "maxUnreleasedBuffers");
67          if (incremental && !IoUring.isRegisterBufferRingIncSupported()) {
68              throw new IllegalArgumentException("Incremental buffer ring is not supported");
69          }
70          this.incremental = incremental;
71          this.allocator = ObjectUtil.checkNotNull(allocator, "allocator");
72      }
73  
74      /**
75       * Returns the buffer group id to use.
76       *
77       * @return the buffer group id to use.
78       */
79      public short bufferGroupId() {
80          return bgId;
81      }
82  
83      /**
84       * Returns the size of the ring.
85       *
86       * @return the size of the ring.
87       */
88      public short bufferRingSize() {
89          return bufferRingSize;
90      }
91  
92      /**
93       * Returns the maximum buffers that can be allocated out of this buffer ring and are
94       * unreleased yet
95       *
96       * @return the max unreleased buffers.
97       */
98      public int maxUnreleasedBuffers() {
99          return maxUnreleasedBuffers;
100     }
101 
102     /**
103      * Returns the {@link IoUringBufferRingAllocator} to use to allocate {@link io.netty.buffer.ByteBuf}s.
104      *
105      * @return  the allocator.
106      */
107     public IoUringBufferRingAllocator allocator() {
108         return allocator;
109     }
110 
111     /**
112      * Returns true if <a href="https://github.com/axboe/liburing/wiki/
113      * What's-new-with-io_uring-in-6.11-and-6.12#incremental-provided-buffer-consumption">incremental mode</a>
114      * should be used for the buffer ring.
115      *
116      * @return {@code true} if incremental mode is used, {@code false} otherwise.
117      */
118     public boolean isIncremental() {
119         return incremental;
120     }
121 
122     private static short checkBufferRingSize(short bufferRingSize) {
123         if (bufferRingSize < 1) {
124             throw new IllegalArgumentException("bufferRingSize: " + bufferRingSize + " (expected: > 0)");
125         }
126 
127         boolean isPowerOfTwo = (bufferRingSize & (bufferRingSize - 1)) == 0;
128         if (!isPowerOfTwo) {
129             throw new IllegalArgumentException("bufferRingSize: " + bufferRingSize + " (expected: power of 2)");
130         }
131         return bufferRingSize;
132     }
133 
134     @Override
135     public boolean equals(Object o) {
136         if (o == null || getClass() != o.getClass()) {
137             return false;
138         }
139         IoUringBufferRingConfig that = (IoUringBufferRingConfig) o;
140         return bgId == that.bgId;
141     }
142 
143     @Override
144     public int hashCode() {
145         return Objects.hashCode(bgId);
146     }
147 }