[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-aio
Subject: [PATCH] libaio: elide the syscall if the completed events greater than min_nr
From: Rain <rain.by.zhou () gmail ! com>
Date: 2021-08-09 8:33:35
Message-ID: 20210809083335.GA95212 () RaindeMacBook-Pro ! local
[Download RAW message or body]
Hi,
> We noticed that many applications elide the call of io_getevents as possible as the \
> can do, like seastar, fio. So let's do it.
I submitted this patch once before, but there was no response at that time. I \
submitted it again, hoping to have some suggestions. The patch related to \
https://pagure.io/libaio/issue/2
Signed-off-by: Rain <rain.by.zhou@gmail.com>
---
src/aio_ring.h | 2 ++
src/arch.h | 14 ++++++++++++++
src/io_getevents.c | 29 ++++++++++++++++++++++++++++-
3 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 src/arch.h
diff --git a/src/aio_ring.h b/src/aio_ring.h
index 3842c4b..489f0d6 100644
--- a/src/aio_ring.h
+++ b/src/aio_ring.h
@@ -31,6 +31,8 @@ struct aio_ring {
unsigned compat_features;
unsigned incompat_features;
unsigned header_length; /* size of aio_ring */
+
+ struct io_event events[0];
};
static inline int aio_ring_is_empty(io_context_t ctx, struct timespec *timeout)
diff --git a/src/arch.h b/src/arch.h
new file mode 100644
index 0000000..a03ed98
--- /dev/null
+++ b/src/arch.h
@@ -0,0 +1,14 @@
+#ifndef _AIO_ARCH_H
+#define _AIO_ARCH_H
+
+#ifdef __x86_64__
+#define read_barrier() __asm__ __volatile__("lfence" ::: "memory")
+#else
+#ifdef __i386__
+#define read_barrier() __asm__ __volatile__("" : : : "memory")
+#else
+#define read_barrier() __sync_synchronize()
+#endif
+#endif
+
+#endif /* _AIO_ARCH_H */
diff --git a/src/io_getevents.c b/src/io_getevents.c
index 90d6081..f594119 100644
--- a/src/io_getevents.c
+++ b/src/io_getevents.c
@@ -22,14 +22,41 @@
#include <time.h>
#include "syscall.h"
#include "aio_ring.h"
+#include "arch.h"
io_syscall5(int, __io_getevents_0_4, io_getevents, io_context_t, ctx, long, min_nr, \
long, nr, struct io_event *, events, struct timespec *, timeout)
+long reap_events_from_ring(io_context_t ctx, long max_nr, struct io_event *events) {
+ struct aio_ring *ring = (struct aio_ring *)ctx;
+ unsigned head;
+ long i = 0;
+
+ while (i < max_nr) {
+ head = ring->head;
+
+ if (head == ring->tail) {
+ break;
+ } else {
+ events[i++] = ring->events[head];
+ read_barrier();
+ ring->head = (head + 1) % ring->nr;
+ }
+ }
+ return i;
+}
+
int io_getevents_0_4(io_context_t ctx, long min_nr, long nr, struct io_event * \
events, struct timespec * timeout) {
+ int n = 0;
+
if (aio_ring_is_empty(ctx, timeout))
return 0;
- return __io_getevents_0_4(ctx, min_nr, nr, events, timeout);
+
+ n = reap_events_from_ring(ctx, nr, events);
+ if (n >= min_nr)
+ return n;
+
+ return __io_getevents_0_4(ctx, min_nr - n, nr - n, &events[n], timeout);
}
DEFSYMVER(io_getevents_0_4, io_getevents, 0.4)
--
2.17.1
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic