[comp.unix.questions] Grave misfeature in Unix?

chris@mimsy.UUCP (Chris Torek) (03/27/88)

In article <2413@zyx.UUCP> aj@zyx.UUCP (Arndt Jonasson) writes:
[does lowering the break really release space?  Not in 4.2BSD:]
>Since the BSD system where I tested this can handle a considerable
>number of processes before swap space becomes scarce (swap space
>140 Mbytes), it probably seldom gets to be a problem. On a
>workstation implementation, however, it is quite another matter.

(Note that Berkeley CSRG does not have a 4BSD release for workstations.)

>In the case of BSD, it turns out not to be an ordinary bug or
>oversight; in the source code (vm_drum.c), the following is to be
>found (I hope this is a small enough piece as not to constitute breach
>of any non-disclosure laws):

(It is)

>/*
> * Expand or contract the virtual swap segment mapped
> * by the argument diskmap so as to just allow the given size.
> *
> * FOR NOW CANT RELEASE UNLESS SHRINKING TO ZERO, SINCE PAGEOUTS MAY
> * BE IN PROGRESS... TYPICALLY NEVER SHRINK ANYWAYS, SO DOESNT MATTER MUCH
> */
>vsexpand(vssize, dmp, canshrink)
>
>I consider this a grave misfeature.

It is `typically' not a problem in 4.2BSD (and 4.3BSD) on a Vax;
as you said, these machines tend to have plenty of swap space,
and as the comment says, programs trying to shrink are rare under
4BSD.

>I am interested in knowing whether any Unix implementors have made
>the effort to really release memory, and, what your suggestions are
>to circumvent this problem on systems where they have not.

Probably.  Most likely you saw the problem on a Sun.  I hope that
the new virtual memory system in SunOS 4.0 gets rid of this
restriction (even if few programs now shrink, more are likely to
do so in the future, given that one can unmap regions).  If you
wanted to fix it in 4BSD, it should not be hard.  Simply lock
that process against pageouts and wait for any pageouts that
are then in progress to complete, then go ahead and shrink.  A
particularly lazy implementation might look like this:

vsexpand(...) {
	oldlock = p->p_flag & SULOCK;
	p->p_flag |= SULOCK;	/* lock against further pageouts */
	s = splimp();
	while (p->p_poip)	/* wait for pageouts to complete */
		sleep((caddr_t)&lbolt, PSWAP);
	splx(s);
	... old vsexpand() code ...
	if (!oldlock)
		p->p_flag &= ~SULOCK;
}

This is untested, but will probably work.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris