(Paul: this is just FYI for now; tested patches will follow eventually in a proper bug report. See https://bugs.debian.org/1002541 for more context.)
On Fri, Jan 21, 2022 at 06:12:51PM +0100, gregor herrmann wrote: > > So t/70future-io.t fails consistently since it is run (0.800-2 and > > 0.801-1). But only on ppc64el. > > And libfuture-io-perl has the same problem: The tests fail on > ppc64el: Both of these issues are a test-only wrong expectation on stdio buffer sizes, which seem to differ on the ppc64el architecture. The attached test program (pardon my C) makes a pair of nonblocking pipes, writes to one end until it's full and then reads from the other end until writes don't block anymore. The output (see below) indicates that on my amd64 host it takes 64kB to fill the pipe, and reading 4kB out is enough to unblock it. This (particularly the 4kB part) is what the tests in libio-async-perl and libfuture-io-perl are expecting. However, on ppc64el it takes 1MB to fill the pipe, and 64kB to unblock it. The tests fail because they only read 4kB out and expect writes to work again. Patches need to go around https://sources.debian.org/src/libfuture-io-perl/0.11-1/lib/Test/Future/IO/Impl.pm/#L302 https://sources.debian.org/src/libio-async-perl/0.801-1/t/70future-io.t/#L59 but I don't have anything finished atm and I'm out of time for now. Note that the test in libio-async-perl also uses the one in Test::Future::IO::Impl, so both fixes are needed to make libio-async-perl pass. amd64: PIPE_BUF: 4096 making nonblocking pipes writing until it blocks wrote 16 * 4096 bytes reading out until write no longer blocks read 1 * 4096 bytes ppc64el (plummer.debian.org): PIPE_BUF: 4096 making nonblocking pipes writing until it blocks wrote 256 * 4096 bytes reading out until write no longer blocks read 16 * 4096 bytes -- Niko Tyni nt...@debian.org
#include <stdio.h> #include <string.h> #include <limits.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> int main(void) { int fds[2]; int i; char r_buf[PIPE_BUF]; char w_buf[PIPE_BUF]; memset(w_buf, 'X', PIPE_BUF); printf("PIPE_BUF: %d\n", PIPE_BUF); printf("making nonblocking pipes\n"); if (pipe(fds)) { perror("pipe"); } if (fcntl(fds[0], F_SETFL, O_NONBLOCK)) perror("fcntl for read handle"); if (fcntl(fds[1], F_SETFL, O_NONBLOCK)) perror("fcntl for write handle"); printf("writing until it blocks\n"); i = 0; while (write(fds[1], w_buf, PIPE_BUF) > 0) { i++; } if (errno != EAGAIN) perror("unexpected write error"); printf("wrote %d * %d bytes\n", i, PIPE_BUF); printf("reading out until write no longer blocks\n"); i = 0; while (write(fds[1], w_buf, PIPE_BUF) < 0) { read(fds[0], r_buf, PIPE_BUF); i++; } printf("read %d * %d bytes\n", i, PIPE_BUF); }