forked from amir/filehasher
Implementation of IO Ring in Windows
Fixing the two compilation warnings.
This commit is contained in:
147
io_ring_test.c
Normal file
147
io_ring_test.c
Normal file
@@ -0,0 +1,147 @@
|
||||
#pragma once
|
||||
|
||||
#include <ioringapi.h>
|
||||
#include <ntioring_x.h>
|
||||
// #include "ioringapi.c"
|
||||
#include <winerror.h>
|
||||
|
||||
// Initialize I/O Ring
|
||||
HIORING io_ring_init(void) {
|
||||
|
||||
// if (!io_ring_load_functions()) {
|
||||
// printf("[I/O Ring] Failed to load functions\n");
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
IORING_CAPABILITIES caps;
|
||||
ZeroMemory(&caps, sizeof(caps));
|
||||
|
||||
HRESULT hr = QueryIoRingCapabilities(&caps);
|
||||
if (FAILED(hr)) {
|
||||
printf("[I/O Ring] QueryIoRingCapabilities failed: 0x%08lx\n", hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// printf("[I/O Ring] MaxVersion=%d, MaxSubmission=%u, MaxCompletion=%u\n",
|
||||
// (int)caps.MaxVersion, caps.MaxSubmissionQueueSize,
|
||||
// caps.MaxCompletionQueueSize);
|
||||
|
||||
if (caps.MaxVersion < IORING_VERSION_1) {
|
||||
printf("[I/O Ring] Version too old\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IORING_CREATE_FLAGS flags = {0};
|
||||
HIORING ring = NULL;
|
||||
|
||||
// hr = CreateIoRing(IORING_VERSION_1, flags, 256, 512, &ring);
|
||||
hr = CreateIoRing(caps.MaxVersion, flags, 256, 512, &ring);
|
||||
if (FAILED(hr)) {
|
||||
printf("[I/O Ring] CreateIoRing failed: 0x%08lx\n", hr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// printf("[I/O Ring] Created successfully\n");
|
||||
|
||||
// Check if read operation is supported
|
||||
|
||||
// HRESULT io_ring_support = IsIoRingOpSupported(ring, IORING_OP_READ);
|
||||
// if (io_ring_support == S_FALSE) {
|
||||
// printf("[I/O Ring] Not supported, %ld /n", io_ring_support);
|
||||
// }
|
||||
|
||||
// Get ring info
|
||||
IORING_INFO info;
|
||||
ZeroMemory(&info, sizeof(info));
|
||||
GetIoRingInfo(ring, &info);
|
||||
// printf("[I/O Ring] Submission: %u, Completion: %u\n",
|
||||
// info.SubmissionQueueSize, info.CompletionQueueSize);
|
||||
|
||||
return ring;
|
||||
}
|
||||
|
||||
void io_ring_cleanup(HIORING ring) {
|
||||
if (ring) {
|
||||
CloseIoRing(ring);
|
||||
// printf("[I/O Ring] Closed\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Read file using I/O Ring
|
||||
int io_ring_read_file(HIORING ring, HANDLE hFile, void *buffer, DWORD size,
|
||||
UINT64 offset) {
|
||||
|
||||
IORING_HANDLE_REF file_ref = IoRingHandleRefFromHandle(hFile);
|
||||
IORING_BUFFER_REF buf_ref = IoRingBufferRefFromPointer(buffer);
|
||||
|
||||
HRESULT hr = BuildIoRingReadFile(ring, file_ref, buf_ref, size, offset,
|
||||
(UINT_PTR)buffer, IOSQE_FLAGS_NONE);
|
||||
|
||||
if (FAILED(hr))
|
||||
return -1;
|
||||
|
||||
UINT32 submitted = 0;
|
||||
hr = SubmitIoRing(ring, 1, INFINITE, &submitted);
|
||||
if (FAILED(hr) || submitted == 0)
|
||||
return -1;
|
||||
|
||||
for (;;) {
|
||||
IORING_CQE cqe;
|
||||
hr = PopIoRingCompletion(ring, &cqe);
|
||||
|
||||
if (FAILED(hr))
|
||||
continue;
|
||||
|
||||
if (cqe.UserData != (UINT_PTR)buffer)
|
||||
continue;
|
||||
|
||||
if (FAILED(cqe.ResultCode))
|
||||
return -1;
|
||||
|
||||
return (int)cqe.Information;
|
||||
}
|
||||
}
|
||||
|
||||
// Test function
|
||||
void test_io_ring(void) {
|
||||
printf("\n=== Testing I/O Ring ===\n");
|
||||
|
||||
HIORING ring = io_ring_init();
|
||||
if (!ring) {
|
||||
printf("I/O Ring not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create test file
|
||||
HANDLE hFile = CreateFileA("test.txt", GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
char test_data[] =
|
||||
"Hello, I/O Ring! This is a test of the Windows I/O Ring API.";
|
||||
DWORD written;
|
||||
WriteFile(hFile, test_data, sizeof(test_data), &written, NULL);
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
// Read using I/O Ring
|
||||
hFile = CreateFileA("test.txt", GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
char buffer[512] = {0};
|
||||
int bytes = io_ring_read_file(ring, hFile, buffer, sizeof(buffer), 0);
|
||||
if (bytes > 0) {
|
||||
printf("Read %d bytes: %s\n", bytes, buffer);
|
||||
} else {
|
||||
printf("Failed to read file\n");
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
} else {
|
||||
printf("Failed to open test file\n");
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
DeleteFileA("test.txt");
|
||||
io_ring_cleanup(ring);
|
||||
|
||||
printf("=== Test complete ===\n\n");
|
||||
}
|
||||
Reference in New Issue
Block a user