[comp.unix.wizards] valloc

jwf@munsell.UUCP (03/13/87)

Concerning valloc() and mmap() on a SUN, lee@srs.UUCP (Lee Hasiuk) writes:

> Since malloc() calls sbrk() and the kernel calls swapexpand() in the code
> which handles sbrk(), Sun claims that you need the space on your swap
> device which is as big as the area that you are going to map.  HOWEVER,
> the code for mmap ACTUALLY FREES THE SWAP AREA of the pages which get
> mapped, so that if you map your frame buffer a megabyte at a time, for
> example, you would only need one meg of free swap area to work with.  You
> shouldn't use valloc to do this, however, if you want the areas to be
> contiguous in the virtual address space of your process.  Instead, you
> should call sbrk() yourself.

Unfortunately, SUN 3.0 only supports *one* hole in the user virtual
space, i.e., one range of pages that do not have corresponding swap
space.  So only the first mmap() frees up swap space, subsequent ones do
the requested mapping but leave the swap space allocated.  This is ugly
and not very useful.

The hole (if any) is kept track of in the u. structure:

	struct	hole {		  /* a data space hole (no swap space) */
		int	uh_first; /* first data page in hole */
		int	uh_last;  /* last data page in hole */
	} u_hole;

Note that this is a single structure, not a linked list.  So there is no
mechanism to record a number of holes in the virtual space.
-----
{harvard!adelie,{decvax,allegra,talcott}!encore}!munsell!jwf

Jim Franklin, Eikonix Corp., 23 Crosby Drive, Bedford, MA 01730
Phone: (617) 275-5070 x415

battle@alphard.cs.utk.edu (David Battle) (12/15/89)

Is it safe to free memory allocated with valloc(3) using free(3) on
an Ultrix system?  I ask because valloc adds some to the pointer
returned by malloc in order to allign the returned address.

					-David L. Battle

mike@umn-cs.CS.UMN.EDU (Mike Haertel) (12/16/89)

In article <1509@utkcs2.cs.utk.edu> battle@alphard.cs.utk.edu (David Battle) writes:
>Is it safe to free memory allocated with valloc(3) using free(3) on
>an Ultrix system?  I ask because valloc adds some to the pointer
>returned by malloc in order to allign the returned address.

It may be safe on an Ultrix system.  In general it is not safe.
The "BUGS" section of the 4bsd manual page on valloc says
"vfree() is not implemented."

In 4.3BSD, valloc() is not compatible with free().

If you want your code to be portable, don't use valloc().  If you
use valloc(), don't try to free what you get from it.
-- 
Mike Haertel <mike@ai.mit.edu>
"Everything there is to know about playing the piano can be taught
 in half an hour, I'm convinced of it." -- Glenn Gould

chris@mimsy.umd.edu (Chris Torek) (12/16/89)

In article <1509@utkcs2.cs.utk.edu> battle@alphard.cs.utk.edu
(David Battle) writes:
>Is it safe to free memory allocated with valloc(3) using free(3) on
>an Ultrix system?  I ask because valloc adds some to the pointer
>returned by malloc in order to allign the returned address.

I am not sure about Ultrix specifically (the answer may well depend
on which release of Ultrix is used), but in general, no, it is not
safe.  Valloc is a botch because there is no vfree.

The following is equivalent to valloc on VAXen and Suns but provides
a way to free the memory allocated:

	char *malloc();

	char *get_page_aligned_memory(nbytes, base)
		unsigned nbytes;
		char **base;
	{
		register char *p;
		static int pageround;

		/* this assumes getpagesize() returns a power of 2 */
		if (pageround == 0)
			pageround = getpagesize() - 1;
		p = malloc((nbytes + pageround) & ~pageround);
		if (base != NULL)
			*base = p;
		if (p == NULL)
			return (NULL);
		return ((char *)(((long)p + pageround) & ~pageround));
	}

		usage:
	...
		char *mem, *base;
		mem = get_page_aligned_memory((unsigned)1024, &base);
		if (mem == NULL) ... error ...
		...
		free(base);

Some versions of malloc `happen' to return page-aligned memory already.
If you wish to trust it, you can change get_page_aligned_memory to

	char *get_page_aligned_memory(unsigned nbytes, char **base) {
		return (*base = malloc(nbytes));
	}

or

	#define get_page_aligned_memory(nbytes, base) \
		(*(base) = malloc(nbytes))

and everything will continue to work.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris