mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Vmalloc is incompatible with Cygwin, but the code to disable it on Cygwin did not work properly, somehow causing the build to freeze at a seemingly unrelated point (i.e., when iffe feature tests attempt to write to sfstdout). Vmalloc has wasted my time for the last time, so now it's getting disabled by default even on development builds and you'll have to pass -D_AST_vmalloc in CCFLAGS to enable it for testing purposes. This commit has a few other build tweaks as well. src/lib/libast/features/vmalloc: - tst map_malloc: Remove no-op #if __CYGWIN__ block which was in the #else clause of another #if __CYGWIN__ block. - Output block ('cat{'): - Instead of disabling vmalloc for certain systems, disable it unless _AST_vmalloc is defined. - To disable it, set _AST_std_malloc as well as _std_malloc, just to be sure. src/lib/libast/vmalloc/malloc.c: - Remove ineffective Cygwin special-casing. src/lib/libcmd/vmstate.c: - This is only useful for vmalloc, so do not pointlessly compile it if vmalloc is disabled. src/lib/libast/man/vmalloc.3: - Add deprecation notice. Resolves: https://github.com/ksh93/ksh/issues/360
665 lines
25 KiB
Groff
665 lines
25 KiB
Groff
.fp 5 CW
|
|
.de MW
|
|
\f3\\$1\fP
|
|
..
|
|
.TH VMALLOC 3 "1 May 1998"
|
|
.SH NAME
|
|
vmalloc \- virtual memory allocation
|
|
.SH SYNOPSIS
|
|
.MW "#include <vmalloc.h>"
|
|
.SS Regions
|
|
.nf
|
|
.MW "Vmalloc_t* vmopen(Vmdisc_t* disc, Vmethod_t* meth, int flags);"
|
|
.MW "int vmclose(Vmalloc_t*);"
|
|
.MW "int vmclear(Vmalloc_t*);"
|
|
.MW "int vmcompact(Vmalloc_t* region);"
|
|
.MW "int vmset(Vmalloc_t* region, int flags, int type);"
|
|
.MW "Vmalloc_t* Vmheap;"
|
|
.MW "Vmdisc_t* vmdisc(Vmalloc_t* region, Vmdisc_t* disc);"
|
|
.MW "Vmalloc_t* vmmopen(char* file, int project, ssize_t size);"
|
|
.MW "Void_t* vmmvalue(Vmalloc_t* vm, int key, Void_t* value, int op);"
|
|
.MW "Void_t* vmmcleanup(Vmalloc_t* vm);"
|
|
.MW "Void_t* vmmaddress(size_t size);"
|
|
.fi
|
|
.SS "Allocation functions"
|
|
.nf
|
|
.MW "Void_t* vmalloc(Vmalloc_t* region, size_t size);"
|
|
.MW "Void_t* vmalign(Vmalloc_t* region, size_t size, size_t align);"
|
|
.MW "Void_t* vmresize(Vmalloc_t* region, Void_t* addr, size_t size, int type);"
|
|
.MW "int vmfree(Vmalloc_t* region, Void_t* addr);"
|
|
.MW "Void_t* vmnewof(Vmalloc_t* region, Void_t* addr, type, size_t n, size_t x);"
|
|
.MW "Void_t* vmoldof(Vmalloc_t* region, Void_t* addr, type, size_t n, size_t x);"
|
|
.MW "Void_t* vmgetmem(Vmalloc_t* region, Void_t* addr, size_t size);"
|
|
.fi
|
|
.SS "Debugging"
|
|
.nf
|
|
.MW "int vmdebug(int);"
|
|
.MW "int vmdbcheck(Vmalloc_t* vm);"
|
|
.MW "int vmdbwatch(Void_t* addr);"
|
|
.MW "static void vmdbwarn(Vmalloc_t*, char* mesg, int n);"
|
|
.fi
|
|
.SS "Profiling"
|
|
.nf
|
|
.MW "void vmprofile(Vmalloc_t* vm, int fd);"
|
|
.fi
|
|
.SS "Information and statistics"
|
|
.nf
|
|
.MW "int vmbusy(Vmalloc_t* region);"
|
|
.MW "Vmalloc_t* vmregion(Void_t* addr);"
|
|
.MW "Void_t* vmsegment(Vmalloc_t* region, Void_t* addr);"
|
|
.MW "int vmwalk(Vmalloc_t* region, int(*walkf)(Vmalloc_t*, Void_t*, size_t, Vmdisc_t*);"
|
|
.MW "long vmaddr(Vmalloc_t* region, Void_t* addr);"
|
|
.MW "long vmsize(Vmalloc_t* region, Void_t* addr);"
|
|
.MW "int vmstat(Vmalloc_t* vm, Vmstat_t* statb);"
|
|
.MW "int vmtrace(int fd);"
|
|
.MW "int vmtrbusy(Vmalloc_t* vm);"
|
|
.MW "Void_t* vmdata(Vmalloc_t* vm);"
|
|
.fi
|
|
.SS "Malloc-compatible functions"
|
|
.nf
|
|
.MW "Void_t* malloc(size_t size);"
|
|
.MW "Void_t* realloc(Void_t* addr, size_t size);"
|
|
.MW "Void_t* calloc(size_t n_obj, size_t s_obj);"
|
|
.MW "int cfree(Void_t* addr);"
|
|
.MW "void free(Void_t* addr);"
|
|
.MW "Void_t* memalign(size_t align, size_t size);"
|
|
.MW "Void_t* valloc(size_t size);"
|
|
.MW "int setregmax(int regmax);"
|
|
.fi
|
|
.SH DEPRECATION NOTICE
|
|
In the 2021 ksh 93u+m distribution, \fIvmalloc\fP(3) was deprecated for
|
|
being unstable and wasteful in comparison to \fImalloc\fP(3) implementations
|
|
that come with modern operating systems.
|
|
By default, the interfaces described here map to the OS's standard
|
|
\fImalloc\fP(3) implementation. \fIvmalloc\fP can be enabled at compile time
|
|
by passing \fB-D_AST_vmalloc\fP in \fBCCFLAGS\fP.
|
|
.SH DESCRIPTION
|
|
These functions for dynamic storage allocation work in
|
|
\fIregions\fP of memory.
|
|
Each region has an \fIallocation method\fP
|
|
for parceling out blocks of storage and a
|
|
\fImemory discipline\fP for obtaining raw space.
|
|
Automatic locking prevents interference by reentrant
|
|
access to a region.
|
|
.PP
|
|
Pointers to space have type \f3Void_t*\fP
|
|
where \f3Void_t\fP is \f3#define\fPd as \f3void\fP if possible, otherwise \f3char\fP.
|
|
Space is counted in type \f3size_t\fP.
|
|
|
|
.ne 4
|
|
.SS Regions
|
|
Regions have type \f3Vmalloc_t\fP.
|
|
Two predefined regions are pointed to by:
|
|
.TP
|
|
.MW Vmheap
|
|
A general-purpose region, with best-fit
|
|
allocation, and system memory discipline \f3Vmdcsystem\fP.
|
|
.PP
|
|
These functions manipulate regions:
|
|
.PP
|
|
.I vmopen
|
|
creates a region with memory discipline \fIdisc\fP,
|
|
allocation method \fImeth\fP,
|
|
and a setting for control \fIflags\fP.
|
|
It returns a pointer to the region on success and \f3NULL\fP on failure.
|
|
The flags, represented by bit values or-ed together, are:
|
|
.TP
|
|
.MW VM_SHARE
|
|
This region may be accessed concurrently by multiple threads or processes.
|
|
.TP
|
|
.MW VM_TRACE
|
|
Place tracing messages for each allocation event
|
|
on the tracing file established by \fIvmtrace\fP.
|
|
.TP
|
|
\f3VM_DBCHECK\fP, \f3VM_DBABORT\fP
|
|
.br
|
|
See \fBDebugging\fP below.
|
|
.PP
|
|
.I vmclose
|
|
closes a \fIregion\fP and releases all associated memory
|
|
according to the region's discipline.
|
|
The first segment obtained from the discipline's
|
|
\f3memoryf\fP function (see `Disciplines' below) will be the last released.
|
|
\fIvmclose\fP returns \-1 on failure and a non-negative value otherwise.
|
|
.PP
|
|
.I vmclear
|
|
frees all allocated blocks in \fIregion\fP regardless of methods.
|
|
It returns \-1 on failure and a non-negative value otherwise.
|
|
.PP
|
|
.I vmcompact
|
|
releases as much of a \fIregion\fP's
|
|
free space to its discipline's \f3memoryf\fP
|
|
function as possible.
|
|
It returns a nonnegative value on success and \-1 on failure.
|
|
.PP
|
|
.I vmset
|
|
adjusts and queries a \fIregion\fP's \fIflags\fP.
|
|
The indicated flags are turned on if \fItype\fP is nonzero, off if zero.
|
|
\fIvmset\fP returns the previous value of all flags.
|
|
Thus, \f3vmset(region,0,0)\fP queries the flags without changing them.
|
|
In addition to the settable flags, one of
|
|
\f3VM_MTBEST\fP, \f3VM_MTDEBUG\fP, \f3VM_MTPROFILE\fP,
|
|
\f3VM_MTPOOL\fP, or \f3VM_MTLAST\fP
|
|
is returned to indicate the method used in creating the \fIregion\fP.
|
|
.PP
|
|
.I vmdisc
|
|
changes the discipline of \fIregion\fP to the given new discipline
|
|
\fIdisc\fP if \fIdisc\fP is not \f3NULL\fP and its \f3memoryf\fP function
|
|
is the same as the current discipline. If the current discipline
|
|
has an \f3exceptf\fP function, it will be called with event \f3VM_DISC\fP.
|
|
This function always returns the current discipline.
|
|
.PP
|
|
.I vmmopen
|
|
creates a region to allocate memory obtained via either
|
|
\fImmap(2)\fP when \fIproject < 0\fP or \fIshmget(2)\fP when \fIproject >= 0\fP.
|
|
The region is built from a single memory segment
|
|
guaranteed to be at least as large as \fIsize\fP.
|
|
When \fIproject >= 0\fP,
|
|
\fIfile\fP and \fIproject\fP are used in a call to \fIftok(3)\fP
|
|
to get a key suitable for getting a shared memory segment via \fIshmget(2)\fP.
|
|
Otherwise, \fIfile\fP is the backing store for the mapped data.
|
|
In this case, not only the region may be used concurrently by different processes,
|
|
it is also persistent. That is, process could even exit, move the file to
|
|
a different but similar machine then restart and open the same
|
|
region to continue working.
|
|
.PP
|
|
Note that Vmalloc can protect concurrent accesses only on region entry and exit
|
|
for memory allocation operations.
|
|
This means that at the time when regions are being opened or closed, there will be no
|
|
protection for the memory segments being attached into or detached from process memory space.
|
|
This limitation has a special impact on \fIvmmopen()\fP as follows.
|
|
.PP
|
|
A shared memory segment opened via \fIvmmopen()\fP corresponds uniquely
|
|
to a combination of the \fIfile\fP and \fIproject\fP parameters.
|
|
Thus, if multiple \fIvmmopen()\fP calls are done in the same process using a
|
|
same combination of \fIfile\fP and \fIproject\fP,
|
|
the joined behavior of such regions will be unpredictable when opening and closing
|
|
are done concurrently with other memory allocation operations.
|
|
Beware that this effect can be subtle with library functions that may attempt
|
|
to create their own memory allocation regions.
|
|
.PP
|
|
.I vmmvalue
|
|
manages pairs of \fIkey\fP and \fIvalue\fP in a region opened via \fIvmopen()\fP.
|
|
If \fIop\fP is \f3VM_MMGET\fP, the value associated with \f3key\fP is returned.
|
|
If \fIop\fP is \f3VM_MMSET\fP, the value associated with \f3key\fP will be
|
|
set to \fIvalue\fP.
|
|
If \fIop\fP is \f3VM_MMADD\fP, the value associated with \f3key\fP will be
|
|
treated as a signed long value to which \f3val\fP (also treated as a signed long value)
|
|
will be added.
|
|
The call always returns the updated data value associated with \fIkey\fP.
|
|
.PP
|
|
.I vmmcleanup
|
|
sets region up to remove backing store or \fIshmid\fP on closing.
|
|
.PP
|
|
.I vmmaddress
|
|
computes an address suitable for attaching a shared memory segment or
|
|
memory mapping a segment of file data of the given \fIsize\fP.
|
|
The address is chosen with hope to minimize collision with other activities
|
|
related to memory such as growth of stack space or space used
|
|
for dynamically linked libraries, etc.
|
|
|
|
.SS "Allocation functions"
|
|
.I vmalloc
|
|
returns a pointer to a block of the requested \fIsize\fP
|
|
in a \fIregion\fP, aligned to the \fIstrictest alignment\fP
|
|
that is suitable for the needs of any basic data type.
|
|
It returns \f3NULL\fP on failure.
|
|
.PP
|
|
.I vmalign
|
|
works like \fIvmalloc\fP, but returns a block aligned to a common
|
|
multiple of \fIalign\fP and the \fIstrictest alignment\fP.
|
|
.PP
|
|
.I vmresize
|
|
attempts to change the length of the block pointed to by
|
|
\fIaddr\fP to the specified \fIsize\fP.
|
|
If that is impossible and \fItype\fP has
|
|
at least one of \f3VM_RSMOVE\fP and \f3VM_RSCOPY\fP,
|
|
a new block is allocated and the old block is freed.
|
|
The bit \f3VM_RSCOPY\fP also causes
|
|
the new block to be initialized with
|
|
as much of the old contents as will fit.
|
|
When a resized block gets larger, the new space will be cleared
|
|
if \fItype\fP has the bit \f3VM_RSZERO\fP.
|
|
\fIvmresize\fP
|
|
returns a pointer to the final block, or \f3NULL\fP on failure.
|
|
If \fIaddr\fP is \f3NULL\fP, \fIvmresize\fP behaves like \fIvmalloc\fP;
|
|
otherwise, if \fIsize\fP is 0, it behaves like \fIvmfree\fP.
|
|
.PP
|
|
.I vmfree
|
|
makes the currently allocated block pointed to by
|
|
\fIaddr\fP available for future allocations in its \fIregion\fP.
|
|
If \fIaddr\fP is \f3NULL\fP, \fIvmfree\fP does nothing.
|
|
It returns \-1 on error, and nonnegative otherwise.
|
|
.PP
|
|
.I vmnewof
|
|
is a macro function that attempts to change the length of
|
|
the block pointed to by \fIaddr\fP to the size \f3n*sizeof(type)+x\fP.
|
|
If the block is moved, new space will be initialized with as much of the
|
|
old content as will fit.
|
|
Additional space will be set to zero.
|
|
.PP
|
|
.I vmoldof
|
|
is similar to \fIvmnewof\fP but it neither copies data nor clears space.
|
|
.PP
|
|
.I vmgetmem
|
|
provides a handy function to create/close regions and allocate/free memory
|
|
based on chunks of memory obtained from the heap region \fIVmheap\fP.
|
|
.TP
|
|
.MW "vmgetmem(0,0,0)"
|
|
This call opens a new region.
|
|
.TP
|
|
.MW "vmgetmem(region, 0, 0)"
|
|
This call closes the given \f3region\fP.
|
|
.TP
|
|
.MW "vmgetmem(region,0,n)"
|
|
This call allocates a block of length \f3n\fP and clears it to zeros.
|
|
.TP
|
|
.MW "vmgetmem(region,p,0)"
|
|
This call frees the block \f3p\fP.
|
|
.TP
|
|
.MW "vmgetmem(region,p,n)"
|
|
This call resizes the block \f3p\fP to length \f3n\fP
|
|
and clears the new memory to zeros if the block grows.
|
|
The block may be moved as deemed necessary by the allocator.
|
|
.PP
|
|
.SS "Memory disciplines"
|
|
Memory disciplines have type \f3Vmdisc_t\fP,
|
|
a structure with these members:
|
|
.in +.5i
|
|
.nf
|
|
.MW "Void_t* (*memoryf)(Vmalloc_t *region, Void_t* obj,"
|
|
.ti +.5i
|
|
.MW "size_t csz, size_t nsz, Vmdisc_t *disc);"
|
|
.MW "int (*exceptf)(Vmalloc_t *region, int type, Void_t* obj, Vmdisc_t *disc);"
|
|
.MW "int round;"
|
|
.fi
|
|
.in -.5i
|
|
.TP
|
|
.MW round
|
|
If this value is positive, all size arguments to the
|
|
\f3memoryf\fP function will be multiples of it.
|
|
.TP
|
|
.MW memoryf
|
|
Points to a function to get or release segments of space for the
|
|
\fIregion\fP.
|
|
.TP
|
|
.MW exceptf
|
|
If this pointer is not \f3NULL\fP,
|
|
the function it points to is called to announce
|
|
events in a \fIregion\fP.
|
|
.PP
|
|
There are two standard disciplines, both with \f3round\fP being 0 and \f3exceptf\fP being \f3NULL\fP.
|
|
.TP
|
|
.MW Vmdcsystem
|
|
A discipline whose \f3memoryf\fP function gets space from the operation system
|
|
via different available methods which include \fImmap(2)\fP, \fIsbrk(2)\fP and
|
|
functions from the WIN32 API.
|
|
For historical reason, \fIVmdcsbrk\fP is also available and functions like \fIVmdcsystem\fP.
|
|
.TP
|
|
.MW Vmdcheap
|
|
A discipline whose \f3memoryf\fP function gets space from the region \f3Vmheap\fP.
|
|
A region with \f3Vmdcheap\fP discipline and \f3Vmlast\fP
|
|
allocation is good for building throwaway data structures.
|
|
.PP
|
|
A \fImemoryf\fP
|
|
function returns a pointer to a memory segment on success, and \f3NULL\fP on failure.
|
|
When \fInsz >= 0\fP and \fIcsz > 0\fP,
|
|
the function first attempts to change the current segment \fIaddr\fP to fit \fInsz\fP
|
|
(for example, \fInsz == 0\fP means deleting the segment \fIaddr\fP).
|
|
If this attempt is successful, it should return \fIaddr\fP.
|
|
Otherwise, if \fInsz > csz\fP, the function may try to allocate a new segment
|
|
of size \fInsz-csz\fP. If successful, it should return the address of the new segment.
|
|
In all other cases, it should return NULL.
|
|
.PP
|
|
An \fIexceptf\fP
|
|
function is called for events identified by \fItype\fP, which is coded thus:
|
|
.TP
|
|
.MW VM_OPEN
|
|
This event is raised at the start of the process to open a new region.
|
|
Argument \fIobj\fP will be a pointer to an object of type \f3Void_t*\fP
|
|
initialized to NULL before the call. The return value of \fIexceptf\fP
|
|
is significant as follows:
|
|
|
|
On a negative return value, \fIvmopen\fP will terminate with failure.
|
|
|
|
On a zero return value, \fIexceptf\fP may set \f3*((Void_t**)obj)\fP
|
|
to some non-NULL value to tell \fIvmopen\fP
|
|
to allocate the region handle itself via \fImemoryf\fP. Otherwise,
|
|
the region handle will be allocated from the \f3Vmheap\fP region.
|
|
|
|
On a positive return value,
|
|
the new region is being reconstructed
|
|
based on existing states of some previous region.
|
|
In this case, \fIexceptf\fP should set \f3*(Void_t**)\fP\fIobj\fP to point to
|
|
the field \f3Vmalloc_t.data\fP of the corresponding previous region
|
|
(see \f3VM_CLOSE\fP below).
|
|
If the handle of the previous region was allocated
|
|
via \fImemoryf\fP as discussed above in the case of the zero return value,
|
|
then it will be exactly restored. Otherwise, a new handle will be allocated from \f3Vmheap\fP.
|
|
The ability to create regions sharing the same states allows for
|
|
managing shared and/or persistent memory.
|
|
.TP
|
|
.MW VM_ENDOPEN
|
|
This event is raised at the end of the process to open a new region.
|
|
The return value of \fIexceptf\fP will be ignored.
|
|
.TP
|
|
.MW VM_CLOSE
|
|
This event is raised at the start of the process to close a region,
|
|
The return value of \fIexceptf\fP is significant as follows:
|
|
|
|
On a negative return value, \fIvmclose\fP immediately returns with failure.
|
|
|
|
On a zero return value, \fIvmclose\fP proceeds normally by calling \f3memoryf\fP to free
|
|
all allocated memory segments and also freeing the region itself.
|
|
|
|
On a positive return value, \fIvmclose\fP will only free the region
|
|
without deallocating the associated memory segments. That is,
|
|
the field \fIVmalloc_t.data\fP of the region handle remains intact.
|
|
This is useful for managing shared and/or persistent memory (see \f3VM_OPEN\fP above).
|
|
.TP
|
|
.MW VM_ENDCLOSE
|
|
This event is raised at the end of the process to close a region.
|
|
The return value of \fIexceptf\fP will be ignored.
|
|
.TP
|
|
.MW VM_NOMEM
|
|
An attempt to extend the region by the amount
|
|
\f3(size_t)\fP\fIobj\fP failed. The region is unlocked, so the
|
|
\fIexceptf\fP function may free blocks.
|
|
If the function returns a positive value the memory
|
|
request will be repeated.
|
|
.TP
|
|
.MW VM_DISC
|
|
The discipline structure is being changed.
|
|
|
|
.SS "Allocation methods"
|
|
Methods are of type \f3Vmethod_t*\fP.
|
|
.TP
|
|
.MW Vmbest
|
|
An approximately best-fit allocation strategy.
|
|
.TP
|
|
.MW Vmlast
|
|
A strategy for building structures that are only deleted in whole.
|
|
Only the latest allocated block can be freed.
|
|
This means that as soon as a block \f3a\fP is allocated,
|
|
\fIvmfree\fP calls on blocks other than \c5a\fP are ignored.
|
|
.TP
|
|
.MW Vmpool
|
|
A strategy for blocks of one size,
|
|
set by the first \fIvmalloc\fP call after \fIvmopen\fP or \fIvmclear\fP.
|
|
.TP
|
|
.MW Vmdebug
|
|
An allocation strategy with extra-stringent checking and locking.
|
|
It is useful for finding misuses of dynamically allocated
|
|
memory, such as writing beyond the boundary of a block, or
|
|
freeing a block twice.
|
|
.ne 3
|
|
.TP
|
|
.MW Vmprofile
|
|
An allocation method that records and prints summaries of memory usage.
|
|
|
|
.SS Debugging
|
|
The method \f3Vmdebug\fP is used to debug common memory violation problems.
|
|
When a problem is found,
|
|
a warning message is written to file descriptor 2 (standard error).
|
|
In addition, if flag \f3VM_DBABORT\fP is on,
|
|
the program is terminated by calling \fIabort\fP(2).
|
|
Each message is a line of self-explanatory fields separated by colons.
|
|
The optional flag \f3-DVMFL\fP, if used during compilation,
|
|
enables recording of file names and line numbers.
|
|
The following functions work with method \f3Vmdebug\fP.
|
|
.PP
|
|
.I vmdebug
|
|
resets the file descriptor to write out warnings to the given argument.
|
|
By default, this file descriptor is 2, the standard error.
|
|
\fIvmdebug\fP returns the previous file descriptor.
|
|
.PP
|
|
.I vmdbcheck
|
|
checks a region using \f3Vmdebug\fP or \f3Vmbest\fP for integrity.
|
|
If \f3Vmdebug\fP, this also checks for block overwriting errors.
|
|
On errors, \fIvmdbwarn\fP is called.
|
|
If flag \f3VM_DBCHECK\fP is on,
|
|
\fIvmdbcheck\fP is called at each invocation of
|
|
\fIvmalloc\fP, \fIvmfree\fP, or \fIvmresize\fP.
|
|
.PP
|
|
.I vmdbwatch
|
|
causes address \fIaddr\fP
|
|
to be watched, and reported whenever met in
|
|
\fIvmalloc\fP, \fIvmresize\fP or \fIvmfree\fP.
|
|
The watch list has finite size and if it becomes full,
|
|
watches will be removed in a first-in-first-out fashion.
|
|
If \fIaddr\fP is \f3NULL\fP,
|
|
all current watches are canceled.
|
|
\fIvmdbwatch\fP returns the watch bumped out due to an insertion
|
|
into a full list or \f3NULL\fP otherwise.
|
|
.PP
|
|
.I vmdbwarn
|
|
is an internal function that processes
|
|
warning messages for discovered errors.
|
|
It can't be called from outside the \fIvmalloc\fP package,
|
|
but is a good place to plant debugger traps because
|
|
control goes there at every trouble.
|
|
|
|
.SS "Profiling"
|
|
The method \f3Vmprofile\fP is used to profile memory usage.
|
|
Profiling data are maintained in private memory of a process so
|
|
\f3Vmprofile\fP should be avoided from regions manipulating
|
|
persistent or shared memory.
|
|
The optional flag \f3-DVMFL\fP, if used during compilation,
|
|
enables recording of file names and line numbers.
|
|
.PP
|
|
.I vmprofile
|
|
prints memory usage summary.
|
|
The summary is restricted to region \fIvm\fP if \fIvm\fP is not \f3NULL\fP;
|
|
otherwise, it is for all regions created with \f3Vmprofile\fP.
|
|
Summary records are written to file descriptor \fIfd\fP as lines with
|
|
colon-separated fields. Here are some of the fields:
|
|
.TP
|
|
.I n_alloc,n_free:
|
|
Number of allocation and free calls respectively. Note that a resize
|
|
operation is coded as a free and an allocation.
|
|
.TP
|
|
.I s_alloc,s_free:
|
|
Total amounts allocated and freed. The difference between these numbers
|
|
is the amount of space not yet freed.
|
|
.TP
|
|
.I max_busy, extent:
|
|
These fields are only with the summary record for region.
|
|
They show the maximum busy space at any time and the extent of the region.
|
|
|
|
.SS "Information and statistics"
|
|
.I vmbusy
|
|
returns the busy status of a region.
|
|
A region is busy if some allocation operation is accessing it.
|
|
.PP
|
|
.I vmregion
|
|
returns the region to which the block pointed to by
|
|
\fIaddr\fP belongs.
|
|
This works only in regions that allocate with
|
|
\f3Vmbest\fP, \f3Vmdebug\fP or \f3Vmprofile\fP.
|
|
.PP
|
|
.I vmsegment
|
|
finds if some segment of memory in \fIregion\fP
|
|
contains the address \fIaddr\fP.
|
|
It returns the address of a found segment or \f3NULL\fP if none found.
|
|
.PP
|
|
.I vmwalk
|
|
walks all segments in \fIregion\fP or if \fIregion\fP is \f3NULL\fP,
|
|
all segments in all regions.
|
|
At each segment, \fI(*walkf)(vm,addr,size,disc)\fP
|
|
is called where \fIvm\fP is the region, \fIaddr\fP is the segment,
|
|
\fIsize\fP is the size of the segment, and \fIdisc\fP is the region's discipline.
|
|
If \fIwalkf\fP returns a negative value, the walk stops and returns the same value.
|
|
On success, \fIvmwalk\fP returns 0; otherwise, it returns \-1.
|
|
.PP
|
|
.I vmaddr
|
|
checks whether \fIaddr\fP
|
|
points to an address within some allocated block of the given region.
|
|
If not, it returns \-1.
|
|
If so, it returns the offset from the beginning of the block.
|
|
The function does not work for a \f3Vmlast\fP region except
|
|
on the latest allocated block.
|
|
.PP
|
|
.I vmsize
|
|
returns the size of the allocated block pointed to by \fIaddr\fP.
|
|
It returns \-1 if \fIaddr\fP
|
|
does not point to a valid block in the region.
|
|
Sizes may be padded beyond that requested; in
|
|
particular no block has size 0.
|
|
The function does not work for a \f3Vmlast\fP region except
|
|
on the latest allocated block.
|
|
.PP
|
|
.I vmstat
|
|
gathers statistics on the given \fIregion\fP.
|
|
If \f3region\fP is NULL, it computes statistics for the \fIMalloc\fP calls.
|
|
This may include summing statistics from more than one regions constructed to avoid blocking
|
|
due to parallel or asynchronous operations.
|
|
If \fIstatb\fP is not NULL, \fIvmstat\fP computes and stores the statistics in \fIstatb\fP then returns 0.
|
|
If \fIstatb\fP is NULL, no statistics will be computed and
|
|
the returned value is either 1 if the region is busy, i.e.,
|
|
being accessed by some allocation call or 0 otherwise.
|
|
|
|
A \f3Vmstat_t\fP structure has at least these members:
|
|
.in +.5i
|
|
.nf
|
|
.ta \w'\f3size_t \fP'u +\w'\f3extent \fP'u
|
|
.MW "int n_busy; /* # of busy blocks */
|
|
.MW "int n_free; /* # of free blocks */
|
|
.MW "size_t s_busy; /* total busy space */
|
|
.MW "size_t s_free; /* total free space */
|
|
.MW "size_t m_busy; /* maximum busy block size */
|
|
.MW "size_t m_free; /* maximum free block size */
|
|
.MW "int n_seg; /* count of segments */
|
|
.MW "size_t extent; /* memory extent of region */
|
|
.MW "int n_region; /* total Malloc regions */
|
|
.MW "int n_open; /* non-blocked operations */
|
|
.MW "int n_lock; /* blocked operations */
|
|
.MW "int n_probe; /* region searches */
|
|
.fi
|
|
.in -.5i
|
|
.PP
|
|
Bookkeeping overhead is counted in \f3extent\fP,
|
|
but not in \f3s_busy\fP or \f3s_free\fP.
|
|
.PP
|
|
.I vmtrace
|
|
establishes file descriptor \fIfd\fP
|
|
as the trace file and returns
|
|
the previous value of the trace file descriptor.
|
|
The trace descriptor is initially invalid.
|
|
Output is sent to the trace file by successful allocation
|
|
events when flag \f3VM_TRACE\fP is on.
|
|
.PP
|
|
Tools for analyzing traces are described in \fImtreplay\fP(1).
|
|
The trace record for an allocation event
|
|
is a line with colon-separated fields, four numbers and one string.
|
|
.TP
|
|
.I old
|
|
Zero for a fresh allocation;
|
|
the address argument for freeing and resizing.
|
|
.TP
|
|
.I new
|
|
Zero for freeing;
|
|
the address returned by allocation or resizing.
|
|
.TP
|
|
.I size
|
|
The size argument for allocation or resizing;
|
|
the size freed by freeing.
|
|
Sizes may differ due to padding for alignment.
|
|
.TP
|
|
.I region
|
|
The address of the affected region.
|
|
.TP
|
|
.I method
|
|
A string that tells the region's method:
|
|
\f3best\fP, \f3last\fP, \f3pool\fP, \f3profile\fP, or \f3debug\fP.
|
|
.PP
|
|
.I vmtrbusy
|
|
outputs a trace of all currently busy blocks in region \f3vm\fP.
|
|
This only works with the \f3Vmbest\fP, \f3Vmdebug\fP and \f3Vmprofile\fP methods.
|
|
.PP
|
|
.I vmdata
|
|
returns the core data of the given region.
|
|
The core data hold the data structures for allocated and free blocks.
|
|
Depending on the region discipline,
|
|
the core data of a region may be in shared or persistent memory even
|
|
if the region pointer created with \fIvmopen\fP is always in private process memory.
|
|
|
|
.SS "Malloc-compatible functions"
|
|
This set of functions implement \fImalloc\fP(3).
|
|
They allocate via the \fIVmregion\fP region which is initially set
|
|
to be \fIVmheap\fP.
|
|
|
|
Concurrent accesses are supported unless an application
|
|
change \fIVmregion\fP to something other than \fIVmheap\fP.
|
|
New regions may be created on the fly to avoid blocking.
|
|
The maximum number of regions that can be created
|
|
this way is set to 64 by default. An application could
|
|
reduce this number by calling \fIsetregmax(regmax)\fP to
|
|
set the maximum number of these extra regions to \fIregmax\fP.
|
|
\fIsetregmax()\fP always returns the previous value.
|
|
.PP
|
|
These functions are instrumented for run-time debugging, profiling and tracing.
|
|
For accurate reporting of files and line numbers,
|
|
application code should include \f3vmalloc.h\fP and compile with \f3-DVMFL\fP.
|
|
The \fBVMALLOC_OPTIONS\fP environment variable, checked once before the first
|
|
memory allocation, controls the memory allocation method, debugging and tracing;
|
|
its value is a comma or space separated list of
|
|
\fB[no]\fP\fIname\fP\fB[=\fP\fIvalue\fP\fB]\fP options.
|
|
The options are:
|
|
.TP
|
|
.B abort
|
|
If Vmregion==Vmdebug then VM_DBABORT is set, otherwise _BLD_DEBUG enabled assertions abort() on failure.
|
|
.TP
|
|
.B break
|
|
Try sbrk() block allocator first.
|
|
.TP
|
|
.B check
|
|
If Vmregion==Vmbest then the region is checked every op.
|
|
.TP
|
|
.B free
|
|
Disable addfreelist().
|
|
.TP
|
|
.B keep
|
|
Disable free -- if code works with this enabled then it probably accesses freed data.
|
|
.TP
|
|
.BI method= method
|
|
Sets Vmregion=\fImethod\fP if not defined, \fImethod\fP (Vm prefix optional) may be one of { \fBbest debug last profile\fP }.
|
|
.TP
|
|
.B mmap
|
|
Try mmap() block allocator first if
|
|
.B break
|
|
is not set.
|
|
.TP
|
|
.BI period= n
|
|
Sets Vmregion=Vmdebug if not defined, if Vmregion==Vmdebug the region is checked every \fIn\fP ops.
|
|
.TP
|
|
.BI profile= file
|
|
Sets Vmregion=Vmprofile if not set, if Vmregion==Vmprofile then profile info printed to file \fIfile\fP.
|
|
.TP
|
|
.BI start= n
|
|
Sets Vmregion=Vmdebug if not defined, if Vmregion==Vmdebug region checking starts after \fIn\fP ops.
|
|
.TP
|
|
.BI trace= file
|
|
Enables tracing to file \fIfile\fP.
|
|
.TP
|
|
.BI warn= file
|
|
Sets Vmregion=Vmdebug if not defined, if Vmregion==Vmdebug then warnings printed to file \fIfile\fP.
|
|
.TP
|
|
.BI watch= address
|
|
Sets Vmregion=Vmdebug if not defined, if Vmregion==Vmdebug then \fIaddress\fP is watched.
|
|
.P
|
|
Output files are created if they don't exist. \fB&\fP\fBn\fP and \fB/dev/fd/\fP\fIn\fP name
|
|
the file descriptor \fIn\fP which must be open for writing. The pattern \fB%p\fP
|
|
in a file name is replaced by the process ID.
|
|
.P
|
|
.B VMALLOC_OPTIONS
|
|
combines the features of these obsolete environment variables:
|
|
{ \fBVMCHECK VMDEBUG VMETHOD VMPROFILE VMTRACE\fP }.
|
|
|
|
.SH RECENT CHANGES
|
|
\f3Vmlast\fP: allocated blocks are now allowed to be resized (09/1998).
|
|
|
|
.SH SEE ALSO
|
|
\fImtreplay\fP(1), \fImalloc\fP(3).
|
|
|
|
.SH AUTHOR
|
|
Kiem-Phong Vo, kpv@research.att.com
|