… | |
… | |
42 | #include <linux/aio_abi.h> |
42 | #include <linux/aio_abi.h> |
43 | |
43 | |
44 | /* we try to fill 4kB pages exactly. |
44 | /* we try to fill 4kB pages exactly. |
45 | * the ring buffer header is 32 bytes, every io event is 32 bytes. |
45 | * the ring buffer header is 32 bytes, every io event is 32 bytes. |
46 | * the kernel takes the io event number, doubles it, adds 2, adds the ring buffer. |
46 | * the kernel takes the io event number, doubles it, adds 2, adds the ring buffer. |
47 | * therefore the calculation below will use "exactly" 8kB for the ring buffer |
47 | * therefore the calculation below will use "exactly" 4kB for the ring buffer |
48 | */ |
48 | */ |
49 | #define EV_LINUXAIO_DEPTH (256 / 2 - 2 - 1) /* max. number of io events per batch */ |
49 | #define EV_LINUXAIO_DEPTH (128 / 2 - 2 - 1) /* max. number of io events per batch */ |
50 | |
50 | |
51 | /*****************************************************************************/ |
51 | /*****************************************************************************/ |
52 | /* syscall wrapdadoop */ |
52 | /* syscall wrapdadoop */ |
53 | |
53 | |
54 | #include <sys/syscall.h> /* no glibc wrappers */ |
54 | #include <sys/syscall.h> /* no glibc wrappers */ |
… | |
… | |
205 | static int |
205 | static int |
206 | linuxaio_get_events_from_ring (EV_P) |
206 | linuxaio_get_events_from_ring (EV_P) |
207 | { |
207 | { |
208 | struct aio_ring *ring = (struct aio_ring *)linuxaio_ctx; |
208 | struct aio_ring *ring = (struct aio_ring *)linuxaio_ctx; |
209 | |
209 | |
210 | ECB_MEMORY_FENCE_ACQUIRE; |
|
|
211 | |
|
|
212 | unsigned head = ring->head; |
210 | unsigned head = ring->head; |
213 | unsigned tail = *(volatile unsigned *)&ring->tail; |
211 | unsigned tail = *(volatile unsigned *)&ring->tail; |
214 | |
212 | |
215 | if (head == tail) |
213 | if (head == tail) |
216 | return 0; |
214 | return 0; |
… | |
… | |
218 | /* bail out if the ring buffer doesn't match the expected layout */ |
216 | /* bail out if the ring buffer doesn't match the expected layout */ |
219 | if (ecb_expect_false (ring->magic != AIO_RING_MAGIC) |
217 | if (ecb_expect_false (ring->magic != AIO_RING_MAGIC) |
220 | || ring->incompat_features != AIO_RING_INCOMPAT_FEATURES |
218 | || ring->incompat_features != AIO_RING_INCOMPAT_FEATURES |
221 | || ring->header_length != sizeof (struct aio_ring)) /* TODO: or use it to find io_event[0]? */ |
219 | || ring->header_length != sizeof (struct aio_ring)) /* TODO: or use it to find io_event[0]? */ |
222 | return 0; |
220 | return 0; |
|
|
221 | |
|
|
222 | ECB_MEMORY_FENCE_ACQUIRE; |
223 | |
223 | |
224 | /* parse all available events, but only once, to avoid starvation */ |
224 | /* parse all available events, but only once, to avoid starvation */ |
225 | if (tail > head) /* normal case around */ |
225 | if (tail > head) /* normal case around */ |
226 | linuxaio_parse_events (EV_A_ ring->io_events + head, tail - head); |
226 | linuxaio_parse_events (EV_A_ ring->io_events + head, tail - head); |
227 | else /* wrapped around */ |
227 | else /* wrapped around */ |