From: ram@eiffel.com (Raphael Manfredi)
Newsgroups: comp.lang.eiffel
Subject: Re: Eiffel on UNIX
Summary: ISE Eiffel 3 uses sbrk()
Keywords: malloc, sbrk, memory management
Date: 29 Jul 92 17:26:33 GMT
Organization: Interactive Software Engineering, Santa Barbara CA

Quoting ian@cs.man.ac.uk (Ian Cottam) from comp.lang.eiffel:
>Will ISE Eiffel 3 still use the UNIX sbrk call for some memory
>management?  Given that many library functions use malloc
>(even fprintf on the SUNs I belive), should not sbrk be reserved
>for the implementors of (alternative) mallocs?

The sbrk() system call is simply used to ask the kernel more core. The
process receives a new chunk of memory which it can freely use for whatever
purposes. The argument to the system call is a single integer, which represents
the amount of memory wanted. For instance, sbrk(65536) would ask for 64K of
memory, starting at the old break position (which is the return value of the
system call). Note that saying sbrk(-65536) actually gives the memory back
to the kernel, starting at the current break position and releasing the top
64K used (before doing so, it might be a good idea to make sure the process
does not reference anything within that area, or you'll get a nice and clean
memory fault -- core dumped at the next dereference :-).

So sbrk() is a low level system call, which of course is the basis for any
memory management package, as it is is the only way to get core under UNIX
(modulo brk(), but that's another story). No wonder malloc() (a library
function) is built on top of that system call. Usually, malloc() asks for
big chunks of memory via sbrk() and then butchers that memory into small
fragments at the user's request, keeping track of what is allocated.

Very few malloc() will allow you to shrink your process's size by actually
giving some memory back to the kernel, and that seemed a desirable feature for
Eiffel, which can allocate vast amounts of memory at instant t, and then
release it in whole at (t + 1) -- via the garbage collector, naturally.

Furthermore, as you correctly stated it, some library functions do use malloc()
internally to be able to perform correctly. Not only fprintf(), but virtually
any standard I/O routine (on SUNs), or some X widgets, or whatever library
function needs non-static memory. However, Eiffel has no way to control the
way malloc() works, and its allocation scheme may not allow the run-time to
shrink the data space when it could be possible, since it has no way of
knowing who references what. Besides, there could be a huge amount of memory
allocated by "the C side" under malloc() control, and then suddenly freed
without giving Eiffel a chance to use that free memory.

This is why it seemed desirable to write our own memory management scheme on
top of sbrk() (so YES, we do use sbrk() in ISE Eiffel 3), and also provide
a C-compatible malloc() interface in our own run-time, which will override
the system provided malloc during the linking phase and force every external
function using malloc() to use OUR malloc() from the Eiffel run-time (which
has malloc(3X) comparable performances, both in size and time). That should
make no difference at all with respect to the standard malloc() use from C
and makes things easier for the run-time.

To give but a single example, the following is allowed in ISE Eiffel 3 and
will be correctly detected by the garbage collector (otherwise, boom!):

In Eiffel:

	some_object: GENERAL;

	allocated: GENERAL is
			-- Allocated C area
		external
			"C"
		end;
	
	f is do some_object := allocated; end

In C:

	char *allocated()
	{
		return malloc(100);	/* For example */
	}

Of course, this is only an example. The correct way of doing the above would
be to use the POINTER type instead of GENERAL, to avoid any accidental
feature call on something which is certainly not an Eiffel object. But that
is beside the point -- we are talking memory management here.

Having your own malloc buys you a lot.
-- 
Raphael Manfredi <ram@eiffel.com>
Interactive Software Engineering Inc.
270 Storke Road, Suite #7                      / Tel +1 (805) 685-1006 \
Goleta, California 93117, USA                  \ Fax +1 (805) 685-6869 /