mailing list of musl libc
 help / color / mirror / code / Atom feed
* Powerful new tool for unit tests
@ 2012-08-17 21:06 Rich Felker
  0 siblings, 0 replies; only message in thread
From: Rich Felker @ 2012-08-17 21:06 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 961 bytes --]

Hi all,

I'm attaching a tool I developed last night for use in unit tests,
which led to the detection and fixing of the latest strtod bug. It
provides a function huge_alloc which creates a huge buffer filled with
a given pad byte, but for which all but the first and last few pages
are shared mappings of a common backing. This makes it possible to
test string functions on buffers gigabytes or even terabytes in length
without the need to have that much physical storage available, and
without the minutes or hours of page fault thrashing to instantiate
that much memory.

There are a few issues I'd still like to fix; mainly the allocation
ends up being unpredictably larger than n (due mainly to laziness on
my part), meaning there's no way for the caller to free the mapping.
Anyway, since I may not get around to improving it right away, I'm
going ahead and sharing it with the list as a potential basis for
developing and performing further tests.

Rich

[-- Attachment #2: huge.c --]
[-- Type: text/plain, Size: 1108 bytes --]

#define _POSIX_C_SOURCE 200809L
#include <sys/mman.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

#ifndef PAGE_SIZE
#define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
#endif

#define BLOCK (128*PAGE_SIZE)

void *alloc_huge(size_t n, int c)
{
	char *vm;
	size_t i;
	int fd;
	FILE *f;

	f = tmpfile();
	if (!f) return 0;
	fd = fileno(f);

	if (n & (BLOCK-1)) n = (n & -BLOCK) + BLOCK;

	vm = mmap(0, n, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
	if (vm == MAP_FAILED) goto fail1;

	if (ftruncate(fd, 128*PAGE_SIZE) < 0)
		goto fail2;
	for (i=0; i<n; i+=BLOCK)
		if (mmap(vm+i, BLOCK, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fd, 0) == MAP_FAILED)
			goto fail2;
	if (mmap(vm, BLOCK, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0) == MAP_FAILED)
		goto fail2;
	if (n>BLOCK && mmap(vm+n-2*BLOCK, 2*BLOCK, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0) == MAP_FAILED)
		goto fail2;

	memset(vm, c, BLOCK);
	if (n > BLOCK) {
		memset(vm+BLOCK, c, BLOCK);
		memset(vm+n-2*BLOCK, c, 2*BLOCK);
	}

	return vm;

fail2:
	munmap(vm, n);
fail1:
	fclose(f);
	return 0;
}

[-- Attachment #3: test_huge_strtod.c --]
[-- Type: text/plain, Size: 252 bytes --]

#include <stdio.h>
#include <stdlib.h>

void *alloc_huge(size_t, int);

int main()
{
	//size_t n = 18400;
	size_t n = 3UL<<29;
	char *buf = alloc_huge(n, '1');
	buf[0] = '1';
	buf[1] = '.';
	buf[n-1] = 0;
	printf("%.21g (%zu)\n", strtod(buf, 0), n);
}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2012-08-17 21:06 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-17 21:06 Powerful new tool for unit tests Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).