diff options
author | Jakub Jelinek <jakub@redhat.com> | 2006-09-07 10:36:13 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2006-09-07 10:36:13 +0000 |
commit | 8021fca5412b5b1664e806556205d5cede365974 (patch) | |
tree | d5679d310773db142bf35e6cde274fa398b6190b | |
parent | bdae5218097f2181710cf9058248e4c549c6ec84 (diff) | |
download | glibc-8021fca5412b5b1664e806556205d5cede365974.zip glibc-8021fca5412b5b1664e806556205d5cede365974.tar.gz glibc-8021fca5412b5b1664e806556205d5cede365974.tar.bz2 |
Forward port of rtkaio.
79 files changed, 1818 insertions, 135 deletions
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in index afdb05b..791e04b 100644 --- a/fedora/glibc.spec.in +++ b/fedora/glibc.spec.in @@ -8,7 +8,7 @@ %define buildxen 0 %define xenpackage 0 %endif -%define rtkaioarches noarch +%define rtkaioarches %{ix86} x86_64 ia64 ppc ppc64 s390 s390x %define debuginfocommonarches %{ix86} alpha alphaev6 sparc sparcv9 %define _unpackaged_files_terminate_build 0 Summary: The GNU libc libraries. @@ -819,17 +819,12 @@ GXX="g++ -m64" %endif BuildFlags="$BuildFlags -DNDEBUG=1" -if gcc -v 2>&1 | grep -q 'gcc version 3.[0123]'; then - BuildFlags="$BuildFlags -finline-limit=2000" -fi EnableKernel="--enable-kernel=%{enablekernel}" -echo "$BuildFlags" > BuildFlags echo "$GCC" > Gcc AddOns=`echo */configure | sed -e 's!/configure!!g;s!\(linuxthreads\|nptl\|rtkaio\)\( \|$\)!!g;s! \+$!!;s! !,!g;s!^!,!;/^,\*$/d'` %ifarch %{rtkaioarches} AddOns=,rtkaio$AddOns %endif -echo "$AddOns" > AddOns build_nptl() { @@ -868,9 +863,7 @@ $GCC -static -L. -Os ../fedora/glibc_post_upgrade.c -o glibc_post_upgrade.%{_tar cd .. %install -BuildFlags=`cat BuildFlags` GCC=`cat Gcc` -AddOns=`cat AddOns` rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT @@ -881,6 +874,12 @@ cd build-%{nptl_target_cpu}-linuxnptl && \ cd .. %endif +%ifarch %{rtkaioarches} +mkdir -p $RPM_BUILD_ROOT/%{_lib}/rtkaio +cp -a rtkaio/librtkaio.so $RPM_BUILD_ROOT/%{_lib}/rtkaio/`basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so | sed s/librt-/librtkaio-/` +ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so | sed s/librt-/librtkaio-/` $RPM_BUILD_ROOT/%{_lib}/rtkaio/`basename $RPM_BUILD_ROOT/%{_lib}/librt.so.*` +%endif + %if %{buildxen} %define nosegneg_subdir_base i686 %define nosegneg_subdir i686/nosegneg @@ -895,15 +894,15 @@ cp -a nptl/libpthread.so $RPM_BUILD_ROOT/%{_lib}/$SubDir/libpthread-%{version}.s pushd $RPM_BUILD_ROOT/%{_lib}/$SubDir ln -sf libpthread-*.so `basename $RPM_BUILD_ROOT/%{_lib}/libpthread.so.*` popd -%ifarch %{rtkaioarches} -cp -a rtkaio/librtkaio.so $RPM_BUILD_ROOT/%{_lib}/$SubDir/`basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so | sed s/librt-/librtkaio-/` -ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so | sed s/librt-/librtkaio-/` $RPM_BUILD_ROOT/%{_lib}/$SubDir/`basename $RPM_BUILD_ROOT/%{_lib}/librt.so.*` -%else cp -a rt/librt.so $RPM_BUILD_ROOT/%{_lib}/$SubDir/`basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so` ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so` $RPM_BUILD_ROOT/%{_lib}/$SubDir/`basename $RPM_BUILD_ROOT/%{_lib}/librt.so.*` -%endif cp -a nptl_db/libthread_db.so $RPM_BUILD_ROOT/%{_lib}/$SubDir/`basename $RPM_BUILD_ROOT/%{_lib}/libthread_db-*.so` ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/libthread_db-*.so` $RPM_BUILD_ROOT/%{_lib}/$SubDir/`basename $RPM_BUILD_ROOT/%{_lib}/libthread_db.so.*` +%ifarch %{rtkaioarches} +mkdir -p $RPM_BUILD_ROOT/%{_lib}/rtkaio/$SubDir +cp -a rtkaio/librtkaio.so $RPM_BUILD_ROOT/%{_lib}/rtkaio/$SubDir/`basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so | sed s/librt-/librtkaio-/` +ln -sf `basename $RPM_BUILD_ROOT/%{_lib}/librt-*.so | sed s/librt-/librtkaio-/` $RPM_BUILD_ROOT/%{_lib}/rtkaio/$SubDir/`basename $RPM_BUILD_ROOT/%{_lib}/librt.so.*` +%endif cd .. %endif @@ -1362,9 +1361,16 @@ rm -f *.filelist* %files -f rpm.filelist %defattr(-,root,root) +%ifarch %{rtkaioarches} +%dir /%{_lib}/rtkaio +%endif %if %{buildxen} && !%{xenpackage} %dir /%{_lib}/%{nosegneg_subdir_base} %dir /%{_lib}/%{nosegneg_subdir} +%ifarch %{rtkaioarches} +%dir /%{_lib}/rtkaio/%{nosegneg_subdir_base} +%dir /%{_lib}/rtkaio/%{nosegneg_subdir} +%endif %endif %ifarch s390x %dir /lib @@ -1451,6 +1457,8 @@ rm -f *.filelist* * Thu Sep 7 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-30 - fix or_IN February name (#204730) - fix pthread_create called from cancellation handlers (BZ#3124) +- add librtkaio, to use it add /%{lib}/rtkaio to your + LD_LIBRARY_PATH or /etc/ld.so.conf * Tue Sep 5 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-29 - randomize resolver query ids before use instead after use (#205113) diff --git a/rtkaio/ChangeLog b/rtkaio/ChangeLog index ac5e77d..41e3295 100644 --- a/rtkaio/ChangeLog +++ b/rtkaio/ChangeLog @@ -1,3 +1,149 @@ +2006-09-07 Jakub Jelinek <jakub@redhat.com> + + * Makefile: Use $(..) in place of ../. + (tests): Add tst-aio{8,9,10}, tst-cpuclock{1,2}, tst-cputimer{1,2,3} + and tst-clock2. + (CPPFLAGS-librtkaio): Append -I$(..)rt. + * Versions.def (librtkaio): Add GLIBC_2.4 version. + * sysdeps/unix/sysv/linux/kaio_misc.c (wait_for_kernel_requests) + [!DONT_NEED_AIO_MISC_COND]: Don't use condvar, use AIO_MISC_WAIT. + * sysdeps/unix/sysv/linux/kaio_misc.h [HAVE_FORCED_UNWIND] + (DONT_NEED_AIO_MISC_COND, AIO_MISC_NOTIFY, AIO_MISC_WAIT): Define. + (struct waitlist) [DONT_NEED_AIO_MISC_COND]: Remove cond. + * sysdeps/unix/sysv/linux/kaio_suspend.c (struct clparam) + [DONT_NEED_AIO_MISC_COND]: Remove cond. + (cleanup) [DONT_NEED_AIO_MISC_COND]: Lock __aio_requests_mutex on + entry. Don't destroy param->cond. + (aio_suspend): Fail if nent is negative. + (aio_suspend) [DONT_NEED_AIO_MISC_COND]: Don't use cond, use + AIO_MISC_WAIT. + * sysdeps/unix/sysv/linux/klio_listio.c (lio_listio): Renamed to... + (lio_listio_internal): ... this. Don't use cond, but AIO_MISC_WAIT, + if DONT_NEED_AIO_MISC_COND. Remove mode parameter check. Only set + sigevent type to SIGEV_NONE if LIO_NO_INDIVIDUAL_EVENT is set. + (__lio_listio_21): New function. Compatiblity version which sets + LIO_NO_INDIVIDUAL_EVENT before calling lio_listio_internal. + (__lio_listio_item_notify): New function. + * sysdeps/unix/sysv/linux/klio_listio64.c: Define __lio_listio_21 and + __lio_listio_item_notify macros. + * aio.h: Removed. + * configure.in: New file + * configure: Regenerated. + * sysdeps/rtkaio/kaio_cancel.c: Moved to... + * kaio_cancel.c: ... here. New file. + * sysdeps/rtkaio/kaio_error.c: Moved to... + * kaio_error.c: ... here. New file. + * sysdeps/rtkaio/kaio_fsync.c: Moved to... + * kaio_fsync.c: ... here. New file. + * sysdeps/rtkaio/kaio_misc.c: Moved to... + * kaio_misc.c: ... here. New file. + * sysdeps/rtkaio/kaio_notify.c: Moved to... + * kaio_notify.c: ... here. New file. + * sysdeps/rtkaio/kaio_read.c: Moved to... + * kaio_read.c: ... here. New file. + * sysdeps/rtkaio/kaio_read64.c: Moved to... + * kaio_read64.c: ... here. New file. + * sysdeps/rtkaio/kaio_return.c: Moved to... + * kaio_return.c: ... here. New file. + * sysdeps/rtkaio/kaio_sigqueue.c: Moved to... + * kaio_sigqueue.c: ... here. New file. + * sysdeps/rtkaio/kaio_suspend.c: Moved to... + * kaio_suspend.c: ... here. New file. + * sysdeps/rtkaio/kaio_write.c: Moved to... + * kaio_write.c: ... here. New file. + * sysdeps/rtkaio/kaio_write64.c: Moved to... + * kaio_write64.c: ... here. New file. + * sysdeps/rtkaio/klio_listio.c: Moved to... + * klio_listio.c: ... here. New file. + * sysdeps/rtkaio/klio_listio64.c: Moved to... + * klio_listio64.c: ... here. New file. + * sysdeps/pthread/Versions: New file. + * tst-aio8.c: New file. + * tst-aio9.c: New file. + * tst-aio10.c: New file. + * tst-clock2.c: New file. + * tst-cpuclock1.c: New file. + * tst-cpuclock2.c: New file. + * tst-cputimer1.c: New file. + * tst-cputimer2.c: New file. + * tst-cputimer3.c: New file. + * sysdeps/unix/sysv/linux/sparc/Makefile: New file. + * sysdeps/unix/sysv/linux/sparc/rtkaio-sysdep.c: New file. + * sysdeps/unix/sysv/linux/sparc/sparc64/Versions: New file. + * sysdeps/mips/Makefile: Removed. + * sysdeps/unix/mips/rtkaio-sysdep.S: Removed. + * sysdeps/unix/sysv/linux/hppa/Versions: Removed. + * sysdeps/unix/sysv/linux/hppa/kaio_cancel.c: Removed. + +2006-07-19 Jakub Jelinek <jakub@redhat.com> + + * sysdeps/unix/sysv/linux/kaio_misc.c: Include atomic.h. + (kernel_callback): Ensure __return_value is updated before + __error_code is set. + +2006-05-11 Jakub Jelinek <jakub@redhat.com> + + * Makefile (tests): Add tst-mqueue{8,9}, tst-timer5 and + tst-aiod{,64,2,3,4,5}. + (LDFLAGS-rtkaio.so): Add -Wl,--enable-new-dtags,-z,nodelete. + * sysdeps/unix/sysv/linux/kaio_misc.h: Include signal.h and + sysdep.h. + (aio_start_notify_thread, aio_create_helper_thread): Define + for !BROKEN_THREAD_SIGNALS. + (__aio_start_notify_thread, __aio_create_helper_thread): New + functions for !BROKEN_THREAD_SIGNALS. + * sysdeps/unix/sysv/linux/kaio_misc.c: Include sys/sysmacros.h. + (aio_create_helper_thread): Define if not yet defined. + (__aio_create_helper_thread): New function. + (__aio_wait_for_events): Pass 1 rather than 0 as min_nr to + io_getevents. + (handle_kernel_aio): Likewise. + (__aio_create_kernel_thread): Use aio_create_helper_thread. + (__aio_enqueue_user_request): Likewise. + (handle_fildes_io): Likewise. Remove noreturn attribute, + return NULL instead of calling pthread_exit (NULL). + (__aio_enqueue_request_ctx): Call fcntl and fxstat64 to avoid using + kaio on non-O_DIRECT non-/dev/raw* filedescriptors. For LIO_SYNC + and LIO_DSYNC also set kctx to KCTX_NONE. + * sysdeps/unix/sysv/linux/kaio_suspend.c (aio_suspend): Don't start + handle_kernel_aio thread if ktotal is zero. + * sysdeps/pthread/Makefile (tests): Add tst-mqueue8x. + (CFLAGS-tst-mqueue8x.c): Add -fexceptions. + * Versions.def (librtkaio): Add GLIBC_2.3.4 version. + * kaio_mq_close.c: New file. + * kaio_mq_getattr.c: New file. + * kaio_mq_notify.c: New file. + * kaio_mq_open.c: New file. + * kaio_mq_receive.c: New file. + * kaio_mq_send.c: New file. + * kaio_mq_setattr.c: New file. + * kaio_mq_timedreceive.c: New file. + * kaio_mq_timedsend.c: New file. + * kaio_mq_unlink.c: New file. + * sysdeps/pthread/tst-mqueue8x.c: New file. + * sysdeps/unix/sysv/linux/syscalls.list: New file. + * tst-mqueue8.c: New file. + * tst-mqueue9.c: New file. + * tst-timer5.c: New file. + * tst-aiod.h: New file. + * tst-aiod.c: New test. + * tst-aiod64.c: New test. + * tst-aiod2.c: New test. + * tst-aiod3.c: New test. + * tst-aiod4.c: New test. + * tst-aiod5.c: New test. + * sysdeps/mips/Makefile: New file. + * sysdeps/unix/alpha/Makefile: New file. + * sysdeps/unix/alpha/rtkaio-sysdep.S: New file. + * sysdeps/unix/mips/rtkaio-sysdep.S: New file. + * sysdeps/unix/sysv/linux/Makefile: New file. + * sysdeps/unix/sysv/linux/s390/Makefile: New file. + * sysdeps/unix/sysv/linux/s390/rtkaio-sysdep.S: New file. + * sysdeps/unix/sysv/linux/powerpc/Makefile: New file. + * sysdeps/unix/sysv/linux/powerpc/rtkaio-sysdep.c: New file. + * sysdeps/unix/sysv/linux/ia64/Makefile: New file. + * sysdeps/unix/sysv/linux/ia64/rtkaio-sysdep.S: New file. + 2004-04-17 Jakub Jelinek <jakub@redhat.com> * rt/Makefile (mq-routines): Set. diff --git a/rtkaio/Makefile b/rtkaio/Makefile index 50c121d..595e71a 100644 --- a/rtkaio/Makefile +++ b/rtkaio/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 2003, 2004 Free Software Foundation, Inc. +# Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. # This file is part of the GNU C Library. # The GNU C Library is free software; you can redistribute it and/or @@ -41,13 +41,19 @@ librtkaio-routines = $(patsubst %,k%,$(aio-routines)) \ tests := tst-shm tst-clock tst-clock_nanosleep tst-timer tst-timer2 \ tst-aio tst-aio64 tst-aio2 tst-aio3 tst-aio4 tst-aio5 tst-aio6 \ - tst-aio7 tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4 \ - tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-timer3 tst-timer4 + tst-aio7 tst-aio8 tst-aio9 tst-aio10 \ + tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4 \ + tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 tst-mqueue9 \ + tst-timer3 tst-timer4 tst-timer5 \ + tst-cpuclock1 tst-cpuclock2 \ + tst-cputimer1 tst-cputimer2 tst-cputimer3 \ + tst-clock2 \ + tst-aiod tst-aiod64 tst-aiod2 tst-aiod3 tst-aiod4 tst-aiod5 extra-libs := librtkaio extra-libs-others := $(extra-libs) -include ../Makeconfig +include $(..)Makeconfig ifeq (yesyes,$(build-shared)$(elf)) generated += librt.so$(librt.so-version) @@ -55,14 +61,15 @@ generated += librt.so$(librt.so-version) $(objpfx)librt.so$(librt.so-version): $(objpfx)librtkaio.so; $(make-link) endif -include ../Rules +include $(..)Rules CFLAGS-kaio_suspend.c = -fexceptions CFLAGS-kaio_clock_nanosleep.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-kaio_librt-cancellation.c = -fasynchronous-unwind-tables -LDFLAGS-rtkaio.so = -Wl,-soname=lib$(libprefix)rt.so$(librt.so-version) -CPPFLAGS-librtkaio += -DIS_IN_librt=1 +LDFLAGS-rtkaio.so = -Wl,-soname=lib$(libprefix)rt.so$(librt.so-version) \ + -Wl,--enable-new-dtags,-z,nodelete +CPPFLAGS-librtkaio += -DIS_IN_librt=1 -I$(..)rt rpath-dirs := $(patsubst rt,rtkaio,$(rpath-dirs)) diff --git a/rtkaio/Versions.def b/rtkaio/Versions.def index 41bb362..4213933 100644 --- a/rtkaio/Versions.def +++ b/rtkaio/Versions.def @@ -3,4 +3,6 @@ librtkaio { GLIBC_2.2 GLIBC_2.3 GLIBC_2.3.3 + GLIBC_2.3.4 + GLIBC_2.4 } diff --git a/rtkaio/aio.h b/rtkaio/aio.h deleted file mode 100644 index c2a4145..0000000 --- a/rtkaio/aio.h +++ /dev/null @@ -1 +0,0 @@ -#include <rt/aio.h> diff --git a/rtkaio/configure b/rtkaio/configure index 4352b69..16ef6d9 100644 --- a/rtkaio/configure +++ b/rtkaio/configure @@ -1,4 +1,4 @@ -# This is only to keep the GNU C library configure mechanism happy. -# -# Perhaps some day we need a real configuration script for different -# kernel versions or so. +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + +libc_add_on_canonical= +libc_add_on_subdirs=. diff --git a/rtkaio/configure.in b/rtkaio/configure.in new file mode 100644 index 0000000..9e1b6a6 --- /dev/null +++ b/rtkaio/configure.in @@ -0,0 +1,5 @@ +dnl glibc configure fragment for rtkaio add-on +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. + +libc_add_on_canonical= +libc_add_on_subdirs=. diff --git a/rtkaio/sysdeps/rtkaio/kaio_cancel.c b/rtkaio/kaio_cancel.c index f1ea4b7..f1ea4b7 100644 --- a/rtkaio/sysdeps/rtkaio/kaio_cancel.c +++ b/rtkaio/kaio_cancel.c diff --git a/rtkaio/kaio_error.c b/rtkaio/kaio_error.c new file mode 100644 index 0000000..9fdf4f5 --- /dev/null +++ b/rtkaio/kaio_error.c @@ -0,0 +1 @@ +#include <aio_error.c> diff --git a/rtkaio/sysdeps/rtkaio/kaio_fsync.c b/rtkaio/kaio_fsync.c index f3483ae..f3483ae 100644 --- a/rtkaio/sysdeps/rtkaio/kaio_fsync.c +++ b/rtkaio/kaio_fsync.c diff --git a/rtkaio/sysdeps/rtkaio/kaio_misc.c b/rtkaio/kaio_misc.c index 16eaa21..16eaa21 100644 --- a/rtkaio/sysdeps/rtkaio/kaio_misc.c +++ b/rtkaio/kaio_misc.c diff --git a/rtkaio/kaio_mq_close.c b/rtkaio/kaio_mq_close.c new file mode 100644 index 0000000..ff6feda --- /dev/null +++ b/rtkaio/kaio_mq_close.c @@ -0,0 +1 @@ +#include <mq_close.c> diff --git a/rtkaio/kaio_mq_getattr.c b/rtkaio/kaio_mq_getattr.c new file mode 100644 index 0000000..87c3d8e --- /dev/null +++ b/rtkaio/kaio_mq_getattr.c @@ -0,0 +1 @@ +#include <mq_getattr.c> diff --git a/rtkaio/kaio_mq_notify.c b/rtkaio/kaio_mq_notify.c new file mode 100644 index 0000000..e464d40 --- /dev/null +++ b/rtkaio/kaio_mq_notify.c @@ -0,0 +1 @@ +#include <mq_notify.c> diff --git a/rtkaio/kaio_mq_open.c b/rtkaio/kaio_mq_open.c new file mode 100644 index 0000000..54a3e48 --- /dev/null +++ b/rtkaio/kaio_mq_open.c @@ -0,0 +1 @@ +#include <mq_open.c> diff --git a/rtkaio/kaio_mq_receive.c b/rtkaio/kaio_mq_receive.c new file mode 100644 index 0000000..38a663b --- /dev/null +++ b/rtkaio/kaio_mq_receive.c @@ -0,0 +1 @@ +#include <mq_receive.c> diff --git a/rtkaio/kaio_mq_send.c b/rtkaio/kaio_mq_send.c new file mode 100644 index 0000000..39b2325 --- /dev/null +++ b/rtkaio/kaio_mq_send.c @@ -0,0 +1 @@ +#include <mq_send.c> diff --git a/rtkaio/kaio_mq_setattr.c b/rtkaio/kaio_mq_setattr.c new file mode 100644 index 0000000..44a1309 --- /dev/null +++ b/rtkaio/kaio_mq_setattr.c @@ -0,0 +1 @@ +#include <mq_setattr.c> diff --git a/rtkaio/kaio_mq_timedreceive.c b/rtkaio/kaio_mq_timedreceive.c new file mode 100644 index 0000000..6c0b727 --- /dev/null +++ b/rtkaio/kaio_mq_timedreceive.c @@ -0,0 +1 @@ +#include <mq_timedreceive.c> diff --git a/rtkaio/kaio_mq_timedsend.c b/rtkaio/kaio_mq_timedsend.c new file mode 100644 index 0000000..9923cb7 --- /dev/null +++ b/rtkaio/kaio_mq_timedsend.c @@ -0,0 +1 @@ +#include <mq_timedsend.c> diff --git a/rtkaio/kaio_mq_unlink.c b/rtkaio/kaio_mq_unlink.c new file mode 100644 index 0000000..3cbf411 --- /dev/null +++ b/rtkaio/kaio_mq_unlink.c @@ -0,0 +1 @@ +#include <mq_unlink.c> diff --git a/rtkaio/sysdeps/rtkaio/kaio_notify.c b/rtkaio/kaio_notify.c index 6861e7f..6861e7f 100644 --- a/rtkaio/sysdeps/rtkaio/kaio_notify.c +++ b/rtkaio/kaio_notify.c diff --git a/rtkaio/sysdeps/rtkaio/kaio_read.c b/rtkaio/kaio_read.c index 5d7774b..5d7774b 100644 --- a/rtkaio/sysdeps/rtkaio/kaio_read.c +++ b/rtkaio/kaio_read.c diff --git a/rtkaio/sysdeps/rtkaio/kaio_read64.c b/rtkaio/kaio_read64.c index becd1be..becd1be 100644 --- a/rtkaio/sysdeps/rtkaio/kaio_read64.c +++ b/rtkaio/kaio_read64.c diff --git a/rtkaio/kaio_return.c b/rtkaio/kaio_return.c new file mode 100644 index 0000000..8f1d2c9 --- /dev/null +++ b/rtkaio/kaio_return.c @@ -0,0 +1 @@ +#include <aio_return.c> diff --git a/rtkaio/sysdeps/rtkaio/kaio_sigqueue.c b/rtkaio/kaio_sigqueue.c index 6e49f01..6e49f01 100644 --- a/rtkaio/sysdeps/rtkaio/kaio_sigqueue.c +++ b/rtkaio/kaio_sigqueue.c diff --git a/rtkaio/sysdeps/rtkaio/kaio_suspend.c b/rtkaio/kaio_suspend.c index 145420b..145420b 100644 --- a/rtkaio/sysdeps/rtkaio/kaio_suspend.c +++ b/rtkaio/kaio_suspend.c diff --git a/rtkaio/sysdeps/rtkaio/kaio_write.c b/rtkaio/kaio_write.c index 68e47ca..68e47ca 100644 --- a/rtkaio/sysdeps/rtkaio/kaio_write.c +++ b/rtkaio/kaio_write.c diff --git a/rtkaio/sysdeps/rtkaio/kaio_write64.c b/rtkaio/kaio_write64.c index 316e55d..316e55d 100644 --- a/rtkaio/sysdeps/rtkaio/kaio_write64.c +++ b/rtkaio/kaio_write64.c diff --git a/rtkaio/sysdeps/rtkaio/klio_listio.c b/rtkaio/klio_listio.c index 08378bd..08378bd 100644 --- a/rtkaio/sysdeps/rtkaio/klio_listio.c +++ b/rtkaio/klio_listio.c diff --git a/rtkaio/sysdeps/rtkaio/klio_listio64.c b/rtkaio/klio_listio64.c index 3a087e4..3a087e4 100644 --- a/rtkaio/sysdeps/rtkaio/klio_listio64.c +++ b/rtkaio/klio_listio64.c diff --git a/rtkaio/sysdeps/pthread/Makefile b/rtkaio/sysdeps/pthread/Makefile index 99561b7..7ced3eb 100644 --- a/rtkaio/sysdeps/pthread/Makefile +++ b/rtkaio/sysdeps/pthread/Makefile @@ -14,6 +14,11 @@ $(objpfx)tst-timer: $(objpfx)librtkaio.so $(shared-thread-library) else $(objpfx)tst-timer: $(objpfx)librtkaio.a $(static-thread-library) endif + +ifeq ($(have-forced-unwind),yes) +tests += tst-mqueue8x +CFLAGS-tst-mqueue8x.c += -fexceptions +endif endif endif diff --git a/rtkaio/sysdeps/pthread/Versions b/rtkaio/sysdeps/pthread/Versions new file mode 100644 index 0000000..7677b76 --- /dev/null +++ b/rtkaio/sysdeps/pthread/Versions @@ -0,0 +1,7 @@ +%ifdef HAVE_FORCED_UNWIND +librtkaio { + GLIBC_2.4 { + lio_listio; lio_listio64; + } +} +%endif diff --git a/rtkaio/sysdeps/pthread/tst-mqueue8x.c b/rtkaio/sysdeps/pthread/tst-mqueue8x.c new file mode 100644 index 0000000..1259ebd --- /dev/null +++ b/rtkaio/sysdeps/pthread/tst-mqueue8x.c @@ -0,0 +1 @@ +#include_next <tst-mqueue8x.c> diff --git a/rtkaio/sysdeps/rtkaio/kaio_error.c b/rtkaio/sysdeps/rtkaio/kaio_error.c deleted file mode 100644 index bad0a22..0000000 --- a/rtkaio/sysdeps/rtkaio/kaio_error.c +++ /dev/null @@ -1 +0,0 @@ -#include <rt/aio_error.c> diff --git a/rtkaio/sysdeps/rtkaio/kaio_return.c b/rtkaio/sysdeps/rtkaio/kaio_return.c deleted file mode 100644 index 7cff9dc..0000000 --- a/rtkaio/sysdeps/rtkaio/kaio_return.c +++ /dev/null @@ -1 +0,0 @@ -#include <rt/aio_return.c> diff --git a/rtkaio/sysdeps/unix/alpha/Makefile b/rtkaio/sysdeps/unix/alpha/Makefile new file mode 100644 index 0000000..223ec37 --- /dev/null +++ b/rtkaio/sysdeps/unix/alpha/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),rtkaio) +librtkaio-sysdep_routines += rtkaio-sysdep +endif diff --git a/rtkaio/sysdeps/unix/alpha/rtkaio-sysdep.S b/rtkaio/sysdeps/unix/alpha/rtkaio-sysdep.S new file mode 100644 index 0000000..11ee214 --- /dev/null +++ b/rtkaio/sysdeps/unix/alpha/rtkaio-sysdep.S @@ -0,0 +1 @@ +#include <rt-sysdep.S> diff --git a/rtkaio/sysdeps/unix/sysv/linux/Makefile b/rtkaio/sysdeps/unix/sysv/linux/Makefile new file mode 100644 index 0000000..9ed3d75 --- /dev/null +++ b/rtkaio/sysdeps/unix/sysv/linux/Makefile @@ -0,0 +1,4 @@ +ifeq ($(subdir),rtkaio) +CFLAGS-kaio_mq_send.c += -fexceptions +CFLAGS-kaio_mq_receive.c += -fexceptions +endif diff --git a/rtkaio/sysdeps/unix/sysv/linux/hppa/Versions b/rtkaio/sysdeps/unix/sysv/linux/hppa/Versions deleted file mode 100644 index b2d59a9..0000000 --- a/rtkaio/sysdeps/unix/sysv/linux/hppa/Versions +++ /dev/null @@ -1,6 +0,0 @@ -librtkaio { - GLIBC_2.3 { - # AIO functions. - aio_cancel; aio_cancel64; - } -} diff --git a/rtkaio/sysdeps/unix/sysv/linux/hppa/kaio_cancel.c b/rtkaio/sysdeps/unix/sysv/linux/hppa/kaio_cancel.c deleted file mode 100644 index 6e345e1..0000000 --- a/rtkaio/sysdeps/unix/sysv/linux/hppa/kaio_cancel.c +++ /dev/null @@ -1,33 +0,0 @@ -#include <shlib-compat.h> - -#define aio_cancel64 XXX -#include <aio.h> -#undef aio_cancel64 -#include <errno.h> - -extern __typeof (aio_cancel) __new_aio_cancel; -extern __typeof (aio_cancel) __old_aio_cancel; - -#define aio_cancel __new_aio_cancel - -#include <sysdeps/unix/sysv/linux/kaio_cancel.c> - -#undef aio_cancel -strong_alias (__new_aio_cancel, __new_aio_cancel64); -versioned_symbol (librt, __new_aio_cancel, aio_cancel, GLIBC_2_3); -versioned_symbol (librt, __new_aio_cancel64, aio_cancel64, GLIBC_2_3); - -#if SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_3) - -#undef ECANCELED -#define aio_cancel __old_aio_cancel -#define ECANCELED 125 - -#include <sysdeps/unix/sysv/linux/kaio_cancel.c> - -#undef aio_cancel -strong_alias (__old_aio_cancel, __old_aio_cancel64); -compat_symbol (librt, __old_aio_cancel, aio_cancel, GLIBC_2_1); -compat_symbol (librt, __old_aio_cancel64, aio_cancel64, GLIBC_2_1); - -#endif diff --git a/rtkaio/sysdeps/unix/sysv/linux/ia64/Makefile b/rtkaio/sysdeps/unix/sysv/linux/ia64/Makefile new file mode 100644 index 0000000..ead21fb --- /dev/null +++ b/rtkaio/sysdeps/unix/sysv/linux/ia64/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),rtkaio) +librtkaio-routines += rtkaio-sysdep +endif diff --git a/rtkaio/sysdeps/unix/sysv/linux/ia64/rtkaio-sysdep.S b/rtkaio/sysdeps/unix/sysv/linux/ia64/rtkaio-sysdep.S new file mode 100644 index 0000000..11ee214 --- /dev/null +++ b/rtkaio/sysdeps/unix/sysv/linux/ia64/rtkaio-sysdep.S @@ -0,0 +1 @@ +#include <rt-sysdep.S> diff --git a/rtkaio/sysdeps/unix/sysv/linux/kaio_cancel.c b/rtkaio/sysdeps/unix/sysv/linux/kaio_cancel.c index 19d7e1b..7d2738d 100644 --- a/rtkaio/sysdeps/unix/sysv/linux/kaio_cancel.c +++ b/rtkaio/sysdeps/unix/sysv/linux/kaio_cancel.c @@ -1,5 +1,5 @@ /* Cancel requests associated with given file descriptor. - Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 2000, 2002, 2003, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. diff --git a/rtkaio/sysdeps/unix/sysv/linux/kaio_error.c b/rtkaio/sysdeps/unix/sysv/linux/kaio_error.c index 509913d..23859c3 100644 --- a/rtkaio/sysdeps/unix/sysv/linux/kaio_error.c +++ b/rtkaio/sysdeps/unix/sysv/linux/kaio_error.c @@ -31,7 +31,7 @@ #include <kaio_misc.h> #ifndef USE_KAIO -#include <rt/aio_error.c> +#include <aio_error.c> #else #include <errno.h> diff --git a/rtkaio/sysdeps/unix/sysv/linux/kaio_misc.c b/rtkaio/sysdeps/unix/sysv/linux/kaio_misc.c index 77c55b3..76e0c43 100644 --- a/rtkaio/sysdeps/unix/sysv/linux/kaio_misc.c +++ b/rtkaio/sysdeps/unix/sysv/linux/kaio_misc.c @@ -1,5 +1,5 @@ /* Handle general operations. - Copyright (C) 1997,1998,1999,2000,2001,2002,2003 + Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -27,6 +27,7 @@ #include <aio.h> #include <assert.h> +#include <atomic.h> #include <errno.h> #include <limits.h> #include <pthread.h> @@ -34,6 +35,28 @@ #include <unistd.h> #include <sys/stat.h> #include <sys/time.h> +#include <sys/sysmacros.h> + +#ifndef aio_create_helper_thread +# define aio_create_helper_thread __aio_create_helper_thread + +extern inline int +__aio_create_helper_thread (pthread_t *threadp, void *(*tf) (void *), void *arg) +{ + pthread_attr_t attr; + + /* Make sure the thread is created detached. */ + pthread_attr_init (&attr); + pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + + int ret = pthread_create (threadp, &attr, tf, arg); + + (void) pthread_attr_destroy (&attr); + return ret; +} + +#endif + static void add_request_to_runlist (struct requestlist *newrequest) internal_function; @@ -359,14 +382,16 @@ static void kernel_callback (kctx_t ctx, struct kiocb *kiocb, long res, long res2) { struct requestlist *req = (struct requestlist *)kiocb; + long errcode = 0; - req->aiocbp->aiocb.__error_code = 0; - req->aiocbp->aiocb.__return_value = res; if (res < 0 && res > -1000) { - req->aiocbp->aiocb.__error_code = -res; - req->aiocbp->aiocb.__return_value = -1; + errcode = -res; + res = -1; } + req->aiocbp->aiocb.__return_value = res; + atomic_write_barrier (); + req->aiocbp->aiocb.__error_code = errcode; __aio_notify (req); assert (req->running == allocated); req->running = done; @@ -421,7 +446,7 @@ __aio_wait_for_events (kctx_t kctx, const struct timespec *timespec) ts.tv_nsec = 0; do { - ret = INTERNAL_SYSCALL (io_getevents, err, 5, kctx, 0, 10, ev, + ret = INTERNAL_SYSCALL (io_getevents, err, 5, kctx, 1, 10, ev, timespec); if (INTERNAL_SYSCALL_ERROR_P (ret, err) || ret == 0) break; @@ -453,16 +478,11 @@ internal_function __aio_create_kernel_thread (void) { pthread_t thid; - pthread_attr_t attr; if (__kernel_thread_started) return 0; - /* Make sure the thread is created detached. */ - pthread_attr_init (&attr); - pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - - if (pthread_create (&thid, &attr, handle_kernel_aio, NULL) != 0) + if (aio_create_helper_thread (&thid, handle_kernel_aio, NULL) != 0) return -1; __kernel_thread_started = 1; return 0; @@ -477,7 +497,7 @@ handle_kernel_aio (void *arg __attribute__((unused))) for (;;) { - ret = INTERNAL_SYSCALL (io_getevents, err, 5, __aio_kioctx, 0, 10, ev, + ret = INTERNAL_SYSCALL (io_getevents, err, 5, __aio_kioctx, 1, 10, ev, NULL); if (INTERNAL_SYSCALL_ERROR_P (ret, err) || ret == 0) continue; @@ -593,16 +613,11 @@ __aio_enqueue_user_request (struct requestlist *newp) if (nthreads < optim.aio_threads && idle_thread_count == 0) { pthread_t thid; - pthread_attr_t attr; - - /* Make sure the thread is created detached. */ - pthread_attr_init (&attr); - pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); running = newp->running = allocated; /* Now try to start a thread. */ - if (pthread_create (&thid, &attr, handle_fildes_io, newp) == 0) + if (aio_create_helper_thread (&thid, handle_fildes_io, newp) == 0) /* We managed to enqueue the request. All errors which can happen now can be recognized by calls to `aio_return' and `aio_error'. */ @@ -653,6 +668,7 @@ __aio_enqueue_request_ctx (aiocb_union *aiocbp, int operation, kctx_t kctx) aiocbp->aiocb.aio_reqprio = 0; /* FIXME: Kernel doesn't support sync yet. */ operation &= ~LIO_KTHREAD; + kctx = KCTX_NONE; } else if (aiocbp->aiocb.aio_reqprio < 0 || aiocbp->aiocb.aio_reqprio > AIO_PRIO_DELTA_MAX) @@ -664,6 +680,23 @@ __aio_enqueue_request_ctx (aiocb_union *aiocbp, int operation, kctx_t kctx) return NULL; } + if ((operation & LIO_KTHREAD) || kctx != KCTX_NONE) + { + /* io_* is only really asynchronous for O_DIRECT or /dev/raw*. */ + int fl = __fcntl (aiocbp->aiocb.aio_fildes, F_GETFL); + if (fl < 0 || (fl & O_DIRECT) == 0) + { + struct stat64 st; + if (__fxstat64 (_STAT_VER, aiocbp->aiocb.aio_fildes, &st) < 0 + || ! S_ISCHR (st.st_mode) + || major (st.st_rdev) != 162) + { + operation &= ~LIO_KTHREAD; + kctx = KCTX_NONE; + } + } + } + /* Compute priority for this request. */ pthread_getschedparam (pthread_self (), &policy, ¶m); prio = param.sched_priority - aiocbp->aiocb.aio_reqprio; @@ -799,7 +832,9 @@ wait_for_kernel_requests (int fildes) return -1; } +#ifndef DONT_NEED_AIO_MISC_COND pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +#endif struct waitlist waitlist[nent]; int cnt = 0; @@ -807,7 +842,10 @@ wait_for_kernel_requests (int fildes) { if (kreq->running == allocated) { +#ifndef DONT_NEED_AIO_MISC_COND waitlist[cnt].cond = &cond; +#endif + waitlist[cnt].result = NULL; waitlist[cnt].next = kreq->waiting; waitlist[cnt].counterp = &nent; waitlist[cnt].sigevp = NULL; @@ -819,11 +857,15 @@ wait_for_kernel_requests (int fildes) kreq = kreq->next_prio; } +#ifdef DONT_NEED_AIO_MISC_COND + AIO_MISC_WAIT (ret, nent, NULL, 0); +#else do pthread_cond_wait (&cond, &__aio_requests_mutex); while (nent); pthread_cond_destroy (&cond); +#endif } pthread_mutex_unlock (&__aio_requests_mutex); @@ -832,7 +874,6 @@ wait_for_kernel_requests (int fildes) static void * -__attribute__ ((noreturn)) handle_fildes_io (void *arg) { pthread_t self = pthread_self (); @@ -1026,16 +1067,11 @@ handle_fildes_io (void *arg) else if (nthreads < optim.aio_threads) { pthread_t thid; - pthread_attr_t attr; - - /* Make sure the thread is created detached. */ - pthread_attr_init (&attr); - pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); /* Now try to start a thread. If we fail, no big deal, because we know that there is at least one thread (us) that is working on AIO operations. */ - if (pthread_create (&thid, &attr, handle_fildes_io, NULL) + if (aio_create_helper_thread (&thid, handle_fildes_io, NULL) == 0) ++nthreads; } @@ -1047,7 +1083,7 @@ handle_fildes_io (void *arg) } while (runp != NULL); - pthread_exit (NULL); + return NULL; } diff --git a/rtkaio/sysdeps/unix/sysv/linux/kaio_misc.h b/rtkaio/sysdeps/unix/sysv/linux/kaio_misc.h index bee75f3..5e0ca19 100644 --- a/rtkaio/sysdeps/unix/sysv/linux/kaio_misc.h +++ b/rtkaio/sysdeps/unix/sysv/linux/kaio_misc.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1997,1999,2000,2001,2002,2003 Free Software Foundation, Inc. +/* Copyright (C) 1997,1999,2000,2001,2002,2003,2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -34,6 +35,68 @@ #include <aio.h> #include <pthread.h> #include <stdint.h> +#include <signal.h> +#include <sysdep.h> +#include <limits.h> + +#ifdef HAVE_FORCED_UNWIND + +/* We define a special synchronization primitive for AIO. POSIX + conditional variables would be ideal but the pthread_cond_*wait + operations do not return on EINTR. This is a requirement for + correct aio_suspend and lio_listio implementations. */ + +#include <assert.h> +#include <pthreadP.h> +#include <lowlevellock.h> + +# define DONT_NEED_AIO_MISC_COND 1 + +# define AIO_MISC_NOTIFY(waitlist) \ + do { \ + if (*waitlist->counterp > 0 && --*waitlist->counterp == 0) \ + lll_futex_wake (waitlist->counterp, 1); \ + } while (0) + +# define AIO_MISC_WAIT(result, futex, timeout, cancel) \ + do { \ + volatile int *futexaddr = &futex; \ + int oldval = futex; \ + \ + if (oldval != 0) \ + { \ + pthread_mutex_unlock (&__aio_requests_mutex); \ + \ + int oldtype; \ + if (cancel) \ + oldtype = LIBC_CANCEL_ASYNC (); \ + \ + int status; \ + do \ + { \ + status = lll_futex_timed_wait (futexaddr, oldval, timeout); \ + if (status != -EWOULDBLOCK) \ + break; \ + \ + oldval = *futexaddr; \ + } \ + while (oldval != 0); \ + \ + if (cancel) \ + LIBC_CANCEL_RESET (oldtype); \ + \ + if (status == -EINTR) \ + result = EINTR; \ + else if (status == -ETIMEDOUT) \ + result = EAGAIN; \ + else \ + assert (status == 0 || status == -EWOULDBLOCK); \ + \ + pthread_mutex_lock (&__aio_requests_mutex); \ + } \ + } while (0) + +#endif typedef unsigned long kctx_t; #define KCTX_NONE ~0UL @@ -95,7 +158,12 @@ struct waitlist { struct waitlist *next; + /* The next two fields is used in synchronous io_listio' operations. */ +#ifndef DONT_NEED_AIO_MISC_COND pthread_cond_t *cond; +#endif + int *result; + volatile int *counterp; /* The next field is used in asynchronous `lio_listio' operations. */ struct sigevent *sigevp; @@ -212,5 +280,49 @@ extern int __aio_create_kernel_thread (void) extern int __have_no_kernel_aio attribute_hidden; extern int __kernel_thread_started attribute_hidden; +#ifndef BROKEN_THREAD_SIGNALS +# define aio_start_notify_thread __aio_start_notify_thread +# define aio_create_helper_thread __aio_create_helper_thread + +extern inline void +__aio_start_notify_thread (void) +{ + sigset_t ss; + sigemptyset (&ss); + INTERNAL_SYSCALL_DECL (err); + INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, NULL, _NSIG / 8); +} + +extern inline int +__aio_create_helper_thread (pthread_t *threadp, void *(*tf) (void *), void *arg) +{ + pthread_attr_t attr; + + /* Make sure the thread is created detached. */ + pthread_attr_init (&attr); + pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + + /* The helper thread needs only very little resources. */ + (void) pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN); + + /* Block all signals in the helper thread. To do this thoroughly we + temporarily have to block all signals here. */ + sigset_t ss; + sigset_t oss; + sigfillset (&ss); + INTERNAL_SYSCALL_DECL (err); + INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &ss, &oss, _NSIG / 8); + + int ret = pthread_create (threadp, &attr, tf, arg); + + /* Restore the signal mask. */ + INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_SETMASK, &oss, NULL, + _NSIG / 8); + + (void) pthread_attr_destroy (&attr); + return ret; +} +#endif + #endif #endif /* aio_misc.h */ diff --git a/rtkaio/sysdeps/unix/sysv/linux/kaio_return.c b/rtkaio/sysdeps/unix/sysv/linux/kaio_return.c index 462514b..1d9f6cb 100644 --- a/rtkaio/sysdeps/unix/sysv/linux/kaio_return.c +++ b/rtkaio/sysdeps/unix/sysv/linux/kaio_return.c @@ -32,7 +32,7 @@ #include <kaio_misc.h> #ifndef USE_KAIO -#include <rt/aio_return.c> +#include <aio_return.c> #else #include <errno.h> diff --git a/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c b/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c index 0b3380f..2400c52 100644 --- a/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c +++ b/rtkaio/sysdeps/unix/sysv/linux/kaio_suspend.c @@ -1,5 +1,6 @@ /* Suspend until termination of a requests. - Copyright (C) 1997,1998,1999,2000,2002,2003 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -37,8 +38,10 @@ #include <assert.h> #include <errno.h> +#include <stdbool.h> #include <stdlib.h> #include <sys/time.h> + #include <bits/libc-lock.h> #include <sysdep-cancel.h> @@ -48,7 +51,9 @@ struct clparam const struct aiocb *const *list; struct waitlist *waitlist; struct requestlist **requestlist; +#ifndef DONT_NEED_AIO_MISC_COND pthread_cond_t *cond; +#endif int nent; }; @@ -56,6 +61,12 @@ struct clparam static void cleanup (void *arg) { +#ifdef DONT_NEED_AIO_MISC_COND + /* Acquire the mutex. If pthread_cond_*wait is used this would + happen implicitly. */ + pthread_mutex_lock (&__aio_requests_mutex); +#endif + const struct clparam *param = (const struct clparam *) arg; /* Now remove the entry in the waiting list for all requests @@ -79,8 +90,10 @@ cleanup (void *arg) *listp = (*listp)->next; } +#ifndef DONT_NEED_AIO_MISC_COND /* Release the conditional variable. */ (void) pthread_cond_destroy (param->cond); +#endif /* Release the mutex. */ pthread_mutex_unlock (&__aio_requests_mutex); @@ -93,11 +106,20 @@ aio_suspend (list, nent, timeout) int nent; const struct timespec *timeout; { + if (__builtin_expect (nent < 0, 0)) + { + __set_errno (EINVAL); + return -1; + } + struct waitlist waitlist[nent]; struct requestlist *requestlist[nent]; +#ifndef DONT_NEED_AIO_MISC_COND pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +#endif int cnt; int result = 0; + int cntr = 1; int total = 0, ktotal = 0; /* Request the mutex. */ @@ -114,9 +136,12 @@ aio_suspend (list, nent, timeout) if (requestlist[cnt] != NULL) { +#ifndef DONT_NEED_AIO_MISC_COND waitlist[cnt].cond = &cond; +#endif + waitlist[cnt].result = NULL; waitlist[cnt].next = requestlist[cnt]->waiting; - waitlist[cnt].counterp = &total; + waitlist[cnt].counterp = &cntr; waitlist[cnt].sigevp = NULL; #ifdef BROKEN_THREAD_SIGNALS waitlist[cnt].caller_pid = 0; /* Not needed. */ @@ -144,13 +169,15 @@ aio_suspend (list, nent, timeout) .list = list, .waitlist = waitlist, .requestlist = requestlist, +#ifndef DONT_NEED_AIO_MISC_COND .cond = &cond, +#endif .nent = nent }; pthread_cleanup_push (cleanup, &clparam); - if (!__kernel_thread_started) + if (!__kernel_thread_started && ktotal) { /* If the kernel aio thread was not started yet all requests are served by the kernel and there are no other threads running, @@ -160,7 +187,7 @@ aio_suspend (list, nent, timeout) { if (timeout == NULL) { - while (total == ktotal) + while (cntr == 1) __aio_wait_for_events (__aio_kioctx, NULL); } else @@ -180,7 +207,7 @@ aio_suspend (list, nent, timeout) for (;;) { result = __aio_wait_for_events (__aio_kioctx, timeout); - if (total < ktotal) + if (cntr < 1) break; if (result == ETIMEDOUT) break; @@ -201,7 +228,7 @@ aio_suspend (list, nent, timeout) timeout = &ts; } - if (total < ktotal) + if (cntr < 1) result = 0; else result = ETIMEDOUT; @@ -219,6 +246,10 @@ aio_suspend (list, nent, timeout) if (total == 0) /* Suspending was handled above. */ ; +#ifdef DONT_NEED_AIO_MISC_COND + else + AIO_MISC_WAIT (result, cntr, timeout, 1); +#else else if (timeout == NULL) result = pthread_cond_wait (&cond, &__aio_requests_mutex); else @@ -240,6 +271,7 @@ aio_suspend (list, nent, timeout) result = pthread_cond_timedwait (&cond, &__aio_requests_mutex, &abstime); } +#endif pthread_cleanup_pop (0); } @@ -263,19 +295,23 @@ aio_suspend (list, nent, timeout) *listp = (*listp)->next; } +#ifndef DONT_NEED_AIO_MISC_COND /* Release the conditional variable. */ if (__builtin_expect (pthread_cond_destroy (&cond) != 0, 0)) /* This must never happen. */ abort (); +#endif if (result != 0) { - /* An error occurred. Possibly it's EINTR. We have to translate +#ifndef DONT_NEED_AIO_MISC_COND + /* An error occurred. Possibly it's ETIMEDOUT. We have to translate the timeout error report of `pthread_cond_timedwait' to the form expected from `aio_suspend'. */ if (result == ETIMEDOUT) __set_errno (EAGAIN); else +#endif __set_errno (result); result = -1; diff --git a/rtkaio/sysdeps/unix/sysv/linux/klio_listio.c b/rtkaio/sysdeps/unix/sysv/linux/klio_listio.c index 73cb0d5..b7676c9 100644 --- a/rtkaio/sysdeps/unix/sysv/linux/klio_listio.c +++ b/rtkaio/sysdeps/unix/sysv/linux/klio_listio.c @@ -1,5 +1,5 @@ /* Enqueue and list of read or write requests. - Copyright (C) 1997,1998,1999,2000,2001,2002,2003 + Copyright (C) 1997,1998,1999,2000,2001,2002,2003,2005,2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -25,16 +25,19 @@ #include <lio_listio.c> #else +#ifndef lio_listio #include <aio.h> #include <assert.h> #include <errno.h> #include <stdlib.h> #include <unistd.h> -#ifndef lio_listio #define LIO_OPCODE_BASE 0 #endif +#include <shlib-compat.h> + + /* We need this special structure to handle asynchronous I/O. */ struct async_waitlist { @@ -43,12 +46,23 @@ struct async_waitlist struct waitlist list[0]; }; -int -lio_listio (mode, list, nent, sig) - int mode; - struct aiocb *const list[]; - int nent; - struct sigevent *sig; + +/* The code in glibc 2.1 to glibc 2.4 issued only one event when all + requests submitted with lio_listio finished. The existing practice + is to issue events for the individual requests as well. This is + what the new code does. */ +#if SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_4) +# define LIO_MODE(mode) ((mode) & 127) +# define NO_INDIVIDUAL_EVENT_P(mode) ((mode) & 128) +#else +# define LIO_MODE(mode) mode +# define NO_INDIVIDUAL_EVENT_P(mode) 0 +#endif + + +static int +lio_listio_internal (int mode, struct aiocb *const list[], int nent, + struct sigevent *sig) { struct sigevent defsigev; struct requestlist *requests[nent]; @@ -57,13 +71,6 @@ lio_listio (mode, list, nent, sig) int result = 0, op = 0; kctx_t kctx = KCTX_NONE; - /* Check arguments. */ - if (mode != LIO_WAIT && mode != LIO_NOWAIT) - { - __set_errno (EINVAL); - return -1; - } - if (sig == NULL) { defsigev.sigev_notify = SIGEV_NONE; @@ -73,7 +80,7 @@ lio_listio (mode, list, nent, sig) /* Request the mutex. */ pthread_mutex_lock (&__aio_requests_mutex); - if (mode == LIO_WAIT && ! __have_no_kernel_aio && nent > 0) + if (LIO_MODE (mode) == LIO_WAIT && ! __have_no_kernel_aio && nent > 0) { int res; INTERNAL_SYSCALL_DECL (err); @@ -90,7 +97,7 @@ lio_listio (mode, list, nent, sig) __have_no_kernel_aio = 1; } } - else if (mode == LIO_NOWAIT) + else if (LIO_MODE (mode) == LIO_NOWAIT) { op = LIO_KTHREAD; if (sig->sigev_notify != SIGEV_NONE) @@ -103,7 +110,8 @@ lio_listio (mode, list, nent, sig) for (cnt = 0; cnt < nent; ++cnt) if (list[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP) { - list[cnt]->aio_sigevent.sigev_notify = SIGEV_NONE; + if (NO_INDIVIDUAL_EVENT_P (mode)) + list[cnt]->aio_sigevent.sigev_notify = SIGEV_NONE; requests[cnt] = __aio_enqueue_request_ctx ((aiocb_union *) list[cnt], list[cnt]->aio_lio_opcode | op, @@ -136,7 +144,7 @@ lio_listio (mode, list, nent, sig) locked forever. */ pthread_mutex_unlock (&__aio_requests_mutex); - if (mode == LIO_NOWAIT) + if (LIO_MODE (mode) == LIO_NOWAIT) { #ifdef BROKEN_THREAD_SIGNALS __aio_notify_only (sig, @@ -148,11 +156,13 @@ lio_listio (mode, list, nent, sig) return result; } - else if (mode == LIO_WAIT) + else if (LIO_MODE (mode) == LIO_WAIT) { +#ifndef DONT_NEED_AIO_MISC_COND pthread_cond_t cond = PTHREAD_COND_INITIALIZER; - struct waitlist waitlist[nent]; int oldstate; +#endif + struct waitlist waitlist[nent]; volatile int ktotal = 0; total = 0; @@ -173,7 +183,10 @@ lio_listio (mode, list, nent, sig) waitlist[cnt].counterp = &total; ++total; } +#ifndef DONT_NEED_AIO_MISC_COND waitlist[cnt].cond = &cond; +#endif + waitlist[cnt].result = &result; waitlist[cnt].next = requests[cnt]->waiting; waitlist[cnt].sigevp = NULL; #ifdef BROKEN_THREAD_SIGNALS @@ -183,29 +196,40 @@ lio_listio (mode, list, nent, sig) } } - /* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancelation + while (ktotal > 0) + __aio_wait_for_events (kctx, NULL); +#ifdef DONT_NEED_AIO_MISC_COND + AIO_MISC_WAIT (result, total, NULL, 0); +#else + /* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancellation points we must be careful. We added entries to the waiting lists - which we must remove. So defer cancelation for now. */ + which we must remove. So defer cancellation for now. */ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate); - while (ktotal > 0) - __aio_wait_for_events (kctx, NULL); while (total > 0) pthread_cond_wait (&cond, &__aio_requests_mutex); - /* Now it's time to restore the cancelation state. */ + /* Now it's time to restore the cancellation state. */ pthread_setcancelstate (oldstate, NULL); + /* Release the conditional variable. */ + if (pthread_cond_destroy (&cond) != 0) + /* This must never happen. */ + abort (); +#endif + if (kctx != KCTX_NONE) { INTERNAL_SYSCALL_DECL (err); INTERNAL_SYSCALL (io_destroy, err, 1, kctx); } - /* Release the conditional variable. */ - if (pthread_cond_destroy (&cond) != 0) - /* This must never happen. */ - abort (); + /* If any of the I/O requests failed, return -1 and set errno. */ + if (result != 0) + { + __set_errno (result == EINTR ? EINTR : EIO); + result = -1; + } } else if (sig->sigev_notify != SIGEV_NONE) { @@ -234,7 +258,10 @@ lio_listio (mode, list, nent, sig) if (requests[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP) { +#ifndef DONT_NEED_AIO_MISC_COND waitlist->list[cnt].cond = NULL; +#endif + waitlist->list[cnt].result = NULL; waitlist->list[cnt].next = requests[cnt]->waiting; waitlist->list[cnt].counterp = &waitlist->counter; waitlist->list[cnt].sigevp = &waitlist->sigev; @@ -256,4 +283,40 @@ lio_listio (mode, list, nent, sig) return result; } + + +#if SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_4) +int +attribute_compat_text_section +__lio_listio_21 (int mode, struct aiocb *const list[], int nent, + struct sigevent *sig) +{ + /* Check arguments. */ + if (mode != LIO_WAIT && mode != LIO_NOWAIT) + { + __set_errno (EINVAL); + return -1; + } + + return lio_listio_internal (mode | LIO_NO_INDIVIDUAL_EVENT, list, nent, sig); +} +compat_symbol (librt, __lio_listio_21, lio_listio, GLIBC_2_1); +#endif + + +int +__lio_listio_item_notify (int mode, struct aiocb *const list[], int nent, + struct sigevent *sig) +{ + /* Check arguments. */ + if (mode != LIO_WAIT && mode != LIO_NOWAIT) + { + __set_errno (EINVAL); + return -1; + } + + return lio_listio_internal (mode, list, nent, sig); +} +versioned_symbol (librt, __lio_listio_item_notify, lio_listio, GLIBC_2_4); + #endif diff --git a/rtkaio/sysdeps/unix/sysv/linux/klio_listio64.c b/rtkaio/sysdeps/unix/sysv/linux/klio_listio64.c index 364d662..937cf1a 100644 --- a/rtkaio/sysdeps/unix/sysv/linux/klio_listio64.c +++ b/rtkaio/sysdeps/unix/sysv/linux/klio_listio64.c @@ -1,5 +1,5 @@ /* Enqueue and list of read or write requests, 64bit offset version. - Copyright (C) 1997, 1998, 1999, 2003 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999, 2003, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -31,6 +31,8 @@ #include <unistd.h> #define lio_listio lio_listio64 +#define __lio_listio_21 __lio_listio64_21 +#define __lio_listio_item_notify __lio_listio64_item_notify #define aiocb aiocb64 #define LIO_OPCODE_BASE 128 #include <klio_listio.c> diff --git a/rtkaio/sysdeps/unix/sysv/linux/powerpc/Makefile b/rtkaio/sysdeps/unix/sysv/linux/powerpc/Makefile new file mode 100644 index 0000000..ead21fb --- /dev/null +++ b/rtkaio/sysdeps/unix/sysv/linux/powerpc/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),rtkaio) +librtkaio-routines += rtkaio-sysdep +endif diff --git a/rtkaio/sysdeps/unix/sysv/linux/powerpc/rtkaio-sysdep.c b/rtkaio/sysdeps/unix/sysv/linux/powerpc/rtkaio-sysdep.c new file mode 100644 index 0000000..ff0440a --- /dev/null +++ b/rtkaio/sysdeps/unix/sysv/linux/powerpc/rtkaio-sysdep.c @@ -0,0 +1 @@ +#include <rt-sysdep.c> diff --git a/rtkaio/sysdeps/unix/sysv/linux/s390/Makefile b/rtkaio/sysdeps/unix/sysv/linux/s390/Makefile new file mode 100644 index 0000000..ead21fb --- /dev/null +++ b/rtkaio/sysdeps/unix/sysv/linux/s390/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),rtkaio) +librtkaio-routines += rtkaio-sysdep +endif diff --git a/rtkaio/sysdeps/unix/sysv/linux/s390/rtkaio-sysdep.S b/rtkaio/sysdeps/unix/sysv/linux/s390/rtkaio-sysdep.S new file mode 100644 index 0000000..11ee214 --- /dev/null +++ b/rtkaio/sysdeps/unix/sysv/linux/s390/rtkaio-sysdep.S @@ -0,0 +1 @@ +#include <rt-sysdep.S> diff --git a/rtkaio/sysdeps/unix/sysv/linux/sparc/Makefile b/rtkaio/sysdeps/unix/sysv/linux/sparc/Makefile new file mode 100644 index 0000000..ead21fb --- /dev/null +++ b/rtkaio/sysdeps/unix/sysv/linux/sparc/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),rtkaio) +librtkaio-routines += rtkaio-sysdep +endif diff --git a/rtkaio/sysdeps/unix/sysv/linux/sparc/rtkaio-sysdep.c b/rtkaio/sysdeps/unix/sysv/linux/sparc/rtkaio-sysdep.c new file mode 100644 index 0000000..ff0440a --- /dev/null +++ b/rtkaio/sysdeps/unix/sysv/linux/sparc/rtkaio-sysdep.c @@ -0,0 +1 @@ +#include <rt-sysdep.c> diff --git a/rtkaio/sysdeps/unix/sysv/linux/sparc/sparc64/Versions b/rtkaio/sysdeps/unix/sysv/linux/sparc/sparc64/Versions new file mode 100644 index 0000000..7443c81 --- /dev/null +++ b/rtkaio/sysdeps/unix/sysv/linux/sparc/sparc64/Versions @@ -0,0 +1,9 @@ +%ifdef HAVE_FORCED_UNWIND +librtkaio { + GLIBC_2.3.3 { + # Changed timer_t. + timer_create; timer_delete; timer_getoverrun; timer_gettime; + timer_settime; + } +} +%endif diff --git a/rtkaio/sysdeps/unix/sysv/linux/syscalls.list b/rtkaio/sysdeps/unix/sysv/linux/syscalls.list new file mode 100644 index 0000000..686b8d5 --- /dev/null +++ b/rtkaio/sysdeps/unix/sysv/linux/syscalls.list @@ -0,0 +1,5 @@ +# File name Caller Syscall name Args Strong name Weak names + +kaio_mq_timedsend - mq_timedsend Ci:ipiip __GI_mq_timedsend mq_timedsend +kaio_mq_timedreceive - mq_timedreceive Ci:ipipp __GI_mq_timedreceive mq_timedreceive +kaio_mq_setattr - mq_getsetattr i:ipp __GI_mq_setattr mq_setattr diff --git a/rtkaio/tst-aio10.c b/rtkaio/tst-aio10.c new file mode 100644 index 0000000..d997301 --- /dev/null +++ b/rtkaio/tst-aio10.c @@ -0,0 +1 @@ +#include <rt/tst-aio10.c> diff --git a/rtkaio/tst-aio8.c b/rtkaio/tst-aio8.c new file mode 100644 index 0000000..9fd46cc --- /dev/null +++ b/rtkaio/tst-aio8.c @@ -0,0 +1 @@ +#include <rt/tst-aio8.c> diff --git a/rtkaio/tst-aio9.c b/rtkaio/tst-aio9.c new file mode 100644 index 0000000..320b05f --- /dev/null +++ b/rtkaio/tst-aio9.c @@ -0,0 +1 @@ +#include <rt/tst-aio9.c> diff --git a/rtkaio/tst-aiod.c b/rtkaio/tst-aiod.c new file mode 100644 index 0000000..d08a7d9 --- /dev/null +++ b/rtkaio/tst-aiod.c @@ -0,0 +1,307 @@ +/* Tests for AIO in librt. + Copyright (C) 1998, 2000, 2002, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. + + The GNU C 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.1 of the License, or (at your option) any later version. + + The GNU C 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 the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <aio.h> +#include <errno.h> +#include <error.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include "tst-aiod.h" + + +/* Prototype for our test function. */ +extern void do_prepare (int argc, char *argv[]); +extern int do_test (int argc, char *argv[]); + +/* We have a preparation function. */ +#define PREPARE do_prepare + +/* We might need a bit longer timeout. */ +#define TIMEOUT 20 /* sec */ + +/* This defines the `main' function and some more. */ +#include <test-skeleton.c> + + +/* These are for the temporary file we generate. */ +char *name; +int fd; +char *tmpbuf; +int blksz = 100; + +void +do_prepare (int argc, char *argv[]) +{ + char name_len; + + name_len = strlen (test_dir); + name = malloc (name_len + sizeof ("/aioXXXXXX")); + mempcpy (mempcpy (name, test_dir, name_len), + "/aioXXXXXX", sizeof ("/aioXXXXXX")); + add_temp_file (name); + + /* Open our test file. */ + fd = mkstemp (name); + if (fd == -1) + error (EXIT_FAILURE, errno, "cannot open test file `%s'", name); + + int sz = set_o_direct (fd); + if (sz != -1) + { + blksz = sz; + printf ("Using O_DIRECT with block size %d\n", blksz); + } +} + + +static int +test_file (const void *buf, size_t size, int fd, const char *msg) +{ + struct stat st; + char *tmp = tmpbuf; + + errno = 0; + if (fstat (fd, &st) < 0) + { + error (0, errno, "%s: failed stat", msg); + return 1; + } + + if (st.st_size != (off_t) size) + { + error (0, errno, "%s: wrong size: %lu, should be %lu", + msg, (unsigned long int) st.st_size, (unsigned long int) size); + return 1; + } + + if (pread (fd, tmp, size, 0) != (ssize_t) size) + { + error (0, errno, "%s: failed pread", msg); + return 1; + } + + if (memcmp (buf, tmp, size) != 0) + { + error (0, errno, "%s: failed comparison", msg); + return 1; + } + + printf ("%s test ok\n", msg); + + return 0; +} + + +static int +do_wait (struct aiocb **cbp, size_t nent, int allowed_err) +{ + int go_on; + size_t cnt; + int result = 0; + + do + { + aio_suspend ((const struct aiocb *const *) cbp, nent, NULL); + go_on = 0; + for (cnt = 0; cnt < nent; ++cnt) + if (cbp[cnt] != NULL) + { + if (aio_error (cbp[cnt]) == EINPROGRESS) + go_on = 1; + else + { + if (aio_return (cbp[cnt]) == -1 + && (allowed_err == 0 + || aio_error (cbp[cnt]) != allowed_err)) + { + error (0, aio_error (cbp[cnt]), "Operation failed\n"); + result = 1; + } + cbp[cnt] = NULL; + } + } + } + while (go_on); + + return result; +} + + +int +do_test (int argc, char *argv[]) +{ + struct aiocb cbs[10]; + struct aiocb cbs_fsync; + struct aiocb *cbp[10]; + struct aiocb *cbp_fsync[1]; + char *buf; + size_t cnt; + int result = 0; + + buf = mmap (NULL, 20 * blksz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + tmpbuf = buf + 10 * blksz; + if (buf == MAP_FAILED) + { + error (0, errno, "mmap failed"); + return 1; + } + + /* Preparation. */ + for (cnt = 0; cnt < 10; ++cnt) + { + cbs[cnt].aio_fildes = fd; + cbs[cnt].aio_reqprio = 0; + cbs[cnt].aio_buf = memset (&buf[cnt * blksz], '0' + cnt, blksz); + cbs[cnt].aio_nbytes = blksz; + cbs[cnt].aio_offset = cnt * blksz; + cbs[cnt].aio_sigevent.sigev_notify = SIGEV_NONE; + + cbp[cnt] = &cbs[cnt]; + } + + /* First a simple test. */ + for (cnt = 10; cnt > 0; ) + if (aio_write (cbp[--cnt]) < 0 && errno == ENOSYS) + { + error (0, 0, "no aio support in this configuration"); + return 0; + } + /* Wait 'til the results are there. */ + result |= do_wait (cbp, 10, 0); + /* Test this. */ + result |= test_file (buf, 10 * blksz, fd, "aio_write"); + + /* Read now as we've written it. */ + memset (buf, '\0', 10 * blksz); + /* Issue the commands. */ + for (cnt = 10; cnt > 0; ) + { + --cnt; + cbp[cnt] = &cbs[cnt]; + aio_read (cbp[cnt]); + } + /* Wait 'til the results are there. */ + result |= do_wait (cbp, 10, 0); + /* Test this. */ + for (cnt = 0; cnt < 10 * blksz; ++cnt) + if (buf[cnt] != '0' + (cnt / blksz)) + { + result = 1; + error (0, 0, "comparison failed for aio_read test"); + break; + } + + if (cnt == 10 * blksz) + puts ("aio_read test ok"); + + /* Remove the test file contents. */ + if (ftruncate (fd, 0) < 0) + { + error (0, errno, "ftruncate failed\n"); + result = 1; + } + + /* Test lio_listio. */ + for (cnt = 0; cnt < 10; ++cnt) + { + cbs[cnt].aio_lio_opcode = LIO_WRITE; + cbp[cnt] = &cbs[cnt]; + } + /* Issue the command. */ + lio_listio (LIO_WAIT, cbp, 10, NULL); + /* ...and immediately test it since we started it in wait mode. */ + result |= test_file (buf, 10 * blksz, fd, "lio_listio (write)"); + + /* Test aio_fsync. */ + cbs_fsync.aio_fildes = fd; + cbs_fsync.aio_sigevent.sigev_notify = SIGEV_NONE; + cbp_fsync[0] = &cbs_fsync; + + /* Remove the test file contents first. */ + if (ftruncate (fd, 0) < 0) + { + error (0, errno, "ftruncate failed\n"); + result = 1; + } + + /* Write again. */ + for (cnt = 10; cnt > 0; ) + aio_write (cbp[--cnt]); + + if (aio_fsync (O_SYNC, &cbs_fsync) < 0) + { + error (0, errno, "aio_fsync failed\n"); + result = 1; + } + result |= do_wait (cbp_fsync, 1, 0); + + /* ...and test since all data should be on disk now. */ + result |= test_file (buf, 10 * blksz, fd, "aio_fsync (aio_write)"); + + /* Test aio_cancel. */ + /* Remove the test file contents first. */ + if (ftruncate (fd, 0) < 0) + { + error (0, errno, "ftruncate failed\n"); + result = 1; + } + + /* Write again. */ + for (cnt = 10; cnt > 0; ) + aio_write (cbp[--cnt]); + + /* Cancel all requests. */ + if (aio_cancel (fd, NULL) == -1) + printf ("aio_cancel (fd, NULL) cannot cancel anything\n"); + + result |= do_wait (cbp, 10, ECANCELED); + + /* Another test for aio_cancel. */ + /* Remove the test file contents first. */ + if (ftruncate (fd, 0) < 0) + { + error (0, errno, "ftruncate failed\n"); + result = 1; + } + + /* Write again. */ + for (cnt = 10; cnt > 0; ) + { + --cnt; + cbp[cnt] = &cbs[cnt]; + aio_write (cbp[cnt]); + } + puts ("finished3"); + + /* Cancel all requests. */ + for (cnt = 10; cnt > 0; ) + if (aio_cancel (fd, cbp[--cnt]) == -1) + /* This is not an error. The request can simply be finished. */ + printf ("aio_cancel (fd, cbp[%Zd]) cannot be canceled\n", cnt); + puts ("finished2"); + + result |= do_wait (cbp, 10, ECANCELED); + + puts ("finished"); + + return result; +} diff --git a/rtkaio/tst-aiod.h b/rtkaio/tst-aiod.h new file mode 100644 index 0000000..57f0e48 --- /dev/null +++ b/rtkaio/tst-aiod.h @@ -0,0 +1,52 @@ +/* Tests for AIO in librt. + Copyright (C) 1998, 2000, 2002, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. + + The GNU C 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.1 of the License, or (at your option) any later version. + + The GNU C 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 the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <fcntl.h> +#include <sys/mman.h> +#include <unistd.h> + +static int +set_o_direct (int fd) +{ + int ret = -1; +#ifdef O_DIRECT + if (fcntl (fd, F_SETFL, fcntl (fd, F_GETFL) | O_DIRECT) >= 0) + { + int pgsz = sysconf (_SC_PAGESIZE); + char *buf = mmap (NULL, 16 * pgsz, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (buf != MAP_FAILED) + { + memset (buf, 0, 16 * pgsz); + for (int sz = 256; sz <= 16 * pgsz; sz *= 2) + if (write (fd, buf, sz) > 0) + { + ret = sz; + break; + } + ftruncate64 (fd, 0); + munmap (buf, 16 * pgsz); + } + if (ret < 0) + fcntl (fd, F_SETFL, fcntl (fd, F_GETFL) & ~O_DIRECT); + } +#endif + return ret; +} diff --git a/rtkaio/tst-aiod2.c b/rtkaio/tst-aiod2.c new file mode 100644 index 0000000..a17e9e8 --- /dev/null +++ b/rtkaio/tst-aiod2.c @@ -0,0 +1,113 @@ +/* Test for notification mechanism in lio_listio. + Copyright (C) 2000, 2002, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000. + + The GNU C 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.1 of the License, or (at your option) any later version. + + The GNU C 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 the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <aio.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include "tst-aiod.h" + +int flag; + + +static void +thrfct (sigval_t arg) +{ + flag = 1; +} + + +static int +do_test (int argc, char *argv[]) +{ + char name[] = "/tmp/aio2.XXXXXX"; + int fd; + struct aiocb *arr[1]; + struct aiocb cb; + static const char buf[] = "Hello World\n"; + + fd = mkstemp (name); + if (fd == -1) + { + printf ("cannot open temp name: %m\n"); + return 1; + } + + unlink (name); + + arr[0] = &cb; + + void *p; + int sz = set_o_direct (fd); + if (sz != -1) + { + int err = posix_memalign (&p, sz, sz); + if (err) + { + errno = err; + printf ("cannot allocate memory: %m\n"); + return 1; + } + memcpy (p, buf, sizeof (buf) - 1); + memset (p + sizeof (buf) - 1, ' ', sz - sizeof (buf) + 1); + printf ("Using O_DIRECT with block size %d\n", sz); + } + else + { + p = (void *) buf; + sz = sizeof (buf) - 1; + } + + cb.aio_fildes = fd; + cb.aio_lio_opcode = LIO_WRITE; + cb.aio_reqprio = 0; + cb.aio_buf = p; + cb.aio_nbytes = sz; + cb.aio_offset = 0; + cb.aio_sigevent.sigev_notify = SIGEV_THREAD; + cb.aio_sigevent.sigev_notify_function = thrfct; + cb.aio_sigevent.sigev_notify_attributes = NULL; + cb.aio_sigevent.sigev_value.sival_ptr = NULL; + + if (lio_listio (LIO_WAIT, arr, 1, NULL) < 0) + { + if (errno == ENOSYS) + { + puts ("no aio support in this configuration"); + return 0; + } + printf ("lio_listio failed: %m\n"); + return 1; + } + + if (flag != 0) + { + puts ("thread created, should not have happened"); + return 1; + } + + puts ("all OK"); + + return 0; +} + +#include "../test-skeleton.c" diff --git a/rtkaio/tst-aiod3.c b/rtkaio/tst-aiod3.c new file mode 100644 index 0000000..545a6d4 --- /dev/null +++ b/rtkaio/tst-aiod3.c @@ -0,0 +1,118 @@ +/* Test for notification mechanism in lio_listio. + Copyright (C) 2000, 2002, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C 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.1 of the License, or (at your option) any later version. + + The GNU C 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 the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <aio.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include "tst-aiod.h" + +int flag; + + +static void +thrfct (sigval_t arg) +{ + flag = 1; +} + + +static int +do_test (int argc, char *argv[]) +{ + char name[] = "/tmp/aio3.XXXXXX"; + int fd; + struct aiocb *arr[1]; + struct aiocb cb; + static const char buf[] = "Hello World\n"; + + fd = mkstemp (name); + if (fd == -1) + { + printf ("cannot open temp name: %m\n"); + return 1; + } + + unlink (name); + + arr[0] = &cb; + + void *p; + int sz = set_o_direct (fd); + if (sz != -1) + { + int err = posix_memalign (&p, sz, sz); + if (err) + { + errno = err; + printf ("cannot allocate memory: %m\n"); + return 1; + } + memcpy (p, buf, sizeof (buf) - 1); + memset (p + sizeof (buf) - 1, ' ', sz - sizeof (buf) + 1); + printf ("Using O_DIRECT with block size %d\n", sz); + } + else + { + p = (void *) buf; + sz = sizeof (buf) - 1; + } + + cb.aio_fildes = fd; + cb.aio_lio_opcode = LIO_WRITE; + cb.aio_reqprio = 0; + cb.aio_buf = p; + cb.aio_nbytes = sz; + cb.aio_offset = 0; + cb.aio_sigevent.sigev_notify = SIGEV_THREAD; + cb.aio_sigevent.sigev_notify_function = thrfct; + cb.aio_sigevent.sigev_notify_attributes = NULL; + cb.aio_sigevent.sigev_value.sival_ptr = NULL; + + if (lio_listio (LIO_NOWAIT, arr, 1, NULL) < 0) + { + if (errno == ENOSYS) + { + puts ("no aio support in this configuration"); + return 0; + } + printf ("lio_listio failed: %m\n"); + return 1; + } + + if (aio_suspend ((const struct aiocb *const *) arr, 1, NULL) < 0) + { + printf ("aio_suspend failed: %m\n"); + return 1; + } + + if (flag != 0) + { + puts ("thread created, should not have happened"); + return 1; + } + + puts ("all OK"); + + return 0; +} + +#include "../test-skeleton.c" diff --git a/rtkaio/tst-aiod4.c b/rtkaio/tst-aiod4.c new file mode 100644 index 0000000..d9ce18a --- /dev/null +++ b/rtkaio/tst-aiod4.c @@ -0,0 +1,182 @@ +/* Test for completion signal handling. + Copyright (C) 2000, 2001, 2002, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C 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.1 of the License, or (at your option) any later version. + + The GNU C 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 the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <aio.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include "tst-aiod.h" + +/* We might need a bit longer timeout. */ +#define TIMEOUT 10 /* sec */ + +int my_signo; + +volatile sig_atomic_t flag; + + +static void +sighandler (const int signo) +{ + flag = signo; +} + +static int +wait_flag (void) +{ + while (flag == 0) + { + puts ("Sleeping..."); + sleep (1); + } + + if (flag != my_signo) + { + printf ("signal handler received wrong signal, flag is %d\n", flag); + return 1; + } + + return 0; +} + +#ifndef SIGRTMIN +# define SIGRTMIN -1 +# define SIGRTMAX -1 +#endif + +static int +do_test (int argc, char *argv[]) +{ + char name[] = "/tmp/aio4.XXXXXX"; + int fd; + struct aiocb *arr[1]; + struct aiocb cb; + static const char buf[] = "Hello World\n"; + struct aioinit init = {10, 20, 0}; + struct sigaction sa; + struct sigevent ev; + + if (SIGRTMIN == -1) + { + printf ("RT signals not supported.\n"); + return 0; + } + + /* Select a signal from the middle of the available choices... */ + my_signo = (SIGRTMAX + SIGRTMIN) / 2; + + fd = mkstemp (name); + if (fd == -1) + { + printf ("cannot open temp name: %m\n"); + return 1; + } + + unlink (name); + + /* Test also aio_init. */ + aio_init (&init); + + arr[0] = &cb; + + void *p; + int sz = set_o_direct (fd); + if (sz != -1) + { + int err = posix_memalign (&p, sz, sz); + if (err) + { + errno = err; + printf ("cannot allocate memory: %m\n"); + return 1; + } + memcpy (p, buf, sizeof (buf) - 1); + memset (p + sizeof (buf) - 1, ' ', sz - sizeof (buf) + 1); + printf ("Using O_DIRECT with block size %d\n", sz); + } + else + { + p = (void *) buf; + sz = sizeof (buf) - 1; + } + + cb.aio_fildes = fd; + cb.aio_lio_opcode = LIO_WRITE; + cb.aio_reqprio = 0; + cb.aio_buf = p; + cb.aio_nbytes = sz; + cb.aio_offset = 0; + cb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; + cb.aio_sigevent.sigev_notify_function = NULL; + cb.aio_sigevent.sigev_notify_attributes = NULL; + cb.aio_sigevent.sigev_signo = my_signo; + cb.aio_sigevent.sigev_value.sival_ptr = NULL; + + ev.sigev_notify = SIGEV_SIGNAL; + ev.sigev_notify_function = NULL; + ev.sigev_notify_attributes = NULL; + ev.sigev_signo = my_signo; + + sa.sa_handler = sighandler; + sigemptyset (&sa.sa_mask); + sa.sa_flags = SA_RESTART; + + if (sigaction (my_signo, &sa, NULL) < 0) + { + printf ("sigaction failed: %m\n"); + return 1; + } + + flag = 0; + /* First use aio_write. */ + if (aio_write (arr[0]) < 0) + { + if (errno == ENOSYS) + { + puts ("no aio support in this configuration"); + return 0; + } + printf ("aio_write failed: %m\n"); + return 1; + } + + if (wait_flag ()) + return 1; + + puts ("aio_write OK"); + + flag = 0; + /* Again with lio_listio. */ + if (lio_listio (LIO_NOWAIT, arr, 1, &ev) < 0) + { + printf ("lio_listio failed: %m\n"); + return 1; + } + + if (wait_flag ()) + return 1; + + puts ("all OK"); + + return 0; +} + +#include "../test-skeleton.c" diff --git a/rtkaio/tst-aiod5.c b/rtkaio/tst-aiod5.c new file mode 100644 index 0000000..780f1b6 --- /dev/null +++ b/rtkaio/tst-aiod5.c @@ -0,0 +1,152 @@ +/* Test for completion thread handling. + Copyright (C) 2000, 2002, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C 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.1 of the License, or (at your option) any later version. + + The GNU C 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 the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <aio.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include "tst-aiod.h" + +/* We might need a bit longer timeout. */ +#define TIMEOUT 10 /* sec */ + +#define MY_SIVAL 27 + +volatile sig_atomic_t flag; + + +static void +callback (sigval_t s) +{ + flag = s.sival_int; +} + +static int +wait_flag (void) +{ + while (flag == 0) + { + puts ("Sleeping..."); + sleep (1); + } + + if (flag != MY_SIVAL) + { + printf ("signal handler received wrong signal, flag is %d\n", flag); + return 1; + } + + return 0; +} + + +static int +do_test (int argc, char *argv[]) +{ + char name[] = "/tmp/aio5.XXXXXX"; + int fd; + struct aiocb *arr[1]; + struct aiocb cb; + static const char buf[] = "Hello World\n"; + struct sigevent ev; + + fd = mkstemp (name); + if (fd == -1) + { + printf ("cannot open temp name: %m\n"); + return 1; + } + + unlink (name); + + arr[0] = &cb; + + void *p; + int sz = set_o_direct (fd); + if (sz != -1) + { + int err = posix_memalign (&p, sz, sz); + if (err) + { + errno = err; + printf ("cannot allocate memory: %m\n"); + return 1; + } + memcpy (p, buf, sizeof (buf) - 1); + memset (p + sizeof (buf) - 1, ' ', sz - sizeof (buf) + 1); + printf ("Using O_DIRECT with block size %d\n", sz); + } + else + { + p = (void *) buf; + sz = sizeof (buf) - 1; + } + + cb.aio_fildes = fd; + cb.aio_lio_opcode = LIO_WRITE; + cb.aio_reqprio = 0; + cb.aio_buf = p; + cb.aio_nbytes = sz; + cb.aio_offset = 0; + cb.aio_sigevent.sigev_notify = SIGEV_THREAD; + cb.aio_sigevent.sigev_notify_function = callback; + cb.aio_sigevent.sigev_notify_attributes = NULL; + cb.aio_sigevent.sigev_value.sival_int = MY_SIVAL; + + ev.sigev_notify = SIGEV_THREAD; + ev.sigev_notify_function = callback; + ev.sigev_notify_attributes = NULL; + ev.sigev_value.sival_int = MY_SIVAL; + + /* First use aio_write. */ + if (aio_write (arr[0]) < 0) + { + if (errno == ENOSYS) + { + puts ("no aio support in this configuration"); + return 0; + } + printf ("aio_write failed: %m\n"); + return 1; + } + + if (wait_flag ()) + return 1; + + puts ("aio_write OK"); + + flag = 0; + /* Again with lio_listio. */ + if (lio_listio (LIO_NOWAIT, arr, 1, &ev) < 0) + { + printf ("lio_listio failed: %m\n"); + return 1; + } + + if (wait_flag ()) + return 1; + + puts ("all OK"); + + return 0; +} + +#include "../test-skeleton.c" diff --git a/rtkaio/tst-aiod64.c b/rtkaio/tst-aiod64.c new file mode 100644 index 0000000..0f0a458 --- /dev/null +++ b/rtkaio/tst-aiod64.c @@ -0,0 +1,308 @@ +/* Tests for 64bit AIO in librt. + Copyright (C) 1998, 1999, 2000, 2002, 2006 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. + + The GNU C 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.1 of the License, or (at your option) any later version. + + The GNU C 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 the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define _LARGEFILE_SOURCE 1 +#include <aio.h> +#include <errno.h> +#include <error.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include "tst-aiod.h" + + +/* Prototype for our test function. */ +extern void do_prepare (int argc, char *argv[]); +extern int do_test (int argc, char *argv[]); + +/* We have a preparation function. */ +#define PREPARE do_prepare + +/* We might need a bit longer timeout. */ +#define TIMEOUT 20 /* sec */ + +/* This defines the `main' function and some more. */ +#include <test-skeleton.c> + + +/* These are for the temporary file we generate. */ +char *name; +int fd; +char *tmpbuf; +int blksz = 100; + +void +do_prepare (int argc, char *argv[]) +{ + char name_len; + + name_len = strlen (test_dir); + name = malloc (name_len + sizeof ("/aioXXXXXX")); + mempcpy (mempcpy (name, test_dir, name_len), + "/aioXXXXXX", sizeof ("/aioXXXXXX")); + add_temp_file (name); + + /* Open our test file. */ + fd = mkstemp (name); + if (fd == -1) + error (EXIT_FAILURE, errno, "cannot open test file `%s'", name); + + int sz = set_o_direct (fd); + if (sz != -1) + { + blksz = sz; + printf ("Using O_DIRECT with block size %d\n", blksz); + } +} + + +static int +test_file (const void *buf, size_t size, int fd, const char *msg) +{ + struct stat st; + char *tmp = tmpbuf; + + errno = 0; + if (fstat (fd, &st) < 0) + { + error (0, errno, "%s: failed stat", msg); + return 1; + } + + if (st.st_size != (off_t) size) + { + error (0, errno, "%s: wrong size: %lu, should be %lu", + msg, (unsigned long int) st.st_size, (unsigned long int) size); + return 1; + } + + if (pread (fd, tmp, size, 0) != (ssize_t) size) + { + error (0, errno, "%s: failed pread", msg); + return 1; + } + + if (memcmp (buf, tmp, size) != 0) + { + error (0, errno, "%s: failed comparison", msg); + return 1; + } + + printf ("%s test ok\n", msg); + + return 0; +} + + +static int +do_wait (struct aiocb64 **cbp, size_t nent, int allowed_err) +{ + int go_on; + size_t cnt; + int result = 0; + + do + { + aio_suspend64 ((const struct aiocb64 *const *) cbp, nent, NULL); + go_on = 0; + for (cnt = 0; cnt < nent; ++cnt) + if (cbp[cnt] != NULL) + { + if (aio_error64 (cbp[cnt]) == EINPROGRESS) + go_on = 1; + else + { + if (aio_return64 (cbp[cnt]) == -1 + && (allowed_err == 0 + || aio_error64 (cbp[cnt]) != allowed_err)) + { + error (0, aio_error64 (cbp[cnt]), "Operation failed\n"); + result = 1; + } + cbp[cnt] = NULL; + } + } + } + while (go_on); + + return result; +} + + +int +do_test (int argc, char *argv[]) +{ + struct aiocb64 cbs[10]; + struct aiocb64 cbs_fsync; + struct aiocb64 *cbp[10]; + struct aiocb64 *cbp_fsync[1]; + char *buf; + size_t cnt; + int result = 0; + + buf = mmap (NULL, 20 * blksz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + tmpbuf = buf + 10 * blksz; + if (buf == MAP_FAILED) + { + error (0, errno, "mmap failed"); + return 1; + } + + /* Preparation. */ + for (cnt = 0; cnt < 10; ++cnt) + { + cbs[cnt].aio_fildes = fd; + cbs[cnt].aio_reqprio = 0; + cbs[cnt].aio_buf = memset (&buf[cnt * blksz], '0' + cnt, blksz); + cbs[cnt].aio_nbytes = blksz; + cbs[cnt].aio_offset = cnt * blksz; + cbs[cnt].aio_sigevent.sigev_notify = SIGEV_NONE; + + cbp[cnt] = &cbs[cnt]; + } + + /* First a simple test. */ + for (cnt = 10; cnt > 0; ) + if (aio_write64 (cbp[--cnt]) < 0 && errno == ENOSYS) + { + error (0, 0, "no aio support in this configuration"); + return 0; + } + /* Wait 'til the results are there. */ + result |= do_wait (cbp, 10, 0); + /* Test this. */ + result |= test_file (buf, 10 * blksz, fd, "aio_write"); + + /* Read now as we've written it. */ + memset (buf, '\0', 10 * blksz); + /* Issue the commands. */ + for (cnt = 10; cnt > 0; ) + { + --cnt; + cbp[cnt] = &cbs[cnt]; + aio_read64 (cbp[cnt]); + } + /* Wait 'til the results are there. */ + result |= do_wait (cbp, 10, 0); + /* Test this. */ + for (cnt = 0; cnt < 10 * blksz; ++cnt) + if (buf[cnt] != '0' + (cnt / blksz)) + { + result = 1; + error (0, 0, "comparison failed for aio_read test"); + break; + } + + if (cnt == 10 * blksz) + puts ("aio_read test ok"); + + /* Remove the test file contents. */ + if (ftruncate64 (fd, 0) < 0) + { + error (0, errno, "ftruncate failed\n"); + result = 1; + } + + /* Test lio_listio. */ + for (cnt = 0; cnt < 10; ++cnt) + { + cbs[cnt].aio_lio_opcode = LIO_WRITE; + cbp[cnt] = &cbs[cnt]; + } + /* Issue the command. */ + lio_listio64 (LIO_WAIT, cbp, 10, NULL); + /* ...and immediately test it since we started it in wait mode. */ + result |= test_file (buf, 10 * blksz, fd, "lio_listio (write)"); + + /* Test aio_fsync. */ + cbs_fsync.aio_fildes = fd; + cbs_fsync.aio_sigevent.sigev_notify = SIGEV_NONE; + cbp_fsync[0] = &cbs_fsync; + + /* Remove the test file contents first. */ + if (ftruncate64 (fd, 0) < 0) + { + error (0, errno, "ftruncate failed\n"); + result = 1; + } + + /* Write again. */ + for (cnt = 10; cnt > 0; ) + aio_write64 (cbp[--cnt]); + + if (aio_fsync64 (O_SYNC, &cbs_fsync) < 0) + { + error (0, errno, "aio_fsync failed\n"); + result = 1; + } + result |= do_wait (cbp_fsync, 1, 0); + + /* ...and test since all data should be on disk now. */ + result |= test_file (buf, 10 * blksz, fd, "aio_fsync (aio_write)"); + + /* Test aio_cancel. */ + /* Remove the test file contents first. */ + if (ftruncate64 (fd, 0) < 0) + { + error (0, errno, "ftruncate failed\n"); + result = 1; + } + + /* Write again. */ + for (cnt = 10; cnt > 0; ) + aio_write64 (cbp[--cnt]); + + /* Cancel all requests. */ + if (aio_cancel64 (fd, NULL) == -1) + printf ("aio_cancel64 (fd, NULL) cannot cancel anything\n"); + + result |= do_wait (cbp, 10, ECANCELED); + + /* Another test for aio_cancel. */ + /* Remove the test file contents first. */ + if (ftruncate64 (fd, 0) < 0) + { + error (0, errno, "ftruncate failed\n"); + result = 1; + } + + /* Write again. */ + for (cnt = 10; cnt > 0; ) + { + --cnt; + cbp[cnt] = &cbs[cnt]; + aio_write64 (cbp[cnt]); + } + puts ("finished3"); + + /* Cancel all requests. */ + for (cnt = 10; cnt > 0; ) + if (aio_cancel64 (fd, cbp[--cnt]) == -1) + /* This is not an error. The request can simply be finished. */ + printf ("aio_cancel64 (fd, cbp[%Zd]) cannot be canceled\n", cnt); + puts ("finished2"); + + result |= do_wait (cbp, 10, ECANCELED); + + puts ("finished"); + + return result; +} diff --git a/rtkaio/tst-clock2.c b/rtkaio/tst-clock2.c new file mode 100644 index 0000000..7d3b7b9 --- /dev/null +++ b/rtkaio/tst-clock2.c @@ -0,0 +1 @@ +#include <rt/tst-clock2.c> diff --git a/rtkaio/tst-cpuclock1.c b/rtkaio/tst-cpuclock1.c new file mode 100644 index 0000000..9d4ca46 --- /dev/null +++ b/rtkaio/tst-cpuclock1.c @@ -0,0 +1 @@ +#include <rt/tst-cpuclock1.c> diff --git a/rtkaio/tst-cpuclock2.c b/rtkaio/tst-cpuclock2.c new file mode 100644 index 0000000..4967d2d --- /dev/null +++ b/rtkaio/tst-cpuclock2.c @@ -0,0 +1 @@ +#include <rt/tst-cpuclock2.c> diff --git a/rtkaio/tst-cputimer1.c b/rtkaio/tst-cputimer1.c new file mode 100644 index 0000000..2ed6d55 --- /dev/null +++ b/rtkaio/tst-cputimer1.c @@ -0,0 +1 @@ +#include <rt/tst-cputimer1.c> diff --git a/rtkaio/tst-cputimer2.c b/rtkaio/tst-cputimer2.c new file mode 100644 index 0000000..f1e200a --- /dev/null +++ b/rtkaio/tst-cputimer2.c @@ -0,0 +1 @@ +#include <rt/tst-cputimer2.c> diff --git a/rtkaio/tst-cputimer3.c b/rtkaio/tst-cputimer3.c new file mode 100644 index 0000000..880edaf6 --- /dev/null +++ b/rtkaio/tst-cputimer3.c @@ -0,0 +1 @@ +#include <rt/tst-cputimer3.c> diff --git a/rtkaio/tst-mqueue8.c b/rtkaio/tst-mqueue8.c new file mode 100644 index 0000000..ca28039 --- /dev/null +++ b/rtkaio/tst-mqueue8.c @@ -0,0 +1 @@ +#include <rt/tst-mqueue8.c> diff --git a/rtkaio/tst-mqueue9.c b/rtkaio/tst-mqueue9.c new file mode 100644 index 0000000..0c5aa2b --- /dev/null +++ b/rtkaio/tst-mqueue9.c @@ -0,0 +1 @@ +#include <rt/tst-mqueue9.c> diff --git a/rtkaio/tst-timer.c b/rtkaio/tst-timer.c new file mode 100644 index 0000000..dab8879 --- /dev/null +++ b/rtkaio/tst-timer.c @@ -0,0 +1 @@ +#include <rt/tst-timer.c> diff --git a/rtkaio/tst-timer5.c b/rtkaio/tst-timer5.c new file mode 100644 index 0000000..e66933c --- /dev/null +++ b/rtkaio/tst-timer5.c @@ -0,0 +1 @@ +#include <rt/tst-timer5.c> |