/*
 * GC.h -- stubbed PCR; based on Mike Agostino's pseudo-PCR
 */

#ifndef ←P←GC←H
#define ←P←GC←H
#include "BasicTypes.h"
#include "Threads.h"
#include "../gc/gc.h"

/*
 * Finalizable Object structures and Finalization Queues:
 */

typedef struct XR←FinalizationQueueStructure {
    struct XR←FinalizableObjectStructure * head;
    struct XR←FinalizableObjectStructure * tail;
    struct XR←CVRep fqNonempty;
} * XR←FinalizationQueue;

typedef struct XR←FinalizableObjectStructure {
    unsigned long firstword;
    unsigned long secondword;
    XR←FinalizationQueue associatedFQ;
    struct XR←FinalizableObjectStructure *next;
} * XR←FinalizationHandle;

extern XR←FinalizationHandle GC←finalizeListHead;

#define XR←IsDisguised(h) ((h)->secondword != 0)

#define XR←FetchFromDisguised(h) ( ((h)->firstword) | ((h)->secondword << 16) )
#define XR←FetchFromUndisguised(h) ( (h)->firstword )

#define XR←StoreDisguised(w,h) { \
	(h)->firstword = ((unsigned long)(w)) & 0xffff; \
	(h)->secondword = (((unsigned long)(w)) >> 16) & 0xffff; \
	}
#define XR←StoreUndisguised(w,h) { \
	(h)->firstword = ((unsigned long)(w)); \
	(h)->secondword = 0; \
	}

typedef enum {
    fzsEnabled = 0,
    fzsOnFQ = 1,
    fzsDisabled = 2,
    fzsError = 0x7fffffff   /* force to 32 bits */
} XR←FinalizationState;



/* extern XR←Pointer
GC←malloc(unsigned ObjectSizeInBytes); */
/* Allocates a new object of at least the specified length. The object is
   cleared.  It will be aligned on at least a 4 byte boundary.  If the
   architecture requires n byte alignment for certain objects, then it will
   be n byte aligned unless the requested size is less than n.  If the
   requested size is a multiple of n, where n is a power of 2 no larger than
   16, then the object will also be n byte aligned.  No space is implicitly
   reserved for type tags or the like. Returns (XR←Pointer)0 if no memory
   is available.
   */

/* extern XR←Pointer
GC←malloc←atomic(unsigned ObjectSizeInBytes); */
/* Identical to GC←malloc, except that the object is assumed to contain no
   pointers, amd the object is not cleared.  Is faster than, and results in
   faster collections than GC←malloc.
   */


extern unsigned XR←GCHeapSize();
/* Size in bytes of garbage collected heap. */

extern unsigned XR←GCTotalByteCount();
/* Number of bytes allocated since the beginning of the world. */


/* This style of finalization cannot really be supported here.
 * The implementations look real, except that nothing ever gets finalized.
 */
 
 
extern XR←FinalizationState
XR←DisableFinalization(/* XR←FinalizationHandle h */);
/* Disable the object described by 'h' for finalization.  Return its
   prior XR←FinalizationState.  If it is already on a finalize q, remote it.
   */

extern XR←FinalizationState
XR←ReenableFinalization(/* XR←FinalizationHandle h;XR←FinalizationQueue fq */);
/* Causes an object which was once finalizable to be so again, now
   on queue 'fq'.  If it is on some other queue, it is removed first.
   Prior state is returned.
   */

extern void
XR←EnableFinalization(/* XR←Pointer object;
             XR←FinalizationQueue fq;
             XR←FinalizationHandle h */);
/* Cause the object to be enabled for finalization.
   'h' is updated to describe the object.  When the time comes,
   fq will be the finalization queue on which the object is placed.
   */

extern bool
XR←FQEmpty(/* XR←FinalizationQueue fq */);

extern XR←FinalizationHandle
XR←NewFinalizationHandle();
/* return a new, empty, initialized handle for an object to be finalized. */

extern XR←FinalizationHandle
XR←FQNextNoAbort(/* XR←FinalizationQueue fq */);
/* return the next handle on queue 'fq', waiting on a condition variable
   until there is an item if necessary.  If there is no item, or the
   wait is interrupted, return NIL */

extern XR←FinalizationState
XR←GetFinalizationState(/* XR←FinalizationHandle h */);
/* get the finalization state of the object */

extern XR←Pointer
XR←HandleToObject(/* XR←FinalizationHandle h */);
/* Get the pointer to the real object, given its handle */

extern XR←FinalizationQueue
XR←NewFQ();
/* return a new, empty, initialized finalization queue. */

extern void
XR←GCollect();
/* initiate a garbage collection. */

#endif ←P←GC←H