(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);
}

Reply via email to