internal unsafe void WriteTo(io_uring_params *p) { if (EnableSubmissionPolling) { p->flags |= IORING_SETUP_SQPOLL; if (SubmissionQueuePollingCpuAffinity >= 0) { p->flags |= IORING_SETUP_SQ_AFF; p->sq_thread_cpu = (uint)SubmissionQueuePollingCpuAffinity; } if (PollingThreadIdleAfter != TimeSpan.Zero) { p->sq_thread_idle = (uint)PollingThreadIdleAfter.Milliseconds; } } if (EnablePolledIo) { p->flags |= IORING_SETUP_IOPOLL; } if (CompletionQueueSize >= 0) { p->cq_entries = (uint)CompletionQueueSize; } }
private static (size_t sqSize, size_t cqSize) GetSize(io_uring_params *p) { size_t sqSize = SqSize(p); size_t cqSize = CqSize(p); if ((p->features & IORING_FEAT_SINGLE_MMAP) != 0) { sqSize = cqSize = (size_t)Math.Max(cqSize, sqSize); } return(sqSize, cqSize); }
private static int Setup(uint entries, io_uring_params *p, RingOptions?options) { options?.WriteTo(p); int fd = io_uring_setup(entries, p); if (fd < 0) { ThrowErrnoException(); } return(fd); }
public unsafe void WriteTo(io_uring_params *p, uint entries) { if (EnableSubmissionPolling) { p->flags |= IORING_SETUP_SQPOLL; if (SubmissionQueuePollingCpuAffinity >= 0) { p->flags |= IORING_SETUP_SQ_AFF; p->sq_thread_cpu = (uint)SubmissionQueuePollingCpuAffinity; } if (PollingThreadIdleAfter != TimeSpan.Zero) { p->sq_thread_idle = (uint)PollingThreadIdleAfter.Milliseconds; } } if (EnablePolledIo) { p->flags |= IORING_SETUP_IOPOLL; } if (CompletionQueueSize >= 0 && KernelVersion.Supports.IORING_SETUP_CQSIZE) { if (CompletionQueueSize <= entries) { ThrowArgumentOutOfRangeException(ExceptionArgument.options); } p->flags |= IORING_SETUP_CQSIZE; p->cq_entries = (uint)CompletionQueueSize; } if (KernelVersion.Supports.IORING_SETUP_CLAMP) { p->flags |= IORING_SETUP_CLAMP; } if (WorkQueueFd != -1 && KernelVersion.Supports.IORING_SETUP_ATTACH_WQ) { p->flags |= IORING_SETUP_ATTACH_WQ; p->wq_fd = (uint)WorkQueueFd; } }
private static SubmissionQueue MapSq(int ringFd, size_t sqSize, io_uring_params *p, out UnmapHandle sqHandle, out UnmapHandle sqeHandle) { var ptr = mmap(NULL, sqSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, ringFd, (long)IORING_OFF_SQ_RING); if (ptr == MAP_FAILED) { ThrowErrnoException(); } sqHandle = new UnmapHandle(ptr, sqSize); size_t sqeSize = SqeSize(p); var sqePtr = mmap(NULL, sqeSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, ringFd, (long)IORING_OFF_SQES); if (sqePtr == MAP_FAILED) { ThrowErrnoException(); } sqeHandle = new UnmapHandle(sqePtr, sqeSize); return(SubmissionQueue.CreateSubmissionQueue(ptr, &p->sq_off, (io_uring_sqe *)sqePtr)); }
private static CompletionQueue MapCq(int ringFd, size_t cqSize, io_uring_params *p, UnmapHandle sqHandle, out UnmapHandle cqHandle) { void *ptr; if ((p->features & IORING_FEAT_SINGLE_MMAP) != 0) { ptr = sqHandle.DangerousGetHandle().ToPointer(); cqHandle = sqHandle; } else { ptr = mmap(NULL, cqSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, ringFd, (long)IORING_OFF_CQ_RING); if (ptr == MAP_FAILED) { ThrowErrnoException(); } cqHandle = new UnmapHandle(ptr, cqSize); } return(CompletionQueue.CreateCompletionQueue(ptr, &p->cq_off)); }
private static size_t CqSize(io_uring_params *p) => (size_t)(p->cq_off.cqes + p->cq_entries * (ulong)sizeof(io_uring_cqe));
private static size_t SqeSize(io_uring_params *p) => (size_t)(p->sq_entries * (ulong)sizeof(io_uring_sqe));
private static size_t SqSize(io_uring_params *p) => p->sq_off.array + p->sq_entries * sizeof(uint);
public static int io_uring_setup(uint entries, io_uring_params *p) { return((int)syscall(__NR_io_uring_setup, entries, p)); }