Subject: Re: Sun 3/60 [NetBSD 1.2] keeps on booting.
To: Jari Kokko <jkokko@tnso13.ntc.nokia.com>
From: Mark Newton <newton@atdot.dotat.org>
List: port-sun3
Date: 01/16/1997 20:00:23
Jari Kokko wrote:

 > PS. Short allocator program source follows (use e.g.'limit 10m' before
 > running it!)

I use this one;  unlimit everything before running it for best effect.
Guaranteed to make everything dump core if si_options == 7.

    - mark




/* thrash.c -- mmap a sparse address space then step through it, referencing
            it page by page.

   author:  Mark Newton <newton@atdot.dotat.org>   (actually, I'm not
            entirely sure that I should be putting my name to something
	    like this :-)

   purpose: gain emperical data about how hard your VM system can suck

   usage:   thrash [ bytes ]
	    bytes: size of the mmap()'ed region in bytes (the bigger the
	      better, up to the size of your swap space).

   bugs:   I think this whole program is a bug.  A misfeature at the
	   very least!
*/

#include <sys/types.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <fcntl.h>
#include <ctype.h>
#include <stdio.h>

/* default size of the mapped region in bytes (overridden by a command line
   argument */
#define REGION_SIZE (1024 * 1024 * 300)   /* 300Mb mapped region */

int pagesize;  /* Size of a system page frame */

void usage(void)
{
    fprintf(stderr, "usage: thrash [ size ]\n");
    fprintf(stderr, "\tsize: Size of mapped address space in bytes (default %ld bytes)\n", REGION_SIZE);
}

/* ugly() - Get ugly with the VM system by walking through and touching
            every page in a large mapping.  Paging should go through the
            roof.   This routine never returns, it just keeps ruining our
            day forever.

   parameters: r:  mapped region we're going to thrash
               s:  size of region r
*/
void ugly(void *r, size_t s)
{
    /* We'll keep these in registers because if we don't we'll have to
       keep hitting one of our stack pages to modify them. */
    register char *stick;    /* the stick we'll hit our memory with */
    register unsigned long iter = 0, pages;

    while(1) {
	++iter;
	for (stick = r, pages = 0; (void *)stick < (void *)((size_t)r + s);
				stick += pagesize, pages++) {
	    *stick += 1;  /* reference and modify one byte in every page */
	    printf("pass %ld page %ld (%ld kbytes)          \r", iter, pages,
				(unsigned long)(pages * pagesize / 1024));
	}
    }
    /*NOTREACHED*/
}


void main(int ac, char **av)
{
    void *region;
    size_t mapsize = REGION_SIZE;
    int zero;

    if (ac == 2) {
	if (!isdigit(*av[1])) {
	    fprintf(stderr, "thrash: address space size must be numeric\n");
	    usage();
	    exit(255);
	}

	mapsize = strtoul(av[1], NULL, 0);
    } else if (ac > 2) {
	fprintf(stderr, "thrash: incorrect argument count\n");
	usage();
	exit(255);
    }

    pagesize = getpagesize();
    printf("system page size = %d bytes\n", pagesize);

    printf("attempting to map region of size %ld bytes\n", mapsize);

    if ((zero = open("/dev/zero", O_RDONLY)) == -1) {
	perror("/dev/zero");
	exit(255);
    }

    if ((region = (char *)mmap(NULL, mapsize, PROT_READ | PROT_WRITE,
			MAP_PRIVATE, zero, 0L)) == (void *)-1) {
	perror("mmap()");
	exit(255);
    }

    printf("mapping successful.  now let's get nasty!\n");
    ugly(region, mapsize); 
    /*NOTREACHED*/
}

/*
--------------------------------------------------------------------
I tried an internal modem,                          newton@dotat.org
     but it hurt when I walked.                          Mark Newton
----- Voice: +61-8-83732429 ------------- Data: +61-8-83736006 -----
*/