source: example/io/filereader.c@ 1612315

ADT ast-experimental enum forall-pointer-decay pthread-emulation qualifiedEnum
Last change on this file since 1612315 was f0d67e5, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Restored io examples to example folder

  • Property mode set to 100644
File size: 2.8 KB
Line 
1/*
2This is a file reading example that users io_uring in non-blocking mode.
3It demonstrates the bare minimum needed to use io_uring.
4It also optionally pre-registers the file descriptors (and a pipe, just to show it works).
5It uses liburing for simplicity.
6*/
7
8
9#include <errno.h>
10#include <fcntl.h>
11#include <liburing.h>
12#include <stdbool.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <unistd.h>
17
18int main(int argc, char * argv[]) {
19 if(argc != 3 && argc != 4) {
20 printf("usage: %s FILE TIMES [fixed] - read FILE from disk TIMES times\n", argv[0]);
21 return EXIT_FAILURE;
22 }
23
24 bool fixed = false;
25 if(argc == 4) {
26 fixed = 0 == strcmp(argv[3], "fixed");
27 }
28
29 int times = atoi( argv[2] );
30 if(times <= 0) {
31 printf("Invalid number of times %d (from %s).\n", times, argv[2]);
32 return EXIT_FAILURE;
33 }
34
35 int fd = open(argv[1], 0);
36 if(fd < 0) {
37 printf("Could not open file %s.\n", argv[1]);
38 return EXIT_FAILURE;
39 }
40
41 int rfd = fd;
42
43 /* prep the array */
44 char data[100];
45 struct iovec iov = { data, 100 };
46
47 /* init liburing */
48 struct io_uring ring;
49 io_uring_queue_init(256, &ring, 0);
50
51 int pipefds[2];
52 if(fixed) {
53 int ret = pipe(pipefds);
54 if( ret < 0 ) {
55 printf("Pipe Error : %s\n", strerror( errno ));
56 return EXIT_FAILURE;
57 }
58 rfd = 0;
59 int fds[] = {
60 fd, pipefds[0], pipefds[1]
61 };
62 int cnt = sizeof(fds) / sizeof(fds[0]);
63 printf("Registering %d files as fixed\n", cnt);
64 ret = io_uring_register_files(&ring, fds, cnt);
65 if( ret < 0 ) {
66 printf("Register Error : %s\n", strerror( -ret ));
67 return EXIT_FAILURE;
68 }
69 }
70
71 /* declare required structs */
72 printf("Reading %s(%d) %d times\n", argv[1], fd, times);
73 size_t counter = 0;
74 for(int i = 0; i < times; i++) {
75 /* get an sqe and fill in a READV operation */
76 struct io_uring_sqe * sqe = io_uring_get_sqe(&ring);
77 io_uring_prep_readv(sqe, rfd, &iov, 1, 0);
78 if(fixed) {
79 sqe->flags = IOSQE_FIXED_FILE;
80 }
81
82 /* tell the kernel we have an sqe ready for consumption */
83 io_uring_submit(&ring);
84
85 /* poll the cq and count how much polling we did */
86 while(true) {
87 struct io_uring_cqe * cqe = NULL;
88 /* wait for the sqe to complete */
89 int ret = io_uring_wait_cqe_nr(&ring, &cqe, 0);
90
91 /* read and process cqe event */
92 switch(ret) {
93 case 0:
94 if( cqe->res < 0 ) {
95 printf("Completion Error : %s\n", strerror( -cqe->res ));
96 return EXIT_FAILURE;
97 }
98 io_uring_cqe_seen(&ring, cqe);
99 goto LOOP;
100 case -EAGAIN:
101 counter++;
102 break;
103 default:
104 printf("Wait Error : %s\n", strerror( -ret ));
105 return EXIT_FAILURE;
106 }
107 }
108
109 LOOP:;
110 }
111
112 printf("%zu\n", counter);
113
114 io_uring_queue_exit(&ring);
115
116 close(fd);
117
118 if(fixed) {
119 close(pipefds[0]);
120 close(pipefds[1]);
121 }
122}
Note: See TracBrowser for help on using the repository browser.