/*
Copyright (c) 1993 Xerox Corporation.  All rights reserved.
*/
/*
$Id$

$Date$
 *
 * PCR Memory Management public interface
 */
/* Chauser, October 28, 1993 4:22 pm PDT */

#ifndef ←←PCR←MM←h
#define ←←PCR←MM←h 1

#include <config/PCR←StdTypes.h>
#include <stddef.h>

/*
 * A simple replace-able memory manager interface
 *
 * This is not *really* object oriented,
 *   since the procs in an object must share state covertly.
 *
 * Implementations are expected to use the POSIX system-provided
 *   malloc/calloc to allocate their own heap space.
 *
 * Clients (wizards excepted) are expected *never* to use 
 *   malloc/calloc/realloc/free directly.
 */


typedef void * ((PCR←MM←AllocProc)(
        size←t size, PCR←Bool ptrFree, PCR←Bool clear ));
/*
    Allocate memory.
    The ptrFree flag is a hint that says it's okay for a GC
      to not trace through the object.
    The clear argument causes the allocated area to be initialized to zeroes.
*/

typedef void * ((PCR←MM←ReallocProc)(void *p, size←t size));
/*
    Grow / shrink object p, as in the standard C library routine.
    The ptrFree property is preserved.
*/

typedef void ((PCR←MM←FreeProc)(void *p));
/*
    Explicit free.
*/


typedef PCR←ERes ((PCR←MM←EnumerateProc)(
    PCR←Bool ptrFree,
    PCR←ERes (*proc)(void *p, size←t size, PCR←Any data),
    PCR←Any data
));
/*
    Enumerate all currently allocated pointer-containing
      (if ptrFree is false) or pointer-free (if ptrFree is true)
      objects.
    The ptrFree characterization is just a hint -- a conservative
      system is free to ignore it and treat all objects as
      pointer-containing.
    Enumeration is terminated if proc returns error.
    
*/



typedef void ((PCR←MM←ShutdownProc)(void));
/*
    Terminate any currently running daemons (e.g GC).
    Calls to allocate/free and enumeration procs are still legitimate
      but will not restart any daemons or cause garbage collections.
    This is called automatically by PCR←MM←Install() below.
*/


extern unsigned long PCR←MM←defaultMagic;

struct PCR←MM←ProcsRep {
    unsigned long mmp←magic;
    PCR←MM←AllocProc *mmp←alloc;
    PCR←MM←ReallocProc *mmp←realloc;
    PCR←MM←FreeProc *mmp←free;
    PCR←MM←FreeProc *mmp←unsafeFree;
    PCR←MM←EnumerateProc *mmp←enumerate;
    PCR←MM←ShutdownProc *mmp←shutdown;
};

typedef struct PCR←MM←ProcsRep PCR←MM←Procs;


extern PCR←MM←Procs * volatile PCR←MM←installedProcs;

extern void
PCR←MM←Install(PCR←MM←Procs *self, PCR←MM←Procs **prev);
/*
    Atomically
      call shutdown proc of previous implementation,
      store previous implementation into *prev
      install self
    No calls to new implementation are performed until
      previous one has been shut down and copied to *prev. 
*/

/*
 * C clients may use the following sugared names:
 *
 * For allocation:
 *   (*(PCR←MM←installedProcs->mmp←alloc))(sz, ptrFree, clear)
 *   PCR←MM←Alloc(sz, ptrFree, clear)
 *
 *   malloc(sz) -- renamed in posix hdr file
 *   PCR←malloc(sz)
 *   PCR←MM←Malloc(sz)
 *
 * etc.
 */


extern void * (PCR←MM←Alloc(size←t size, PCR←Bool ptrFree, PCR←Bool clear));
#   define PCR←MM←Alloc(sz,pf,cl) \
	(*(PCR←MM←installedProcs->mmp←alloc))((sz), (pf), (cl))


extern void * (PCR←MM←New(size←t size));
#   define PCR←MM←New(sz) \
	(*(PCR←MM←installedProcs->mmp←alloc))( \
		(sz), PCR←Bool←false, PCR←Bool←true )


extern void * (PCR←MM←Malloc(size←t size));
#   define PCR←MM←Malloc(sz) \
	(*(PCR←MM←installedProcs->mmp←alloc))( \
		(sz), PCR←Bool←false, PCR←Bool←false )


extern void * (PCR←MM←Realloc(void *p, size←t size));
#   define PCR←MM←Realloc(p,sz) \
	(*(PCR←MM←installedProcs->mmp←realloc))((p), (sz))


extern void (PCR←MM←Free(void *p));
#   define PCR←MM←Free(p) \
	(*(PCR←MM←installedProcs->mmp←free))(p)


extern void (PCR←MM←UnsafeFree(void *p));
#   define PCR←MM←UnsafeFree(p) \
	(*(PCR←MM←installedProcs->mmp←unsafeFree))(p)


extern PCR←ERes (PCR←MM←Enumerate(
    PCR←Bool ptrFree,
    PCR←ERes (*proc)(void *p, size←t size, PCR←Any data),
    PCR←Any data
));
#   define PCR←MM←Enumerate(pf,proc,data) \
	(*(PCR←MM←installedProcs->mmp←enumerate))((pf), (proc), (data))


#endif /* ! ←←PCR←MM←h */
/*
$Log$
*/