libaio_srcs += io_queue_wait.c io_queue_run.c
# real syscalls
+libaio_srcs += aio_pgetevents.c aio_getevents.c
libaio_srcs += io_getevents.c io_submit.c io_cancel.c
libaio_srcs += io_setup.c io_destroy.c io_pgetevents.c
--- /dev/null
+/* aio_getevents.c
+ libaio Linux async I/O interface
+ Copyright 2002 Red Hat, Inc.
+ Copyright 2024 Guillem Jover <guillem@hadrons.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <libaio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include "syscall.h"
+#include "aio_time.h"
+#include "aio_ring.h"
+
+io_syscall5(int, __aio_getevents, io_getevents, io_context_t, ctx,
+ long, min_nr, long, nr, struct io_event *, events,
+ struct sys_timespec *, timeout)
+
+int aio_getevents(io_context_t ctx, long min_nr, long nr,
+ struct io_event * events, struct __kernel_timespec * timeout)
+{
+ struct sys_timespec ts;
+ int ret;
+
+ ret = aio_pgetevents(ctx, min_nr, nr, events, timeout, NULL);
+ if (ret != -ENOSYS)
+ return ret;
+
+ if (aio_ring_is_empty(ctx, timeout))
+ return 0;
+
+ if (timeout)
+ sys_get_timespec(&ts, timeout);
+ return __aio_getevents(ctx, min_nr, nr, events, timeout ? &ts : NULL);
+}
--- /dev/null
+/*
+ libaio Linux async I/O interface
+ Copyright 2018 Christoph Hellwig.
+ Copyright 2024 Guillem Jover <guillem@hadrons.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <libaio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include <signal.h>
+#include "syscall.h"
+#include "aio_time.h"
+#include "aio_ring.h"
+
+#ifdef __NR_io_pgetevents
+io_syscall6(int, __io_pgetevents, io_pgetevents, io_context_t, ctx,
+ long, min_nr, long, nr, struct io_event *, events,
+ struct sys_timespec *, timeout, void *, sigmask);
+#endif
+
+#ifdef __NR_io_pgetevents_time64
+io_syscall6(int, __io_pgetevents_time64, io_pgetevents_time64,
+ io_context_t, ctx,
+ long, min_nr, long, nr, struct io_event *, events,
+ struct __kernel_timespec *, timeout, void *, sigmask);
+#endif
+
+int aio_pgetevents(io_context_t ctx, long min_nr, long nr,
+ struct io_event *events, struct __kernel_timespec *timeout,
+ sigset_t *sigmask)
+{
+ int ret;
+#if defined(__NR_io_pgetevents) || defined(__NR_io_pgetevents_time64)
+ struct {
+ unsigned long ss;
+ unsigned long ss_len;
+ } aio_sigset;
+ struct sys_timespec sys_ts;
+
+ if (aio_ring_is_empty(ctx, timeout))
+ return 0;
+
+ aio_sigset.ss = (unsigned long)sigmask;
+ aio_sigset.ss_len = _NSIG / 8;
+#endif
+
+#ifdef __NR_io_pgetevents_time64
+ /*
+ * On 32-bit systems that have a time64 variant of the syscall at
+ * compile-time we try to use that, and if missing we fallback to
+ * the 32-bit variant.
+ */
+ ret = __io_pgetevents_time64(ctx, min_nr, nr, events, timeout,
+ sigmask ? &aio_sigset : NULL);
+ if (ret != -ENOSYS)
+ return ret;
+#endif
+
+#ifdef __NR_io_pgetevents
+ if (timeout)
+ sys_get_timespec(&sys_ts, timeout);
+
+ ret = __io_pgetevents(ctx, min_nr, nr, events,
+ timeout ? &sys_ts : NULL, &aio_sigset);
+#else
+ ret = -ENOSYS;
+#endif
+
+ return ret;
+}
unsigned header_length; /* size of aio_ring */
};
-static inline int aio_ring_is_empty(io_context_t ctx, struct timespec *timeout)
+static inline int aio_ring_is_empty(io_context_t ctx,
+ struct __kernel_timespec *timeout)
{
struct aio_ring *ring = (struct aio_ring *)ctx;
--- /dev/null
+/*
+ libaio Linux async I/O interface
+ Copyright 2024 Guillem Jover <guillem@hadrons.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _AIO_TIME_H
+#define _AIO_TIME_H
+
+#include <linux/time_types.h>
+
+#if __BITS_PER_LONG == 32
+# define sys_timespec __kernel_old_timespec
+# define sys_get_timespec(sys_ts, kern_ts) \
+ aio_get_old_timespec(sys_ts, kern_ts)
+#else
+# define sys_timespec __kernel_timespec
+# define sys_get_timespec(sys_ts, kern_ts) *sys_ts = *kern_ts
+#endif
+
+static inline void aio_get_timespec(struct __kernel_timespec *kts,
+ const struct timespec *uts)
+{
+ kts->tv_sec = uts->tv_sec;
+ kts->tv_nsec = uts->tv_nsec;
+}
+
+static inline void aio_get_old_timespec(struct __kernel_old_timespec *ots,
+ const struct __kernel_timespec *kts)
+{
+ ots->tv_sec = kts->tv_sec;
+ ots->tv_nsec = kts->tv_nsec;
+}
+
+int aio_pgetevents(io_context_t ctx, long min_nr, long nr,
+ struct io_event *events, struct __kernel_timespec *timeout,
+ sigset_t *sigmask);
+
+int aio_getevents(io_context_t ctx, long min_nr, long nr,
+ struct io_event * events, struct __kernel_timespec * timeout);
+
+#endif /* _AIO_TIME_H */
compat-0_1.c : compatibility symbols for libaio 0.1.x-0.3.x
Copyright 2002 Red Hat, Inc.
+ Copyright 2024 Guillem Jover <guillem@hadrons.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
#include <asm/errno.h>
#include "libaio.h"
+#include "aio_time.h"
#include "syscall.h"
int compat0_1_io_queue_wait(io_context_t ctx, struct timespec *when)
{
- struct timespec timeout;
+ struct __kernel_timespec timeout;
if (when)
- timeout = *when;
- return io_getevents(ctx, 0, 0, NULL, when ? &timeout : NULL);
+ aio_get_timespec(&timeout, when);
+ return aio_getevents(ctx, 0, 0, NULL, when ? &timeout : NULL);
}
SYMVER(compat0_1_io_queue_wait, io_queue_wait, 0.1);
struct io_event *events,
const struct timespec *const_timeout)
{
- struct timespec timeout;
+ struct __kernel_timespec timeout;
if (const_timeout)
- timeout = *const_timeout;
- return io_getevents(ctx, 1, nr, events,
+ aio_get_timespec(&timeout, const_timeout);
+ return aio_getevents(ctx, 1, nr, events,
const_timeout ? &timeout : NULL);
}
SYMVER(compat0_1_io_getevents, io_getevents, 0.1);
/* io_getevents.c
libaio Linux async I/O interface
Copyright 2002 Red Hat, Inc.
+ Copyright 2024 Guillem Jover <guillem@hadrons.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
#include <stdlib.h>
#include <time.h>
#include "syscall.h"
-#include "aio_ring.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)
+#include "aio_time.h"
int io_getevents_0_4(io_context_t ctx, long min_nr, long nr,
struct io_event * events, struct timespec * timeout)
{
- if (aio_ring_is_empty(ctx, timeout))
- return 0;
- return __io_getevents_0_4(ctx, min_nr, nr, events, timeout);
+ struct __kernel_timespec ts;
+
+ if (timeout)
+ aio_get_timespec(&ts, timeout);
+ return aio_getevents(ctx, min_nr, nr, events, timeout ? &ts : NULL);
}
DEFSYMVER(io_getevents_0_4, io_getevents, 0.4);
/*
libaio Linux async I/O interface
Copyright 2018 Christoph Hellwig.
+ Copyright 2024 Guillem Jover <guillem@hadrons.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
#include <stdlib.h>
#include <time.h>
#include <signal.h>
-#include "syscall.h"
-#include "aio_ring.h"
-
-#ifdef __NR_io_pgetevents
-io_syscall6(int, __io_pgetevents, io_pgetevents, io_context_t, ctx,
- long, min_nr, long, nr, struct io_event *, events,
- struct timespec *, timeout, void *, sigmask);
+#include "aio_time.h"
int io_pgetevents(io_context_t ctx, long min_nr, long nr,
struct io_event *events, struct timespec *timeout,
sigset_t *sigmask)
{
- struct {
- unsigned long ss;
- unsigned long ss_len;
- } aio_sigset;
-
- if (aio_ring_is_empty(ctx, timeout))
- return 0;
-
- aio_sigset.ss = (unsigned long)sigmask;
- aio_sigset.ss_len = _NSIG / 8;
- return __io_pgetevents(ctx, min_nr, nr, events, timeout, &aio_sigset);
-}
-#else
-int io_pgetevents(io_context_t ctx, long min_nr, long nr,
- struct io_event *events, struct timespec *timeout,
- sigset_t *sigmask)
+ struct __kernel_timespec ts;
-{
- return -ENOSYS;
+ if (timeout)
+ aio_get_timespec(&ts, timeout);
+ return aio_pgetevents(ctx, min_nr, nr, events, timeout ? &ts : NULL,
+ sigmask);
}
-#endif /* __NR_io_pgetevents */
#include <errno.h>
#include <stdlib.h>
#include <time.h>
+#include "aio_time.h"
int io_queue_run(io_context_t ctx)
{
- static struct timespec timeout = { 0, 0 };
+ static struct __kernel_timespec timeout = { 0, 0 };
struct io_event event;
int ret;
/* FIXME: batch requests? */
- while (1 == (ret = io_getevents(ctx, 0, 1, &event, &timeout))) {
+ while (1 == (ret = aio_getevents(ctx, 0, 1, &event, &timeout))) {
io_callback_t cb = (io_callback_t)event.data;
struct iocb *iocb = event.obj;
/* io_submit
libaio Linux async I/O interface
Copyright 2002 Red Hat, Inc.
+ Copyright 2024 Guillem Jover <guillem@hadrons.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
#include <sys/types.h>
#include <libaio.h>
#include <errno.h>
+#include "aio_time.h"
#include "syscall.h"
struct timespec;
int io_queue_wait_0_4(io_context_t ctx, struct timespec *timeout)
{
- return io_getevents(ctx, 0, 0, NULL, timeout);
+ struct __kernel_timespec ts;
+
+ if (timeout)
+ aio_get_timespec(&ts, timeout);
+ return aio_getevents(ctx, 0, 0, NULL, timeout ? &ts : NULL);
}
DEFSYMVER(io_queue_wait_0_4, io_queue_wait, 0.4);