Commit 0f7997e2 authored by gregor herrmann's avatar gregor herrmann

Imported Upstream version 4.20

parent 24bf14c7
......@@ -70,7 +70,6 @@ call C<poll_cb> (or other C<aio_> functions) recursively.
This is a simple example that uses the EV module and loads
F</etc/passwd> asynchronously:
use Fcntl;
use EV;
use IO::AIO;
......@@ -170,7 +169,7 @@ use common::sense;
use base 'Exporter';
BEGIN {
our $VERSION = '4.18';
our $VERSION = 4.2;
our @AIO_REQ = qw(aio_sendfile aio_seek aio_read aio_write aio_open aio_close
aio_stat aio_lstat aio_unlink aio_rmdir aio_readdir aio_readdirx
......@@ -605,8 +604,8 @@ Example: stat C</wd> and dump out the data if successful.
fsid => 1810
}
Here is a (likely partial) list of fsid values used by Linux - it is safe
to hardcode these when the $^O is C<linux>:
Here is a (likely partial - send me updates!) list of fsid values used by
Linux - it is safe to hardcode these when C<$^O> is C<linux>:
0x0000adf5 adfs
0x0000adff affs
......@@ -785,7 +784,7 @@ callback.
=item aio_realpath $pathname, $callback->($path)
Asynchronously make the path absolute and resolve any symlinks in
C<$path>. The resulting path only consists of directories (Same as
C<$path>. The resulting path only consists of directories (same as
L<Cwd::realpath>).
This request can be used to get the absolute path of the current working
......@@ -797,6 +796,10 @@ directory by passing it a path of F<.> (a single dot).
Asynchronously rename the object at C<$srcpath> to C<$dstpath>, just as
rename(2) and call the callback with the result code.
On systems that support the AIO::WD working directory abstraction
natively, the case C<[$wd, "."]> as C<$srcpath> is specialcased - instead
of failing, C<rename> is called on the absolute path of C<$wd>.
=item aio_mkdir $pathname, $mode, $callback->($status)
......@@ -810,6 +813,10 @@ request is executed, so do not change your umask.
Asynchronously rmdir (delete) a directory and call the callback with the
result code.
On systems that support the AIO::WD working directory abstraction
natively, the case C<[$wd, "."]> is specialcased - instead of failing,
C<rmdir> is called on the absolute path of C<$wd>.
=item aio_readdir $pathname, $callback->($entries)
......@@ -1183,7 +1190,7 @@ sub aio_scandir($$;$) {
=item aio_rmtree $pathname, $callback->($status)
Delete a directory tree starting (and including) C<$path>, return the
status of the final C<rmdir> only. This is a composite request that
status of the final C<rmdir> only. This is a composite request that
uses C<aio_scandir> to recurse into and rmdir directories, and unlink
everything else.
......@@ -1313,10 +1320,10 @@ This is a rather advanced IO::AIO call, which works best on mmap(2)ed
scalars.
It touches (reads or writes) all memory pages in the specified
range inside the scalar. All caveats and parameters are the same
range inside the scalar. All caveats and parameters are the same
as for C<aio_msync>, above, except for flags, which must be either
C<0> (which reads all pages and ensures they are instantiated) or
C<IO::AIO::MT_MODIFY>, which modifies the memory page s(by reading and
C<IO::AIO::MT_MODIFY>, which modifies the memory pages (by reading and
writing an octet from it, which dirties the page).
=item aio_mlock $scalar, $offset = 0, $length = undef, $callback->($status)
......@@ -1527,7 +1534,7 @@ pathname will use the directory fd on newer systems, and the string on
older systems. Some functions (such as realpath) will always rely on the
string form of the pathname.
So this fucntionality is mainly useful to get some protection against
So this functionality is mainly useful to get some protection against
C<chdir>, to easily get an absolute path out of a relative path for future
reference, and to speed up doing many operations in the same directory
(e.g. when stat'ing all files in a directory).
......@@ -1550,23 +1557,29 @@ request with C<ENOENT>, there is often no need for error checking in the
C<aio_wd> callback, as future requests using the value will fail in the
expected way.
If this call isn't available because your OS lacks it or it couldn't be
detected, it will be emulated by calling C<fsync> instead.
=item IO::AIO::CWD
This is a compiletime constant (object) that represents the process
current working directory.
Specifying this object as working directory object for a pathname is as
if the pathname would be specified directly, without a directory object,
e.g., these calls are functionally identical:
Specifying this object as working directory object for a pathname is as if
the pathname would be specified directly, without a directory object. For
example, these calls are functionally identical:
aio_stat "somefile", sub { ... };
aio_stat [IO::AIO::CWD, "somefile"], sub { ... };
=back
To recover the path associated with an IO::AIO::WD object, you can use
C<aio_realpath>:
aio_realpath $wd, sub {
warn "path is $_[0]\n";
};
Currently, C<aio_statvfs> always, and C<aio_rename> and C<aio_rmdir>
sometimes, fall back to using an absolue path.
=head2 IO::AIO::REQ CLASS
......@@ -1754,16 +1767,19 @@ See C<poll_cb> for an example.
=item IO::AIO::poll_cb
Process some outstanding events on the result pipe. You have to call
this regularly. Returns C<0> if all events could be processed (or there
were no events to process), or C<-1> if it returned earlier for whatever
reason. Returns immediately when no events are outstanding. The amount of
events processed depends on the settings of C<IO::AIO::max_poll_req> and
C<IO::AIO::max_poll_time>.
Process some requests that have reached the result phase (i.e. they have
been executed but the results are not yet reported). You have to call
this "regularly" to finish outstanding requests.
Returns C<0> if all events could be processed (or there were no
events to process), or C<-1> if it returned earlier for whatever
reason. Returns immediately when no events are outstanding. The amount
of events processed depends on the settings of C<IO::AIO::max_poll_req>,
C<IO::AIO::max_poll_time> and C<IO::AIO::max_outstanding>.
If not all requests were processed for whatever reason, the filehandle
will still be ready when C<poll_cb> returns, so normally you don't have to
do anything special to have it called later.
If not all requests were processed for whatever reason, the poll file
descriptor will still be ready when C<poll_cb> returns, so normally you
don't have to do anything special to have it called later.
Apart from calling C<IO::AIO::poll_cb> when the event filehandle becomes
ready, it can be beneficial to call this function from loops which submit
......@@ -1782,10 +1798,11 @@ SYNOPSIS section, at the top of this document):
=item IO::AIO::poll_wait
If there are any outstanding requests and none of them in the result
phase, wait till the result filehandle becomes ready for reading (simply
does a C<select> on the filehandle. This is useful if you want to
synchronously wait for some requests to finish).
Wait until either at least one request is in the result phase or no
requests are outstanding anymore.
This is useful if you want to synchronously wait for some requests to
become ready, without actually handling them.
See C<nreqs> for an example.
......@@ -2098,6 +2115,13 @@ See the C<splice(2)> manpage for details.
Calls the GNU/Linux C<tee(2)> syscall, see it's manpage and the
description for C<IO::AIO::splice> above for details.
=item $actual_size = IO::AIO::pipesize $r_fh[, $new_size]
Attempts to query or change the pipe buffer size. Obviously works only
on pipes, and currently works only on GNU/Linux systems, and fails with
C<-1>/C<ENOSYS> everywhere else. If anybody knows how to influence pipe buffer
size on other systems, drop me a note.
=back
=cut
......
......@@ -155,7 +155,7 @@ static void req_destroy (eio_req *grp);
# define minor(dev) ((dev) & 0xff)
#endif
#ifndef PAGESIZE
#if PAGESIZE <= 0
# define PAGESIZE sysconf (_SC_PAGESIZE)
#endif
......@@ -200,7 +200,7 @@ fiemap (eio_req *req)
goto done;
/* else we have to loop -
* it would be tempting (atcually I tried that first) to just query the
* it would be tempting (actually I tried that first) to just query the
* number of extents needed, but linux often feels like not returning all
* extents, without telling us it left any out. this complicates
* this quite a bit.
......@@ -223,6 +223,9 @@ fiemap (eio_req *req)
if (ioctl (req->int1, FS_IOC_FIEMAP, incmap) < 0)
return;
if (!incmap->fm_mapped_extents)
goto done;
count = fiemap->fm_mapped_extents + incmap->fm_mapped_extents;
fiemap = realloc (fiemap, sizeof (*fiemap) + sizeof (struct fiemap_extent) * count);
errno = ENOMEM;
......@@ -1615,7 +1618,10 @@ aio_group (SV *callback=&PL_sv_undef)
req->type = EIO_GROUP;
PUTBACK;
req_submit (req);
SPAGAIN;
XPUSHs (req_sv (req, aio_grp_stash));
}
......@@ -1869,6 +1875,22 @@ tee (aio_rfd rfh, aio_wfd wfh, size_t length, unsigned int flags)
OUTPUT:
RETVAL
int
pipesize (aio_rfd rfh, int new_size = -1)
PROTOTYPE: $;$
CODE:
#if defined(F_SETPIPE_SZ) && defined(F_GETPIPE_SZ)
if (new_size >= 0)
RETVAL = fcntl (rfh, F_SETPIPE_SZ, new_size);
else
RETVAL = fcntl (rfh, F_GETPIPE_SZ);
#else
errno = ENOSYS;
RETVAL = -1;
#endif
OUTPUT:
RETVAL
void _on_next_submit (SV *cb)
CODE:
SvREFCNT_dec (on_next_submit);
......
Revision history for IO::AIO
TODO: scandir - some dirs mostly contain subdirs - invert logic?
TODO: aio_cptree/mvtree
TODO: reduce condvar fairness: schedule hot-cache-threads first?
TODO: vmsplice? (http://kerneltrap.org/node/6505 http://lwn.net/Articles/178199/)
......@@ -9,6 +10,32 @@ TODO: getxattr etc.?
TODO: F_DUPFD_CLOEXEC
TODO: emulation for splice?
TODO: eio_mmap|mlock|munmap|splice...
TODO: syncfs/sync windows:
TODO: F_SETPIPE_SZ, F_GETPIPE_SZ
http://stackoverflow.com/questions/65170/how-to-get-name-associated-with-open-handle/5286888#5286888
http://blogs.msdn.com/b/adioltean/archive/2005/04/16/408947.aspx
http://msdn.microsoft.com/en-us/library/aa366789%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366789%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364425%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364963%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364996%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364994%28v=vs.85%29.aspx
TODO: extra socket/tcp constants &c?
4.2 Sat Jan 25 01:13:14 CET 2014
- aio_group could corrupt memory because it didn't restore
the stack after req_submit.
- be more careful on (e.g. permission) errors in bin/treescan.
- work around changes in ExtUtils::MakeMaker.
- (libeio) implement aio_realpath for win32.
- (xthread) work around compile time bugs in ptw32.
- added IO::AIO::pipesize.
- (libecb) insignificant update.
4.19 Sun Jan 6 12:47:26 CET 2013
- avoid endless loop in fiemap with some XFS files.
- in aio_rename and aio_rmdir, specialcase the case of [$wd, "."]
and call rename/rmdir instead of renameat/unlinkat.
4.18 Thu Oct 11 07:01:26 CEST 2012
- fix unintended xthread_create by intentionalising it :)
......
......@@ -23,6 +23,7 @@ libeio/xthread.h
libeio/ecb.h
libeio/eio.h
libeio/eio.c
libeio/etp.c
libeio/libeio.m4
libeio/config.h.in
......
......@@ -4,7 +4,7 @@
"unknown"
],
"dynamic_config" : 1,
"generated_by" : "ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.112150",
"generated_by" : "ExtUtils::MakeMaker version 6.86, CPAN::Meta::Converter version 2.133380",
"license" : [
"unknown"
],
......@@ -22,20 +22,20 @@
"prereqs" : {
"build" : {
"requires" : {
"ExtUtils::MakeMaker" : 0
"ExtUtils::MakeMaker" : "0"
}
},
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : 0
"ExtUtils::MakeMaker" : "0"
}
},
"runtime" : {
"requires" : {
"common::sense" : 0
"common::sense" : "0"
}
}
},
"release_status" : "stable",
"version" : "4.18"
"version" : "4.2"
}
......@@ -7,7 +7,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: 0
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.112150'
generated_by: 'ExtUtils::MakeMaker version 6.86, CPAN::Meta::Converter version 2.133380'
license: unknown
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
......@@ -19,4 +19,4 @@ no_index:
- inc
requires:
common::sense: 0
version: 4.18
version: 4.2
......@@ -16,15 +16,20 @@ if ($^O eq "MSWin32") {
*** also, the windows SDK is expected to be installed in /sdk
*** and visual C is expected to be installed in /vc98
***
*** Akternatively, set the INC and LIBS environment variables
*** accordingly before running Makeifle.PL, or you can
*** Alternatively, set the INC and LIBS environment variables
*** accordingly before running Makefile.PL, or you can
*** pass INC and LIBS arguments to Makefile.PL itself.
***
EOF
$INC = "$ENV{INC} -I/sdk/include -I/vc98/include -I/gtk/include";
$LIBS = ["$ENV{LIBS} -L/gtk/lib -lpthreadVC2"];
if ($Config{cc} =~ /(?:^|\\|\/)gcc(?:|.*\.exe)$/) {
$INC = "$ENV{INC} -I/gtk/include";
$LIBS = ["$ENV{LIBS} -L/gtk/lib -lpthreadGC2"];
} else {
$INC = "$ENV{INC} -I/sdk/include -I/vc98/include -I/gtk/include";
$LIBS = ["$ENV{LIBS} -L/gtk/lib -lpthreadVC2"];
}
open my $fh, ">libeio/config.h"
or die "libeio/config.h: $!";
......@@ -95,7 +100,7 @@ my $mm = MM->new({
SUFFIX => '.gz',
},
depend => {
"AIO.c" => "schmorp.h libeio/eio.h libeio/xthread.h libeio/eio.c libeio/config.h",
"AIO.c" => "schmorp.h libeio/eio.h libeio/xthread.h libeio/etp.c libeio/eio.c libeio/config.h",
},
NAME => "IO::AIO",
VERSION_FROM => "AIO.pm",
......@@ -103,7 +108,7 @@ my $mm = MM->new({
LIBS => $LIBS,
EXE_FILES => ["bin/treescan"],
PM => {
'AIO.pm' => '$(INST_LIBDIR)/AIO.pm',
'AIO.pm' => '$(INST_LIB)/IO/AIO.pm',
},
PREREQ_PM => {
"common::sense" => 0,
......
......@@ -66,7 +66,6 @@ DESCRIPTION
This is a simple example that uses the EV module and loads /etc/passwd
asynchronously:
use Fcntl;
use EV;
use IO::AIO;
......@@ -532,8 +531,8 @@ FUNCTIONS
fsid => 1810
}
Here is a (likely partial) list of fsid values used by Linux - it is
safe to hardcode these when the $^O is "linux":
Here is a (likely partial - send me updates!) list of fsid values
used by Linux - it is safe to hardcode these when $^O is "linux":
0x0000adf5 adfs
0x0000adff affs
......@@ -694,7 +693,7 @@ FUNCTIONS
aio_realpath $pathname, $callback->($path)
Asynchronously make the path absolute and resolve any symlinks in
$path. The resulting path only consists of directories (Same as
$path. The resulting path only consists of directories (same as
Cwd::realpath).
This request can be used to get the absolute path of the current
......@@ -704,6 +703,10 @@ FUNCTIONS
Asynchronously rename the object at $srcpath to $dstpath, just as
rename(2) and call the callback with the result code.
On systems that support the AIO::WD working directory abstraction
natively, the case "[$wd, "."]" as $srcpath is specialcased -
instead of failing, "rename" is called on the absolute path of $wd.
aio_mkdir $pathname, $mode, $callback->($status)
Asynchronously mkdir (create) a directory and call the callback with
the result code. $mode will be modified by the umask at the time the
......@@ -713,6 +716,10 @@ FUNCTIONS
Asynchronously rmdir (delete) a directory and call the callback with
the result code.
On systems that support the AIO::WD working directory abstraction
natively, the case "[$wd, "."]" is specialcased - instead of
failing, "rmdir" is called on the absolute path of $wd.
aio_readdir $pathname, $callback->($entries)
Unlike the POSIX call of the same name, "aio_readdir" reads an
entire directory (i.e. opendir + readdir + closedir). The entries
......@@ -944,7 +951,7 @@ FUNCTIONS
inside the scalar. All caveats and parameters are the same as for
"aio_msync", above, except for flags, which must be either 0 (which
reads all pages and ensures they are instantiated) or
"IO::AIO::MT_MODIFY", which modifies the memory page s(by reading
"IO::AIO::MT_MODIFY", which modifies the memory pages (by reading
and writing an octet from it, which dirties the page).
aio_mlock $scalar, $offset = 0, $length = undef, $callback->($status)
......@@ -1155,7 +1162,7 @@ FUNCTIONS
older systems. Some functions (such as realpath) will always rely on the
string form of the pathname.
So this fucntionality is mainly useful to get some protection against
So this functionality is mainly useful to get some protection against
"chdir", to easily get an absolute path out of a relative path for
future reference, and to speed up doing many operations in the same
directory (e.g. when stat'ing all files in a directory).
......@@ -1175,20 +1182,27 @@ FUNCTIONS
checking in the "aio_wd" callback, as future requests using the
value will fail in the expected way.
If this call isn't available because your OS lacks it or it couldn't
be detected, it will be emulated by calling "fsync" instead.
IO::AIO::CWD
This is a compiletime constant (object) that represents the process
current working directory.
Specifying this object as working directory object for a pathname is
as if the pathname would be specified directly, without a directory
object, e.g., these calls are functionally identical:
object. For example, these calls are functionally identical:
aio_stat "somefile", sub { ... };
aio_stat [IO::AIO::CWD, "somefile"], sub { ... };
To recover the path associated with an IO::AIO::WD object, you can use
"aio_realpath":
aio_realpath $wd, sub {
warn "path is $_[0]\n";
};
Currently, "aio_statvfs" always, and "aio_rename" and "aio_rmdir"
sometimes, fall back to using an absolue path.
IO::AIO::REQ CLASS
All non-aggregate "aio_*" functions return an object of this class when
called in non-void context.
......@@ -1349,16 +1363,20 @@ FUNCTIONS
See "poll_cb" for an example.
IO::AIO::poll_cb
Process some outstanding events on the result pipe. You have to call
this regularly. Returns 0 if all events could be processed (or there
were no events to process), or -1 if it returned earlier for
whatever reason. Returns immediately when no events are outstanding.
The amount of events processed depends on the settings of
"IO::AIO::max_poll_req" and "IO::AIO::max_poll_time".
Process some requests that have reached the result phase (i.e. they
have been executed but the results are not yet reported). You have
to call this "regularly" to finish outstanding requests.
If not all requests were processed for whatever reason, the
filehandle will still be ready when "poll_cb" returns, so normally
you don't have to do anything special to have it called later.
Returns 0 if all events could be processed (or there were no events
to process), or -1 if it returned earlier for whatever reason.
Returns immediately when no events are outstanding. The amount of
events processed depends on the settings of "IO::AIO::max_poll_req",
"IO::AIO::max_poll_time" and "IO::AIO::max_outstanding".
If not all requests were processed for whatever reason, the poll
file descriptor will still be ready when "poll_cb" returns, so
normally you don't have to do anything special to have it called
later.
Apart from calling "IO::AIO::poll_cb" when the event filehandle
becomes ready, it can be beneficial to call this function from loops
......@@ -1376,10 +1394,11 @@ FUNCTIONS
cb => \&IO::AIO::poll_cb);
IO::AIO::poll_wait
If there are any outstanding requests and none of them in the result
phase, wait till the result filehandle becomes ready for reading
(simply does a "select" on the filehandle. This is useful if you
want to synchronously wait for some requests to finish).
Wait until either at least one request is in the result phase or no
requests are outstanding anymore.
This is useful if you want to synchronously wait for some requests
to become ready, without actually handling them.
See "nreqs" for an example.
......@@ -1664,6 +1683,12 @@ FUNCTIONS
Calls the GNU/Linux tee(2) syscall, see it's manpage and the
description for "IO::AIO::splice" above for details.
$actual_size = IO::AIO::pipesize $r_fh[, $new_size]
Attempts to query or change the pipe buffer size. Obviously works
only on pipes, and currently works only on GNU/Linux systems, and
fails with -1/"ENOSYS" everywhere else. If anybody knows how to
influence pipe buffer size on other systems, drop me a note.
EVENT LOOP INTEGRATION
It is recommended to use AnyEvent::AIO to integrate IO::AIO
automatically into many event loops:
......
......@@ -3,7 +3,7 @@
# inspired by treescan by Jamie Lokier <jamie@imbolc.ucc.ie>
# about 40% faster than the original version (on my fs and raid :)
use strict;
use common::sense;
use Getopt::Long;
use Time::HiRes ();
use IO::AIO;
......@@ -67,7 +67,7 @@ sub scan {
++$n_dirs;
aio_scandir $path, 8, sub {
my ($dirs, $files) = @_
or warn "$path: $!\n";
or return warn "$path: $!\n";
printfn "", [$path] unless $opt_nodirs;
printfn $path, $files unless $opt_nofiles;
......
/* GENERATED FILE */
/* use ./gendef0 to regenerate this file */
#ifndef ENOSYS
#define ENOSYS 0
#endif
......
......@@ -6,6 +6,11 @@ open STDIN, "<AIO.xs"
open STDOUT, ">def0.h"
or die "def0.h: $!";
print <<EOF;
/* GENERATED FILE */
/* use ./gendef0 to regenerate this file */
EOF
while (<>) {
if (/^\s*const_iv\s*\((\S+)\)\s*$/ || /^\s*const_niv\s*\([^,]+,\s*(\S+)\)\s*$/) {
print "#ifndef $1\n",
......
/*
* libecb - http://software.schmorp.de/pkg/libecb
*
* Copyright (©) 2009-2012 Marc Alexander Lehmann <libecb@schmorp.de>
* Copyright (©) 2009-2013 Marc Alexander Lehmann <libecb@schmorp.de>
* Copyright (©) 2011 Emanuele Giaquinta
* All rights reserved.
*
......@@ -31,7 +31,7 @@
#define ECB_H
/* 16 bits major, 16 bits minor */
#define ECB_VERSION 0x00010002
#define ECB_VERSION 0x00010003
#ifdef _WIN32
typedef signed char int8_t;
......@@ -65,6 +65,15 @@
#endif
#endif
/* work around x32 idiocy by defining proper macros */
#if __amd64 || __x86_64 || _M_AMD64 || _M_X64
#if _ILP32
#define ECB_AMD64_X32 1
#else
#define ECB_AMD64 1
#endif
#endif
/* many compilers define _GNUC_ to some versions but then only implement
* what their idiot authors think are the "more important" extensions,
* causing enormous grief in return for some better fake benchmark numbers.
......@@ -80,12 +89,20 @@
#endif
#endif
#define ECB_C (__STDC__+0) /* this assumes that __STDC__ is either empty or a number */
#define ECB_C99 (__STDC_VERSION__ >= 199901L)
#define ECB_C11 (__STDC_VERSION__ >= 201112L)
#define ECB_CPP (__cplusplus+0)
#define ECB_CPP11 (__cplusplus >= 201103L)
#if ECB_CPP
#define ECB_C 0
#define ECB_STDC_VERSION 0
#else
#define ECB_C 1
#define ECB_STDC_VERSION __STDC_VERSION__
#endif
#define ECB_C99 (ECB_STDC_VERSION >= 199901L)
#define ECB_C11 (ECB_STDC_VERSION >= 201112L)
#if ECB_CPP
#define ECB_EXTERN_C extern "C"
#define ECB_EXTERN_C_BEG ECB_EXTERN_C {
......@@ -127,14 +144,16 @@
#elif defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ \
|| defined __ARM_ARCH_7M__ || defined __ARM_ARCH_7R__
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb" : : : "memory")
#elif __sparc || __sparc__
#elif (__sparc || __sparc__) && !__sparcv8
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad | #StoreStore | #StoreLoad" : : : "memory")
#define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad" : : : "memory")
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("membar #LoadStore | #StoreStore")
#elif defined __s390__ || defined __s390x__
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("bcr 15,0" : : : "memory")
#elif defined __mips__
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
/* GNU/Linux emulates sync on mips1 architectures, so we force its use */
/* anybody else who still uses mips1 is supposed to send in their version, with detection code. */
#define ECB_MEMORY_FENCE __asm__ __volatile__ (".set mips2; sync; .set mips0" : : : "memory")
#elif defined __alpha__
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("mb" : : : "memory")
#elif defined __hppa__
......@@ -142,6 +161,12 @@
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
#elif defined __ia64__
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("mf" : : : "memory")
#elif defined __m68k__
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory")
#elif defined __m88k__
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("tb1 0,%%r0,128" : : : "memory")
#elif defined __sh__
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory")
#endif
#endif
#endif
......@@ -150,6 +175,8 @@
#if ECB_GCC_VERSION(4,7)
/* see comment below (stdatomic.h) about the C11 memory model. */
#define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST)
#define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE)
#define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE)
/* The __has_feature syntax from clang is so misdesigned that we cannot use it
* without risking compile time errors with other compilers. We *could*
......@@ -158,10 +185,18 @@
* #elif defined __clang && __has_feature (cxx_atomic)
* // see comment below (stdatomic.h) about the C11 memory model.
* #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST)
* #define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE)
* #define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE)
*/
#elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__
#define ECB_MEMORY_FENCE __sync_synchronize ()
#elif _MSC_VER >= 1500 /* VC++ 2008 */
/* apparently, microsoft broke all the memory barrier stuff in Visual Studio 2008... */
#pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
#define ECB_MEMORY_FENCE _ReadWriteBarrier (); MemoryBarrier()
#define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier (); MemoryBarrier() /* according to msdn, _ReadBarrier is not a load fence */
#define ECB_MEMORY_FENCE_RELEASE _WriteBarrier (); MemoryBarrier()
#elif _MSC_VER >= 1400 /* VC++ 2005 */
#pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
#define ECB_MEMORY_FENCE _ReadWriteBarrier ()
......@@ -191,6 +226,8 @@
/* for most usages, or gcc and clang have a bug */
/* I *currently* lean towards the latter, and inefficiently implement */
/* all three of ecb's fences as a seq_cst fence */
/* Update, gcc-4.8 generates mfence for all c++ fences, but nothing */
/* for all __atomic_thread_fence's except seq_cst */
#define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst)
#endif
#endif
......@@ -257,6 +294,11 @@ typedef int ecb_bool;
#define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)
#else
#define ecb_attribute(attrlist)
/* possible C11 impl for integral types
typedef struct ecb_is_constant_struct ecb_is_constant_struct;
#define ecb_is_constant(expr) _Generic ((1 ? (struct ecb_is_constant_struct *)0 : (void *)((expr) - (expr)), ecb_is_constant_struct *: 0, default: 1)) */
#define ecb_is_constant(expr) 0
#define ecb_expect(expr,value) (expr)
#define ecb_prefetch(addr,rw,locality)
......@@ -558,16 +600,50 @@ ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () ==
|| defined __alpha__ \
|| defined __hppa__ \
|| defined __ia64__ \
|| defined __m68k__ \
|| defined __m88k__ \
|| defined __sh__ \
|| defined _M_IX86 || defined _M_AMD64 || defined _M_IA64
#define ECB_STDFP 1
#include <string.h> /* for memcpy */
#else
#define ECB_STDFP 0
#include <math.h> /* for frexp*, ldexp* */
#endif
#ifndef ECB_NO_LIBM
#include <math.h> /* for frexp*, ldexp*, INFINITY, NAN */
/* only the oldest of old doesn't have this one. solaris. */
#ifdef INFINITY
#define ECB_INFINITY INFINITY
#else
#define ECB_INFINITY HUGE_VAL
#endif
#ifdef NAN
#define ECB_NAN NAN
#else
#define ECB_NAN ECB_INFINITY
#endif
/* converts an ieee half/binary16 to a float */
ecb_function_ float ecb_binary16_to_float (uint16_t x) ecb_const;
ecb_function_ float
ecb_binary16_to_float (uint16_t x)
{
int e = (x >> 10) & 0x1f;
int m = x & 0x3ff;
float r;
if (!e ) r = ldexpf (m , -24);
else if (e != 31) r = ldexpf (m + 0x400, e - 25);
else if (m ) r = ECB_NAN;
else r = ECB_INFINITY;
return x & 0x8000 ? -r : r;
}
/* convert a float to ieee single/binary32 */
ecb_function_ uint32_t ecb_float_to_binary32 (float x) ecb_const;
ecb_function_ uint32_t
......
This diff is collapsed.
......@@ -256,16 +256,17 @@ struct eio_req
eio_tstamp nv1; /* utime, futime: atime; busy: sleep time */
eio_tstamp nv2; /* utime, futime: mtime */
int type; /* EIO_xxx constant ETP */
int int1; /* all applicable requests: file descriptor; sendfile: output fd; open, msync, mlockall, readdir: flags */
long int2; /* chown, fchown: uid; sendfile: input fd; open, chmod, mkdir, mknod: file mode, seek: whence, sync_file_range, fallocate: flags */
long int3; /* chown, fchown: gid; rename, link: working directory of new name */
int errorno; /* errno value on syscall return */
signed char type;/* EIO_xxx constant ETP */
#if __i386 || __amd64
unsigned char cancelled;
unsigned char cancelled; /* ETP */
#else
sig_atomic_t cancelled;
sig_atomic_t cancelled; /* ETP */
#endif
unsigned char flags; /* private */
......@@ -278,7 +279,7 @@ struct eio_req
EIO_REQ_MEMBERS
eio_req *grp, *grp_prev, *grp_next, *grp_first; /* private */
eio_req *grp, *grp_prev, *grp_next, *grp_first; /* private ETP */
};
/* _private_ request flags */
......
This diff is collapsed.
......@@ -9,7 +9,7 @@ AC_SEARCH_LIBS(