\section{Isomalloc}

It is occasionally useful to allocate memory at a globally unique
virtual address.  This is trivial on a shared memory machine
(where every address is globally unique); but more difficult on
a distributed memory machine (where each node has its own separate data
at address 0x80000000).
Isomalloc provides a uniform interface for allocating globally unique
virtual addresses.

Isomalloc can thus be thought of as a software distributed shared
memory implementation; except data movement between
processors is explicit (by making a subroutine call), not on demand
(by taking a page fault).

Isomalloc is useful when moving highly interlinked data structures
from one processor to another, because internal pointers will still
point to the correct locations, even on a new processor.  This is especially
useful when the format of the data structure is complex or unknown, as with
thread stacks.

\function{void *CmiIsomalloc(int size)}
\index{CmiIsomalloc}
\desc{Allocate size bytes at a unique virtual address.  Returns
a pointer to the allocated region.

CmiIsomalloc makes allocations with page granularity (typically several
kilobytes); so it is not recommended for small allocations.
}

\function{void CmiIsomallocFree(void *doomedBlock)}
\index{CmiIsomallocFree}
\desc{Release the given block, which must have been previously
returned by CmiIsomalloc.  Also releases the used virtual
address range, which the system may subsequently reuse.

After a CmiIsomallocFree, references to that block will 
likely result in a segmentation violation.  It is illegal to
call CmiIsomallocFree more than once on the same block.
}

\function{void CmiIsomallocPup(pup\_er p,void **block)}
\index{CmiIsomallocPup}
\desc{Pack/Unpack the given block.  This routine can be used to move
blocks across processors, save blocks to disk, or checkpoint blocks.

After unpacking, the pointer is guaranteed
to have the same value that it did before packing.
}

Note- Use of this function to pup individual blocks is not supported any longer.
All the blocks allocated via CmiIsomalloc are pupped by the RTS as one single
unit.

\function{int CmiIsomallocLength(void *block);}
\index{CmiIsomallocLength}
\desc{
Return the length, in bytes, of this isomalloc'd block.
}

\function{int CmiIsomallocInRange(void *address)}
\index{CmiIsomallocInRange}
\desc{Return 1 if the given address may have been previously allocated to 
this processor using Isomalloc; 0 otherwise.  CmiIsomallocInRange(malloc(size))
is guaranteed to be zero; CmiIsomallocInRange(CmiIsomalloc(size))
is guaranteed to be one.
}
