[comp.realtime] Memory management under VxWorks

hmp@cive.ri.cmu.edu (Henning Pangels) (02/23/90)

The problem of memory fragmentation under vxWorks has been discussed in this
group before, I know, but I'm curious if anyone has found a workaround, if
not an outright solution by now. The general problem I'm seeing is that
frequent use of malloc() and free() leads to more and more fragmentation,
eventually causing an exception when the largest chunk of memory isn't large
enough for a particular operation. While it is somewhat possible to control
explicit use of these calls in application code, they also seem to be used
by many system calls that create and delete system objects like sockets,
semaphores etc. A simple experiment shows that
socket(AF_INET,SOCK_STREAM,0), for example, makes 6 calls to malloc(), using
up a total of 140 bytes. 

Now, if the answer is that you just shouldn't be creating and deleting these
things on a regular basis, what good is having dynamic memory allocation in
the first place? If you knew beforehand exactly what and how many data
objects your application needed, you'd just allocate them statically in your
code.

An approach I've thought about is to create the objects you need when you
need them, and reuse them from then on whenever possible. In a way, that
amounts to writing you own memory manager, which is something an application
really shouldn't have to deal with. 

Another idea is to play with memory pools, but as far as I can see, there is
no way to have system calls allocate memory out of anything but the system
pool.

Do others out there continue to run into this problem, too? How about Wind
River? Any comments or promises of future enhancements in this area?

-- 
Henning Pangels                                   Field Robotics Center
ARPAnet/Internet: hmp@cive.ri.cmu.edu             Robotics Institute
(412) 268-7088                                    Carnegie-Mellon University

ghfeil@white.toronto.edu (Georg Feil) (02/24/90)

Although I'm not a VxWorks user (soon...), I often use a 'secondary'
memory allocator in conjunction with malloc(). The secondary allocator
is very simple and works only with fixed-size memory blocks, so it is fast.
It requests memory from malloc() in fairly large chunks (say 4K). I find 
that most data structures I use require only a single size of memory block 
(e.g.  the size of each entry in a linked list), or it is not too hard to
impose this restriction. Different data structures use different size blocks,
but in each case the secondary allocator only ends up calling malloc() for 
the 'large' memory chunks.  This means less fragmentation and better 
performance all around. 

This won't help in cases where the OS itself calls malloc(), but can eliminate
or reduce the problem for user code. I have C++ code for the secondary
allocator if anyone is interested (it wouldn't be hard to convert to 
regular C). It should also be easy to write from scratch.

Georg.
--
Georg Feil                                 Internet: ghfeil@white.toronto.edu
                                             -or-  : georg@sgl.ists.ca
..if all else fails, try:
{uunet,pyramid,watmath,utzoo}!utcsri!white!ghfeil      (UUCP)
ghfeil%white.toronto.edu@relay.cs.net                  (ARPA)

rlk@telesoft.com (Bob Kitzberger @sation) (02/25/90)

In article <8136@pt.cs.cmu.edu>, hmp@cive.ri.cmu.edu (Henning Pangels) writes:
> 
> An approach I've thought about is to create the objects you need when you
> need them, and reuse them from then on whenever possible. In a way, that
> amounts to writing you own memory manager, which is something an application
> really shouldn't have to deal with. 

This is the rationale behind Ada's "sized collections".  When
specifying an access type (pointer), you can pre-allocate a storage
area in a global heap to use for all dynamic allocations of that type.
Prevents framentation yet allows flexibility in dynamic data
structures.  Provisions are provided to prevent garbage collection on a
collection-by-collection basis.

	.Bob.

-- 
Bob Kitzberger                  Internet : rlk@telesoft.com
TeleSoft                        uucp  :    ...!ucsd.ucsd.edu!telesoft!rlk
5959 Cornerstone Ct. West       at&t  :    (619) 457-2700 x163
San Diego, CA 92121-9891        "Dawn : The time when men of reason go to bed."
------------------------------------------------------------------------------

hopper@ntmtv.UUCP (Ian Hopper) (03/03/90)

From article <8136@pt.cs.cmu.edu>, by hmp@cive.ri.cmu.edu (Henning Pangels):
> 
> no way to have system calls allocate memory out of anything but the system
> pool.
> 

I think a simple solution might go as follows:

VxWorks is a library-based OS.  You generally statically link your application
with the OS into a single executable file/PROM/ROM/Whatever.

Now you look at the Unix linker that you are probably cross-compiliing with.
When a reference to malloc occurs within "VxWorks.a", if a malloc (that you
have written and placed earlier in the linker command line) exists then the
malloc from VxWorks.a gets ignored, and yours get used.

So perhaps:

ld -"crypic" yourApplication.o yourMalloc.o VxWorks.a

might result in the VxWorks OS using your version of malloc.

However, you must now implement malloc *from scratch*.

yourMalloc.c:

char FreeSpace[LARGE_NUMEBER];

char *FreePtr = &FreeSpace;

... and so on ...

Let the net know how things go.

-- 
Ian Hopper		{amdahl.com,ames.arpa,hplabs}!ntmtv!hopper
Northern Telecom Inc.	[Clever comment under construction.]