Library Memory Standard, 1st Draft
A proposal for high performance libraries
By Phil Frisbie, Jr.
Background
Many programmers use libraries to speed up the development time of applications. The standard C
library is an example of a library used by most C applications. Other third party libraries
provide enhanced functions for such things as graphics, sound, networking, and input. Many
libraries also offer cross platform compatibility so that porting applications is easier.
Libraries vary in quality and functionality, but many have one flaw in common, and that is poor
memory integration with the application. These libraries need to allocate temporary memory, and
they simply use the C run-time (CRT) malloc() and free() functions. While this is fine for many
applications, it can cause problems with high performance applications that use a custom memory
manager (CMM).
High performance applications, such as games, can often receive a large boost in performance by
using a CMM. The CRT memory functions are designed to be general purpose, but the CMM can be
tuned to the type of memory allocations common in the application. The CMM can also include
additional run-time debugging to help quickly track down memory access errors. When an
application using a CMM is linked to a library that uses CRT memory functions, it will not
perform it's best, it can make debugging harder, and it could cause memory leaks if memory is
allocated by the CRT and the application tries to free it using the CMM.
There is another problem unique to Windows when the library is supplied as a DLL. There are two
CRT DLLs that the application or library might dynamically link to (single and multithreaded),
or it may even be statically linked to one of those CRTs. So, there are 16 possible combinations
of application and library run times! The following proposal also eliminates this problem.
The proposal
The Library Memory Standard is composed of three parts:
The API interface between the application and the library.
The optional CMM for use inside the library (the library internal CMM, or LCMM).
Documentation listing the library functions that allocate and free memory.
The API interface provides a way to allow the library to be made aware of the application's CMM.
The API is two functions with three type defines, as prototyped below. (Note: 'xyz' is the prefix
used by the example library, and will be substituted by the library prefix in a real library)
typedef void *(*CMMmalloc)(size_t size); /* CMM malloc implementation */
typedef void (*CMMfree)(void *memblock); /* CMM free implementation */
typedef void *(*CMMrealloc)(void *memblock, size_t size); /* CMM realloc
implementation, optional */
void xyzSetCMM(CMMmalloc m, CMMfree f, CMMrealloc r);
void xyzHint(enum hint);
The first function, xyzSetCMM(), is used to set, or hook, the library's memory allocation
functions. This should be called before any other library function so that all memory
allocations will use the application's CMM. If the application's CMM does not implement the
equivalent to realloc(), then pass NULL so that the library will use it's own realloc() function.
The three function prototypes, CMMmalloc, CMMfree, and CMMrealloc are fully interchangeable with
the ANSI C functions malloc, free, and realloc.
The second function, xyzHint(), is used to control the optional LCMM, and as such it is also
optional. If it is provided, the hints will include at least the following: CONSERVE_MEMORY, and
USE_CMM. CONSERVE_MEMORY will disable the use of the LCMM, and USE_CMM will enable it. USE_CMM
can be used with or without xyzSetCMM. If the application does not have a CMM, then the LCMM will
boost the performance of the library, but even if the application does have a CMM, it may not
work well for the library. The LCMM will cause more memory to be allocated to the library, so
performance testing should be done to see if the performance boost is worth the extra memory
usage.
The library code needed to implement the LCMM is beyond the scope of this proposal. If it is
provided, it should be highly tuned to the needs of the library.
The last item, the documentation listing the library functions that allocate and free memory, is
the easiest part, but still very important to the application programmer. This documentation
should at least list which functions allocate and/or free memory. The approximate amount of
memory allocated could also be useful in cases where the library will be using the application's
CMM. The application's CMM could then be tuned for the common allocation sizes needed by the
library.
Conclusion
These guidelines are designed to make libraries not only easier to use, but faster and better
documented. They are not intentionally biased towards any operating system, compiler, or library
type. Although my examples are specific to C applications and libraries, these guidelines can be
adapted to any language that supports allocating and freeing memory dynamically.
Comments and suggestions are welcome, and these guidelines will be updated accordingly. Send all
comments to Phil Frisbie, Jr..