AIO的DEMO
#include <iostream>
#include <cstring>
#include <vector>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <algorithm>
#include <thread>
#include <linux/aio_abi.h>
#include <deque>
#include <atomic>
#include <assert.h>
#include <sys/syscall.h>
#include <mutex>
#include <unistd.h>
#define RET_OK 0
#define RET_ERROR 1
#define READ 0
#define RANDREAD 1
#define WRITE 2
#define RANDWRITE 3
#define BLOCKALIGNMENT 4096
struct IOInfo
{
struct iocb iocb;
uint32_t ioMode;
bool isFailed;
uint32_t reqOff;
uint32_t reqLen;
uint64_t offset;
uint64_t length;
uint8_t *buf;
struct timespec startTime;
struct timespec endTime;
};
std::mutex mtx;
aio_context_t g_ioContext;
inline int32_t io_setup(unsigned nr, aio_context_t *ctx)
{
return syscall(__NR_io_setup, nr, ctx);
}
inline int32_t io_submit(aio_context_t ctx, int32_t nr, struct iocb **cbs)
{
return syscall(__NR_io_submit, ctx, nr, cbs);
}
inline int32_t io_getevents(aio_context_t ctx, int32_t min_nr, int32_t max_nr, struct io_event *evts, struct timespec *timeout)
{
return syscall(__NR_io_getevents, ctx, min_nr, max_nr, evts, timeout);
}
inline int32_t io_destroy(aio_context_t ctx)
{
return syscall(__NR_io_destroy, ctx);
}
static int32_t InputParameterCheck(int32_t argc, char *argv[], int32_t *ioMode, int32_t *fd, uint32_t *bs,
uint32_t *qd, off_t *fileSize, uint32_t *testLoop)
{
if (argc < 7) {
std::cout << "EXAMPLE: " << argv[0] << " rwmode qd bs filename filesize looptime" << std::endl;
return RET_ERROR;
}
if (strcmp(argv[1], "read") == 0) {
*ioMode = READ;
} else if (strcmp(argv[1], "randread") == 0) {
*ioMode = RANDREAD;
} else if (strcmp(argv[1], "write") == 0){
*ioMode = WRITE;
} else if (strcmp(argv[1], "randwrite") == 0) {
*ioMode = RANDWRITE;
} else {
std::cout << "ioMode mode error! Example: read/randread/write/randwrite" << std::endl;
return RET_ERROR;
}
*qd = (uint32_t)std::stoi(argv[2]);
if (*qd == 0) {
std::cout << "qd error" << std::endl;
return RET_ERROR;
}
std::cout << "qd: " << *qd << std::endl;
*bs = (uint32_t)std::stoi(argv[3]);
*bs = *bs * 1024 * 1024;
if (*bs == 0 || *bs % BLOCKALIGNMENT != 0) {
std::cout << "bs error" << std::endl;
return RET_ERROR;
}
std::cout << "bs: " << *bs << std::endl;
if (*ioMode <= RANDREAD) {
*fd = open(argv[4], O_RDONLY | O_DIRECT);
} else {
*fd = open(argv[4], O_WRONLY | O_CREAT | O_TRUNC | O_DIRECT, 0644);
}
if (*fd < 0) {
std::cout << "open " << argv[4] << " failed" << std::endl;
return RET_ERROR;
}
*fileSize = (uint32_t)std::stoi(argv[5]);
if (*fileSize == 0) {
std::cout << "filesize error" << std::endl;
return RET_ERROR;
}
*testLoop = (uint32_t)std::stoi(argv[6]);
if (*testLoop == 0) {
std::cout << "testLoop error" << std::endl;
return RET_ERROR;
}
std::cout << "filesize: " << *fileSize << "G X " << *testLoop << std::endl;
*fileSize = *fileSize * 1024 * 1024 * 1024;
*fileSize -= *fileSize % *bs;
return RET_OK;
}
static int32_t InitContext(uint32_t qd)
{
memset(&g_ioContext, 0, sizeof(aio_context_t));
return io_setup(qd, &g_ioContext);
}
static int32_t InitBuffers(std::deque<uint8_t *> *bufQue, uint32_t qd, int32_t bs)
{
uint8_t *buf;
for (uint32_t i = 0; i < qd; i++) {
if (posix_memalign((void **)&buf, BLOCKALIGNMENT, bs))
{
std::cout << "posix_memalign failed" << std::endl;
for (uint32_t j = 0; j < i; j++) {
free(bufQue->at(j));
}
bufQue->clear();
return RET_ERROR;
}
bufQue->push_back(buf);
}
return RET_OK;
}
static void FreeBuffers(std