-
Notifications
You must be signed in to change notification settings - Fork 4
/
aio-example.c
109 lines (93 loc) · 2.79 KB
/
aio-example.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h> // syscall numbers
#include <linux/aio_abi.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <inttypes.h>
#include <assert.h>
// uses the kernel-based aio syscalls directly
// (NOT libc's aio(7) that use threads)
// syscall wrappers
static inline int
io_setup(unsigned maxevents, aio_context_t *ctx) {
return syscall(SYS_io_setup, maxevents, ctx);
}
static inline int
io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp) {
return syscall(SYS_io_submit, ctx, nr, iocbpp);
}
static inline int
io_getevents(aio_context_t ctx, long min_nr, long nr,
struct io_event *events, struct timespec *timeout) {
return syscall(SYS_io_getevents, ctx, min_nr, nr, events, timeout);
}
static inline int
io_destroy(aio_context_t ctx)
{
return syscall(SYS_io_destroy, ctx);
}
int main(int argc, char *argv[])
{
aio_context_t ioctx = 0;
unsigned maxevents = 128;
int fd = open("FILE", O_RDONLY | O_DIRECT);
if (fd == -1) {
perror(argv[1]);
exit(1);
}
if (io_setup(maxevents, &ioctx) < 0) {
perror("io_setup");
exit(1);
}
// first operation
char buff1[512];
struct iocb iocb1 = {0};
iocb1.aio_data = 0xbeef; /* will be returned in events data */
iocb1.aio_fildes = fd;
iocb1.aio_lio_opcode = IOCB_CMD_PREAD;
iocb1.aio_reqprio = 0;
iocb1.aio_buf = (uintptr_t)buff1;
iocb1.aio_nbytes = sizeof(buff1);
iocb1.aio_offset = 0;
// second operation
char buff2[512];
struct iocb iocb2 = {0};
iocb2.aio_data = 0xbaba; /* will be returned in events data */
iocb2.aio_fildes = fd;
iocb2.aio_lio_opcode = IOCB_CMD_PREAD;
iocb2.aio_reqprio = 0;
iocb2.aio_buf = (uintptr_t)buff2;
iocb2.aio_nbytes = sizeof(buff2);
iocb2.aio_offset = 4096;
struct iocb *iocb_ptrs[2] = { &iocb1, &iocb2 };
// submit operations
int ret = io_submit(ioctx, 2, iocb_ptrs);
if (ret < 0) {
perror("io_submit");
exit(1);
} else if (ret != 2) {
perror("io_submit: unhandled partial success");
exit(1);
}
size_t nevents = 2;
struct io_event events[nevents];
while (nevents > 0) {
// wait for at least one event
ret = io_getevents(ioctx, 1 /* min */, nevents, events, NULL);
if (ret < 0) {
perror("io_getevents");
exit(1);
}
for (size_t i=0; i<ret; i++) {
struct io_event *ev = &events[i];
assert(ev->data == 0xbeef || ev->data == 0xbaba);
printf("Event returned with res=%lld res2=%lld\n", ev->res, ev->res2);
nevents--;
}
}
io_destroy(ioctx);
close(fd);
}